|
| 1 | +package slack |
| 2 | + |
| 3 | +import ( |
| 4 | + "testing" |
| 5 | + |
| 6 | + "github.com/codeGROOVE-dev/slacker/pkg/config" |
| 7 | +) |
| 8 | + |
| 9 | +// TestWorkspaceOrgs_MultipleOrgs verifies that workspaceOrgs correctly identifies all orgs for a workspace. |
| 10 | +func TestWorkspaceOrgs_MultipleOrgs(t *testing.T) { |
| 11 | + t.Parallel() |
| 12 | + |
| 13 | + // Create mock config manager with multiple orgs for same workspace |
| 14 | + teamID := "T123" |
| 15 | + configs := map[string]*config.RepoConfig{ |
| 16 | + "org1": { |
| 17 | + Users: map[string]string{"gh-user1": "user1@example.com"}, |
| 18 | + }, |
| 19 | + "org2": { |
| 20 | + Users: map[string]string{"gh-user2": "user2@example.com"}, |
| 21 | + }, |
| 22 | + "org3": { |
| 23 | + Users: map[string]string{"gh-user3": "user3@example.com"}, |
| 24 | + }, |
| 25 | + "org4": { // Different teamID - should be excluded |
| 26 | + Users: map[string]string{"gh-user4": "user4@example.com"}, |
| 27 | + }, |
| 28 | + } |
| 29 | + |
| 30 | + // Set TeamIDs |
| 31 | + configs["org1"].Global.TeamID = teamID |
| 32 | + configs["org2"].Global.TeamID = teamID |
| 33 | + configs["org3"].Global.TeamID = teamID |
| 34 | + configs["org4"].Global.TeamID = "T999" // Different workspace |
| 35 | + |
| 36 | + // Create a mock implementation that simulates the workspaceOrgs logic |
| 37 | + allOrgs := []string{"org1", "org2", "org3", "org4"} |
| 38 | + var workspaceOrgs []string |
| 39 | + |
| 40 | + for _, org := range allOrgs { |
| 41 | + cfg, exists := configs[org] |
| 42 | + if !exists { |
| 43 | + continue |
| 44 | + } |
| 45 | + if cfg.Global.TeamID == teamID { |
| 46 | + workspaceOrgs = append(workspaceOrgs, org) |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + // Verify all matching orgs were found |
| 51 | + if len(workspaceOrgs) != 3 { |
| 52 | + t.Errorf("expected 3 workspace orgs, got %d", len(workspaceOrgs)) |
| 53 | + } |
| 54 | + |
| 55 | + expectedOrgs := map[string]bool{ |
| 56 | + "org1": true, |
| 57 | + "org2": true, |
| 58 | + "org3": true, |
| 59 | + } |
| 60 | + |
| 61 | + for _, org := range workspaceOrgs { |
| 62 | + if !expectedOrgs[org] { |
| 63 | + t.Errorf("unexpected org in workspace: %s", org) |
| 64 | + } |
| 65 | + delete(expectedOrgs, org) |
| 66 | + } |
| 67 | + |
| 68 | + if len(expectedOrgs) > 0 { |
| 69 | + t.Errorf("missing expected orgs: %v", expectedOrgs) |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +// TestCollectOverrides_MultipleOrgs verifies that user overrides are collected from all workspace orgs. |
| 74 | +func TestCollectOverrides_MultipleOrgs(t *testing.T) { |
| 75 | + t.Parallel() |
| 76 | + |
| 77 | + workspaceOrgs := []string{"org1", "org2", "org3"} |
| 78 | + |
| 79 | + // Simulate configs for multiple orgs |
| 80 | + configs := map[string]*config.RepoConfig{ |
| 81 | + "org1": { |
| 82 | + Users: map[string]string{ |
| 83 | + "github-user-1": "user1@example.com", |
| 84 | + "github-user-2": "user2@example.com", |
| 85 | + }, |
| 86 | + }, |
| 87 | + "org2": { |
| 88 | + Users: map[string]string{ |
| 89 | + "github-user-3": "user3@example.com", |
| 90 | + }, |
| 91 | + }, |
| 92 | + "org3": { |
| 93 | + Users: nil, // No overrides |
| 94 | + }, |
| 95 | + } |
| 96 | + |
| 97 | + // Simulate the override collection logic from tryHandleAppHomeOpened |
| 98 | + allOverrides := make(map[string]string) |
| 99 | + for _, org := range workspaceOrgs { |
| 100 | + cfg, exists := configs[org] |
| 101 | + if exists && len(cfg.Users) > 0 { |
| 102 | + for ghUser, email := range cfg.Users { |
| 103 | + allOverrides[ghUser] = email |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + // Verify all overrides were collected |
| 109 | + expected := map[string]string{ |
| 110 | + "github-user-1": "user1@example.com", |
| 111 | + "github-user-2": "user2@example.com", |
| 112 | + "github-user-3": "user3@example.com", |
| 113 | + } |
| 114 | + |
| 115 | + if len(allOverrides) != len(expected) { |
| 116 | + t.Errorf("expected %d overrides, got %d", len(expected), len(allOverrides)) |
| 117 | + } |
| 118 | + |
| 119 | + for ghUser, expectedEmail := range expected { |
| 120 | + if actualEmail, ok := allOverrides[ghUser]; !ok { |
| 121 | + t.Errorf("missing override for %s", ghUser) |
| 122 | + } else if actualEmail != expectedEmail { |
| 123 | + t.Errorf("wrong email for %s: expected %s, got %s", ghUser, expectedEmail, actualEmail) |
| 124 | + } |
| 125 | + } |
| 126 | +} |
| 127 | + |
| 128 | +// TestUserMappingFallback_MultipleOrgs verifies that user mapping attempts all orgs until one succeeds. |
| 129 | +func TestUserMappingFallback_MultipleOrgs(t *testing.T) { |
| 130 | + t.Parallel() |
| 131 | + |
| 132 | + workspaceOrgs := []string{"org1", "org2", "org3"} |
| 133 | + |
| 134 | + // Simulate configs for multiple orgs |
| 135 | + configs := map[string]*config.RepoConfig{ |
| 136 | + "org1": {Users: nil}, |
| 137 | + "org2": {Users: nil}, |
| 138 | + "org3": {Users: nil}, |
| 139 | + } |
| 140 | + configs["org1"].Global.EmailDomain = "example.com" |
| 141 | + configs["org2"].Global.EmailDomain = "example.org" |
| 142 | + configs["org3"].Global.EmailDomain = "example.net" |
| 143 | + |
| 144 | + // Simulate the user mapping loop logic |
| 145 | + type attempt struct { |
| 146 | + org string |
| 147 | + domain string |
| 148 | + } |
| 149 | + var attempts []attempt |
| 150 | + |
| 151 | + // Simulate mapping attempts (fail on first two, succeed on third) |
| 152 | + var foundMapping bool |
| 153 | + for _, org := range workspaceOrgs { |
| 154 | + cfg, exists := configs[org] |
| 155 | + if !exists { |
| 156 | + continue |
| 157 | + } |
| 158 | + |
| 159 | + attempts = append(attempts, attempt{ |
| 160 | + org: org, |
| 161 | + domain: cfg.Global.EmailDomain, |
| 162 | + }) |
| 163 | + |
| 164 | + // Simulate: fail on org1 and org2, succeed on org3 |
| 165 | + if org == "org3" { |
| 166 | + foundMapping = true |
| 167 | + break |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + // Verify all three orgs were attempted (loop broke on success) |
| 172 | + if len(attempts) != 3 { |
| 173 | + t.Errorf("expected 3 attempts, got %d", len(attempts)) |
| 174 | + } |
| 175 | + |
| 176 | + // Verify the attempts were in order |
| 177 | + expectedAttempts := []attempt{ |
| 178 | + {"org1", "example.com"}, |
| 179 | + {"org2", "example.org"}, |
| 180 | + {"org3", "example.net"}, |
| 181 | + } |
| 182 | + |
| 183 | + for i, expected := range expectedAttempts { |
| 184 | + if i >= len(attempts) { |
| 185 | + t.Errorf("missing attempt %d", i) |
| 186 | + continue |
| 187 | + } |
| 188 | + actual := attempts[i] |
| 189 | + if actual.org != expected.org || actual.domain != expected.domain { |
| 190 | + t.Errorf("attempt %d: expected (%s, %s), got (%s, %s)", |
| 191 | + i, expected.org, expected.domain, actual.org, actual.domain) |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + if !foundMapping { |
| 196 | + t.Error("mapping should have been found") |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +// TestUserMappingEarlyExit_FirstOrgSucceeds verifies that when first org succeeds, subsequent orgs are not attempted. |
| 201 | +func TestUserMappingEarlyExit_FirstOrgSucceeds(t *testing.T) { |
| 202 | + t.Parallel() |
| 203 | + |
| 204 | + workspaceOrgs := []string{"org1", "org2", "org3"} |
| 205 | + |
| 206 | + // Simulate configs |
| 207 | + configs := map[string]*config.RepoConfig{ |
| 208 | + "org1": {Users: nil}, |
| 209 | + "org2": {Users: nil}, |
| 210 | + "org3": {Users: nil}, |
| 211 | + } |
| 212 | + configs["org1"].Global.EmailDomain = "example.com" |
| 213 | + configs["org2"].Global.EmailDomain = "example.org" |
| 214 | + configs["org3"].Global.EmailDomain = "example.net" |
| 215 | + |
| 216 | + // Simulate mapping attempts (succeed on first) |
| 217 | + var attempts int |
| 218 | + var foundMapping bool |
| 219 | + for _, org := range workspaceOrgs { |
| 220 | + _, exists := configs[org] |
| 221 | + if !exists { |
| 222 | + continue |
| 223 | + } |
| 224 | + |
| 225 | + attempts++ |
| 226 | + |
| 227 | + // Simulate: succeed on first org |
| 228 | + if org == "org1" { |
| 229 | + foundMapping = true |
| 230 | + break |
| 231 | + } |
| 232 | + } |
| 233 | + |
| 234 | + // Verify only one attempt was made |
| 235 | + if attempts != 1 { |
| 236 | + t.Errorf("expected 1 attempt, got %d (should break early on success)", attempts) |
| 237 | + } |
| 238 | + |
| 239 | + if !foundMapping { |
| 240 | + t.Error("mapping should have been found") |
| 241 | + } |
| 242 | +} |
0 commit comments