Files
wehub-resource-sync 75f3dd141c
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CI and Release / lint-frontend (push) Has been cancelled
CI and Release / dockerfile-scan (push) Has been cancelled
CI and Release / test-frontend (push) Has been cancelled
CI and Release / lint-verification-agent (push) Has been cancelled
CI and Release / test-verification-agent (push) Has been cancelled
CI and Release / e2e-verification-agent (push) Has been cancelled
CI and Release / test-backend (push) Has been cancelled
CI and Release / build-dev-image (push) Has been cancelled
CI and Release / push-dev-image (push) Has been cancelled
CI and Release / build-image (push) Has been cancelled
CI and Release / build-verification-image (push) Has been cancelled
CI and Release / determine-version (push) Has been cancelled
CI and Release / push-image (push) Has been cancelled
CI and Release / push-verification-image (12) (push) Has been cancelled
CI and Release / lint-backend (push) Has been cancelled
CI and Release / push-verification-image (17) (push) Has been cancelled
CI and Release / push-verification-image (18) (push) Has been cancelled
CI and Release / release (push) Has been cancelled
CI and Release / publish-helm-chart (push) Has been cancelled
CI and Release / push-verification-image (13) (push) Has been cancelled
CI and Release / push-verification-image (14) (push) Has been cancelled
CI and Release / push-verification-image (15) (push) Has been cancelled
CI and Release / push-verification-image (16) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:11:07 +08:00

378 lines
12 KiB
Go

