Skip to content

Commit 319de80

Browse files
committed
Adds ReadWithOptions to Project
1 parent 79c51d8 commit 319de80

File tree

4 files changed

+85
-6
lines changed

4 files changed

+85
-6
lines changed

project.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ type Projects interface {
2828
// Read a project by its ID.
2929
Read(ctx context.Context, projectID string) (*Project, error)
3030

31+
// ReadWithOptions a project by its ID.
32+
ReadWithOptions(ctx context.Context, projectID string, options ProjectReadOptions) (*Project, error)
33+
3134
// Update a project.
3235
Update(ctx context.Context, projectID string, options ProjectUpdateOptions) (*Project, error)
3336

@@ -101,6 +104,11 @@ type ProjectListOptions struct {
101104
Include []ProjectIncludeOpt `url:"include,omitempty"`
102105
}
103106

107+
type ProjectReadOptions struct {
108+
// Optional: A list of relations to include
109+
Include []ProjectIncludeOpt `url:"include,omitempty"`
110+
}
111+
104112
// ProjectCreateOptions represents the options for creating a project
105113
type ProjectCreateOptions struct {
106114
// Type is a public field utilized by JSON:API to
@@ -205,6 +213,27 @@ func (s *projects) Create(ctx context.Context, organization string, options Proj
205213
return p, nil
206214
}
207215

216+
// ReadWithOptions a project by its ID.
217+
func (s *projects) ReadWithOptions(ctx context.Context, projectID string, options ProjectReadOptions) (*Project, error) {
218+
if !validStringID(&projectID) {
219+
return nil, ErrInvalidProjectID
220+
}
221+
222+
u := fmt.Sprintf("projects/%s", url.PathEscape(projectID))
223+
req, err := s.client.NewRequest("GET", u, options)
224+
if err != nil {
225+
return nil, err
226+
}
227+
228+
p := &Project{}
229+
err = req.Do(ctx, p)
230+
if err != nil {
231+
return nil, err
232+
}
233+
234+
return p, nil
235+
}
236+
208237
// Read a single project by its ID.
209238
func (s *projects) Read(ctx context.Context, projectID string) (*Project, error) {
210239
if !validStringID(&projectID) {

projects_integration_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@ func TestProjectsList(t *testing.T) {
142142
})
143143
}
144144

145+
func TestProjectsReadWithOptions(t *testing.T) {
146+
client := testClient(t)
147+
ctx := context.Background()
148+
149+
orgTest, orgTestCleanup := createOrganization(t, client)
150+
defer orgTestCleanup()
151+
152+
pTest, pTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{
153+
Name: "project-with-tags",
154+
TagBindings: []*TagBinding{
155+
{Key: "foo", Value: "bar"},
156+
},
157+
})
158+
defer pTestCleanup()
159+
160+
t.Run("when the project exists", func(t *testing.T) {
161+
p, err := client.Projects.ReadWithOptions(ctx, pTest.ID, ProjectReadOptions{
162+
Include: []ProjectIncludeOpt{ProjectEffectiveTagBindings},
163+
})
164+
require.NoError(t, err)
165+
assert.Equal(t, orgTest.Name, p.Organization.Name)
166+
167+
// Tag data is included
168+
assert.Len(t, p.EffectiveTagBindings, 1)
169+
assert.Equal(t, "foo", p.EffectiveTagBindings[0].Key)
170+
assert.Equal(t, "bar", p.EffectiveTagBindings[0].Value)
171+
})
172+
}
173+
145174
func TestProjectsRead(t *testing.T) {
146175
client := testClient(t)
147176
ctx := context.Background()

tag.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@ type TagBinding struct {
2525
}
2626

2727
type EffectiveTagBinding struct {
28-
ID string `jsonapi:"primary,effective-tag-bindings"`
29-
Key string `jsonapi:"attr,key"`
30-
Value string `jsonapi:"attr,value,omitempty"`
31-
28+
ID string `jsonapi:"primary,effective-tag-bindings"`
29+
Key string `jsonapi:"attr,key"`
30+
Value string `jsonapi:"attr,value,omitempty"`
3231
Links map[string]interface{} `jsonapi:"links,omitempty"`
3332
}
3433

workspace_integration_test.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,17 @@ func TestWorkspacesList(t *testing.T) {
305305
orgTest2, orgTest2Cleanup := createOrganization(t, client)
306306
t.Cleanup(orgTest2Cleanup)
307307

308+
prj, pTestCleanup1 := createProjectWithOptions(t, client, orgTest2, ProjectCreateOptions{
309+
Name: randomStringWithoutSpecialChar(t),
310+
TagBindings: []*TagBinding{
311+
{Key: "key3", Value: "value3"},
312+
},
313+
})
314+
t.Cleanup(pTestCleanup1)
315+
308316
_, wTestCleanup1 := createWorkspaceWithOptions(t, client, orgTest2, WorkspaceCreateOptions{
309-
Name: String(randomString(t)),
317+
Name: String(randomString(t)),
318+
Project: prj,
310319
TagBindings: []*TagBinding{
311320
{Key: "key1", Value: "value1"},
312321
{Key: "key2", Value: "value2a"},
@@ -319,11 +328,24 @@ func TestWorkspacesList(t *testing.T) {
319328
})
320329
require.NoError(t, err)
321330
require.Len(t, wl.Items, 1)
322-
require.Len(t, wl.Items[0].EffectiveTagBindings, 2)
331+
require.Len(t, wl.Items[0].EffectiveTagBindings, 3)
323332
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[0].Key)
324333
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[0].Value)
325334
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[1].Key)
326335
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[1].Value)
336+
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[2].Key)
337+
assert.NotEmpty(t, wl.Items[0].EffectiveTagBindings[2].Value)
338+
339+
inheritedTagsFound := 0
340+
for _, tag := range wl.Items[0].EffectiveTagBindings {
341+
if tag.Links["inherited-from"] != nil {
342+
inheritedTagsFound += 1
343+
}
344+
}
345+
346+
if inheritedTagsFound != 1 {
347+
t.Fatalf("Expected 1 inherited tag, got %d", inheritedTagsFound)
348+
}
327349
})
328350

329351
t.Run("when using project id filter and project contains workspaces", func(t *testing.T) {

0 commit comments

Comments
 (0)