Files
2026-09-05 15:30:20 +00:00

188 lines
6.7 KiB
Go

package gitlab
import (
"context"
"testing"
"time"
"github.com/kandev/kandev/internal/testutil"
)
func TestPostgresStoreSchemaReplay(t *testing.T) {
ctx := context.Background()
database := testutil.OpenIsolatedPostgres(t, testutil.PostgresDSNFromEnv(t))
if _, err := database.Exec(`
CREATE TABLE workspaces (id TEXT PRIMARY KEY);
CREATE TABLE tasks (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL,
archived_at TIMESTAMPTZ
);
INSERT INTO workspaces (id) VALUES ('ws-1');
INSERT INTO tasks (id, workspace_id, archived_at) VALUES ('task-1', 'ws-1', NULL)`); err != nil {
t.Fatalf("create prerequisite tables: %v", err)
}
store, err := NewStore(database, database)
if err != nil {
t.Fatalf("first GitLab store schema init: %v", err)
}
if _, err := NewStore(database, database); err != nil {
t.Fatalf("second GitLab store schema init: %v", err)
}
config := &GitLabConfig{
Host: "https://gitlab.example.com",
AuthMethod: "pat",
Username: "alice",
}
if err := store.UpsertConfigForWorkspace(ctx, "ws-1", config); err != nil {
t.Fatalf("upsert GitLab config: %v", err)
}
gotConfig, err := store.GetConfigForWorkspace(ctx, "ws-1")
if err != nil || gotConfig == nil || gotConfig.Host != config.Host {
t.Fatalf("get GitLab config: config=%+v err=%v", gotConfig, err)
}
if updated, err := store.UpdateConfigHealthForRevision(
ctx, "ws-1", "alice", true, "", time.Now().UTC(), gotConfig.Revision,
); err != nil || !updated {
t.Fatalf("update GitLab config health: updated=%v err=%v", updated, err)
}
if err := store.UpsertMentionScope(ctx, &MentionScope{
WorkspaceID: "ws-1",
Host: "https://gitlab.example.com",
Projects: []MentionProjectScope{{ID: 7, Path: "group/project"}},
}); err != nil {
t.Fatalf("upsert GitLab mention scope: %v", err)
}
gotScope, err := store.GetMentionScope(ctx, "ws-1")
if err != nil || gotScope == nil || len(gotScope.Projects) != 1 {
t.Fatalf("get GitLab mention scope: scope=%+v err=%v", gotScope, err)
}
mergeRequest := &TaskMR{
TaskID: "task-1",
ProjectPath: "group/project",
MRIID: 42,
MRURL: "https://gitlab.example.com/group/project/-/merge_requests/42",
MRTitle: "Parity",
HeadBranch: "feature/parity",
BaseBranch: "main",
Draft: true,
}
if err := store.UpsertTaskMR(ctx, mergeRequest); err != nil {
t.Fatalf("upsert GitLab task MR: %v", err)
}
gotMR, err := store.GetTaskMR(ctx, "task-1", "", "group/project", 42)
if err != nil || gotMR == nil || !gotMR.Draft {
t.Fatalf("get GitLab task MR: mr=%+v err=%v", gotMR, err)
}
if err := store.UpdateTaskMRUnresolvedDiscussions(ctx, mergeRequest.ID, 3); err != nil {
t.Fatalf("update GitLab task MR discussions: %v", err)
}
identity := MRIdentity{ProjectPath: "group/project", MRIID: 42}
trueValue := true
options, err := store.UpdateTaskMRAutomationOptionsForMR(ctx, "task-1", identity, TaskMRAutomationSwitchPatch{
AutoMergeEnabled: &trueValue,
PromptOnReviewRequested: &trueValue,
})
if err != nil || options == nil || !options.AutoMergeEnabled || !options.PromptOnReviewRequested {
t.Fatalf("update GitLab MR automation: options=%+v err=%v", options, err)
}
if err := store.SetTaskMRReviewRequestState(ctx, "task-1", "", "group/project", 42, true); err != nil {
t.Fatalf("set GitLab MR review state: %v", err)
}
if err := store.SetTaskMRObservedState(ctx, "task-1", "", "group/project", 42, gitlabStateMerged); err != nil {
t.Fatalf("set GitLab MR observed state: %v", err)
}
if err := store.RecordTaskMRLifecyclePrompt(ctx, TaskMRLifecyclePrompt{
TaskID: "task-1",
ProjectPath: "group/project",
MRIID: 42,
Event: mrLifecycleEventReviewRequested,
ReviewRequested: true,
}); err != nil {
t.Fatalf("record GitLab MR lifecycle prompt: %v", err)
}
if _, err := store.GetTaskMRLifecycleState(ctx, "task-1", "", "group/project", 42); err != nil {
t.Fatalf("get GitLab MR lifecycle state: %v", err)
}
if subscribed, err := store.ListAutomationSubscribedTaskMRs(ctx); err != nil || len(subscribed) != 1 {
t.Fatalf("list GitLab automation MRs: mrs=%d err=%v", len(subscribed), err)
}
refreshWatch := &MRWatch{
SessionID: "session-1",
TaskID: "task-1",
ProjectPath: "group/project",
MRIID: 42,
Branch: "feature/parity",
}
if err := store.CreateMRWatch(ctx, refreshWatch); err != nil {
t.Fatalf("create GitLab MR watch: %v", err)
}
if got, err := store.GetMRWatchBySession(ctx, "session-1"); err != nil || got == nil {
t.Fatalf("get GitLab MR watch: watch=%+v err=%v", got, err)
}
reviewWatch := &ReviewWatch{
WorkspaceID: "ws-1",
WorkflowID: "workflow-1",
WorkflowStepID: "step-1",
Projects: []ProjectFilter{{Path: "group/project"}},
AgentProfileID: "agent-1",
ExecutorProfileID: "executor-1",
Enabled: true,
}
if err := store.CreateReviewWatch(ctx, reviewWatch); err != nil {
t.Fatalf("create GitLab review watch: %v", err)
}
if _, err := store.ListEnabledReviewWatchesForWorkspace(ctx, "ws-1"); err != nil {
t.Fatalf("list GitLab review watches: %v", err)
}
reserved, err := store.ReserveReviewMRTask(ctx, reviewWatch.ID, "group/project", 43, "https://gitlab.example.com/mr/43")
if err != nil || !reserved {
t.Fatalf("reserve GitLab review MR task: reserved=%v err=%v", reserved, err)
}
if err := store.AssignReviewMRTaskID(ctx, reviewWatch.ID, "group/project", 43, "task-1"); err != nil {
t.Fatalf("assign GitLab review MR task: %v", err)
}
issueWatch := &IssueWatch{
WorkspaceID: "ws-1",
WorkflowID: "workflow-1",
WorkflowStepID: "step-1",
Projects: []ProjectFilter{{Path: "group/project"}},
Labels: []string{"bug"},
AgentProfileID: "agent-1",
ExecutorProfileID: "executor-1",
Enabled: true,
}
if err := store.CreateIssueWatch(ctx, issueWatch); err != nil {
t.Fatalf("create GitLab issue watch: %v", err)
}
if _, err := store.ListEnabledIssueWatchesForWorkspace(ctx, "ws-1"); err != nil {
t.Fatalf("list GitLab issue watches: %v", err)
}
reserved, err = store.ReserveIssueWatchTask(ctx, issueWatch.ID, "group/project", 9, "https://gitlab.example.com/issue/9")
if err != nil || !reserved {
t.Fatalf("reserve GitLab issue task: reserved=%v err=%v", reserved, err)
}
if err := store.AssignIssueWatchTaskID(ctx, issueWatch.ID, "group/project", 9, "task-1"); err != nil {
t.Fatalf("assign GitLab issue task: %v", err)
}
if err := store.UpsertActionPresets(ctx, &ActionPresets{
WorkspaceID: "ws-1",
MR: DefaultMRActionPresets(),
Issue: DefaultIssueActionPresets(),
}); err != nil {
t.Fatalf("upsert GitLab action presets: %v", err)
}
if _, err := store.GetActionPresets(ctx, "ws-1"); err != nil {
t.Fatalf("get GitLab action presets: %v", err)
}
}