package verification_config
import (
"encoding/json"
"net/http"
"testing"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"databasus-backend/internal/features/databases"
"databasus-backend/internal/features/intervals"
users_enums "databasus-backend/internal/features/users/enums"
users_testing "databasus-backend/internal/features/users/testing"
workspaces_controllers "databasus-backend/internal/features/workspaces/controllers"
workspaces_testing "databasus-backend/internal/features/workspaces/testing"
test_utils "databasus-backend/internal/util/testing"
)
func createTestRouter() *gin.Engine {
return workspaces_testing.CreateTestRouter(
workspaces_controllers.GetWorkspaceController(),
workspaces_controllers.GetMembershipController(),
databases.GetDatabaseController(),
GetVerificationConfigController(),
)
}
func newEnabledRequest() SaveBackupVerificationConfigDTO {
return SaveBackupVerificationConfigDTO{
IsScheduledVerificationEnabled: true,
ScheduleType: VerificationScheduleInterval,
VerificationInterval: intervals.Interval{
Type: intervals.IntervalWeekly,
TimeOfDay: new("04:00"),
Weekday: new(0),
},
SendNotificationsOn: []VerificationNotificationType{
NotificationVerificationFailed,
},
}
}
func createTestDatabaseViaAPI(
name string,
workspaceID uuid.UUID,
token string,
router *gin.Engine,
) *databases.Database {
request := databases.Database{
WorkspaceID: &workspaceID,
Name: name,
Type: databases.DatabaseTypePostgresLogical,
PostgresqlLogical: databases.GetTestPostgresConfig(),
}
w := workspaces_testing.MakeAPIRequest(
router,
"POST",
"/api/v1/databases/create",
"Bearer "+token,
request,
)
if w.Code != http.StatusCreated {
panic("Failed to create database")
}
var database databases.Database
if err := json.Unmarshal(w.Body.Bytes(), &database); err != nil {
panic(err)
}
return &database
}
func Test_GetByDatabaseID_WhenNoRowExists_LazyCreatesDisabledDefault(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
var response BackupVerificationConfig
test_utils.MakeGetRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
http.StatusOK,
&response,
)
assert.Equal(t, database.ID, response.DatabaseID)
assert.False(t, response.IsScheduledVerificationEnabled)
assert.Equal(t, VerificationScheduleAfterBackup, response.ScheduleType)
assert.Equal(t, intervals.IntervalWeekly, response.VerificationInterval.Type)
assert.NotNil(t, response.VerificationInterval.TimeOfDay)
assert.Equal(t, "04:00", *response.VerificationInterval.TimeOfDay)
assert.NotNil(t, response.VerificationInterval.Weekday)
assert.Equal(t, 0, *response.VerificationInterval.Weekday)
assert.Equal(
t,
[]VerificationNotificationType{NotificationVerificationFailed},
response.SendNotificationsOn,
)
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_GetByDatabaseID_WhenUserNotInWorkspace_ReturnsError(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
nonMember := users_testing.CreateTestUser(users_enums.UserRoleMember)
resp := test_utils.MakeGetRequest(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+nonMember.Token,
http.StatusBadRequest,
)
assert.Contains(t, string(resp.Body), "insufficient permissions")
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_AsOwner_PersistsAndReturns(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
request := newEnabledRequest()
request.SendNotificationsOn = []VerificationNotificationType{
NotificationVerificationSuccess,
NotificationVerificationFailed,
}
var response BackupVerificationConfig
test_utils.MakePutRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
request,
http.StatusOK,
&response,
)
assert.Equal(t, database.ID, response.DatabaseID)
assert.True(t, response.IsScheduledVerificationEnabled)
assert.Equal(t, intervals.IntervalWeekly, response.VerificationInterval.Type)
assert.ElementsMatch(t,
[]VerificationNotificationType{
NotificationVerificationSuccess,
NotificationVerificationFailed,
},
response.SendNotificationsOn,
)
var fetched BackupVerificationConfig
test_utils.MakeGetRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
http.StatusOK,
&fetched,
)
assert.True(t, fetched.IsScheduledVerificationEnabled)
assert.ElementsMatch(t,
[]VerificationNotificationType{
NotificationVerificationSuccess,
NotificationVerificationFailed,
},
fetched.SendNotificationsOn,
)
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_AsViewer_RejectedWithPermissionError(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
viewer := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspaces_testing.AddMemberToWorkspace(
workspace,
viewer,
users_enums.WorkspaceRoleViewer,
owner.Token,
router,
)
resp := test_utils.MakePutRequest(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+viewer.Token,
newEnabledRequest(),
http.StatusBadRequest,
)
assert.Contains(t, string(resp.Body), "insufficient permissions")
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_WhenEnabled_WithInvalidInterval_ReturnsValidationError(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
request := newEnabledRequest()
request.VerificationInterval = intervals.Interval{
Type: intervals.IntervalCron,
}
resp := test_utils.MakePutRequest(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
request,
http.StatusBadRequest,
)
assert.Contains(t, string(resp.Body), "cron expression")
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_WithInvalidNotificationType_ReturnsValidationError(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
request := newEnabledRequest()
request.SendNotificationsOn = []VerificationNotificationType{
VerificationNotificationType("VERIFICATION_EXPIRED"),
}
resp := test_utils.MakePutRequest(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
request,
http.StatusBadRequest,
)
assert.Contains(t, string(resp.Body), "invalid verification notification type")
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_WhenScheduleTypeAfterBackup_SkipsIntervalValidationAndPersists(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
request := SaveBackupVerificationConfigDTO{
IsScheduledVerificationEnabled: true,
ScheduleType: VerificationScheduleAfterBackup,
// Deliberately invalid as a time interval — must be ignored in after-backup mode.
VerificationInterval: intervals.Interval{Type: intervals.IntervalCron},
SendNotificationsOn: []VerificationNotificationType{NotificationVerificationFailed},
}
var response BackupVerificationConfig
test_utils.MakePutRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
request,
http.StatusOK,
&response,
)
assert.True(t, response.IsScheduledVerificationEnabled)
assert.Equal(t, VerificationScheduleAfterBackup, response.ScheduleType)
var fetched BackupVerificationConfig
test_utils.MakeGetRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
http.StatusOK,
&fetched,
)
assert.Equal(t, VerificationScheduleAfterBackup, fetched.ScheduleType)
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_Save_WhenScheduleTypeInvalid_ReturnsValidationError(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
database := createTestDatabaseViaAPI("Test Database", workspace.ID, owner.Token, router)
request := newEnabledRequest()
request.ScheduleType = VerificationScheduleType("WHENEVER")
resp := test_utils.MakePutRequest(
t,
router,
"/api/v1/verification-config/"+database.ID.String(),
"Bearer "+owner.Token,
request,
http.StatusBadRequest,
)
assert.Contains(t, string(resp.Body), "invalid verification schedule type")
databases.RemoveTestDatabase(database)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}
func Test_OnDatabaseCopied_CopiesConfigOntoNewDatabase(t *testing.T) {
router := createTestRouter()
owner := users_testing.CreateTestUser(users_enums.UserRoleMember)
workspace := workspaces_testing.CreateTestWorkspace("Test Workspace", owner, router)
source := createTestDatabaseViaAPI("Source Database", workspace.ID, owner.Token, router)
target := createTestDatabaseViaAPI("Target Database", workspace.ID, owner.Token, router)
saveRequest := newEnabledRequest()
saveRequest.SendNotificationsOn = []VerificationNotificationType{
NotificationVerificationSuccess,
NotificationVerificationFailed,
}
var saved BackupVerificationConfig
test_utils.MakePutRequestAndUnmarshal(
t,
router,
"/api/v1/verification-config/"+source.ID.String(),
"Bearer "+owner.Token,
saveRequest,
http.StatusOK,
&saved,
)
verificationConfigService.OnDatabaseCopied(source.ID, target.ID)
copied, err := verificationConfigRepository.GetByDatabaseID(target.ID)
assert.NoError(t, err)
assert.NotNil(t, copied)
assert.Equal(t, target.ID, copied.DatabaseID)
assert.True(t, copied.IsScheduledVerificationEnabled)
assert.Equal(t, intervals.IntervalWeekly, copied.VerificationInterval.Type)
assert.ElementsMatch(t,
[]VerificationNotificationType{
NotificationVerificationSuccess,
NotificationVerificationFailed,
},
copied.SendNotificationsOn,
)
databases.RemoveTestDatabase(source)
databases.RemoveTestDatabase(target)
workspaces_testing.RemoveTestWorkspace(workspace, router)
}