117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"testing"
|
||
|
||
"verstak/internal/core/activity"
|
||
"verstak/internal/core/util"
|
||
"verstak/internal/core/worklog"
|
||
)
|
||
|
||
// TestAcceptSuggestionWithEndToEnd verifies the full chain:
|
||
// 1. Create a node
|
||
// 2. Create activity events for that node
|
||
// 3. Accept a suggestion with those event IDs
|
||
// 4. Verify worklog_entry_events contains exactly those events
|
||
// 5. Verify GetWorklogEntryEvents returns the linked events
|
||
func TestAcceptSuggestionWithEndToEnd(t *testing.T) {
|
||
app, _ := setupTestApp(t)
|
||
|
||
// 1. Create a node
|
||
n, err := app.CreateNodeFromTemplate("", "Test Suggestion", "folder.default")
|
||
if err != nil {
|
||
t.Fatalf("create node: %v", err)
|
||
}
|
||
|
||
// 2. Create activity events for the node.
|
||
// We need to insert events with today's timestamp so GetSuggestions picks them up.
|
||
// But to avoid time dependency, we also directly accept with known event IDs.
|
||
eid1 := insertTestEvent(t, app, n.ID, activity.TypeNoteCreated, "note", "note1", "Test note 1")
|
||
eid2 := insertTestEvent(t, app, n.ID, activity.TypeNoteUpdated, "note", "note1", "Test note 1 updated")
|
||
eid3 := insertTestEvent(t, app, n.ID, activity.TypeFileAdded, "file", "file1", "Test file")
|
||
|
||
eventIDs := []string{eid1, eid2, eid3}
|
||
eventIDsJSON, _ := json.Marshal(eventIDs)
|
||
|
||
// 3. Accept suggestion with these event IDs
|
||
dto, err := app.AcceptSuggestionWith(n.ID, "Работа с заметками", 15, "", string(eventIDsJSON))
|
||
if err != nil {
|
||
t.Fatalf("AcceptSuggestionWith: %v", err)
|
||
}
|
||
|
||
if dto.ID == "" {
|
||
t.Fatal("AcceptSuggestionWith returned empty entry ID")
|
||
}
|
||
|
||
// 4. Verify worklog_entry_events count
|
||
var linkCount int
|
||
err = app.db.QueryRow(
|
||
`SELECT COUNT(*) FROM worklog_entry_events WHERE entry_id = ?`, dto.ID).Scan(&linkCount)
|
||
if err != nil {
|
||
t.Fatalf("count worklog_entry_events: %v", err)
|
||
}
|
||
if linkCount != 3 {
|
||
t.Errorf("worklog_entry_events count = %d, want 3", linkCount)
|
||
}
|
||
|
||
// 5. Verify JOIN with activity_events
|
||
var joinCount int
|
||
err = app.db.QueryRow(
|
||
`SELECT COUNT(*) FROM worklog_entry_events wle
|
||
JOIN activity_events ae ON ae.id = wle.event_id
|
||
WHERE wle.entry_id = ?`, dto.ID).Scan(&joinCount)
|
||
if err != nil {
|
||
t.Fatalf("join count: %v", err)
|
||
}
|
||
if joinCount != 3 {
|
||
t.Errorf("JOIN count = %d, want 3", joinCount)
|
||
}
|
||
|
||
// 6. Call GetWorklogEntryEvents and verify 3 events
|
||
events, err := app.GetWorklogEntryEvents(dto.ID)
|
||
if err != nil {
|
||
t.Fatalf("GetWorklogEntryEvents: %v", err)
|
||
}
|
||
if len(events) != 3 {
|
||
t.Errorf("GetWorklogEntryEvents returned %d events, want 3", len(events))
|
||
}
|
||
|
||
// 7. Verify the returned event IDs match
|
||
returnedIDs := make(map[string]bool, len(events))
|
||
for _, ev := range events {
|
||
returnedIDs[ev.ID] = true
|
||
}
|
||
for _, want := range eventIDs {
|
||
if !returnedIDs[want] {
|
||
t.Errorf("event %s not found in GetWorklogEntryEvents result", want)
|
||
}
|
||
}
|
||
|
||
// 8. Verify source is 'suggestion'
|
||
var source string
|
||
err = app.db.QueryRow(
|
||
`SELECT source FROM worklog_entries WHERE id = ?`, dto.ID).Scan(&source)
|
||
if err != nil {
|
||
t.Fatalf("get source: %v", err)
|
||
}
|
||
if source != worklog.SourceSuggestion {
|
||
t.Errorf("source = %q, want %q", source, worklog.SourceSuggestion)
|
||
}
|
||
}
|
||
|
||
// insertTestEvent inserts an activity event and returns its ID.
|
||
func insertTestEvent(t *testing.T, app *App, nodeID, eventType, targetType, targetID, title string) string {
|
||
t.Helper()
|
||
id := util.UUID7()
|
||
now := "2026-06-03T12:00:00Z"
|
||
_, err := app.db.Exec(
|
||
`INSERT INTO activity_events(id,node_id,event_type,target_type,target_id,target_path,title,metadata,created_at)
|
||
VALUES(?,?,?,?,?,?,?,?,?)`,
|
||
id, nodeID, eventType, targetType, targetID, "", title, "{}", now)
|
||
if err != nil {
|
||
t.Fatalf("insert event: %v", err)
|
||
}
|
||
return id
|
||
}
|