forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at master 9.6 kB view raw
1package models 2 3import ( 4 "strings" 5 "testing" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/workflow" 9) 10 11func TestBuildCloneStep_PushTrigger(t *testing.T) { 12 twf := tangled.Pipeline_Workflow{ 13 Clone: &tangled.Pipeline_CloneOpts{ 14 Depth: 1, 15 Submodules: false, 16 Skip: false, 17 }, 18 } 19 tr := tangled.Pipeline_TriggerMetadata{ 20 Kind: string(workflow.TriggerKindPush), 21 Push: &tangled.Pipeline_PushTriggerData{ 22 NewSha: "abc123", 23 OldSha: "def456", 24 Ref: "refs/heads/main", 25 }, 26 Repo: &tangled.Pipeline_TriggerRepo{ 27 Knot: "example.com", 28 Did: "did:plc:user123", 29 Repo: "my-repo", 30 }, 31 } 32 33 step := BuildCloneStep(twf, tr, false) 34 35 if step.Kind() != StepKindSystem { 36 t.Errorf("Expected StepKindSystem, got %v", step.Kind()) 37 } 38 39 if step.Name() != "Clone repository into workspace" { 40 t.Errorf("Expected 'Clone repository into workspace', got '%s'", step.Name()) 41 } 42 43 commands := step.Commands() 44 if len(commands) != 4 { 45 t.Errorf("Expected 4 commands, got %d", len(commands)) 46 } 47 48 // Verify commands contain expected git operations 49 allCmds := strings.Join(commands, " ") 50 if !strings.Contains(allCmds, "git init") { 51 t.Error("Commands should contain 'git init'") 52 } 53 if !strings.Contains(allCmds, "git remote add origin") { 54 t.Error("Commands should contain 'git remote add origin'") 55 } 56 if !strings.Contains(allCmds, "git fetch") { 57 t.Error("Commands should contain 'git fetch'") 58 } 59 if !strings.Contains(allCmds, "abc123") { 60 t.Error("Commands should contain commit SHA") 61 } 62 if !strings.Contains(allCmds, "git checkout FETCH_HEAD") { 63 t.Error("Commands should contain 'git checkout FETCH_HEAD'") 64 } 65 if !strings.Contains(allCmds, "https://example.com/did:plc:user123/my-repo") { 66 t.Error("Commands should contain expected repo URL") 67 } 68} 69 70func TestBuildCloneStep_PullRequestTrigger(t *testing.T) { 71 twf := tangled.Pipeline_Workflow{ 72 Clone: &tangled.Pipeline_CloneOpts{ 73 Depth: 1, 74 Skip: false, 75 }, 76 } 77 tr := tangled.Pipeline_TriggerMetadata{ 78 Kind: string(workflow.TriggerKindPullRequest), 79 PullRequest: &tangled.Pipeline_PullRequestTriggerData{ 80 SourceSha: "pr-sha-789", 81 SourceBranch: "feature-branch", 82 TargetBranch: "main", 83 Action: "opened", 84 }, 85 Repo: &tangled.Pipeline_TriggerRepo{ 86 Knot: "example.com", 87 Did: "did:plc:user123", 88 Repo: "my-repo", 89 }, 90 } 91 92 step := BuildCloneStep(twf, tr, false) 93 94 allCmds := strings.Join(step.Commands(), " ") 95 if !strings.Contains(allCmds, "pr-sha-789") { 96 t.Error("Commands should contain PR commit SHA") 97 } 98} 99 100func TestBuildCloneStep_ManualTrigger(t *testing.T) { 101 twf := tangled.Pipeline_Workflow{ 102 Clone: &tangled.Pipeline_CloneOpts{ 103 Depth: 1, 104 Skip: false, 105 }, 106 } 107 tr := tangled.Pipeline_TriggerMetadata{ 108 Kind: string(workflow.TriggerKindManual), 109 Manual: &tangled.Pipeline_ManualTriggerData{ 110 Inputs: nil, 111 }, 112 Repo: &tangled.Pipeline_TriggerRepo{ 113 Knot: "example.com", 114 Did: "did:plc:user123", 115 Repo: "my-repo", 116 }, 117 } 118 119 step := BuildCloneStep(twf, tr, false) 120 121 // Manual triggers don't have a SHA yet (TODO), so git fetch won't include a SHA 122 allCmds := strings.Join(step.Commands(), " ") 123 // Should still have basic git commands 124 if !strings.Contains(allCmds, "git init") { 125 t.Error("Commands should contain 'git init'") 126 } 127 if !strings.Contains(allCmds, "git fetch") { 128 t.Error("Commands should contain 'git fetch'") 129 } 130} 131 132func TestBuildCloneStep_SkipFlag(t *testing.T) { 133 twf := tangled.Pipeline_Workflow{ 134 Clone: &tangled.Pipeline_CloneOpts{ 135 Skip: true, 136 }, 137 } 138 tr := tangled.Pipeline_TriggerMetadata{ 139 Kind: string(workflow.TriggerKindPush), 140 Push: &tangled.Pipeline_PushTriggerData{ 141 NewSha: "abc123", 142 }, 143 Repo: &tangled.Pipeline_TriggerRepo{ 144 Knot: "example.com", 145 Did: "did:plc:user123", 146 Repo: "my-repo", 147 }, 148 } 149 150 step := BuildCloneStep(twf, tr, false) 151 152 // Empty step when skip is true 153 if step.Name() != "" { 154 t.Error("Expected empty step name when Skip is true") 155 } 156 if len(step.Commands()) != 0 { 157 t.Errorf("Expected no commands when Skip is true, got %d commands", len(step.Commands())) 158 } 159} 160 161func TestBuildCloneStep_DevMode(t *testing.T) { 162 twf := tangled.Pipeline_Workflow{ 163 Clone: &tangled.Pipeline_CloneOpts{ 164 Depth: 1, 165 Skip: false, 166 }, 167 } 168 tr := tangled.Pipeline_TriggerMetadata{ 169 Kind: string(workflow.TriggerKindPush), 170 Push: &tangled.Pipeline_PushTriggerData{ 171 NewSha: "abc123", 172 }, 173 Repo: &tangled.Pipeline_TriggerRepo{ 174 Knot: "localhost:3000", 175 Did: "did:plc:user123", 176 Repo: "my-repo", 177 }, 178 } 179 180 step := BuildCloneStep(twf, tr, true) 181 182 // In dev mode, should use http:// and replace localhost with host.docker.internal 183 allCmds := strings.Join(step.Commands(), " ") 184 expectedURL := "http://host.docker.internal:3000/did:plc:user123/my-repo" 185 if !strings.Contains(allCmds, expectedURL) { 186 t.Errorf("Expected dev mode URL '%s' in commands", expectedURL) 187 } 188} 189 190func TestBuildCloneStep_DepthAndSubmodules(t *testing.T) { 191 twf := tangled.Pipeline_Workflow{ 192 Clone: &tangled.Pipeline_CloneOpts{ 193 Depth: 10, 194 Submodules: true, 195 Skip: false, 196 }, 197 } 198 tr := tangled.Pipeline_TriggerMetadata{ 199 Kind: string(workflow.TriggerKindPush), 200 Push: &tangled.Pipeline_PushTriggerData{ 201 NewSha: "abc123", 202 }, 203 Repo: &tangled.Pipeline_TriggerRepo{ 204 Knot: "example.com", 205 Did: "did:plc:user123", 206 Repo: "my-repo", 207 }, 208 } 209 210 step := BuildCloneStep(twf, tr, false) 211 212 allCmds := strings.Join(step.Commands(), " ") 213 if !strings.Contains(allCmds, "--depth=10") { 214 t.Error("Commands should contain '--depth=10'") 215 } 216 217 if !strings.Contains(allCmds, "--recurse-submodules=yes") { 218 t.Error("Commands should contain '--recurse-submodules=yes'") 219 } 220} 221 222func TestBuildCloneStep_DefaultDepth(t *testing.T) { 223 twf := tangled.Pipeline_Workflow{ 224 Clone: &tangled.Pipeline_CloneOpts{ 225 Depth: 0, // Default should be 1 226 Skip: false, 227 }, 228 } 229 tr := tangled.Pipeline_TriggerMetadata{ 230 Kind: string(workflow.TriggerKindPush), 231 Push: &tangled.Pipeline_PushTriggerData{ 232 NewSha: "abc123", 233 }, 234 Repo: &tangled.Pipeline_TriggerRepo{ 235 Knot: "example.com", 236 Did: "did:plc:user123", 237 Repo: "my-repo", 238 }, 239 } 240 241 step := BuildCloneStep(twf, tr, false) 242 243 allCmds := strings.Join(step.Commands(), " ") 244 if !strings.Contains(allCmds, "--depth=1") { 245 t.Error("Commands should default to '--depth=1'") 246 } 247} 248 249func TestBuildCloneStep_NilPushData(t *testing.T) { 250 twf := tangled.Pipeline_Workflow{ 251 Clone: &tangled.Pipeline_CloneOpts{ 252 Depth: 1, 253 Skip: false, 254 }, 255 } 256 tr := tangled.Pipeline_TriggerMetadata{ 257 Kind: string(workflow.TriggerKindPush), 258 Push: nil, // Nil push data should create error step 259 Repo: &tangled.Pipeline_TriggerRepo{ 260 Knot: "example.com", 261 Did: "did:plc:user123", 262 Repo: "my-repo", 263 }, 264 } 265 266 step := BuildCloneStep(twf, tr, false) 267 268 // Should return an error step 269 if !strings.Contains(step.Name(), "error") { 270 t.Error("Expected error in step name when push data is nil") 271 } 272 273 allCmds := strings.Join(step.Commands(), " ") 274 if !strings.Contains(allCmds, "Failed to get clone info") { 275 t.Error("Commands should contain error message") 276 } 277 if !strings.Contains(allCmds, "exit 1") { 278 t.Error("Commands should exit with error") 279 } 280} 281 282func TestBuildCloneStep_NilPRData(t *testing.T) { 283 twf := tangled.Pipeline_Workflow{ 284 Clone: &tangled.Pipeline_CloneOpts{ 285 Depth: 1, 286 Skip: false, 287 }, 288 } 289 tr := tangled.Pipeline_TriggerMetadata{ 290 Kind: string(workflow.TriggerKindPullRequest), 291 PullRequest: nil, // Nil PR data should create error step 292 Repo: &tangled.Pipeline_TriggerRepo{ 293 Knot: "example.com", 294 Did: "did:plc:user123", 295 Repo: "my-repo", 296 }, 297 } 298 299 step := BuildCloneStep(twf, tr, false) 300 301 // Should return an error step 302 if !strings.Contains(step.Name(), "error") { 303 t.Error("Expected error in step name when pull request data is nil") 304 } 305 306 allCmds := strings.Join(step.Commands(), " ") 307 if !strings.Contains(allCmds, "Failed to get clone info") { 308 t.Error("Commands should contain error message") 309 } 310} 311 312func TestBuildCloneStep_UnknownTriggerKind(t *testing.T) { 313 twf := tangled.Pipeline_Workflow{ 314 Clone: &tangled.Pipeline_CloneOpts{ 315 Depth: 1, 316 Skip: false, 317 }, 318 } 319 tr := tangled.Pipeline_TriggerMetadata{ 320 Kind: "unknown_trigger", 321 Repo: &tangled.Pipeline_TriggerRepo{ 322 Knot: "example.com", 323 Did: "did:plc:user123", 324 Repo: "my-repo", 325 }, 326 } 327 328 step := BuildCloneStep(twf, tr, false) 329 330 // Should return an error step 331 if !strings.Contains(step.Name(), "error") { 332 t.Error("Expected error in step name for unknown trigger kind") 333 } 334 335 allCmds := strings.Join(step.Commands(), " ") 336 if !strings.Contains(allCmds, "unknown trigger kind") { 337 t.Error("Commands should contain error message about unknown trigger kind") 338 } 339} 340 341func TestBuildCloneStep_NilCloneOpts(t *testing.T) { 342 twf := tangled.Pipeline_Workflow{ 343 Clone: nil, // Nil clone options should use defaults 344 } 345 tr := tangled.Pipeline_TriggerMetadata{ 346 Kind: string(workflow.TriggerKindPush), 347 Push: &tangled.Pipeline_PushTriggerData{ 348 NewSha: "abc123", 349 }, 350 Repo: &tangled.Pipeline_TriggerRepo{ 351 Knot: "example.com", 352 Did: "did:plc:user123", 353 Repo: "my-repo", 354 }, 355 } 356 357 step := BuildCloneStep(twf, tr, false) 358 359 // Should still work with default options 360 if step.Kind() != StepKindSystem { 361 t.Errorf("Expected StepKindSystem, got %v", step.Kind()) 362 } 363 364 allCmds := strings.Join(step.Commands(), " ") 365 if !strings.Contains(allCmds, "--depth=1") { 366 t.Error("Commands should default to '--depth=1' when Clone is nil") 367 } 368 if !strings.Contains(allCmds, "git init") { 369 t.Error("Commands should contain 'git init'") 370 } 371}