mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-10 01:02:52 +01:00
feat: improve python actions (#1083)
This commit is contained in:
@@ -6,18 +6,16 @@ import (
|
||||
)
|
||||
|
||||
func TestReactionsCollection(t *testing.T) {
|
||||
baseApp, adminToken, analystToken, baseAppCleanup := BaseApp(t)
|
||||
defer baseAppCleanup()
|
||||
t.Parallel()
|
||||
|
||||
testSets := []authMatrixText{
|
||||
testSets := []catalystTest{
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "ListReactions",
|
||||
Method: http.MethodGet,
|
||||
URL: "/api/collections/reactions/records",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
Name: "ListReactions",
|
||||
Method: http.MethodGet,
|
||||
URL: "/api/collections/reactions/records",
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusOK,
|
||||
@@ -29,7 +27,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"totalItems":3`,
|
||||
@@ -42,7 +40,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"totalItems":3`,
|
||||
@@ -68,9 +66,8 @@ func TestReactionsCollection(t *testing.T) {
|
||||
"action": "python",
|
||||
"actiondata": map[string]any{"script": "print('Hello, World!')"},
|
||||
}),
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusBadRequest,
|
||||
@@ -80,7 +77,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"name":"test"`,
|
||||
@@ -97,7 +94,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"name":"test"`,
|
||||
@@ -120,9 +117,8 @@ func TestReactionsCollection(t *testing.T) {
|
||||
Method: http.MethodGet,
|
||||
RequestHeaders: map[string]string{"Content-Type": "application/json"},
|
||||
URL: "/api/collections/reactions/records/r_reaction",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
@@ -132,7 +128,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"id":"r_reaction"`,
|
||||
@@ -141,7 +137,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"id":"r_reaction"`,
|
||||
@@ -157,9 +153,8 @@ func TestReactionsCollection(t *testing.T) {
|
||||
RequestHeaders: map[string]string{"Content-Type": "application/json"},
|
||||
URL: "/api/collections/reactions/records/r_reaction",
|
||||
Body: s(map[string]any{"name": "update"}),
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
@@ -169,7 +164,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"id":"r_reaction"`,
|
||||
@@ -184,7 +179,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"id":"r_reaction"`,
|
||||
@@ -201,12 +196,11 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "DeleteReaction",
|
||||
Method: http.MethodDelete,
|
||||
URL: "/api/collections/reactions/records/r_reaction",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
Name: "DeleteReaction",
|
||||
Method: http.MethodDelete,
|
||||
URL: "/api/collections/reactions/records/r_reaction",
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusNotFound,
|
||||
@@ -216,7 +210,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusNoContent,
|
||||
ExpectedEvents: map[string]int{
|
||||
"OnModelAfterDelete": 1,
|
||||
@@ -227,7 +221,7 @@ func TestReactionsCollection(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusNoContent,
|
||||
ExpectedEvents: map[string]int{
|
||||
"OnModelAfterDelete": 1,
|
||||
@@ -241,9 +235,14 @@ func TestReactionsCollection(t *testing.T) {
|
||||
}
|
||||
for _, testSet := range testSets {
|
||||
t.Run(testSet.baseTest.Name, func(t *testing.T) {
|
||||
for _, authBasedExpectation := range testSet.authBasedExpectations {
|
||||
scenario := mergeScenario(testSet.baseTest, authBasedExpectation)
|
||||
scenario.Test(t)
|
||||
t.Parallel()
|
||||
|
||||
for _, userTest := range testSet.userTests {
|
||||
t.Run(userTest.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
runMatrixTest(t, testSet.baseTest, userTest)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
36
testing/counter.go
Normal file
36
testing/counter.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package testing
|
||||
|
||||
import "sync"
|
||||
|
||||
type Counter struct {
|
||||
mux sync.Mutex
|
||||
counts map[string]int
|
||||
}
|
||||
|
||||
func NewCounter() *Counter {
|
||||
return &Counter{
|
||||
counts: make(map[string]int),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Counter) Increment(name string) {
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
if _, ok := c.counts[name]; !ok {
|
||||
c.counts[name] = 0
|
||||
}
|
||||
|
||||
c.counts[name]++
|
||||
}
|
||||
|
||||
func (c *Counter) Count(name string) int {
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
if _, ok := c.counts[name]; !ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
return c.counts[name]
|
||||
}
|
||||
41
testing/counter_test.go
Normal file
41
testing/counter_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCounter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
name string
|
||||
repeat int
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "Test Counter",
|
||||
args: args{name: "test", repeat: 5},
|
||||
want: 5,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := NewCounter()
|
||||
|
||||
for range tt.args.repeat {
|
||||
c.Increment(tt.args.name)
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.want, c.Count(tt.args.name))
|
||||
})
|
||||
}
|
||||
}
|
||||
37
testing/http.go
Normal file
37
testing/http.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func WaitForStatus(url string, status int, timeout time.Duration) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for {
|
||||
if time.Since(start) > timeout {
|
||||
return errors.New("timeout")
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err == nil && resp.StatusCode == status {
|
||||
resp.Body.Close()
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,93 +3,80 @@ package testing
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWebhookReactions(t *testing.T) {
|
||||
baseApp, adminToken, analystToken, baseAppCleanup := BaseApp(t)
|
||||
defer baseAppCleanup()
|
||||
t.Parallel()
|
||||
|
||||
server := NewRecordingServer()
|
||||
|
||||
go http.ListenAndServe("127.0.0.1:12345", server) //nolint:gosec,errcheck
|
||||
|
||||
testSets := []authMatrixText{
|
||||
if err := WaitForStatus("http://127.0.0.1:12345/health", http.StatusOK, 5*time.Second); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testSets := []catalystTest{
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "TriggerWebhookReaction",
|
||||
Method: http.MethodGet,
|
||||
RequestHeaders: map[string]string{"Authorization": "Bearer 1234567890"},
|
||||
URL: "/reaction/test",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`Hello, World!`},
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`Hello, World!`},
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`Hello, World!`},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "TriggerWebhookReaction2",
|
||||
Method: http.MethodGet,
|
||||
URL: "/reaction/test2",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
Name: "TriggerWebhookReaction2",
|
||||
Method: http.MethodGet,
|
||||
URL: "/reaction/test2",
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`"test":true`},
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`"test":true`},
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{`"test":true`},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, testSet := range testSets {
|
||||
t.Run(testSet.baseTest.Name, func(t *testing.T) {
|
||||
for _, authBasedExpectation := range testSet.authBasedExpectations {
|
||||
scenario := mergeScenario(testSet.baseTest, authBasedExpectation)
|
||||
scenario.Test(t)
|
||||
t.Parallel()
|
||||
|
||||
for _, userTest := range testSet.userTests {
|
||||
t.Run(userTest.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
runMatrixTest(t, testSet.baseTest, userTest)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookReactions(t *testing.T) {
|
||||
baseApp, _, analystToken, baseAppCleanup := BaseApp(t)
|
||||
defer baseAppCleanup()
|
||||
t.Parallel()
|
||||
|
||||
server := NewRecordingServer()
|
||||
|
||||
go http.ListenAndServe("127.0.0.1:12346", server) //nolint:gosec,errcheck
|
||||
|
||||
testSets := []authMatrixText{
|
||||
if err := WaitForStatus("http://127.0.0.1:12346/health", http.StatusOK, 5*time.Second); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testSets := []catalystTest{
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "TriggerHookReaction",
|
||||
@@ -99,9 +86,8 @@ func TestHookReactions(t *testing.T) {
|
||||
Body: s(map[string]any{
|
||||
"name": "test",
|
||||
}),
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
// {
|
||||
// Name: "Unauthorized",
|
||||
// ExpectedStatus: http.StatusOK,
|
||||
@@ -109,7 +95,7 @@ func TestHookReactions(t *testing.T) {
|
||||
// },
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"collectionName":"tickets"`,
|
||||
@@ -133,12 +119,17 @@ func TestHookReactions(t *testing.T) {
|
||||
}
|
||||
for _, testSet := range testSets {
|
||||
t.Run(testSet.baseTest.Name, func(t *testing.T) {
|
||||
for _, authBasedExpectation := range testSet.authBasedExpectations {
|
||||
scenario := mergeScenario(testSet.baseTest, authBasedExpectation)
|
||||
scenario.Test(t)
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
require.NotEmpty(t, server.Entries)
|
||||
for _, userTest := range testSet.userTests {
|
||||
t.Run(userTest.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
runMatrixTest(t, testSet.baseTest, userTest)
|
||||
|
||||
require.NotEmpty(t, server.Entries)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
package testing
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v5"
|
||||
)
|
||||
|
||||
type RecordingServer struct {
|
||||
server *echo.Echo
|
||||
|
||||
Entries []string
|
||||
}
|
||||
|
||||
func NewRecordingServer() *RecordingServer {
|
||||
return &RecordingServer{}
|
||||
e := echo.New()
|
||||
|
||||
e.GET("/health", func(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, map[string]any{
|
||||
"status": "ok",
|
||||
})
|
||||
})
|
||||
e.Any("/*", func(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, map[string]any{
|
||||
"test": true,
|
||||
})
|
||||
})
|
||||
|
||||
return &RecordingServer{
|
||||
server: e,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RecordingServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.Entries = append(s.Entries, r.URL.Path)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"test":true}`)) //nolint:errcheck
|
||||
s.server.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@@ -6,63 +6,60 @@ import (
|
||||
)
|
||||
|
||||
func Test_Routes(t *testing.T) {
|
||||
baseApp, adminToken, analystToken, baseAppCleanup := BaseApp(t)
|
||||
defer baseAppCleanup()
|
||||
t.Parallel()
|
||||
|
||||
testSets := []authMatrixText{
|
||||
testSets := []catalystTest{
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "Root",
|
||||
Method: http.MethodGet,
|
||||
URL: "/",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
Name: "Root",
|
||||
Method: http.MethodGet,
|
||||
URL: "/",
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusFound,
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusFound,
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusFound,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
baseTest: BaseTest{
|
||||
Name: "Config",
|
||||
Method: http.MethodGet,
|
||||
URL: "/api/config",
|
||||
TestAppFactory: AppFactory(baseApp),
|
||||
Name: "Config",
|
||||
Method: http.MethodGet,
|
||||
URL: "/api/config",
|
||||
},
|
||||
authBasedExpectations: []AuthBasedExpectation{
|
||||
userTests: []UserTest{
|
||||
{
|
||||
Name: "Unauthorized",
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"flags":null`,
|
||||
`"flags":[]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Analyst",
|
||||
RequestHeaders: map[string]string{"Authorization": analystToken},
|
||||
AuthRecord: analystEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"flags":null`,
|
||||
`"flags":[]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Admin",
|
||||
RequestHeaders: map[string]string{"Authorization": adminToken},
|
||||
Admin: adminEmail,
|
||||
ExpectedStatus: http.StatusOK,
|
||||
ExpectedContent: []string{
|
||||
`"flags":null`,
|
||||
`"flags":[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -70,9 +67,14 @@ func Test_Routes(t *testing.T) {
|
||||
}
|
||||
for _, testSet := range testSets {
|
||||
t.Run(testSet.baseTest.Name, func(t *testing.T) {
|
||||
for _, authBasedExpectation := range testSet.authBasedExpectations {
|
||||
scenario := mergeScenario(testSet.baseTest, authBasedExpectation)
|
||||
scenario.Test(t)
|
||||
t.Parallel()
|
||||
|
||||
for _, userTest := range testSet.userTests {
|
||||
t.Run(userTest.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
runMatrixTest(t, testSet.baseTest, userTest)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
160
testing/testapp.go
Normal file
160
testing/testapp.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tokens"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/app"
|
||||
"github.com/SecurityBrewery/catalyst/migrations"
|
||||
)
|
||||
|
||||
func App(t *testing.T) (*pocketbase.PocketBase, *Counter, func()) {
|
||||
t.Helper()
|
||||
|
||||
temp, err := os.MkdirTemp("", "catalyst_test_data")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
baseApp, err := app.App(temp, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
baseApp.Settings().Logs.MaxDays = 0
|
||||
|
||||
defaultTestData(t, baseApp)
|
||||
|
||||
counter := countEvents(baseApp)
|
||||
|
||||
return baseApp, counter, func() { _ = os.RemoveAll(temp) }
|
||||
}
|
||||
|
||||
func generateAdminToken(t *testing.T, baseApp core.App, email string) (string, error) {
|
||||
t.Helper()
|
||||
|
||||
admin, err := baseApp.Dao().FindAdminByEmail(email)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to find admin: %w", err)
|
||||
}
|
||||
|
||||
return tokens.NewAdminAuthToken(baseApp, admin)
|
||||
}
|
||||
|
||||
func generateRecordToken(t *testing.T, baseApp core.App, email string) (string, error) {
|
||||
t.Helper()
|
||||
|
||||
record, err := baseApp.Dao().FindAuthRecordByEmail(migrations.UserCollectionName, email)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to find record: %w", err)
|
||||
}
|
||||
|
||||
return tokens.NewRecordAuthToken(baseApp, record)
|
||||
}
|
||||
|
||||
func countEvents(t *pocketbase.PocketBase) *Counter {
|
||||
c := NewCounter()
|
||||
|
||||
t.OnBeforeApiError().Add(count[*core.ApiErrorEvent](c, "OnBeforeApiError"))
|
||||
t.OnBeforeApiError().Add(count[*core.ApiErrorEvent](c, "OnBeforeApiError"))
|
||||
t.OnAfterApiError().Add(count[*core.ApiErrorEvent](c, "OnAfterApiError"))
|
||||
t.OnModelBeforeCreate().Add(count[*core.ModelEvent](c, "OnModelBeforeCreate"))
|
||||
t.OnModelAfterCreate().Add(count[*core.ModelEvent](c, "OnModelAfterCreate"))
|
||||
t.OnModelBeforeUpdate().Add(count[*core.ModelEvent](c, "OnModelBeforeUpdate"))
|
||||
t.OnModelAfterUpdate().Add(count[*core.ModelEvent](c, "OnModelAfterUpdate"))
|
||||
t.OnModelBeforeDelete().Add(count[*core.ModelEvent](c, "OnModelBeforeDelete"))
|
||||
t.OnModelAfterDelete().Add(count[*core.ModelEvent](c, "OnModelAfterDelete"))
|
||||
t.OnRecordsListRequest().Add(count[*core.RecordsListEvent](c, "OnRecordsListRequest"))
|
||||
t.OnRecordViewRequest().Add(count[*core.RecordViewEvent](c, "OnRecordViewRequest"))
|
||||
t.OnRecordBeforeCreateRequest().Add(count[*core.RecordCreateEvent](c, "OnRecordBeforeCreateRequest"))
|
||||
t.OnRecordAfterCreateRequest().Add(count[*core.RecordCreateEvent](c, "OnRecordAfterCreateRequest"))
|
||||
t.OnRecordBeforeUpdateRequest().Add(count[*core.RecordUpdateEvent](c, "OnRecordBeforeUpdateRequest"))
|
||||
t.OnRecordAfterUpdateRequest().Add(count[*core.RecordUpdateEvent](c, "OnRecordAfterUpdateRequest"))
|
||||
t.OnRecordBeforeDeleteRequest().Add(count[*core.RecordDeleteEvent](c, "OnRecordBeforeDeleteRequest"))
|
||||
t.OnRecordAfterDeleteRequest().Add(count[*core.RecordDeleteEvent](c, "OnRecordAfterDeleteRequest"))
|
||||
t.OnRecordAuthRequest().Add(count[*core.RecordAuthEvent](c, "OnRecordAuthRequest"))
|
||||
t.OnRecordBeforeAuthWithPasswordRequest().Add(count[*core.RecordAuthWithPasswordEvent](c, "OnRecordBeforeAuthWithPasswordRequest"))
|
||||
t.OnRecordAfterAuthWithPasswordRequest().Add(count[*core.RecordAuthWithPasswordEvent](c, "OnRecordAfterAuthWithPasswordRequest"))
|
||||
t.OnRecordBeforeAuthWithOAuth2Request().Add(count[*core.RecordAuthWithOAuth2Event](c, "OnRecordBeforeAuthWithOAuth2Request"))
|
||||
t.OnRecordAfterAuthWithOAuth2Request().Add(count[*core.RecordAuthWithOAuth2Event](c, "OnRecordAfterAuthWithOAuth2Request"))
|
||||
t.OnRecordBeforeAuthRefreshRequest().Add(count[*core.RecordAuthRefreshEvent](c, "OnRecordBeforeAuthRefreshRequest"))
|
||||
t.OnRecordAfterAuthRefreshRequest().Add(count[*core.RecordAuthRefreshEvent](c, "OnRecordAfterAuthRefreshRequest"))
|
||||
t.OnRecordBeforeRequestPasswordResetRequest().Add(count[*core.RecordRequestPasswordResetEvent](c, "OnRecordBeforeRequestPasswordResetRequest"))
|
||||
t.OnRecordAfterRequestPasswordResetRequest().Add(count[*core.RecordRequestPasswordResetEvent](c, "OnRecordAfterRequestPasswordResetRequest"))
|
||||
t.OnRecordBeforeConfirmPasswordResetRequest().Add(count[*core.RecordConfirmPasswordResetEvent](c, "OnRecordBeforeConfirmPasswordResetRequest"))
|
||||
t.OnRecordAfterConfirmPasswordResetRequest().Add(count[*core.RecordConfirmPasswordResetEvent](c, "OnRecordAfterConfirmPasswordResetRequest"))
|
||||
t.OnRecordBeforeRequestVerificationRequest().Add(count[*core.RecordRequestVerificationEvent](c, "OnRecordBeforeRequestVerificationRequest"))
|
||||
t.OnRecordAfterRequestVerificationRequest().Add(count[*core.RecordRequestVerificationEvent](c, "OnRecordAfterRequestVerificationRequest"))
|
||||
t.OnRecordBeforeConfirmVerificationRequest().Add(count[*core.RecordConfirmVerificationEvent](c, "OnRecordBeforeConfirmVerificationRequest"))
|
||||
t.OnRecordAfterConfirmVerificationRequest().Add(count[*core.RecordConfirmVerificationEvent](c, "OnRecordAfterConfirmVerificationRequest"))
|
||||
t.OnRecordBeforeRequestEmailChangeRequest().Add(count[*core.RecordRequestEmailChangeEvent](c, "OnRecordBeforeRequestEmailChangeRequest"))
|
||||
t.OnRecordAfterRequestEmailChangeRequest().Add(count[*core.RecordRequestEmailChangeEvent](c, "OnRecordAfterRequestEmailChangeRequest"))
|
||||
t.OnRecordBeforeConfirmEmailChangeRequest().Add(count[*core.RecordConfirmEmailChangeEvent](c, "OnRecordBeforeConfirmEmailChangeRequest"))
|
||||
t.OnRecordAfterConfirmEmailChangeRequest().Add(count[*core.RecordConfirmEmailChangeEvent](c, "OnRecordAfterConfirmEmailChangeRequest"))
|
||||
t.OnRecordListExternalAuthsRequest().Add(count[*core.RecordListExternalAuthsEvent](c, "OnRecordListExternalAuthsRequest"))
|
||||
t.OnRecordBeforeUnlinkExternalAuthRequest().Add(count[*core.RecordUnlinkExternalAuthEvent](c, "OnRecordBeforeUnlinkExternalAuthRequest"))
|
||||
t.OnRecordAfterUnlinkExternalAuthRequest().Add(count[*core.RecordUnlinkExternalAuthEvent](c, "OnRecordAfterUnlinkExternalAuthRequest"))
|
||||
t.OnMailerBeforeAdminResetPasswordSend().Add(count[*core.MailerAdminEvent](c, "OnMailerBeforeAdminResetPasswordSend"))
|
||||
t.OnMailerAfterAdminResetPasswordSend().Add(count[*core.MailerAdminEvent](c, "OnMailerAfterAdminResetPasswordSend"))
|
||||
t.OnMailerBeforeRecordResetPasswordSend().Add(count[*core.MailerRecordEvent](c, "OnMailerBeforeRecordResetPasswordSend"))
|
||||
t.OnMailerAfterRecordResetPasswordSend().Add(count[*core.MailerRecordEvent](c, "OnMailerAfterRecordResetPasswordSend"))
|
||||
t.OnMailerBeforeRecordVerificationSend().Add(count[*core.MailerRecordEvent](c, "OnMailerBeforeRecordVerificationSend"))
|
||||
t.OnMailerAfterRecordVerificationSend().Add(count[*core.MailerRecordEvent](c, "OnMailerAfterRecordVerificationSend"))
|
||||
t.OnMailerBeforeRecordChangeEmailSend().Add(count[*core.MailerRecordEvent](c, "OnMailerBeforeRecordChangeEmailSend"))
|
||||
t.OnMailerAfterRecordChangeEmailSend().Add(count[*core.MailerRecordEvent](c, "OnMailerAfterRecordChangeEmailSend"))
|
||||
t.OnRealtimeConnectRequest().Add(count[*core.RealtimeConnectEvent](c, "OnRealtimeConnectRequest"))
|
||||
t.OnRealtimeDisconnectRequest().Add(count[*core.RealtimeDisconnectEvent](c, "OnRealtimeDisconnectRequest"))
|
||||
t.OnRealtimeBeforeMessageSend().Add(count[*core.RealtimeMessageEvent](c, "OnRealtimeBeforeMessageSend"))
|
||||
t.OnRealtimeAfterMessageSend().Add(count[*core.RealtimeMessageEvent](c, "OnRealtimeAfterMessageSend"))
|
||||
t.OnRealtimeBeforeSubscribeRequest().Add(count[*core.RealtimeSubscribeEvent](c, "OnRealtimeBeforeSubscribeRequest"))
|
||||
t.OnRealtimeAfterSubscribeRequest().Add(count[*core.RealtimeSubscribeEvent](c, "OnRealtimeAfterSubscribeRequest"))
|
||||
t.OnSettingsListRequest().Add(count[*core.SettingsListEvent](c, "OnSettingsListRequest"))
|
||||
t.OnSettingsBeforeUpdateRequest().Add(count[*core.SettingsUpdateEvent](c, "OnSettingsBeforeUpdateRequest"))
|
||||
t.OnSettingsAfterUpdateRequest().Add(count[*core.SettingsUpdateEvent](c, "OnSettingsAfterUpdateRequest"))
|
||||
t.OnCollectionsListRequest().Add(count[*core.CollectionsListEvent](c, "OnCollectionsListRequest"))
|
||||
t.OnCollectionViewRequest().Add(count[*core.CollectionViewEvent](c, "OnCollectionViewRequest"))
|
||||
t.OnCollectionBeforeCreateRequest().Add(count[*core.CollectionCreateEvent](c, "OnCollectionBeforeCreateRequest"))
|
||||
t.OnCollectionAfterCreateRequest().Add(count[*core.CollectionCreateEvent](c, "OnCollectionAfterCreateRequest"))
|
||||
t.OnCollectionBeforeUpdateRequest().Add(count[*core.CollectionUpdateEvent](c, "OnCollectionBeforeUpdateRequest"))
|
||||
t.OnCollectionAfterUpdateRequest().Add(count[*core.CollectionUpdateEvent](c, "OnCollectionAfterUpdateRequest"))
|
||||
t.OnCollectionBeforeDeleteRequest().Add(count[*core.CollectionDeleteEvent](c, "OnCollectionBeforeDeleteRequest"))
|
||||
t.OnCollectionAfterDeleteRequest().Add(count[*core.CollectionDeleteEvent](c, "OnCollectionAfterDeleteRequest"))
|
||||
t.OnCollectionsBeforeImportRequest().Add(count[*core.CollectionsImportEvent](c, "OnCollectionsBeforeImportRequest"))
|
||||
t.OnCollectionsAfterImportRequest().Add(count[*core.CollectionsImportEvent](c, "OnCollectionsAfterImportRequest"))
|
||||
t.OnAdminsListRequest().Add(count[*core.AdminsListEvent](c, "OnAdminsListRequest"))
|
||||
t.OnAdminViewRequest().Add(count[*core.AdminViewEvent](c, "OnAdminViewRequest"))
|
||||
t.OnAdminBeforeCreateRequest().Add(count[*core.AdminCreateEvent](c, "OnAdminBeforeCreateRequest"))
|
||||
t.OnAdminAfterCreateRequest().Add(count[*core.AdminCreateEvent](c, "OnAdminAfterCreateRequest"))
|
||||
t.OnAdminBeforeUpdateRequest().Add(count[*core.AdminUpdateEvent](c, "OnAdminBeforeUpdateRequest"))
|
||||
t.OnAdminAfterUpdateRequest().Add(count[*core.AdminUpdateEvent](c, "OnAdminAfterUpdateRequest"))
|
||||
t.OnAdminBeforeDeleteRequest().Add(count[*core.AdminDeleteEvent](c, "OnAdminBeforeDeleteRequest"))
|
||||
t.OnAdminAfterDeleteRequest().Add(count[*core.AdminDeleteEvent](c, "OnAdminAfterDeleteRequest"))
|
||||
t.OnAdminAuthRequest().Add(count[*core.AdminAuthEvent](c, "OnAdminAuthRequest"))
|
||||
t.OnAdminBeforeAuthWithPasswordRequest().Add(count[*core.AdminAuthWithPasswordEvent](c, "OnAdminBeforeAuthWithPasswordRequest"))
|
||||
t.OnAdminAfterAuthWithPasswordRequest().Add(count[*core.AdminAuthWithPasswordEvent](c, "OnAdminAfterAuthWithPasswordRequest"))
|
||||
t.OnAdminBeforeAuthRefreshRequest().Add(count[*core.AdminAuthRefreshEvent](c, "OnAdminBeforeAuthRefreshRequest"))
|
||||
t.OnAdminAfterAuthRefreshRequest().Add(count[*core.AdminAuthRefreshEvent](c, "OnAdminAfterAuthRefreshRequest"))
|
||||
t.OnAdminBeforeRequestPasswordResetRequest().Add(count[*core.AdminRequestPasswordResetEvent](c, "OnAdminBeforeRequestPasswordResetRequest"))
|
||||
t.OnAdminAfterRequestPasswordResetRequest().Add(count[*core.AdminRequestPasswordResetEvent](c, "OnAdminAfterRequestPasswordResetRequest"))
|
||||
t.OnAdminBeforeConfirmPasswordResetRequest().Add(count[*core.AdminConfirmPasswordResetEvent](c, "OnAdminBeforeConfirmPasswordResetRequest"))
|
||||
t.OnAdminAfterConfirmPasswordResetRequest().Add(count[*core.AdminConfirmPasswordResetEvent](c, "OnAdminAfterConfirmPasswordResetRequest"))
|
||||
t.OnFileDownloadRequest().Add(count[*core.FileDownloadEvent](c, "OnFileDownloadRequest"))
|
||||
t.OnFileBeforeTokenRequest().Add(count[*core.FileTokenEvent](c, "OnFileBeforeTokenRequest"))
|
||||
t.OnFileAfterTokenRequest().Add(count[*core.FileTokenEvent](c, "OnFileAfterTokenRequest"))
|
||||
t.OnFileAfterTokenRequest().Add(count[*core.FileTokenEvent](c, "OnFileAfterTokenRequest"))
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func count[T any](c *Counter, name string) func(_ T) error {
|
||||
return func(_ T) error {
|
||||
c.Increment(name)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ func defaultTestData(t *testing.T, app core.App) {
|
||||
|
||||
adminTestData(t, app)
|
||||
userTestData(t, app)
|
||||
ticketTestData(t, app)
|
||||
reactionTestData(t, app)
|
||||
}
|
||||
|
||||
@@ -57,6 +58,30 @@ func userTestData(t *testing.T, app core.App) {
|
||||
}
|
||||
}
|
||||
|
||||
func ticketTestData(t *testing.T, app core.App) {
|
||||
t.Helper()
|
||||
|
||||
collection, err := app.Dao().FindCollectionByNameOrId(migrations.TicketCollectionName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
record := models.NewRecord(collection)
|
||||
record.SetId("t_test")
|
||||
|
||||
record.Set("name", "Test Ticket")
|
||||
record.Set("type", "incident")
|
||||
record.Set("description", "This is a test ticket.")
|
||||
record.Set("open", true)
|
||||
record.Set("schema", `{"type":"object","properties":{"tlp":{"title":"TLP","type":"string"}}}`)
|
||||
record.Set("state", `{"tlp":"AMBER"}`)
|
||||
record.Set("owner", "u_bob_analyst")
|
||||
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func reactionTestData(t *testing.T, app core.App) {
|
||||
t.Helper()
|
||||
|
||||
@@ -69,9 +94,9 @@ func reactionTestData(t *testing.T, app core.App) {
|
||||
record.SetId("r_reaction")
|
||||
record.Set("name", "Reaction")
|
||||
record.Set("trigger", "webhook")
|
||||
record.Set("triggerdata", `{"path":"test"}`)
|
||||
record.Set("triggerdata", `{"token":"1234567890","path":"test"}`)
|
||||
record.Set("action", "python")
|
||||
record.Set("actiondata", `{"bootstrap":"requests","script":"print('Hello, World!')"}`)
|
||||
record.Set("actiondata", `{"requirements":"requests","script":"print('Hello, World!')"}`)
|
||||
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -95,7 +120,7 @@ func reactionTestData(t *testing.T, app core.App) {
|
||||
record.Set("trigger", "hook")
|
||||
record.Set("triggerdata", `{"collections":["tickets"],"events":["create"]}`)
|
||||
record.Set("action", "python")
|
||||
record.Set("actiondata", `{"bootstrap":"requests","script":"import requests\nrequests.post('http://127.0.0.1:12346/test', json={'test':True})"}`)
|
||||
record.Set("actiondata", `{"requirements":"requests","script":"import requests\nrequests.post('http://127.0.0.1:12346/test', json={'test':True})"}`)
|
||||
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -3,162 +3,95 @@ package testing
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"fmt"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase/apis"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tests"
|
||||
"github.com/pocketbase/pocketbase/tokens"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/app"
|
||||
"github.com/SecurityBrewery/catalyst/migrations"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func BaseApp(t *testing.T) (core.App, string, string, func()) {
|
||||
t.Helper()
|
||||
|
||||
temp, err := os.MkdirTemp("", "catalyst_test_data")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
baseApp := app.App(temp)
|
||||
|
||||
if err := app.Bootstrap(baseApp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defaultTestData(t, baseApp)
|
||||
|
||||
adminToken, err := generateAdminToken(t, baseApp, adminEmail)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
analystToken, err := generateRecordToken(t, baseApp, analystEmail)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return baseApp, adminToken, analystToken, func() { _ = os.RemoveAll(temp) }
|
||||
}
|
||||
|
||||
func AppFactory(baseApp core.App) func(t *testing.T) *tests.TestApp {
|
||||
return func(t *testing.T) *tests.TestApp {
|
||||
t.Helper()
|
||||
|
||||
testApp, err := tests.NewTestApp(baseApp.DataDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
app.BindHooks(testApp)
|
||||
|
||||
if err := app.Bootstrap(testApp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return testApp
|
||||
}
|
||||
}
|
||||
|
||||
func App(t *testing.T) (*tests.TestApp, func()) {
|
||||
t.Helper()
|
||||
|
||||
baseApp, _, _, cleanup := BaseApp(t)
|
||||
|
||||
testApp := AppFactory(baseApp)(t)
|
||||
|
||||
return testApp, cleanup
|
||||
}
|
||||
|
||||
func generateAdminToken(t *testing.T, baseApp core.App, email string) (string, error) {
|
||||
t.Helper()
|
||||
|
||||
app, err := tests.NewTestApp(baseApp.DataDir())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer app.Cleanup()
|
||||
|
||||
admin, err := app.Dao().FindAdminByEmail(email)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokens.NewAdminAuthToken(app, admin)
|
||||
}
|
||||
|
||||
func generateRecordToken(t *testing.T, baseApp core.App, email string) (string, error) {
|
||||
t.Helper()
|
||||
|
||||
app, err := tests.NewTestApp(baseApp.DataDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer app.Cleanup()
|
||||
|
||||
record, err := app.Dao().FindAuthRecordByEmail(migrations.UserCollectionName, email)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokens.NewRecordAuthToken(app, record)
|
||||
}
|
||||
|
||||
type BaseTest struct {
|
||||
Name string
|
||||
Method string
|
||||
RequestHeaders map[string]string
|
||||
URL string
|
||||
Body string
|
||||
TestAppFactory func(t *testing.T) *tests.TestApp
|
||||
}
|
||||
|
||||
type AuthBasedExpectation struct {
|
||||
type UserTest struct {
|
||||
Name string
|
||||
RequestHeaders map[string]string
|
||||
AuthRecord string
|
||||
Admin string
|
||||
ExpectedStatus int
|
||||
ExpectedContent []string
|
||||
NotExpectedContent []string
|
||||
ExpectedEvents map[string]int
|
||||
}
|
||||
|
||||
type authMatrixText struct {
|
||||
baseTest BaseTest
|
||||
authBasedExpectations []AuthBasedExpectation
|
||||
type catalystTest struct {
|
||||
baseTest BaseTest
|
||||
userTests []UserTest
|
||||
}
|
||||
|
||||
func mergeScenario(base BaseTest, expectation AuthBasedExpectation) tests.ApiScenario {
|
||||
return tests.ApiScenario{
|
||||
Name: expectation.Name,
|
||||
Method: base.Method,
|
||||
Url: base.URL,
|
||||
Body: bytes.NewBufferString(base.Body),
|
||||
TestAppFactory: base.TestAppFactory,
|
||||
func runMatrixTest(t *testing.T, baseTest BaseTest, userTest UserTest) {
|
||||
t.Helper()
|
||||
|
||||
RequestHeaders: mergeMaps(base.RequestHeaders, expectation.RequestHeaders),
|
||||
ExpectedStatus: expectation.ExpectedStatus,
|
||||
ExpectedContent: expectation.ExpectedContent,
|
||||
NotExpectedContent: expectation.NotExpectedContent,
|
||||
ExpectedEvents: expectation.ExpectedEvents,
|
||||
}
|
||||
}
|
||||
baseApp, counter, baseAppCleanup := App(t)
|
||||
defer baseAppCleanup()
|
||||
|
||||
func mergeMaps(a, b map[string]string) map[string]string {
|
||||
if a == nil {
|
||||
return b
|
||||
server, err := apis.InitApi(baseApp)
|
||||
require.NoError(t, err)
|
||||
|
||||
if err := baseApp.OnBeforeServe().Trigger(&core.ServeEvent{
|
||||
App: baseApp,
|
||||
Router: server,
|
||||
}); err != nil {
|
||||
t.Fatal(fmt.Errorf("failed to trigger OnBeforeServe: %w", err))
|
||||
}
|
||||
|
||||
if b == nil {
|
||||
return a
|
||||
recorder := httptest.NewRecorder()
|
||||
body := bytes.NewBufferString(baseTest.Body)
|
||||
req := httptest.NewRequest(baseTest.Method, baseTest.URL, body)
|
||||
|
||||
for k, v := range baseTest.RequestHeaders {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
for k, v := range b {
|
||||
a[k] = v
|
||||
if userTest.AuthRecord != "" {
|
||||
token, err := generateRecordToken(t, baseApp, userTest.AuthRecord)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set("Authorization", token)
|
||||
}
|
||||
|
||||
return a
|
||||
if userTest.Admin != "" {
|
||||
token, err := generateAdminToken(t, baseApp, userTest.Admin)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set("Authorization", token)
|
||||
}
|
||||
|
||||
server.ServeHTTP(recorder, req)
|
||||
|
||||
res := recorder.Result()
|
||||
defer res.Body.Close()
|
||||
|
||||
assert.Equal(t, userTest.ExpectedStatus, res.StatusCode)
|
||||
|
||||
for _, expectedContent := range userTest.ExpectedContent {
|
||||
assert.Contains(t, recorder.Body.String(), expectedContent)
|
||||
}
|
||||
|
||||
for _, notExpectedContent := range userTest.NotExpectedContent {
|
||||
assert.NotContains(t, recorder.Body.String(), notExpectedContent)
|
||||
}
|
||||
|
||||
for event, count := range userTest.ExpectedEvents {
|
||||
assert.Equal(t, count, counter.Count(event))
|
||||
}
|
||||
}
|
||||
|
||||
func b(data map[string]any) []byte {
|
||||
|
||||
Reference in New Issue
Block a user