diff --git a/pkg/controller/apikey/create_test.go b/pkg/controller/apikey/create_test.go index 2406039f7..9f8df1050 100644 --- a/pkg/controller/apikey/create_test.go +++ b/pkg/controller/apikey/create_test.go @@ -15,25 +15,19 @@ package apikey_test import ( - "context" + "fmt" "net/http" - "net/http/httptest" "net/url" - "strconv" "strings" "testing" - "github.com/chromedp/chromedp" - "github.com/gorilla/sessions" - - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" + "github.com/gorilla/sessions" ) func TestHandleCreate(t *testing.T) { @@ -46,23 +40,14 @@ func TestHandleCreate(t *testing.T) { if err != nil { t.Fatal(err) } + ctx = controller.WithSession(ctx, session) - cookie, err := harness.SessionCookie(session) - if err != nil { - t.Fatal(err) - } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := c.HandleCreate() t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleCreate() - envstest.ExerciseSessionMissing(t, handler) envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) @@ -71,76 +56,41 @@ func TestHandleCreate(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) handler := c.HandleCreate() ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(url.Values{ + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPost, "/", &url.Values{ "name": []string{"banana"}, "type": []string{"1"}, - }.Encode())) - r = r.Clone(ctx) - r.Header.Set("Accept", "text/html") - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - w := httptest.NewRecorder() - + }) handler.ServeHTTP(w, r) - w.Flush() if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) t.Run("validation", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleCreate() - ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(url.Values{ + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPost, "/", &url.Values{ "type": []string{"-1"}, - }.Encode())) - r = r.Clone(ctx) - r.Header.Set("Accept", "text/html") - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - w := httptest.NewRecorder() - + }) handler.ServeHTTP(w, r) - w.Flush() if got, want := w.Code, http.StatusUnprocessableEntity; got != want { t.Errorf("Expected %d to be %d", got, want) @@ -150,27 +100,32 @@ func TestHandleCreate(t *testing.T) { } }) - t.Run("creates", func(t *testing.T) { + t.Run("success", func(t *testing.T) { t.Parallel() - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() + session := &sessions.Session{} - var apiKey string - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(`http://`+harness.Server.Addr()+`/realm/apikeys/new`), - chromedp.WaitVisible(`body#apikeys-new`, chromedp.ByQuery), + ctx := ctx + ctx = controller.WithSession(ctx, session) + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyWrite, + }) + + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPost, "/", &url.Values{ + "name": []string{"Test API key"}, + "type": []string{fmt.Sprintf("%d", database.APIKeyTypeDevice)}, + }) + handler.ServeHTTP(w, r) - chromedp.SetValue(`input#name`, "Example API key", chromedp.ByQuery), - chromedp.SetValue(`select#type`, strconv.Itoa(int(database.APIKeyTypeDevice)), chromedp.ByQuery), - chromedp.Click(`#submit`, chromedp.ByQuery), + if got, want := w.Code, http.StatusSeeOther; got != want { + t.Errorf("Expected %d to be %d", got, want) + } - chromedp.WaitVisible(`body#apikeys-show`, chromedp.ByQuery), - chromedp.Value(`#apikey-value`, &apiKey, chromedp.ByQuery), - ); err != nil { - t.Fatal(err) + apiKey, ok := session.Values["apiKey"].(string) + if !ok { + t.Fatalf("expected apiKey in session: %#v", session.Values) } // Ensure API key is valid. @@ -182,7 +137,7 @@ func TestHandleCreate(t *testing.T) { if got, want := record.RealmID, realm.ID; got != want { t.Errorf("expected %v to be %v", got, want) } - if got, want := record.Name, "Example API key"; got != want { + if got, want := record.Name, "Test API key"; got != want { t.Errorf("expected %v to be %v", got, want) } if got, want := record.APIKeyType, database.APIKeyTypeDevice; got != want { diff --git a/pkg/controller/apikey/disable_test.go b/pkg/controller/apikey/disable_test.go index f6191176b..ff24cc3ec 100644 --- a/pkg/controller/apikey/disable_test.go +++ b/pkg/controller/apikey/disable_test.go @@ -15,24 +15,17 @@ package apikey_test import ( - "context" "fmt" "net/http" - "net/http/httptest" - "strings" "testing" - "github.com/chromedp/chromedp" - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" "github.com/gorilla/mux" - "github.com/gorilla/sessions" ) func TestHandleDisable(t *testing.T) { @@ -45,30 +38,22 @@ func TestHandleDisable(t *testing.T) { if err != nil { t.Fatal(err) } + ctx = controller.WithSession(ctx, session) authApp := &database.AuthorizedApp{ RealmID: realm.ID, - Name: "Disables app", + Name: "Appy", } if _, err := realm.CreateAuthorizedApp(harness.Database, authApp, database.SystemTest); err != nil { t.Fatal(err) } - cookie, err := harness.SessionCookie(session) - if err != nil { - t.Fatal(err) - } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := c.HandleDisable() t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleDisable() - envstest.ExerciseSessionMissing(t, handler) envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) @@ -82,68 +67,41 @@ func TestHandleDisable(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - - mux := mux.NewRouter() - mux.Handle("/{id}", c.HandleDisable()).Methods(http.MethodPut) + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) + handler := c.HandleDisable() ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPut, "/1", nil) - r = r.Clone(ctx) - r.Header.Set("Content-Type", "text/html") - - w := httptest.NewRecorder() - - mux.ServeHTTP(w, r) - w.Flush() + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) - t.Run("disables", func(t *testing.T) { + t.Run("success", func(t *testing.T) { t.Parallel() - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() - - // Click "confirm" when it pops up. - confirmErrCh := envstest.AutoConfirmDialogs(taskCtx, true) - - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(`http://`+harness.Server.Addr()+`/realm/apikeys`), - chromedp.WaitVisible(`body#apikeys-index`, chromedp.ByQuery), - - chromedp.Click(fmt.Sprintf(`a#disable-apikey-%d`, authApp.ID), chromedp.ByQuery), + ctx := ctx + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyWrite, + }) - chromedp.WaitVisible(`body#apikeys-index`, chromedp.ByQuery), - ); err != nil { - t.Fatal(err) - } + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) - if err := <-confirmErrCh; err != nil { - t.Fatal(err) + if got, want := w.Code, http.StatusSeeOther; got != want { + t.Errorf("Expected %d to be %d", got, want) } // Ensure disabled diff --git a/pkg/controller/apikey/enable_test.go b/pkg/controller/apikey/enable_test.go index 4436b5b99..b5f453a4f 100644 --- a/pkg/controller/apikey/enable_test.go +++ b/pkg/controller/apikey/enable_test.go @@ -15,25 +15,18 @@ package apikey_test import ( - "context" "fmt" "net/http" - "net/http/httptest" - "strings" "testing" "time" - "github.com/chromedp/chromedp" - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" "github.com/gorilla/mux" - "github.com/gorilla/sessions" "github.com/jinzhu/gorm" ) @@ -47,22 +40,26 @@ func TestHandleEnable(t *testing.T) { if err != nil { t.Fatal(err) } - - cookie, err := harness.SessionCookie(session) - if err != nil { + ctx = controller.WithSession(ctx, session) + + now := time.Now().UTC().Add(-5 * time.Second) + authApp := &database.AuthorizedApp{ + RealmID: realm.ID, + Name: "Appy", + Model: gorm.Model{ + DeletedAt: &now, + }, + } + if _, err := realm.CreateAuthorizedApp(harness.Database, authApp, database.SystemTest); err != nil { t.Fatal(err) } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := c.HandleEnable() + t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleEnable() - envstest.ExerciseSessionMissing(t, handler) envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) @@ -76,80 +73,41 @@ func TestHandleEnable(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - - mux := mux.NewRouter() - mux.Handle("/{id}", c.HandleEnable()).Methods(http.MethodPut) + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) + handler := c.HandleEnable() ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPut, "/1", nil) - r = r.Clone(ctx) - r.Header.Set("Content-Type", "text/html") - - w := httptest.NewRecorder() - - mux.ServeHTTP(w, r) - w.Flush() + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) - t.Run("enables", func(t *testing.T) { + t.Run("success", func(t *testing.T) { t.Parallel() - now := time.Now().UTC().Add(-5 * time.Second) - authApp := &database.AuthorizedApp{ - RealmID: realm.ID, - Name: "Disables app", - Model: gorm.Model{ - DeletedAt: &now, - }, - } - if _, err := realm.CreateAuthorizedApp(harness.Database, authApp, database.SystemTest); err != nil { - t.Fatal(err) - } - - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() - - // Click "confirm" when it pops up. - confirmErrCh := envstest.AutoConfirmDialogs(taskCtx, true) - - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(`http://`+harness.Server.Addr()+`/realm/apikeys`), - chromedp.WaitVisible(`body#apikeys-index`, chromedp.ByQuery), - - chromedp.Click(fmt.Sprintf(`a#enable-apikey-%d`, authApp.ID), chromedp.ByQuery), + ctx := ctx + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyWrite, + }) - chromedp.WaitVisible(`body#apikeys-index`, chromedp.ByQuery), - ); err != nil { - t.Fatal(err) - } + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) - if err := <-confirmErrCh; err != nil { - t.Fatal(err) + if got, want := w.Code, http.StatusSeeOther; got != want { + t.Errorf("Expected %d to be %d", got, want) } // Ensure enabled diff --git a/pkg/controller/apikey/index_test.go b/pkg/controller/apikey/index_test.go index 8337468b0..4d9676b02 100644 --- a/pkg/controller/apikey/index_test.go +++ b/pkg/controller/apikey/index_test.go @@ -15,23 +15,16 @@ package apikey_test import ( - "context" - "fmt" "net/http" - "net/http/httptest" - "strings" "testing" - "github.com/chromedp/chromedp" - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" + "github.com/google/exposure-notifications-verification-server/pkg/controller/middleware" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" - "github.com/gorilla/sessions" ) func TestHandleIndex(t *testing.T) { @@ -44,22 +37,22 @@ func TestHandleIndex(t *testing.T) { if err != nil { t.Fatal(err) } + ctx = controller.WithSession(ctx, session) - cookie, err := harness.SessionCookie(session) - if err != nil { + authApp := &database.AuthorizedApp{ + RealmID: realm.ID, + Name: "Appy", + } + if _, err := realm.CreateAuthorizedApp(harness.Database, authApp, database.SystemTest); err != nil { t.Fatal(err) } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := middleware.InjectCurrentPath()(c.HandleIndex()) + t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleIndex() - envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) envstest.ExerciseBadPagination(t, &database.Membership{ @@ -72,64 +65,39 @@ func TestHandleIndex(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleIndex() + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) + handler := middleware.InjectCurrentPath()(c.HandleIndex()) ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyRead, }) - r := httptest.NewRequest(http.MethodGet, "/", nil) - r = r.Clone(ctx) - r.Header.Set("Content-Type", "text/html") - - w := httptest.NewRecorder() - + w, r := envstest.BuildFormRequest(ctx, t, http.MethodGet, "/", nil) handler.ServeHTTP(w, r) - w.Flush() if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) - t.Run("lists", func(t *testing.T) { + t.Run("success", func(t *testing.T) { t.Parallel() - authApp := &database.AuthorizedApp{ - RealmID: realm.ID, - Name: "Appy", - } - if _, err := realm.CreateAuthorizedApp(harness.Database, authApp, database.SystemTest); err != nil { - t.Fatal(err) - } + ctx := ctx + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyRead, + }) + + w, r := envstest.BuildFormRequest(ctx, t, http.MethodGet, "/", nil) + handler.ServeHTTP(w, r) - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() - - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(`http://`+harness.Server.Addr()+`/realm/apikeys`), - chromedp.WaitVisible(`body#apikeys-index`, chromedp.ByQuery), - chromedp.WaitVisible(fmt.Sprintf(`tr#apikey-%d`, authApp.ID), chromedp.ByQuery), - ); err != nil { - t.Fatal(err) + if got, want := w.Code, http.StatusOK; got != want { + t.Errorf("Expected %d to be %d: %s", got, want, w.Body.String()) } }) } diff --git a/pkg/controller/apikey/show_test.go b/pkg/controller/apikey/show_test.go index 3b7517691..071c4881b 100644 --- a/pkg/controller/apikey/show_test.go +++ b/pkg/controller/apikey/show_test.go @@ -15,24 +15,18 @@ package apikey_test import ( - "context" "fmt" "net/http" - "net/http/httptest" - "strings" "testing" - "github.com/chromedp/chromedp" - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" + "github.com/google/exposure-notifications-verification-server/pkg/controller/middleware" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" "github.com/gorilla/mux" - "github.com/gorilla/sessions" ) func TestHandleShow(t *testing.T) { @@ -45,6 +39,7 @@ func TestHandleShow(t *testing.T) { if err != nil { t.Fatal(err) } + ctx = controller.WithSession(ctx, session) authApp := &database.AuthorizedApp{ RealmID: realm.ID, @@ -54,21 +49,12 @@ func TestHandleShow(t *testing.T) { t.Fatal(err) } - cookie, err := harness.SessionCookie(session) - if err != nil { - t.Fatal(err) - } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := middleware.InjectCurrentPath()(c.HandleShow()) t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleShow() - envstest.ExerciseSessionMissing(t, handler) envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) @@ -82,67 +68,41 @@ func TestHandleShow(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - - mux := mux.NewRouter() - mux.Handle("/{id}", c.HandleShow()).Methods(http.MethodGet) + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) + handler := middleware.InjectCurrentPath()(c.HandleShow()) ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyRead, }) - r := httptest.NewRequest(http.MethodGet, "/1", nil) - r = r.Clone(ctx) - r.Header.Set("Content-Type", "text/html") - - w := httptest.NewRecorder() - - mux.ServeHTTP(w, r) - w.Flush() + w, r := envstest.BuildFormRequest(ctx, t, http.MethodGet, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) t.Run("shows", func(t *testing.T) { t.Parallel() - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() - - u := fmt.Sprintf("http://%s/realm/apikeys/%d", harness.Server.Addr(), authApp.ID) - - var name string - - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(u), - chromedp.WaitVisible(`body#apikeys-show`, chromedp.ByQuery), + ctx := ctx + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyRead, + }) - chromedp.Text(`#apikey-name`, &name, chromedp.ByQuery), - ); err != nil { - t.Fatal(err) - } + w, r := envstest.BuildFormRequest(ctx, t, http.MethodGet, "/", nil) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) - if got, want := strings.TrimSpace(name), authApp.Name; got != want { - t.Errorf("Expected %q to be %q", got, want) + if got, want := w.Code, http.StatusOK; got != want { + t.Errorf("Expected %d to be %d", got, want) } }) } diff --git a/pkg/controller/apikey/update_test.go b/pkg/controller/apikey/update_test.go index c1c946642..bb557bd66 100644 --- a/pkg/controller/apikey/update_test.go +++ b/pkg/controller/apikey/update_test.go @@ -15,25 +15,19 @@ package apikey_test import ( - "context" "fmt" "net/http" - "net/http/httptest" "net/url" "strings" "testing" - "github.com/chromedp/chromedp" - "github.com/google/exposure-notifications-verification-server/internal/browser" "github.com/google/exposure-notifications-verification-server/internal/envstest" "github.com/google/exposure-notifications-verification-server/internal/project" "github.com/google/exposure-notifications-verification-server/pkg/controller" "github.com/google/exposure-notifications-verification-server/pkg/controller/apikey" "github.com/google/exposure-notifications-verification-server/pkg/database" "github.com/google/exposure-notifications-verification-server/pkg/rbac" - "github.com/google/exposure-notifications-verification-server/pkg/render" "github.com/gorilla/mux" - "github.com/gorilla/sessions" ) func TestHandleUpdate(t *testing.T) { @@ -46,11 +40,7 @@ func TestHandleUpdate(t *testing.T) { if err != nil { t.Fatal(err) } - - cookie, err := harness.SessionCookie(session) - if err != nil { - t.Fatal(err) - } + ctx = controller.WithSession(ctx, session) authApp := &database.AuthorizedApp{ RealmID: realm.ID, @@ -60,17 +50,12 @@ func TestHandleUpdate(t *testing.T) { t.Fatal(err) } + c := apikey.New(harness.Cacher, harness.Database, harness.Renderer) + handler := c.HandleUpdate() + t.Run("middleware", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - handler := c.HandleUpdate() - envstest.ExerciseSessionMissing(t, handler) envstest.ExerciseMembershipMissing(t, handler) envstest.ExercisePermissionMissing(t, handler) @@ -84,80 +69,43 @@ func TestHandleUpdate(t *testing.T) { t.Run("internal_error", func(t *testing.T) { t.Parallel() - harness := envstest.NewServerConfig(t, testDatabaseInstance) - harness.Database.SetRawDB(envstest.NewFailingDatabase()) - - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - - mux := mux.NewRouter() - mux.Handle("/{id}", c.HandleUpdate()).Methods(http.MethodPut) + c := apikey.New(harness.Cacher, harness.BadDatabase, harness.Renderer) + handler := c.HandleUpdate() ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPut, "/1", strings.NewReader(url.Values{ - "name": []string{"apple"}, - }.Encode())) - r = r.Clone(ctx) - r.Header.Set("Accept", "text/html") - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - w := httptest.NewRecorder() - - mux.ServeHTTP(w, r) - w.Flush() + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", &url.Values{ + "name": []string{"Appy McApperson"}, + }) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) if got, want := w.Code, http.StatusInternalServerError; got != want { t.Errorf("Expected %d to be %d", got, want) } - if got, want := w.Body.String(), "Internal server error"; !strings.Contains(got, want) { - t.Errorf("Expected %q to contain %q", got, want) - } }) t.Run("validation", func(t *testing.T) { t.Parallel() - h, err := render.New(ctx, envstest.ServerAssetsPath(), true) - if err != nil { - t.Fatal(err) - } - - c := apikey.New(harness.Cacher, harness.Database, h) - - mux := mux.NewRouter() - mux.Handle("/{id}", c.HandleUpdate()).Methods(http.MethodPut) - ctx := ctx - ctx = controller.WithSession(ctx, &sessions.Session{}) ctx = controller.WithMembership(ctx, &database.Membership{ Realm: realm, User: user, Permissions: rbac.APIKeyWrite, }) - r := httptest.NewRequest(http.MethodPut, "/1", strings.NewReader(url.Values{ + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", &url.Values{ "name": []string{""}, "type": []string{"-1"}, - }.Encode())) - r = r.Clone(ctx) - r.Header.Set("Accept", "text/html") - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - w := httptest.NewRecorder() - - mux.ServeHTTP(w, r) - w.Flush() + }) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) if got, want := w.Code, http.StatusUnprocessableEntity; got != want { t.Errorf("Expected %d to be %d", got, want) @@ -167,26 +115,24 @@ func TestHandleUpdate(t *testing.T) { } }) - t.Run("updates", func(t *testing.T) { + t.Run("success", func(t *testing.T) { t.Parallel() - browserCtx := browser.New(t) - taskCtx, done := context.WithTimeout(browserCtx, project.TestTimeout()) - defer done() - - u := fmt.Sprintf("http://%s/realm/apikeys/%d/edit", harness.Server.Addr(), authApp.ID) - - if err := chromedp.Run(taskCtx, - browser.SetCookie(cookie), - chromedp.Navigate(u), - chromedp.WaitVisible(`body#apikeys-edit`, chromedp.ByQuery), + ctx := ctx + ctx = controller.WithMembership(ctx, &database.Membership{ + Realm: realm, + User: user, + Permissions: rbac.APIKeyWrite, + }) - chromedp.SetValue(`input#name`, "Updated name", chromedp.ByQuery), - chromedp.Click(`#submit`, chromedp.ByQuery), + w, r := envstest.BuildFormRequest(ctx, t, http.MethodPut, "/", &url.Values{ + "name": []string{"Appy McApperson"}, + }) + r = mux.SetURLVars(r, map[string]string{"id": fmt.Sprintf("%d", authApp.ID)}) + handler.ServeHTTP(w, r) - chromedp.WaitVisible(`body#apikeys-show`, chromedp.ByQuery), - ); err != nil { - t.Fatal(err) + if got, want := w.Code, http.StatusSeeOther; got != want { + t.Errorf("Expected %d to be %d", got, want) } // Ensure updated @@ -195,7 +141,7 @@ func TestHandleUpdate(t *testing.T) { t.Fatal(err) } - if got, want := record.Name, "Updated name"; got != want { + if got, want := record.Name, "Appy McApperson"; got != want { t.Errorf("Expected %q to be %q", got, want) } })