package apis_test import ( "net/http" "testing" "time" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tests" "github.com/spf13/cast" ) func TestCronsList(t *testing.T) { t.Parallel() scenarios := []tests.ApiScenario{ { Name: "unauthorized", Method: http.MethodGet, URL: "/api/crons", ExpectedStatus: 401, ExpectedContent: []string{`"data":{}`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as regular user", Method: http.MethodGet, URL: "/api/crons", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo", }, ExpectedStatus: 403, ExpectedContent: []string{`"data":{}`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as superuser (empty list)", Method: http.MethodGet, URL: "/api/crons", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", }, BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) { app.Cron().RemoveAll() }, ExpectedStatus: 200, ExpectedContent: []string{`[]`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as superuser", Method: http.MethodGet, URL: "/api/crons", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", }, ExpectedStatus: 200, ExpectedContent: []string{ `{"id":"__pbLogsCleanup__","expression":"0 */6 * * *"}`, `{"id":"__pbDBOptimize__","expression":"0 0 * * *"}`, `{"id":"__pbMFACleanup__","expression":"0 * * * *"}`, `{"id":"__pbOTPCleanup__","expression":"0 * * * *"}`, }, ExpectedEvents: map[string]int{"*": 0}, }, } for _, scenario := range scenarios { scenario.Test(t) } } func TestCronsRun(t *testing.T) { t.Parallel() beforeTestFunc := func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) { app.Cron().Add("test", "* * * * *", func() { app.Store().Set("testJobCalls", cast.ToInt(app.Store().Get("testJobCalls"))+1) }) } expectedCalls := func(expected int) func(t testing.TB, app *tests.TestApp, res *http.Response) { return func(t testing.TB, app *tests.TestApp, res *http.Response) { total := cast.ToInt(app.Store().Get("testJobCalls")) if total != expected { t.Fatalf("Expected total testJobCalls %d, got %d", expected, total) } } } scenarios := []tests.ApiScenario{ { Name: "unauthorized", Method: http.MethodPost, URL: "/api/crons/test", Delay: 50 * time.Millisecond, BeforeTestFunc: beforeTestFunc, AfterTestFunc: expectedCalls(0), ExpectedStatus: 401, ExpectedContent: []string{`"data":{}`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as regular user", Method: http.MethodPost, URL: "/api/crons/test", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo", }, Delay: 50 * time.Millisecond, BeforeTestFunc: beforeTestFunc, AfterTestFunc: expectedCalls(0), ExpectedStatus: 403, ExpectedContent: []string{`"data":{}`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as superuser (missing job)", Method: http.MethodPost, URL: "/api/crons/missing", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", }, Delay: 50 * time.Millisecond, BeforeTestFunc: beforeTestFunc, AfterTestFunc: expectedCalls(0), ExpectedStatus: 404, ExpectedContent: []string{`"data":{}`}, ExpectedEvents: map[string]int{"*": 0}, }, { Name: "authorized as superuser (existing job)", Method: http.MethodPost, URL: "/api/crons/test", Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", }, Delay: 50 * time.Millisecond, BeforeTestFunc: beforeTestFunc, AfterTestFunc: expectedCalls(1), ExpectedStatus: 204, ExpectedEvents: map[string]int{"*": 0}, }, } for _, scenario := range scenarios { scenario.Test(t) } }