package store import ( "context" "testing" ) // AddAccountError persists individual errors; ListAccountErrors returns them in // insertion order; ClearAccountErrors wipes them for the next run. func TestAccountErrorsAddListClear(t *testing.T) { s := testStore(t) ctx := context.Background() epSrc, _ := s.CreateEndpoint(ctx, Endpoint{RoleLabel: "src", Host: "a", Port: 993, TLSMode: "ssl"}) epDst, _ := s.CreateEndpoint(ctx, Endpoint{RoleLabel: "dst", Host: "b", Port: 993, TLSMode: "ssl"}) taskID, _ := s.CreateTask(ctx, Task{Name: "t", SrcEndpointID: epSrc, DstEndpointID: epDst}) runID, _ := s.CreateRun(ctx, taskID, "manual") accID, _ := s.CreateAccount(ctx, Account{TaskID: taskID, SrcLogin: "u", SrcPassEnc: "x", DstLogin: "u2", DstPassEnc: "y"}) if err := s.AddAccountError(ctx, accID, runID, "folder", "INBOX", "", "examine failed"); err != nil { t.Fatalf("add folder: %v", err) } if err := s.AddAccountError(ctx, accID, runID, "message", "INBOX", "UID 42: hi", "append rejected"); err != nil { t.Fatalf("add message: %v", err) } errs, err := s.ListAccountErrors(ctx, accID) if err != nil { t.Fatalf("list: %v", err) } if len(errs) != 2 { t.Fatalf("len=%d want 2", len(errs)) } if errs[0].Kind != "folder" || errs[0].Folder != "INBOX" || errs[0].Error != "examine failed" { t.Fatalf("errs[0]=%+v", errs[0]) } if errs[1].Kind != "message" || errs[1].MessageRef != "UID 42: hi" || errs[1].Error != "append rejected" { t.Fatalf("errs[1]=%+v", errs[1]) } if errs[0].ID >= errs[1].ID { t.Fatalf("expected insertion order by id: %d then %d", errs[0].ID, errs[1].ID) } if err := s.ClearAccountErrors(ctx, accID); err != nil { t.Fatalf("clear: %v", err) } errs, err = s.ListAccountErrors(ctx, accID) if err != nil { t.Fatalf("list after clear: %v", err) } if len(errs) != 0 { t.Fatalf("after clear len=%d want 0", len(errs)) } } // Deleting an account cascades its errors (ON DELETE CASCADE). func TestAccountErrorsCascadeOnAccountDelete(t *testing.T) { s := testStore(t) ctx := context.Background() epSrc, _ := s.CreateEndpoint(ctx, Endpoint{RoleLabel: "src", Host: "a", Port: 993, TLSMode: "ssl"}) epDst, _ := s.CreateEndpoint(ctx, Endpoint{RoleLabel: "dst", Host: "b", Port: 993, TLSMode: "ssl"}) taskID, _ := s.CreateTask(ctx, Task{Name: "t", SrcEndpointID: epSrc, DstEndpointID: epDst}) accID, _ := s.CreateAccount(ctx, Account{TaskID: taskID, SrcLogin: "u", SrcPassEnc: "x", DstLogin: "u2", DstPassEnc: "y"}) _ = s.AddAccountError(ctx, accID, 0, "account", "", "", "login failed") if err := s.DeleteAccount(ctx, accID); err != nil { t.Fatalf("delete: %v", err) } var n int if err := s.Pool.QueryRow(ctx, `SELECT count(*) FROM account_errors WHERE account_id=$1`, accID).Scan(&n); err != nil { t.Fatalf("count: %v", err) } if n != 0 { t.Fatalf("account_errors not cascaded: %d rows", n) } }