Files
sm-user-plugin/updates/organisations_test.go
Jakub Zych 4e3e5b05b5 feat: device authorization by QR or short code
PHP's device flow on golem15_user_device_auth_sessions (PHP's columns,
the token stored as its SHA-256, plus jwt_jti): POST /devices/initiate
answers a 64-character token, an XXXX-XXXX short code, the configurable
auth_url (golem15.user.device_auth.auth_url) and the expiry; a signed-in
user authorizes it with POST /devices/authorize (short_code or token,
one guarded pending-to-confirmed UPDATE); the device's first poll of
GET /devices/status/{token} after that receives a session JWT through one
guarded confirmed-to-used UPDATE, so exactly one poll gets it. Used and
revoked sessions never turn into expired; each initiate deletes a bounded
batch of stale sessions.
2026-10-26 10:14:48 +01:00

82 lines
2.3 KiB
Go

package updates
import (
"testing"
"git.golem15.com/golem15/summercms/modules/lagoon"
"github.com/go-gormigrate/gormigrate/v2"
)
func TestCreateOrganisationsMigration(t *testing.T) {
sqlDB := dedicatedDB(t, "user_organisations")
gdb, err := lagoon.Use(t.Context(), sqlDB)
if err != nil {
t.Fatal(err)
}
opts := &gormigrate.Options{
TableName: "summer_migrations_golem15_user",
UseTransaction: true,
}
m := gormigrate.New(gdb, opts, All())
if err := m.Migrate(); err != nil {
t.Fatal(err)
}
if !gdb.Migrator().HasTable("golem15_user_organisations") {
t.Fatal("golem15_user_organisations missing after migrate")
}
if !gdb.Migrator().HasTable("users") {
t.Fatal("users missing after migrate")
}
for _, col := range []string{"id", "slug", "name", "description", "created_at", "updated_at"} {
if !gdb.Migrator().HasColumn("golem15_user_organisations", col) {
t.Fatalf("missing column %s", col)
}
}
var ids []string
if err := gdb.Raw(`SELECT id FROM summer_migrations_golem15_user ORDER BY id`).Scan(&ids).Error; err != nil {
t.Fatal(err)
}
want := []string{
"202609170001_create_users",
"202609180002_create_organisations",
"202609220005_extend_users",
"202609220006_create_user_throttle",
"202609220007_create_jwt_blacklist",
"202610020001_create_user_groups",
"202610040001_add_users_permissions",
"202610040001_create_user_api_tokens",
"202610040002_add_users_last_seen",
"202610040003_create_frontend_permissions",
"202610050001_create_oauth_identities",
"202610160002_add_handle_to_users",
"202610210001_add_users_email_verified_at",
"202610220001_create_golem15_user_backend_links",
"202610260001_create_device_auth_sessions",
}
if len(ids) != len(want) {
t.Fatalf("history = %v", ids)
}
for i := range want {
if ids[i] != want[i] {
t.Fatalf("history = %v", ids)
}
}
// Device auth sessions (golem15_user_device_auth_sessions), backend links, email proof, handle, OAuth
// identities, the three admin migrations, API tokens, user groups, jwt blacklist, throttle, extend-users,
// then organisations.
for range 14 {
if err := m.RollbackLast(); err != nil {
t.Fatal(err)
}
}
if gdb.Migrator().HasTable("golem15_user_organisations") {
t.Fatal("rollback must drop golem15_user_organisations")
}
if !gdb.Migrator().HasTable("users") {
t.Fatal("users must survive organisations rollback")
}
}