mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
Remove all _hz_ prefixes from collection IDs, internal markers, and test fixtures. The default users collection is now _users_auth_ instead of _hz_users_auth_. Internal SQL parser tokens renamed from __hz_join__/__hz_discard__ to __join__/__discard__. Backup prefix changed from @auto_hz_backup_ to @auto_backup_. Test database updated with correct collection IDs and indexes. JWT tokens in test files regenerated with new collection IDs. Add LogoURL field to MetaConfig so the admin UI logo is configurable via app settings instead of hardcoded. FullPage.svelte and App.svelte sidebar now read logo and app name from the settings store, falling back to defaults when not configured.
406 lines
13 KiB
Go
406 lines
13 KiB
Go
package apis_test
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hanzoai/base/core"
|
|
"github.com/hanzoai/base/tests"
|
|
)
|
|
|
|
func TestRecordCrudOTPList(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "guest",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"page":1`,
|
|
`"perPage":30`,
|
|
`"totalItems":0`,
|
|
`"totalPages":0`,
|
|
`"items":[]`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordsListRequest": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "regular auth with otps",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
Headers: map[string]string{
|
|
// users, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfdXNlcnNfYXV0aF8iLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiNHExeGxjbG1mbG9rdTMzIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.AuFTIzCsdLEy-5adFzpjZzbqAdTP6Iu9B1wPBAxLBgo",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"page":1`,
|
|
`"perPage":30`,
|
|
`"totalItems":1`,
|
|
`"totalPages":1`,
|
|
`"id":"user1_0"`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordsListRequest": 1,
|
|
"OnRecordEnrich": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "regular auth without otps",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
Headers: map[string]string{
|
|
// clients, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJ2ODUxcTRyNzkwcmhrbmwiLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiZ2szOTBxZWdzNHk0N3duIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.xCGkWuACPNAEUBLQVK4KKp72HzA2aOtWZnP47iBs5os",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"page":1`,
|
|
`"perPage":30`,
|
|
`"totalItems":0`,
|
|
`"totalPages":0`,
|
|
`"items":[]`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordsListRequest": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestRecordCrudOTPView(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "guest",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 404,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "non-owner",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// clients, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJ2ODUxcTRyNzkwcmhrbmwiLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiZ2szOTBxZWdzNHk0N3duIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.xCGkWuACPNAEUBLQVK4KKp72HzA2aOtWZnP47iBs5os",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 404,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "owner",
|
|
Method: http.MethodGet,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// users, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfdXNlcnNfYXV0aF8iLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiNHExeGxjbG1mbG9rdTMzIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.AuFTIzCsdLEy-5adFzpjZzbqAdTP6Iu9B1wPBAxLBgo",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{`"id":"user1_0"`},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordViewRequest": 1,
|
|
"OnRecordEnrich": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestRecordCrudOTPDelete(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "guest",
|
|
Method: http.MethodDelete,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "non-owner auth",
|
|
Method: http.MethodDelete,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// clients, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJ2ODUxcTRyNzkwcmhrbmwiLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiZ2szOTBxZWdzNHk0N3duIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.xCGkWuACPNAEUBLQVK4KKp72HzA2aOtWZnP47iBs5os",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "owner regular auth",
|
|
Method: http.MethodDelete,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// users, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfdXNlcnNfYXV0aF8iLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiNHExeGxjbG1mbG9rdTMzIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.AuFTIzCsdLEy-5adFzpjZzbqAdTP6Iu9B1wPBAxLBgo",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "superusers auth",
|
|
Method: http.MethodDelete,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// superusers, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJoYmNfMzE0MjYzNTgyMyIsImV4cCI6MjUyNDYwNDQ2MSwiaWQiOiJzeXdiaGVjbmg0NnJobTAiLCJyZWZyZXNoYWJsZSI6dHJ1ZSwidHlwZSI6ImF1dGgifQ.CXBf8BazmUeg2RnJW8OEs1UFYF41rbCMOa6YZa4wZio",
|
|
},
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 204,
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordDeleteRequest": 1,
|
|
"OnModelDelete": 1,
|
|
"OnModelDeleteExecute": 1,
|
|
"OnModelAfterDeleteSuccess": 1,
|
|
"OnRecordDelete": 1,
|
|
"OnRecordDeleteExecute": 1,
|
|
"OnRecordAfterDeleteSuccess": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestRecordCrudOTPCreate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
body := func() *strings.Reader {
|
|
return strings.NewReader(`{
|
|
"recordRef": "4q1xlclmfloku33",
|
|
"collectionRef": "_users_auth_",
|
|
"password": "abc"
|
|
}`)
|
|
}
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "guest",
|
|
Method: http.MethodPost,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "owner regular auth",
|
|
Method: http.MethodPost,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
Headers: map[string]string{
|
|
// users, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfdXNlcnNfYXV0aF8iLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiNHExeGxjbG1mbG9rdTMzIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.AuFTIzCsdLEy-5adFzpjZzbqAdTP6Iu9B1wPBAxLBgo",
|
|
},
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "superusers auth",
|
|
Method: http.MethodPost,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records",
|
|
Headers: map[string]string{
|
|
// superusers, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJoYmNfMzE0MjYzNTgyMyIsImV4cCI6MjUyNDYwNDQ2MSwiaWQiOiJzeXdiaGVjbmg0NnJobTAiLCJyZWZyZXNoYWJsZSI6dHJ1ZSwidHlwZSI6ImF1dGgifQ.CXBf8BazmUeg2RnJW8OEs1UFYF41rbCMOa6YZa4wZio",
|
|
},
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedContent: []string{
|
|
`"recordRef":"4q1xlclmfloku33"`,
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordCreateRequest": 1,
|
|
"OnRecordEnrich": 1,
|
|
"OnModelCreate": 1,
|
|
"OnModelCreateExecute": 1,
|
|
"OnModelAfterCreateSuccess": 1,
|
|
"OnModelValidate": 1,
|
|
"OnRecordCreate": 1,
|
|
"OnRecordCreateExecute": 1,
|
|
"OnRecordAfterCreateSuccess": 1,
|
|
"OnRecordValidate": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestRecordCrudOTPUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
body := func() *strings.Reader {
|
|
return strings.NewReader(`{
|
|
"password":"abc"
|
|
}`)
|
|
}
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "guest",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "owner regular auth",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// users, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfdXNlcnNfYXV0aF8iLCJleHAiOjI1MjQ2MDQ0NjEsImlkIjoiNHExeGxjbG1mbG9rdTMzIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.AuFTIzCsdLEy-5adFzpjZzbqAdTP6Iu9B1wPBAxLBgo",
|
|
},
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "superusers auth",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
|
Headers: map[string]string{
|
|
// superusers, [email protected]
|
|
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJoYmNfMzE0MjYzNTgyMyIsImV4cCI6MjUyNDYwNDQ2MSwiaWQiOiJzeXdiaGVjbmg0NnJobTAiLCJyZWZyZXNoYWJsZSI6dHJ1ZSwidHlwZSI6ImF1dGgifQ.CXBf8BazmUeg2RnJW8OEs1UFYF41rbCMOa6YZa4wZio",
|
|
},
|
|
Body: body(),
|
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
|
if err := tests.StubOTPRecords(app); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
},
|
|
ExpectedContent: []string{
|
|
`"id":"user1_0"`,
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnRecordUpdateRequest": 1,
|
|
"OnRecordEnrich": 1,
|
|
"OnModelUpdate": 1,
|
|
"OnModelUpdateExecute": 1,
|
|
"OnModelAfterUpdateSuccess": 1,
|
|
"OnModelValidate": 1,
|
|
"OnRecordUpdate": 1,
|
|
"OnRecordUpdateExecute": 1,
|
|
"OnRecordAfterUpdateSuccess": 1,
|
|
"OnRecordValidate": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|