(t *testing.T)
| 99 | } |
| 100 | |
| 101 | func TestEngine_Idempotent(t *testing.T) { |
| 102 | sourceName := "test-idempotent" |
| 103 | defer cleanupRegistry(sourceName) |
| 104 | |
| 105 | tasks := []ExternalTask{ |
| 106 | {ExternalID: "EXT-1", Title: "A task", Status: "open"}, |
| 107 | } |
| 108 | setupMockSource(sourceName, tasks) |
| 109 | |
| 110 | dir := t.TempDir() |
| 111 | outputDir := filepath.Join(dir, "tasks") |
| 112 | |
| 113 | engine := &Engine{ConfigDir: dir} |
| 114 | srcCfg := SourceConfig{ |
| 115 | Name: sourceName, |
| 116 | OutputDir: outputDir, |
| 117 | FieldMap: FieldMap{Status: map[string]string{"open": "pending"}}, |
| 118 | } |
| 119 | |
| 120 | // First sync |
| 121 | result1, err := engine.RunSync(srcCfg) |
| 122 | if err != nil { |
| 123 | t.Fatalf("first sync error: %v", err) |
| 124 | } |
| 125 | if len(result1.Created) != 1 { |
| 126 | t.Fatalf("expected 1 created, got %d", len(result1.Created)) |
| 127 | } |
| 128 | |
| 129 | // Second sync — same data, should skip |
| 130 | result2, err := engine.RunSync(srcCfg) |
| 131 | if err != nil { |
| 132 | t.Fatalf("second sync error: %v", err) |
| 133 | } |
| 134 | if len(result2.Created) != 0 { |
| 135 | t.Errorf("expected 0 created on second sync, got %d", len(result2.Created)) |
| 136 | } |
| 137 | if len(result2.Skipped) != 1 { |
| 138 | t.Errorf("expected 1 skipped on second sync, got %d", len(result2.Skipped)) |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | func TestEngine_UpdateOnExternalChange(t *testing.T) { |
| 143 | sourceName := "test-update" |
nothing calls this directly
no test coverage detected