- Destroy allow-lists providers and shares WriteNotFound for unknown, missing and foreign rows - Last remaining identity is refused with a localized 409; password flags are unused - EN and PL last_method_blocked strings match the PHP texts
74 lines
2.4 KiB
Go
74 lines
2.4 KiB
Go
package user
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-user-plugin/controllers"
|
|
"git.golem15.com/golem15/sm-user-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/bouncer"
|
|
)
|
|
|
|
func TestOAuthIdentitiesIndexEmptyList(t *testing.T) {
|
|
app, db := sessionApp(t, "0s")
|
|
user := insertUser(t, db, "oauth-empty@example.test", "correct-horse")
|
|
req := httptest.NewRequest(http.MethodGet, "/_fonoteka/api/v1/oauth-identities", nil)
|
|
req = req.WithContext(bouncer.WithUser(req.Context(), &bouncer.Principal{ID: user.ID}))
|
|
rec := httptest.NewRecorder()
|
|
controllers.OAuthIdentitiesIndex(app).ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
|
|
}
|
|
if rec.Body.String() != `{"data":[]}` {
|
|
t.Fatalf("body = %s", rec.Body.String())
|
|
}
|
|
var body map[string]any
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(body) != 1 {
|
|
t.Fatalf("top-level keys = %#v", body)
|
|
}
|
|
if cc := rec.Header().Get("Cache-Control"); !strings.Contains(cc, "no-cache") {
|
|
t.Fatalf("Cache-Control = %q", cc)
|
|
}
|
|
}
|
|
|
|
func TestOAuthIdentitiesDestroyNoContentKeepsSibling(t *testing.T) {
|
|
app, db := sessionApp(t, "0s")
|
|
user := insertUser(t, db, "oauth-unlink@example.test", "correct-horse")
|
|
for _, row := range []models.OAuthIdentity{
|
|
{UserID: user.ID, Provider: "facebook", ProviderID: "fb-alice"},
|
|
{UserID: user.ID, Provider: "google", ProviderID: "goog-alice"},
|
|
} {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
req := httptest.NewRequest(http.MethodDelete, "/_fonoteka/api/v1/oauth-identities/facebook", nil)
|
|
req.SetPathValue("provider", "facebook")
|
|
req = req.WithContext(bouncer.WithUser(req.Context(), &bouncer.Principal{ID: user.ID}))
|
|
rec := httptest.NewRecorder()
|
|
controllers.OAuthIdentitiesDestroy(app, controllers.OAuthIdentitiesOptions{
|
|
WriteNotFound: func(http.ResponseWriter, *http.Request) {
|
|
t.Fatal("WriteNotFound called")
|
|
},
|
|
}).ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusNoContent {
|
|
t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
|
|
}
|
|
if rec.Body.Len() != 0 {
|
|
t.Fatalf("body = %q", rec.Body.String())
|
|
}
|
|
var leftover []models.OAuthIdentity
|
|
if err := db.Where("user_id = ?", user.ID).Order("provider").Find(&leftover).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(leftover) != 1 || leftover[0].Provider != "google" {
|
|
t.Fatalf("remaining = %#v", leftover)
|
|
}
|
|
}
|