From 3f565cb6b3626411b3bc078515891123a0f160d8 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Wed, 2 Feb 2022 02:21:07 +0500 Subject: [PATCH] :recycle: Added dependencies helper in delivery layer tests --- internal/auth/delivery/http/auth_http_test.go | 77 ++++++++----- .../client/delivery/http/client_http_test.go | 62 ++++++++--- .../health/delivery/http/health_http_test.go | 10 +- .../ticket/delivery/http/ticket_http_test.go | 91 ++++++++++------ .../token/delivery/http/token_http_test.go | 101 ++++++++++-------- 5 files changed, 217 insertions(+), 124 deletions(-) diff --git a/internal/auth/delivery/http/auth_http_test.go b/internal/auth/delivery/http/auth_http_test.go index 2670e1e..5cd15e8 100644 --- a/internal/auth/delivery/http/auth_http_test.go +++ b/internal/auth/delivery/http/auth_http_test.go @@ -7,58 +7,55 @@ import ( "testing" "github.com/fasthttp/router" - "github.com/fasthttp/session/v2" - "github.com/fasthttp/session/v2/providers/memory" http "github.com/valyala/fasthttp" "golang.org/x/text/language" "golang.org/x/text/message" + "source.toby3d.me/website/indieauth/internal/auth" delivery "source.toby3d.me/website/indieauth/internal/auth/delivery/http" ucase "source.toby3d.me/website/indieauth/internal/auth/usecase" + "source.toby3d.me/website/indieauth/internal/client" clientrepo "source.toby3d.me/website/indieauth/internal/client/repository/memory" clientucase "source.toby3d.me/website/indieauth/internal/client/usecase" "source.toby3d.me/website/indieauth/internal/domain" profilerepo "source.toby3d.me/website/indieauth/internal/profile/repository/memory" + "source.toby3d.me/website/indieauth/internal/session" sessionrepo "source.toby3d.me/website/indieauth/internal/session/repository/memory" "source.toby3d.me/website/indieauth/internal/testing/httptest" userrepo "source.toby3d.me/website/indieauth/internal/user/repository/memory" ) -//nolint: funlen +type dependencies struct { + authService auth.UseCase + clients client.Repository + clientService client.UseCase + config *domain.Config + matcher language.Matcher + sessions session.Repository + store *sync.Map +} + func TestRender(t *testing.T) { t.Parallel() - provider, err := memory.New(memory.Config{}) - if err != nil { - t.Fatal(err) - } - - s := session.New(session.NewDefaultConfig()) - if err = s.SetProvider(provider); err != nil { - t.Fatal(err) - } - + deps := NewDependencies(t) me := domain.TestMe(t, "https://user.example.net") - client := domain.TestClient(t) - config := domain.TestConfig(t) - store := new(sync.Map) user := domain.TestUser(t) - store.Store(path.Join(userrepo.DefaultPathPrefix, me.String()), user) - store.Store(path.Join(clientrepo.DefaultPathPrefix, client.ID.String()), client) - store.Store(path.Join(profilerepo.DefaultPathPrefix, me.String()), user.Profile) + client := domain.TestClient(t) - router := router.New() + deps.store.Store(path.Join(clientrepo.DefaultPathPrefix, client.ID.String()), client) + deps.store.Store(path.Join(profilerepo.DefaultPathPrefix, me.String()), user.Profile) + deps.store.Store(path.Join(userrepo.DefaultPathPrefix, me.String()), user) + + r := router.New() delivery.NewRequestHandler(delivery.NewRequestHandlerOptions{ - Clients: clientucase.NewClientUseCase(clientrepo.NewMemoryClientRepository(store)), - Config: config, - Matcher: language.NewMatcher(message.DefaultCatalog.Languages()), - Auth: ucase.NewAuthUseCase( - sessionrepo.NewMemorySessionRepository(config, store), - config, - ), - }).Register(router) + Auth: deps.authService, + Clients: deps.clientService, + Config: deps.config, + Matcher: deps.matcher, + }).Register(r) - httpClient, _, cleanup := httptest.New(t, router.Handler) + httpClient, _, cleanup := httptest.New(t, r.Handler) t.Cleanup(cleanup) uri := http.AcquireURI() @@ -97,3 +94,25 @@ func TestRender(t *testing.T) { t.Errorf("GET %s = %s, want %s", uri.String(), result, expResult) } } + +func NewDependencies(tb testing.TB) dependencies { + tb.Helper() + + config := domain.TestConfig(tb) + matcher := language.NewMatcher(message.DefaultCatalog.Languages()) + store := new(sync.Map) + clients := clientrepo.NewMemoryClientRepository(store) + sessions := sessionrepo.NewMemorySessionRepository(config, store) + authService := ucase.NewAuthUseCase(sessions, config) + clientService := clientucase.NewClientUseCase(clients) + + return dependencies{ + authService: authService, + clients: clients, + clientService: clientService, + config: config, + matcher: matcher, + sessions: sessions, + store: store, + } +} diff --git a/internal/client/delivery/http/client_http_test.go b/internal/client/delivery/http/client_http_test.go index 0af099a..3301e96 100644 --- a/internal/client/delivery/http/client_http_test.go +++ b/internal/client/delivery/http/client_http_test.go @@ -11,37 +11,47 @@ import ( delivery "source.toby3d.me/website/indieauth/internal/client/delivery/http" "source.toby3d.me/website/indieauth/internal/domain" + "source.toby3d.me/website/indieauth/internal/session" sessionrepo "source.toby3d.me/website/indieauth/internal/session/repository/memory" "source.toby3d.me/website/indieauth/internal/testing/httptest" + "source.toby3d.me/website/indieauth/internal/token" tokenrepo "source.toby3d.me/website/indieauth/internal/token/repository/memory" tokenucase "source.toby3d.me/website/indieauth/internal/token/usecase" ) +type dependencies struct { + client *domain.Client + config *domain.Config + matcher language.Matcher + sessions session.Repository + store *sync.Map + tokens token.Repository + tokenService token.UseCase +} + func TestRead(t *testing.T) { t.Parallel() - store := new(sync.Map) - config := domain.TestConfig(t) + deps := NewDependencies(t) - router := router.New() + r := router.New() delivery.NewRequestHandler(delivery.NewRequestHandlerOptions{ - Client: domain.TestClient(t), - Config: config, - Matcher: language.NewMatcher(message.DefaultCatalog.Languages()), - Tokens: tokenucase.NewTokenUseCase(tokenrepo.NewMemoryTokenRepository(store), - sessionrepo.NewMemorySessionRepository(config, store), config), - }).Register(router) + Client: deps.client, + Config: deps.config, + Matcher: deps.matcher, + Tokens: deps.tokenService, + }).Register(r) - client, _, cleanup := httptest.New(t, router.Handler) + client, _, cleanup := httptest.New(t, r.Handler) t.Cleanup(cleanup) const requestURI string = "https://app.example.com/" + req, resp := httptest.NewRequest(http.MethodGet, requestURI, nil), http.AcquireResponse() - req := httptest.NewRequest(http.MethodGet, requestURI, nil) - defer http.ReleaseRequest(req) - - resp := http.AcquireResponse() - defer http.ReleaseResponse(resp) + t.Cleanup(func() { + http.ReleaseRequest(req) + http.ReleaseResponse(resp) + }) if err := client.Do(req, resp); err != nil { t.Error(err) @@ -51,3 +61,25 @@ func TestRead(t *testing.T) { t.Errorf("GET %s = %d, want %d", requestURI, resp.StatusCode(), http.StatusOK) } } + +func NewDependencies(tb testing.TB) dependencies { + tb.Helper() + + client := domain.TestClient(tb) + config := domain.TestConfig(tb) + matcher := language.NewMatcher(message.DefaultCatalog.Languages()) + store := new(sync.Map) + sessions := sessionrepo.NewMemorySessionRepository(config, store) + tokens := tokenrepo.NewMemoryTokenRepository(store) + tokenService := tokenucase.NewTokenUseCase(tokens, sessions, config) + + return dependencies{ + client: client, + config: config, + matcher: matcher, + sessions: sessions, + store: store, + tokens: tokens, + tokenService: tokenService, + } +} diff --git a/internal/health/delivery/http/health_http_test.go b/internal/health/delivery/http/health_http_test.go index 82b4203..6c38905 100644 --- a/internal/health/delivery/http/health_http_test.go +++ b/internal/health/delivery/http/health_http_test.go @@ -20,12 +20,12 @@ func TestRequestHandler(t *testing.T) { t.Cleanup(cleanup) const requestURL = "https://app.example.com/health" + req, resp := httptest.NewRequest(http.MethodGet, requestURL, nil), http.AcquireResponse() - req := httptest.NewRequest(http.MethodGet, requestURL, nil) - defer http.ReleaseRequest(req) - - resp := http.AcquireResponse() - defer http.ReleaseResponse(resp) + t.Cleanup(func() { + http.ReleaseRequest(req) + http.ReleaseResponse(resp) + }) if err := client.Do(req, resp); err != nil { t.Fatal(err) diff --git a/internal/ticket/delivery/http/ticket_http_test.go b/internal/ticket/delivery/http/ticket_http_test.go index c119178..f9c1fa4 100644 --- a/internal/ticket/delivery/http/ticket_http_test.go +++ b/internal/ticket/delivery/http/ticket_http_test.go @@ -12,44 +12,30 @@ import ( "source.toby3d.me/website/indieauth/internal/common" "source.toby3d.me/website/indieauth/internal/domain" "source.toby3d.me/website/indieauth/internal/testing/httptest" + "source.toby3d.me/website/indieauth/internal/ticket" delivery "source.toby3d.me/website/indieauth/internal/ticket/delivery/http" ticketrepo "source.toby3d.me/website/indieauth/internal/ticket/repository/memory" ucase "source.toby3d.me/website/indieauth/internal/ticket/usecase" ) +type dependencies struct { + client *http.Client + config *domain.Config + matcher language.Matcher + store *sync.Map + ticket *domain.Ticket + tickets ticket.Repository + ticketService ticket.UseCase + token *domain.Token +} + func TestUpdate(t *testing.T) { t.Parallel() - config := domain.TestConfig(t) - ticket := domain.TestTicket(t) - token := domain.TestToken(t) - - userRouter := router.New() - // NOTE(toby3d): private resource - userRouter.GET(ticket.Resource.URL().EscapedPath(), func(ctx *http.RequestCtx) { - ctx.SuccessString( - common.MIMETextHTMLCharsetUTF8, - ``, - ) - }) - // NOTE(toby3d): token endpoint - userRouter.POST("/token", func(ctx *http.RequestCtx) { - ctx.SuccessString(common.MIMEApplicationJSONCharsetUTF8, `{ - "access_token": "`+token.AccessToken+`", - "me": "`+token.Me.String()+`", - "scope": "`+token.Scope.String()+`", - "token_type": "Bearer" - }`) - }) - - userClient, _, userCleanup := httptest.New(t, userRouter.Handler) - t.Cleanup(userCleanup) + deps := NewDependencies(t) r := router.New() - delivery.NewRequestHandler( - ucase.NewTicketUseCase(ticketrepo.NewMemoryTicketRepository(new(sync.Map), config), userClient, config), - language.NewMatcher(message.DefaultCatalog.Languages()), config, - ).Register(r) + delivery.NewRequestHandler(deps.ticketService, deps.matcher, deps.config).Register(r) client, _, cleanup := httptest.New(t, r.Handler) t.Cleanup(cleanup) @@ -57,9 +43,9 @@ func TestUpdate(t *testing.T) { const requestURI string = "https://example.com/ticket" req := httptest.NewRequest(http.MethodPost, requestURI, []byte( - `ticket=`+ticket.Ticket+ - `&resource=`+ticket.Resource.String()+ - `&subject=`+ticket.Subject.String(), + `ticket=`+deps.ticket.Ticket+ + `&resource=`+deps.ticket.Resource.String()+ + `&subject=`+deps.ticket.Subject.String(), )) defer http.ReleaseRequest(req) req.Header.SetContentType(common.MIMEApplicationForm) @@ -83,3 +69,46 @@ func TestUpdate(t *testing.T) { t.Errorf("POST %s = nil, want something", requestURI) } } + +func NewDependencies(tb testing.TB) dependencies { + tb.Helper() + + config := domain.TestConfig(tb) + matcher := language.NewMatcher(message.DefaultCatalog.Languages()) + store := new(sync.Map) + ticket := domain.TestTicket(tb) + token := domain.TestToken(tb) + + r := router.New() + // NOTE(toby3d): private resource + r.GET(ticket.Resource.URL().EscapedPath(), func(ctx *http.RequestCtx) { + ctx.SuccessString(common.MIMETextHTMLCharsetUTF8, + ``) + }) + // NOTE(toby3d): token endpoint + r.POST("/token", func(ctx *http.RequestCtx) { + ctx.SuccessString(common.MIMEApplicationJSONCharsetUTF8, `{ + "access_token": "`+token.AccessToken+`", + "me": "`+token.Me.String()+`", + "scope": "`+token.Scope.String()+`", + "token_type": "Bearer" + }`) + }) + + client, _, cleanup := httptest.New(tb, r.Handler) + tb.Cleanup(cleanup) + + tickets := ticketrepo.NewMemoryTicketRepository(store, config) + ticketService := ucase.NewTicketUseCase(tickets, client, config) + + return dependencies{ + client: client, + config: config, + matcher: matcher, + store: store, + ticket: ticket, + tickets: tickets, + ticketService: ticketService, + token: token, + } +} diff --git a/internal/token/delivery/http/token_http_test.go b/internal/token/delivery/http/token_http_test.go index 07b5df3..8dee715 100644 --- a/internal/token/delivery/http/token_http_test.go +++ b/internal/token/delivery/http/token_http_test.go @@ -12,15 +12,30 @@ import ( "source.toby3d.me/website/indieauth/internal/common" "source.toby3d.me/website/indieauth/internal/domain" + "source.toby3d.me/website/indieauth/internal/session" sessionrepo "source.toby3d.me/website/indieauth/internal/session/repository/memory" "source.toby3d.me/website/indieauth/internal/testing/httptest" + "source.toby3d.me/website/indieauth/internal/ticket" ticketrepo "source.toby3d.me/website/indieauth/internal/ticket/repository/memory" ticketucase "source.toby3d.me/website/indieauth/internal/ticket/usecase" + "source.toby3d.me/website/indieauth/internal/token" delivery "source.toby3d.me/website/indieauth/internal/token/delivery/http" tokenrepo "source.toby3d.me/website/indieauth/internal/token/repository/memory" tokenucase "source.toby3d.me/website/indieauth/internal/token/usecase" ) +type dependencies struct { + client *http.Client + config *domain.Config + sessions session.Repository + store *sync.Map + tickets ticket.Repository + ticketService ticket.UseCase + token *domain.Token + tokens token.Repository + tokenService token.UseCase +} + /* TODO(toby3d) func TestExchange(t *testing.T) { t.Parallel() @@ -30,24 +45,10 @@ func TestExchange(t *testing.T) { func TestVerification(t *testing.T) { t.Parallel() - store := new(sync.Map) - config := domain.TestConfig(t) - token := domain.TestToken(t) + deps := NewDependencies(t) router := router.New() - // TODO(toby3d): provide tickets - delivery.NewRequestHandler( - tokenucase.NewTokenUseCase( - tokenrepo.NewMemoryTokenRepository(store), - sessionrepo.NewMemorySessionRepository(config, store), - config, - ), - ticketucase.NewTicketUseCase( - ticketrepo.NewMemoryTicketRepository(store, config), - new(http.Client), - config, - ), - ).Register(router) + delivery.NewRequestHandler(deps.tokenService, deps.ticketService).Register(router) client, _, cleanup := httptest.New(t, router.Handler) t.Cleanup(cleanup) @@ -57,7 +58,7 @@ func TestVerification(t *testing.T) { req := httptest.NewRequest(http.MethodGet, requestURL, nil) defer http.ReleaseRequest(req) req.Header.Set(http.HeaderAccept, common.MIMEApplicationJSON) - token.SetAuthHeader(req) + deps.token.SetAuthHeader(req) resp := http.AcquireResponse() defer http.ReleaseResponse(resp) @@ -75,38 +76,24 @@ func TestVerification(t *testing.T) { t.Fatal(err) } - token.AccessToken = "" + deps.token.AccessToken = "" - if result.ClientID.String() != token.ClientID.String() || - result.Me.String() != token.Me.String() || - result.Scope.String() != token.Scope.String() { - t.Errorf("GET %s = %+v, want %+v", requestURL, result, token) + if result.ClientID.String() != deps.token.ClientID.String() || + result.Me.String() != deps.token.Me.String() || + result.Scope.String() != deps.token.Scope.String() { + t.Errorf("GET %s = %+v, want %+v", requestURL, result, deps.token) } } func TestRevocation(t *testing.T) { t.Parallel() - config := domain.TestConfig(t) - store := new(sync.Map) - tokens := tokenrepo.NewMemoryTokenRepository(store) - accessToken := domain.TestToken(t) + deps := NewDependencies(t) - router := router.New() - delivery.NewRequestHandler( - tokenucase.NewTokenUseCase( - tokens, - sessionrepo.NewMemorySessionRepository(config, store), - config, - ), - ticketucase.NewTicketUseCase( - ticketrepo.NewMemoryTicketRepository(store, config), - new(http.Client), - config, - ), - ).Register(router) + r := router.New() + delivery.NewRequestHandler(deps.tokenService, deps.ticketService).Register(r) - client, _, cleanup := httptest.New(t, router.Handler) + client, _, cleanup := httptest.New(t, r.Handler) t.Cleanup(cleanup) const requestURL = "https://app.example.com/token" @@ -116,7 +103,7 @@ func TestRevocation(t *testing.T) { req.Header.Set(http.HeaderAccept, common.MIMEApplicationJSON) req.Header.SetContentType(common.MIMEApplicationForm) req.PostArgs().Set("action", domain.ActionRevoke.String()) - req.PostArgs().Set("token", accessToken.AccessToken) + req.PostArgs().Set("token", deps.token.AccessToken) resp := http.AcquireResponse() defer http.ReleaseResponse(resp) @@ -134,12 +121,38 @@ func TestRevocation(t *testing.T) { t.Errorf("POST %s = %s, want %s", requestURL, result, expBody) } - result, err := tokens.Get(context.TODO(), accessToken.AccessToken) + result, err := deps.tokens.Get(context.TODO(), deps.token.AccessToken) if err != nil { t.Fatal(err) } - if result.String() != accessToken.String() { - t.Errorf("Get(%+v) = %s, want %s", accessToken.AccessToken, result, accessToken) + if result.String() != deps.token.String() { + t.Errorf("Get(%+v) = %s, want %s", deps.token.AccessToken, result, deps.token) + } +} + +func NewDependencies(tb testing.TB) dependencies { + tb.Helper() + + client := new(http.Client) + config := domain.TestConfig(tb) + store := new(sync.Map) + token := domain.TestToken(tb) + sessions := sessionrepo.NewMemorySessionRepository(config, store) + tickets := ticketrepo.NewMemoryTicketRepository(store, config) + tokens := tokenrepo.NewMemoryTokenRepository(store) + ticketService := ticketucase.NewTicketUseCase(tickets, client, config) + tokenService := tokenucase.NewTokenUseCase(tokens, sessions, config) + + return dependencies{ + client: client, + config: config, + sessions: sessions, + store: store, + tickets: tickets, + ticketService: ticketService, + token: token, + tokens: tokens, + tokenService: tokenService, } }