Skip to content

Commit 43497be

Browse files
authored
fix: change custom_db_role resource to use *string (#264)
1 parent 77290cf commit 43497be

File tree

2 files changed

+140
-71
lines changed

2 files changed

+140
-71
lines changed

mongodbatlas/custom_db_roles.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ var _ CustomDBRolesService = &CustomDBRolesServiceOp{}
4141

4242
// A Resource describes a specific resource the Role will allow operating on.
4343
type Resource struct {
44-
Collection string `json:"collection,omitempty"`
45-
Db string `json:"db,omitempty"` //nolint:stylecheck // not changing this as is a breaking change
46-
Cluster *bool `json:"cluster,omitempty"`
44+
Collection *string `json:"collection,omitempty"`
45+
DB *string `json:"db,omitempty"`
46+
Cluster *bool `json:"cluster,omitempty"`
4747
}
4848

4949
// An Action describes the operation the role will include, for a specific set of Resources.

mongodbatlas/custom_db_roles_test.go

Lines changed: 137 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"testing"
2323

2424
"github.com/go-test/deep"
25+
"github.com/openlyinc/pointy"
2526
)
2627

2728
func TestCustomDBRoles_ListCustomDBRoles(t *testing.T) {
@@ -42,8 +43,8 @@ func TestCustomDBRoles_ListCustomDBRoles(t *testing.T) {
4243
Actions: []Action{{
4344
Action: "CREATE_INDEX",
4445
Resources: []Resource{{
45-
Collection: "test-collection",
46-
Db: "test-db",
46+
Collection: pointy.String("test-collection"),
47+
DB: pointy.String("test-db"),
4748
}},
4849
}},
4950
InheritedRoles: []InheritedRole{{
@@ -76,8 +77,8 @@ func TestCustomDBRoles_GetCustomDBRole(t *testing.T) {
7677
Actions: []Action{{
7778
Action: "CREATE_INDEX",
7879
Resources: []Resource{{
79-
Collection: "test-collection",
80-
Db: "test-db",
80+
Collection: pointy.String("test-collection"),
81+
DB: pointy.String("test-db"),
8182
}},
8283
}},
8384
InheritedRoles: []InheritedRole{{
@@ -92,83 +93,151 @@ func TestCustomDBRoles_GetCustomDBRole(t *testing.T) {
9293
}
9394

9495
func TestCustomDBRoles_CreateCustomDBRole(t *testing.T) {
96+
type createCase struct {
97+
input CustomDBRole
98+
expected map[string]interface{}
99+
}
100+
createExamples := []createCase{
101+
{
102+
input: CustomDBRole{
103+
Actions: []Action{{
104+
Action: "CREATE_INDEX",
105+
Resources: []Resource{{
106+
Collection: pointy.String("test-collection"),
107+
DB: pointy.String("test-db"),
108+
}},
109+
}},
110+
InheritedRoles: []InheritedRole{{
111+
Db: "test-db",
112+
Role: "read",
113+
}},
114+
RoleName: "test-role-name",
115+
},
116+
expected: map[string]interface{}{
117+
"actions": []interface{}{map[string]interface{}{
118+
"action": "CREATE_INDEX",
119+
"resources": []interface{}{map[string]interface{}{
120+
"collection": "test-collection",
121+
"db": "test-db",
122+
}},
123+
}},
124+
"inheritedRoles": []interface{}{map[string]interface{}{
125+
"db": "test-db",
126+
"role": "read",
127+
}},
128+
"roleName": "test-role-name",
129+
},
130+
},
131+
// the following case verifies https://github.com/mongodb/go-client-mongodb-atlas/issues/263
132+
{
133+
input: CustomDBRole{
134+
Actions: []Action{
135+
{
136+
Action: "CREATE_INDEX",
137+
Resources: []Resource{
138+
{
139+
Collection: pointy.String(""),
140+
DB: pointy.String("admin"),
141+
},
142+
},
143+
},
144+
},
145+
InheritedRoles: []InheritedRole{
146+
{
147+
Db: "test-db",
148+
Role: "read",
149+
},
150+
},
151+
RoleName: "empty-collection-test",
152+
},
153+
expected: map[string]interface{}{
154+
"roleName": "empty-collection-test",
155+
"actions": []interface{}{
156+
map[string]interface{}{
157+
"action": "CREATE_INDEX",
158+
"resources": []interface{}{
159+
map[string]interface{}{
160+
"collection": "",
161+
"db": "admin",
162+
},
163+
},
164+
},
165+
},
166+
"inheritedRoles": []interface{}{
167+
map[string]interface{}{
168+
"db": "test-db",
169+
"role": "read",
170+
},
171+
},
172+
},
173+
},
174+
{
175+
input: CustomDBRole{
176+
RoleName: "just-cluster-action",
177+
Actions: []Action{
178+
{
179+
Action: "CONN_POOL_STATS",
180+
Resources: []Resource{
181+
{
182+
Cluster: pointy.Bool(true),
183+
},
184+
},
185+
},
186+
},
187+
InheritedRoles: []InheritedRole{},
188+
},
189+
expected: map[string]interface{}{
190+
"roleName": "just-cluster-action",
191+
"actions": []interface{}{
192+
map[string]interface{}{
193+
"action": "CONN_POOL_STATS",
194+
"resources": []interface{}{
195+
map[string]interface{}{
196+
"cluster": true,
197+
},
198+
},
199+
},
200+
},
201+
"inheritedRoles": []interface{}{},
202+
},
203+
},
204+
}
205+
206+
// keep the mux creation outside of the loop to avoid allocations.
95207
client, mux, teardown := setup()
96208
defer teardown()
97209

98-
createRequest := &CustomDBRole{
99-
Actions: []Action{{
100-
Action: "CREATE_INDEX",
101-
Resources: []Resource{{
102-
Collection: "test-collection",
103-
Db: "test-db",
104-
}},
105-
}},
106-
InheritedRoles: []InheritedRole{{
107-
Db: "test-db",
108-
Role: "read",
109-
}},
110-
RoleName: "test-role-name",
111-
}
210+
// allows mux to expect different values at each iteration.
211+
var muxExpected map[string]interface{}
112212

113213
mux.HandleFunc("/api/atlas/v1.0/groups/1/customDBRoles/roles", func(w http.ResponseWriter, r *http.Request) {
114-
expected := map[string]interface{}{
115-
"actions": []interface{}{map[string]interface{}{
116-
"action": "CREATE_INDEX",
117-
"resources": []interface{}{map[string]interface{}{
118-
"collection": "test-collection",
119-
"db": "test-db",
120-
}},
121-
}},
122-
"inheritedRoles": []interface{}{map[string]interface{}{
123-
"db": "test-db",
124-
"role": "read",
125-
}},
126-
"roleName": "test-role-name",
127-
}
128-
129-
jsonBlob := `
130-
{
131-
"actions": [
132-
{
133-
"action": "CREATE_INDEX",
134-
"resources": [
135-
{
136-
"collection": "test-collection",
137-
"db": "test-db"
138-
}
139-
]
140-
}
141-
],
142-
"inheritedRoles": [
143-
{
144-
"db": "test-db",
145-
"role": "read"
146-
}
147-
],
148-
"roleName":"test-role-name"
149-
}
150-
`
151-
152214
var v map[string]interface{}
153215
err := json.NewDecoder(r.Body).Decode(&v)
216+
154217
if err != nil {
155218
t.Fatalf("decode json: %v", err)
156219
}
157220

158-
if diff := deep.Equal(v, expected); diff != nil {
221+
if diff := deep.Equal(v, muxExpected); diff != nil {
159222
t.Error(diff)
160223
}
161224

162-
fmt.Fprint(w, jsonBlob)
225+
if err := json.NewEncoder(w).Encode(v); err != nil {
226+
t.Error(err)
227+
}
163228
})
164229

165-
customDBRole, _, err := client.CustomDBRoles.Create(ctx, "1", createRequest)
166-
if err != nil {
167-
t.Fatalf("CustomDBRoles.Create returned error: %v", err)
168-
}
230+
for _, example := range createExamples {
231+
muxExpected = example.expected
169232

170-
if roleName := customDBRole.RoleName; roleName != "test-role-name" {
171-
t.Errorf("expected roleName '%s', received '%s'", "test-role-name", roleName)
233+
customDBRole, _, err := client.CustomDBRoles.Create(ctx, "1", &example.input)
234+
if err != nil {
235+
t.Fatalf("CustomDBRoles.Create returned error: %v", err)
236+
}
237+
238+
if roleName := customDBRole.RoleName; roleName != example.expected["roleName"] {
239+
t.Errorf("expected roleName '%s', received '%s'", example.expected["roleName"], roleName)
240+
}
172241
}
173242
}
174243

@@ -180,8 +249,8 @@ func TestCustomDBRoles_UpdateCustomDBRole(t *testing.T) {
180249
Actions: []Action{{
181250
Action: "CREATE_INDEX",
182251
Resources: []Resource{{
183-
Collection: "test-collection",
184-
Db: "test-db",
252+
Collection: pointy.String("test-collection"),
253+
DB: pointy.String("test-db"),
185254
}},
186255
}},
187256
InheritedRoles: []InheritedRole{{
@@ -278,8 +347,8 @@ func TestCustomDBRoles_DeleteInheritedRole(t *testing.T) {
278347
Actions: []Action{{
279348
Action: "CREATE_INDEX",
280349
Resources: []Resource{{
281-
Collection: "test-collection",
282-
Db: "test-db",
350+
Collection: pointy.String("test-collection"),
351+
DB: pointy.String("test-db"),
283352
}},
284353
}},
285354
InheritedRoles: []InheritedRole{},

0 commit comments

Comments
 (0)