Skip to content

Commit fe66caf

Browse files
committed
Add PATCH tag-bindings to Projects
1 parent a8b7788 commit fe66caf

File tree

3 files changed

+113
-5
lines changed

3 files changed

+113
-5
lines changed

project.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ type Projects interface {
3434

3535
// ListTagBindings lists all tag bindings associated with the project.
3636
ListTagBindings(ctx context.Context, projectID string) ([]*TagBinding, error)
37+
38+
// AddTagBindings adds or modifies the value of existing tag binding keys for a project.
39+
AddTagBindings(ctx context.Context, projectID string, options ProjectAddTagBindingsOptions) ([]*TagBinding, error)
3740
}
3841

3942
// projects implements Projects
@@ -113,6 +116,12 @@ type ProjectUpdateOptions struct {
113116
TagBindings []*TagBinding `jsonapi:"relation,tag-bindings,omitempty"`
114117
}
115118

119+
// ProjectAddTagBindingsOptions represents the options for adding tag bindings
120+
// to a project.
121+
type ProjectAddTagBindingsOptions struct {
122+
TagBindings []*TagBinding
123+
}
124+
116125
// List all projects.
117126
func (s *projects) List(ctx context.Context, organization string, options *ProjectListOptions) (*ProjectList, error) {
118127
if !validStringID(&organization) {
@@ -209,6 +218,31 @@ func (s *projects) ListTagBindings(ctx context.Context, projectID string) ([]*Ta
209218
return list.Items, nil
210219
}
211220

221+
// AddTagBindings adds or modifies the value of existing tag binding keys for a project
222+
func (s *projects) AddTagBindings(ctx context.Context, projectID string, options ProjectAddTagBindingsOptions) ([]*TagBinding, error) {
223+
if !validStringID(&projectID) {
224+
return nil, ErrInvalidProjectID
225+
}
226+
227+
if err := options.valid(); err != nil {
228+
return nil, err
229+
}
230+
231+
u := fmt.Sprintf("projects/%s/tag-bindings", url.PathEscape(projectID))
232+
req, err := s.client.NewRequest("PATCH", u, options.TagBindings)
233+
if err != nil {
234+
return nil, err
235+
}
236+
237+
var response = struct {
238+
*Pagination
239+
Items []*TagBinding
240+
}{}
241+
err = req.Do(ctx, &response)
242+
243+
return response.Items, err
244+
}
245+
212246
// Update a project by its ID
213247
func (s *projects) Update(ctx context.Context, projectID string, options ProjectUpdateOptions) (*Project, error) {
214248
if !validStringID(&projectID) {
@@ -259,3 +293,11 @@ func (o ProjectCreateOptions) valid() error {
259293
func (o ProjectUpdateOptions) valid() error {
260294
return nil
261295
}
296+
297+
func (o ProjectAddTagBindingsOptions) valid() error {
298+
if len(o.TagBindings) == 0 {
299+
return ErrRequiredTagBindings
300+
}
301+
302+
return nil
303+
}

projects_integration_test.go

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,22 @@ func TestProjectsList(t *testing.T) {
6666
t.Run("when using a tags filter", func(t *testing.T) {
6767
skipUnlessBeta(t)
6868

69-
p1, wTestCleanup1 := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{
69+
p1, pTestCleanup1 := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{
7070
Name: randomStringWithoutSpecialChar(t),
7171
TagBindings: []*TagBinding{
7272
{Key: "key1", Value: "value1"},
7373
{Key: "key2", Value: "value2a"},
7474
},
7575
})
76-
p2, wTestCleanup2 := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{
76+
p2, pTestCleanup2 := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{
7777
Name: randomStringWithoutSpecialChar(t),
7878
TagBindings: []*TagBinding{
7979
{Key: "key2", Value: "value2b"},
8080
{Key: "key3", Value: "value3"},
8181
},
8282
})
83-
t.Cleanup(wTestCleanup1)
84-
t.Cleanup(wTestCleanup2)
83+
t.Cleanup(pTestCleanup1)
84+
t.Cleanup(pTestCleanup2)
8585

8686
// List all the workspaces under the given tag
8787
pl, err := client.Projects.List(ctx, orgTest.Name, &ProjectListOptions{
@@ -247,6 +247,70 @@ func TestProjectsUpdate(t *testing.T) {
247247
})
248248
}
249249

250+
func TestProjectsAddTagBindings(t *testing.T) {
251+
skipUnlessBeta(t)
252+
253+
client := testClient(t)
254+
ctx := context.Background()
255+
256+
pTest, wCleanup := createProject(t, client, nil)
257+
t.Cleanup(wCleanup)
258+
259+
t.Run("when adding tag bindings to a project", func(t *testing.T) {
260+
tagBindings := []*TagBinding{
261+
{Key: "foo", Value: "bar"},
262+
{Key: "baz", Value: "qux"},
263+
}
264+
265+
bindings, err := client.Projects.AddTagBindings(ctx, pTest.ID, ProjectAddTagBindingsOptions{
266+
TagBindings: tagBindings,
267+
})
268+
require.NoError(t, err)
269+
270+
assert.Len(t, bindings, 2)
271+
assert.Equal(t, tagBindings[0].Key, bindings[0].Key)
272+
assert.Equal(t, tagBindings[0].Value, bindings[0].Value)
273+
assert.Equal(t, tagBindings[1].Key, bindings[1].Key)
274+
assert.Equal(t, tagBindings[1].Value, bindings[1].Value)
275+
})
276+
277+
t.Run("when adding 26 tags", func(t *testing.T) {
278+
tagBindings := []*TagBinding{
279+
{Key: "alpha"},
280+
{Key: "bravo"},
281+
{Key: "charlie"},
282+
{Key: "delta"},
283+
{Key: "echo"},
284+
{Key: "foxtrot"},
285+
{Key: "golf"},
286+
{Key: "hotel"},
287+
{Key: "india"},
288+
{Key: "juliet"},
289+
{Key: "kilo"},
290+
{Key: "lima"},
291+
{Key: "mike"},
292+
{Key: "november"},
293+
{Key: "oscar"},
294+
{Key: "papa"},
295+
{Key: "quebec"},
296+
{Key: "romeo"},
297+
{Key: "sierra"},
298+
{Key: "tango"},
299+
{Key: "uniform"},
300+
{Key: "victor"},
301+
{Key: "whiskey"},
302+
{Key: "xray"},
303+
{Key: "yankee"},
304+
{Key: "zulu"},
305+
}
306+
307+
_, err := client.Workspaces.AddTagBindings(ctx, pTest.ID, WorkspaceAddTagBindingsOptions{
308+
TagBindings: tagBindings,
309+
})
310+
require.Error(t, err, "cannot exceed 10 bindings per resource")
311+
})
312+
}
313+
250314
func TestProjectsDelete(t *testing.T) {
251315
client := testClient(t)
252316
ctx := context.Background()

workspace_integration_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,9 @@ func TestWorkspacesReadByID(t *testing.T) {
11731173
})
11741174
}
11751175

1176-
func TestWorkspaceAddTagBindings(t *testing.T) {
1176+
func TestWorkspacesAddTagBindings(t *testing.T) {
1177+
skipUnlessBeta(t)
1178+
11771179
client := testClient(t)
11781180
ctx := context.Background()
11791181

0 commit comments

Comments
 (0)