forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at spindle-workflow 421 lines 10 kB view raw
1package steps 2 3import ( 4 "strings" 5 "testing" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/workflow" 9) 10 11func TestBuildCloneCommands_PushTrigger(t *testing.T) { 12 cfg := CloneConfig{ 13 Workflow: tangled.Pipeline_Workflow{ 14 Clone: &tangled.Pipeline_CloneOpts{ 15 Depth: 1, 16 Submodules: false, 17 Skip: false, 18 }, 19 }, 20 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 21 Kind: string(workflow.TriggerKindPush), 22 Push: &tangled.Pipeline_PushTriggerData{ 23 NewSha: "abc123", 24 OldSha: "def456", 25 Ref: "refs/heads/main", 26 }, 27 Repo: &tangled.Pipeline_TriggerRepo{ 28 Knot: "example.com", 29 Did: "did:plc:user123", 30 Repo: "my-repo", 31 }, 32 }, 33 DevMode: false, 34 WorkspaceDir: "/tangled/workspace", 35 } 36 37 cmds, err := BuildCloneCommands(cfg) 38 if err != nil { 39 t.Fatalf("BuildCloneCommands failed: %v", err) 40 } 41 42 if cmds.Skip { 43 t.Error("Expected Skip to be false") 44 } 45 46 if cmds.CommitSHA != "abc123" { 47 t.Errorf("Expected CommitSHA 'abc123', got '%s'", cmds.CommitSHA) 48 } 49 50 expectedURL := "https://example.com/did:plc:user123/my-repo" 51 if cmds.RepoURL != expectedURL { 52 t.Errorf("Expected RepoURL '%s', got '%s'", expectedURL, cmds.RepoURL) 53 } 54 55 if !strings.Contains(cmds.Init, "git init") { 56 t.Error("Init command should contain 'git init'") 57 } 58 59 if !strings.Contains(cmds.Remote, "git remote add origin") { 60 t.Error("Remote command should contain 'git remote add origin'") 61 } 62 63 if !strings.Contains(cmds.Fetch, "git fetch") { 64 t.Error("Fetch command should contain 'git fetch'") 65 } 66 67 if !strings.Contains(cmds.Fetch, "abc123") { 68 t.Error("Fetch command should contain commit SHA") 69 } 70 71 if cmds.Checkout != "git checkout FETCH_HEAD" { 72 t.Errorf("Expected Checkout 'git checkout FETCH_HEAD', got '%s'", cmds.Checkout) 73 } 74 75 if len(cmds.All) != 5 { 76 t.Errorf("Expected 5 commands, got %d", len(cmds.All)) 77 } 78} 79 80func TestBuildCloneCommands_PullRequestTrigger(t *testing.T) { 81 cfg := CloneConfig{ 82 Workflow: tangled.Pipeline_Workflow{ 83 Clone: &tangled.Pipeline_CloneOpts{ 84 Depth: 1, 85 Skip: false, 86 }, 87 }, 88 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 89 Kind: string(workflow.TriggerKindPullRequest), 90 PullRequest: &tangled.Pipeline_PullRequestTriggerData{ 91 SourceSha: "pr-sha-789", 92 SourceBranch: "feature-branch", 93 TargetBranch: "main", 94 Action: "opened", 95 }, 96 Repo: &tangled.Pipeline_TriggerRepo{ 97 Knot: "example.com", 98 Did: "did:plc:user123", 99 Repo: "my-repo", 100 }, 101 }, 102 DevMode: false, 103 WorkspaceDir: "/tangled/workspace", 104 } 105 106 cmds, err := BuildCloneCommands(cfg) 107 if err != nil { 108 t.Fatalf("BuildCloneCommands failed: %v", err) 109 } 110 111 if cmds.CommitSHA != "pr-sha-789" { 112 t.Errorf("Expected CommitSHA 'pr-sha-789', got '%s'", cmds.CommitSHA) 113 } 114 115 if !strings.Contains(cmds.Fetch, "pr-sha-789") { 116 t.Error("Fetch command should contain PR commit SHA") 117 } 118} 119 120func TestBuildCloneCommands_ManualTrigger(t *testing.T) { 121 cfg := CloneConfig{ 122 Workflow: tangled.Pipeline_Workflow{ 123 Clone: &tangled.Pipeline_CloneOpts{ 124 Depth: 1, 125 Skip: false, 126 }, 127 }, 128 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 129 Kind: string(workflow.TriggerKindManual), 130 Manual: &tangled.Pipeline_ManualTriggerData{ 131 Inputs: nil, 132 }, 133 Repo: &tangled.Pipeline_TriggerRepo{ 134 Knot: "example.com", 135 Did: "did:plc:user123", 136 Repo: "my-repo", 137 }, 138 }, 139 DevMode: false, 140 WorkspaceDir: "/tangled/workspace", 141 } 142 143 cmds, err := BuildCloneCommands(cfg) 144 if err != nil { 145 t.Fatalf("BuildCloneCommands failed: %v", err) 146 } 147 148 // Manual triggers don't have a SHA yet (TODO) 149 if cmds.CommitSHA != "" { 150 t.Errorf("Expected empty CommitSHA for manual trigger, got '%s'", cmds.CommitSHA) 151 } 152} 153 154func TestBuildCloneCommands_SkipFlag(t *testing.T) { 155 cfg := CloneConfig{ 156 Workflow: tangled.Pipeline_Workflow{ 157 Clone: &tangled.Pipeline_CloneOpts{ 158 Skip: true, 159 }, 160 }, 161 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 162 Kind: string(workflow.TriggerKindPush), 163 Push: &tangled.Pipeline_PushTriggerData{ 164 NewSha: "abc123", 165 }, 166 Repo: &tangled.Pipeline_TriggerRepo{ 167 Knot: "example.com", 168 Did: "did:plc:user123", 169 Repo: "my-repo", 170 }, 171 }, 172 } 173 174 cmds, err := BuildCloneCommands(cfg) 175 if err != nil { 176 t.Fatalf("BuildCloneCommands failed: %v", err) 177 } 178 179 if !cmds.Skip { 180 t.Error("Expected Skip to be true") 181 } 182 183 if len(cmds.All) != 0 { 184 t.Errorf("Expected no commands when Skip is true, got %d commands", len(cmds.All)) 185 } 186} 187 188func TestBuildCloneCommands_DevMode(t *testing.T) { 189 cfg := CloneConfig{ 190 Workflow: tangled.Pipeline_Workflow{ 191 Clone: &tangled.Pipeline_CloneOpts{ 192 Depth: 1, 193 Skip: false, 194 }, 195 }, 196 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 197 Kind: string(workflow.TriggerKindPush), 198 Push: &tangled.Pipeline_PushTriggerData{ 199 NewSha: "abc123", 200 }, 201 Repo: &tangled.Pipeline_TriggerRepo{ 202 Knot: "localhost:3000", 203 Did: "did:plc:user123", 204 Repo: "my-repo", 205 }, 206 }, 207 DevMode: true, 208 WorkspaceDir: "/tangled/workspace", 209 } 210 211 cmds, err := BuildCloneCommands(cfg) 212 if err != nil { 213 t.Fatalf("BuildCloneCommands failed: %v", err) 214 } 215 216 // In dev mode, should use http:// and replace localhost with host.docker.internal 217 expectedURL := "http://host.docker.internal:3000/did:plc:user123/my-repo" 218 if cmds.RepoURL != expectedURL { 219 t.Errorf("Expected dev mode URL '%s', got '%s'", expectedURL, cmds.RepoURL) 220 } 221} 222 223func TestBuildCloneCommands_DepthAndSubmodules(t *testing.T) { 224 cfg := CloneConfig{ 225 Workflow: tangled.Pipeline_Workflow{ 226 Clone: &tangled.Pipeline_CloneOpts{ 227 Depth: 10, 228 Submodules: true, 229 Skip: false, 230 }, 231 }, 232 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 233 Kind: string(workflow.TriggerKindPush), 234 Push: &tangled.Pipeline_PushTriggerData{ 235 NewSha: "abc123", 236 }, 237 Repo: &tangled.Pipeline_TriggerRepo{ 238 Knot: "example.com", 239 Did: "did:plc:user123", 240 Repo: "my-repo", 241 }, 242 }, 243 DevMode: false, 244 WorkspaceDir: "/tangled/workspace", 245 } 246 247 cmds, err := BuildCloneCommands(cfg) 248 if err != nil { 249 t.Fatalf("BuildCloneCommands failed: %v", err) 250 } 251 252 if !strings.Contains(cmds.Fetch, "--depth=10") { 253 t.Error("Fetch command should contain '--depth=10'") 254 } 255 256 if !strings.Contains(cmds.Fetch, "--recurse-submodules=yes") { 257 t.Error("Fetch command should contain '--recurse-submodules=yes'") 258 } 259} 260 261func TestBuildCloneCommands_DefaultDepth(t *testing.T) { 262 cfg := CloneConfig{ 263 Workflow: tangled.Pipeline_Workflow{ 264 Clone: &tangled.Pipeline_CloneOpts{ 265 Depth: 0, // Default should be 1 266 Skip: false, 267 }, 268 }, 269 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 270 Kind: string(workflow.TriggerKindPush), 271 Push: &tangled.Pipeline_PushTriggerData{ 272 NewSha: "abc123", 273 }, 274 Repo: &tangled.Pipeline_TriggerRepo{ 275 Knot: "example.com", 276 Did: "did:plc:user123", 277 Repo: "my-repo", 278 }, 279 }, 280 WorkspaceDir: "/tangled/workspace", 281 } 282 283 cmds, err := BuildCloneCommands(cfg) 284 if err != nil { 285 t.Fatalf("BuildCloneCommands failed: %v", err) 286 } 287 288 if !strings.Contains(cmds.Fetch, "--depth=1") { 289 t.Error("Fetch command should default to '--depth=1'") 290 } 291} 292 293func TestBuildCloneCommands_NilPushData(t *testing.T) { 294 cfg := CloneConfig{ 295 Workflow: tangled.Pipeline_Workflow{ 296 Clone: &tangled.Pipeline_CloneOpts{ 297 Depth: 1, 298 Skip: false, 299 }, 300 }, 301 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 302 Kind: string(workflow.TriggerKindPush), 303 Push: nil, // Nil push data should return error 304 Repo: &tangled.Pipeline_TriggerRepo{ 305 Knot: "example.com", 306 Did: "did:plc:user123", 307 Repo: "my-repo", 308 }, 309 }, 310 WorkspaceDir: "/tangled/workspace", 311 } 312 313 _, err := BuildCloneCommands(cfg) 314 if err == nil { 315 t.Error("Expected error when push data is nil") 316 } 317 318 if !strings.Contains(err.Error(), "push trigger metadata is nil") { 319 t.Errorf("Expected error about nil push metadata, got: %v", err) 320 } 321} 322 323func TestBuildCloneCommands_NilPRData(t *testing.T) { 324 cfg := CloneConfig{ 325 Workflow: tangled.Pipeline_Workflow{ 326 Clone: &tangled.Pipeline_CloneOpts{ 327 Depth: 1, 328 Skip: false, 329 }, 330 }, 331 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 332 Kind: string(workflow.TriggerKindPullRequest), 333 PullRequest: nil, // Nil PR data should return error 334 Repo: &tangled.Pipeline_TriggerRepo{ 335 Knot: "example.com", 336 Did: "did:plc:user123", 337 Repo: "my-repo", 338 }, 339 }, 340 WorkspaceDir: "/tangled/workspace", 341 } 342 343 _, err := BuildCloneCommands(cfg) 344 if err == nil { 345 t.Error("Expected error when pull request data is nil") 346 } 347 348 if !strings.Contains(err.Error(), "pull request trigger metadata is nil") { 349 t.Errorf("Expected error about nil PR metadata, got: %v", err) 350 } 351} 352 353func TestBuildCloneCommands_CustomWorkspace(t *testing.T) { 354 cfg := CloneConfig{ 355 Workflow: tangled.Pipeline_Workflow{ 356 Clone: &tangled.Pipeline_CloneOpts{ 357 Depth: 1, 358 Skip: false, 359 }, 360 }, 361 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 362 Kind: string(workflow.TriggerKindPush), 363 Push: &tangled.Pipeline_PushTriggerData{ 364 NewSha: "abc123", 365 }, 366 Repo: &tangled.Pipeline_TriggerRepo{ 367 Knot: "example.com", 368 Did: "did:plc:user123", 369 Repo: "my-repo", 370 }, 371 }, 372 DevMode: false, 373 WorkspaceDir: "/custom/path", 374 } 375 376 cmds, err := BuildCloneCommands(cfg) 377 if err != nil { 378 t.Fatalf("BuildCloneCommands failed: %v", err) 379 } 380 381 if !strings.Contains(cmds.Init, "/custom/path") { 382 t.Error("Init command should use custom workspace directory") 383 } 384 385 if !strings.Contains(cmds.All[1], "/custom/path") { 386 t.Error("cd command should use custom workspace directory") 387 } 388} 389 390func TestBuildCloneCommands_DefaultWorkspace(t *testing.T) { 391 cfg := CloneConfig{ 392 Workflow: tangled.Pipeline_Workflow{ 393 Clone: &tangled.Pipeline_CloneOpts{ 394 Depth: 1, 395 Skip: false, 396 }, 397 }, 398 TriggerMetadata: tangled.Pipeline_TriggerMetadata{ 399 Kind: string(workflow.TriggerKindPush), 400 Push: &tangled.Pipeline_PushTriggerData{ 401 NewSha: "abc123", 402 }, 403 Repo: &tangled.Pipeline_TriggerRepo{ 404 Knot: "example.com", 405 Did: "did:plc:user123", 406 Repo: "my-repo", 407 }, 408 }, 409 DevMode: false, 410 WorkspaceDir: "", // Empty should default to /tangled/workspace 411 } 412 413 cmds, err := BuildCloneCommands(cfg) 414 if err != nil { 415 t.Fatalf("BuildCloneCommands failed: %v", err) 416 } 417 418 if !strings.Contains(cmds.Init, "/tangled/workspace") { 419 t.Error("Init command should default to /tangled/workspace") 420 } 421}