1package tfe 2 3import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9) 10 11func TestTeamAccessesList(t *testing.T) { 12 client := testClient(t) 13 ctx := context.Background() 14 15 orgTest, orgTestCleanup := createOrganization(t, client) 16 defer orgTestCleanup() 17 18 wTest, _ := createWorkspace(t, client, orgTest) 19 20 tmTest1, tmTest1Cleanup := createTeam(t, client, orgTest) 21 defer tmTest1Cleanup() 22 tmTest2, tmTest2Cleanup := createTeam(t, client, orgTest) 23 defer tmTest2Cleanup() 24 25 taTest1, taTest1Cleanup := createTeamAccess(t, client, tmTest1, wTest, orgTest) 26 defer taTest1Cleanup() 27 taTest2, taTest2Cleanup := createTeamAccess(t, client, tmTest2, wTest, orgTest) 28 defer taTest2Cleanup() 29 30 t.Run("with valid options", func(t *testing.T) { 31 tal, err := client.TeamAccess.List(ctx, TeamAccessListOptions{ 32 WorkspaceID: String(wTest.ID), 33 }) 34 require.NoError(t, err) 35 assert.Contains(t, tal.Items, taTest1) 36 assert.Contains(t, tal.Items, taTest2) 37 38 t.Skip("paging not supported yet in API") 39 assert.Equal(t, 1, tal.CurrentPage) 40 assert.Equal(t, 2, tal.TotalCount) 41 }) 42 43 t.Run("with list options", func(t *testing.T) { 44 t.Skip("paging not supported yet in API") 45 // Request a page number which is out of range. The result should 46 // be successful, but return no results if the paging options are 47 // properly passed along. 48 tal, err := client.TeamAccess.List(ctx, TeamAccessListOptions{ 49 ListOptions: ListOptions{ 50 PageNumber: 999, 51 PageSize: 100, 52 }, 53 }) 54 require.NoError(t, err) 55 assert.Empty(t, tal.Items) 56 assert.Equal(t, 999, tal.CurrentPage) 57 assert.Equal(t, 2, tal.TotalCount) 58 }) 59 60 t.Run("without list options", func(t *testing.T) { 61 tal, err := client.TeamAccess.List(ctx, TeamAccessListOptions{}) 62 assert.Nil(t, tal) 63 assert.EqualError(t, err, "workspace ID is required") 64 }) 65 66 t.Run("without a valid workspace ID", func(t *testing.T) { 67 tal, err := client.TeamAccess.List(ctx, TeamAccessListOptions{ 68 WorkspaceID: String(badIdentifier), 69 }) 70 assert.Nil(t, tal) 71 assert.EqualError(t, err, "invalid value for workspace ID") 72 }) 73} 74 75func TestTeamAccessesAdd(t *testing.T) { 76 client := testClient(t) 77 ctx := context.Background() 78 79 orgTest, orgTestCleanup := createOrganization(t, client) 80 defer orgTestCleanup() 81 82 wTest, _ := createWorkspace(t, client, orgTest) 83 84 tmTest, tmTestCleanup := createTeam(t, client, orgTest) 85 defer tmTestCleanup() 86 87 t.Run("with valid options", func(t *testing.T) { 88 options := TeamAccessAddOptions{ 89 Access: Access(AccessAdmin), 90 Team: tmTest, 91 Workspace: wTest, 92 } 93 94 ta, err := client.TeamAccess.Add(ctx, options) 95 defer client.TeamAccess.Remove(ctx, ta.ID) 96 97 require.NoError(t, err) 98 99 // Get a refreshed view from the API. 100 refreshed, err := client.TeamAccess.Read(ctx, ta.ID) 101 require.NoError(t, err) 102 103 for _, item := range []*TeamAccess{ 104 ta, 105 refreshed, 106 } { 107 assert.NotEmpty(t, item.ID) 108 assert.Equal(t, *options.Access, item.Access) 109 } 110 }) 111 112 t.Run("with valid custom options", func(t *testing.T) { 113 options := TeamAccessAddOptions{ 114 Access: Access(AccessCustom), 115 Runs: RunsPermission(RunsPermissionRead), 116 StateVersions: StateVersionsPermission(StateVersionsPermissionNone), 117 Team: tmTest, 118 Workspace: wTest, 119 } 120 121 ta, err := client.TeamAccess.Add(ctx, options) 122 defer client.TeamAccess.Remove(ctx, ta.ID) 123 124 require.NoError(t, err) 125 126 // Get a refreshed view from the API. 127 refreshed, err := client.TeamAccess.Read(ctx, ta.ID) 128 require.NoError(t, err) 129 130 for _, item := range []*TeamAccess{ 131 ta, 132 refreshed, 133 } { 134 assert.NotEmpty(t, item.ID) 135 assert.Equal(t, *options.Access, item.Access) 136 } 137 }) 138 139 t.Run("with invalid custom options", func(t *testing.T) { 140 options := TeamAccessAddOptions{ 141 Access: Access(AccessRead), 142 Runs: RunsPermission(RunsPermissionApply), 143 Team: tmTest, 144 Workspace: wTest, 145 } 146 147 _, err := client.TeamAccess.Add(ctx, options) 148 149 assert.EqualError(t, err, "invalid attribute\n\nRuns is read-only when access level is 'read'; use the 'custom' access level to set this attribute.") 150 }) 151 152 t.Run("when the team already has access", func(t *testing.T) { 153 _, taTestCleanup := createTeamAccess(t, client, tmTest, wTest, nil) 154 defer taTestCleanup() 155 156 options := TeamAccessAddOptions{ 157 Access: Access(AccessAdmin), 158 Team: tmTest, 159 Workspace: wTest, 160 } 161 162 _, err := client.TeamAccess.Add(ctx, options) 163 assert.Error(t, err) 164 }) 165 166 t.Run("when options is missing access", func(t *testing.T) { 167 ta, err := client.TeamAccess.Add(ctx, TeamAccessAddOptions{ 168 Team: tmTest, 169 Workspace: wTest, 170 }) 171 assert.Nil(t, ta) 172 assert.EqualError(t, err, "access is required") 173 }) 174 175 t.Run("when options is missing team", func(t *testing.T) { 176 ta, err := client.TeamAccess.Add(ctx, TeamAccessAddOptions{ 177 Access: Access(AccessAdmin), 178 Workspace: wTest, 179 }) 180 assert.Nil(t, ta) 181 assert.EqualError(t, err, "team is required") 182 }) 183 184 t.Run("when options is missing workspace", func(t *testing.T) { 185 ta, err := client.TeamAccess.Add(ctx, TeamAccessAddOptions{ 186 Access: Access(AccessAdmin), 187 Team: tmTest, 188 }) 189 assert.Nil(t, ta) 190 assert.EqualError(t, err, "workspace is required") 191 }) 192} 193 194func TestTeamAccessesRead(t *testing.T) { 195 client := testClient(t) 196 ctx := context.Background() 197 198 taTest, taTestCleanup := createTeamAccess(t, client, nil, nil, nil) 199 defer taTestCleanup() 200 201 t.Run("when the team access exists", func(t *testing.T) { 202 ta, err := client.TeamAccess.Read(ctx, taTest.ID) 203 require.NoError(t, err) 204 205 assert.Equal(t, AccessAdmin, ta.Access) 206 207 t.Run("permission attributes are decoded", func(t *testing.T) { 208 assert.Equal(t, RunsPermissionApply, ta.Runs) 209 assert.Equal(t, VariablesPermissionWrite, ta.Variables) 210 assert.Equal(t, StateVersionsPermissionWrite, ta.StateVersions) 211 assert.Equal(t, SentinelMocksPermissionRead, ta.SentinelMocks) 212 assert.Equal(t, true, ta.WorkspaceLocking) 213 }) 214 215 t.Run("team relationship is decoded", func(t *testing.T) { 216 assert.NotEmpty(t, ta.Team) 217 }) 218 219 t.Run("workspace relationship is decoded", func(t *testing.T) { 220 assert.NotEmpty(t, ta.Workspace) 221 }) 222 }) 223 224 t.Run("when the team access does not exist", func(t *testing.T) { 225 ta, err := client.TeamAccess.Read(ctx, "nonexisting") 226 assert.Nil(t, ta) 227 assert.Equal(t, err, ErrResourceNotFound) 228 }) 229 230 t.Run("without a valid team access ID", func(t *testing.T) { 231 ta, err := client.TeamAccess.Read(ctx, badIdentifier) 232 assert.Nil(t, ta) 233 assert.EqualError(t, err, "invalid value for team access ID") 234 }) 235} 236 237func TestTeamAccessesUpdate(t *testing.T) { 238 client := testClient(t) 239 ctx := context.Background() 240 241 orgTest, orgTestCleanup := createOrganization(t, client) 242 defer orgTestCleanup() 243 244 wTest, wTestCleanup := createWorkspace(t, client, orgTest) 245 defer wTestCleanup() 246 247 tmTest, tmTestCleanup := createTeam(t, client, orgTest) 248 defer tmTestCleanup() 249 250 taTest, taTestCleanup := createTeamAccess(t, client, tmTest, wTest, nil) 251 defer taTestCleanup() 252 253 t.Run("with valid attributes", func(t *testing.T) { 254 options := TeamAccessUpdateOptions{ 255 Access: Access(AccessCustom), 256 Runs: RunsPermission(RunsPermissionPlan), 257 } 258 259 ta, err := client.TeamAccess.Update(ctx, taTest.ID, options) 260 require.NoError(t, err) 261 262 assert.Equal(t, ta.Access, AccessCustom) 263 assert.Equal(t, ta.Runs, RunsPermissionPlan) 264 }) 265} 266 267func TestTeamAccessesRemove(t *testing.T) { 268 client := testClient(t) 269 ctx := context.Background() 270 271 orgTest, orgTestCleanup := createOrganization(t, client) 272 defer orgTestCleanup() 273 274 tmTest, tmTestCleanup := createTeam(t, client, orgTest) 275 defer tmTestCleanup() 276 277 taTest, _ := createTeamAccess(t, client, tmTest, nil, orgTest) 278 279 t.Run("with valid options", func(t *testing.T) { 280 err := client.TeamAccess.Remove(ctx, taTest.ID) 281 require.NoError(t, err) 282 283 // Try loading the workspace - it should fail. 284 _, err = client.TeamAccess.Read(ctx, taTest.ID) 285 assert.Equal(t, err, ErrResourceNotFound) 286 }) 287 288 t.Run("when the team access does not exist", func(t *testing.T) { 289 err := client.TeamAccess.Remove(ctx, taTest.ID) 290 assert.Equal(t, err, ErrResourceNotFound) 291 }) 292 293 t.Run("when the team access ID is invalid", func(t *testing.T) { 294 err := client.TeamAccess.Remove(ctx, badIdentifier) 295 assert.EqualError(t, err, "invalid value for team access ID") 296 }) 297} 298