Skip to content

Commit ff26ce6

Browse files
authored
Handle empty IP restrictions (#177)
* Handle empty IP restrictions
1 parent 5dc0bed commit ff26ce6

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed

pkg/service/account/model.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package account
22

3-
import "github.com/ans-group/sdk-go/pkg/connection"
3+
import (
4+
"encoding/json"
5+
6+
"github.com/ans-group/sdk-go/pkg/connection"
7+
)
48

59
type ContactType string
610

@@ -117,3 +121,25 @@ type ApplicationRestriction struct {
117121
IPRestrictionType string `json:"ip_restriction_type"`
118122
IPRanges []string `json:"ip_ranges"`
119123
}
124+
125+
func (a *ApplicationRestriction) UnmarshalJSON(data []byte) error {
126+
var raw json.RawMessage
127+
if err := json.Unmarshal(data, &raw); err != nil {
128+
return err
129+
}
130+
131+
// If the data starts with '[', it's an array (empty restrictions)
132+
if len(raw) > 0 && raw[0] == '[' {
133+
a.IPRestrictionType = ""
134+
a.IPRanges = nil
135+
return nil
136+
}
137+
138+
type Alias ApplicationRestriction
139+
aux := &struct {
140+
*Alias
141+
}{
142+
Alias: (*Alias)(a),
143+
}
144+
return json.Unmarshal(data, aux)
145+
}

pkg/service/account/model_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package account
22

33
import (
4+
"encoding/json"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -13,3 +14,88 @@ func TestContactType_String_Expected(t *testing.T) {
1314

1415
assert.Equal(t, "Accounts", s)
1516
}
17+
18+
func TestApplicationRestriction_UnmarshalJSON(t *testing.T) {
19+
tests := []struct {
20+
name string
21+
jsonData string
22+
expected ApplicationRestriction
23+
expectError bool
24+
}{
25+
{
26+
name: "Empty array returns empty restriction",
27+
jsonData: `[]`,
28+
expected: ApplicationRestriction{
29+
IPRestrictionType: "",
30+
IPRanges: nil,
31+
},
32+
expectError: false,
33+
},
34+
{
35+
name: "Valid object with allowlist unmarshals correctly",
36+
jsonData: `{"ip_restriction_type":"allowlist","ip_ranges":["198.51.100.1","198.51.100.2"]}`,
37+
expected: ApplicationRestriction{
38+
IPRestrictionType: "allowlist",
39+
IPRanges: []string{"198.51.100.1", "198.51.100.2"},
40+
},
41+
expectError: false,
42+
},
43+
{
44+
name: "Valid object with denylist unmarshals correctly",
45+
jsonData: `{"ip_restriction_type":"denylist","ip_ranges":["198.51.100.3"]}`,
46+
expected: ApplicationRestriction{
47+
IPRestrictionType: "denylist",
48+
IPRanges: []string{"198.51.100.3"},
49+
},
50+
expectError: false,
51+
},
52+
{
53+
name: "Empty object unmarshals correctly",
54+
jsonData: `{"ip_restriction_type":"","ip_ranges":[]}`,
55+
expected: ApplicationRestriction{
56+
IPRestrictionType: "",
57+
IPRanges: []string{},
58+
},
59+
expectError: false,
60+
},
61+
{
62+
name: "Object with null ip_ranges unmarshals correctly",
63+
jsonData: `{"ip_restriction_type":"allowlist","ip_ranges":null}`,
64+
expected: ApplicationRestriction{
65+
IPRestrictionType: "allowlist",
66+
IPRanges: nil,
67+
},
68+
expectError: false,
69+
},
70+
{
71+
name: "Invalid JSON returns error",
72+
jsonData: `{invalid json}`,
73+
expected: ApplicationRestriction{},
74+
expectError: true,
75+
},
76+
{
77+
name: "Array with content treated as empty restriction",
78+
jsonData: `["some","content"]`,
79+
expected: ApplicationRestriction{
80+
IPRestrictionType: "",
81+
IPRanges: nil,
82+
},
83+
expectError: false,
84+
},
85+
}
86+
87+
for _, tt := range tests {
88+
t.Run(tt.name, func(t *testing.T) {
89+
var restriction ApplicationRestriction
90+
err := json.Unmarshal([]byte(tt.jsonData), &restriction)
91+
92+
if tt.expectError {
93+
assert.Error(t, err)
94+
} else {
95+
assert.NoError(t, err)
96+
assert.Equal(t, tt.expected.IPRestrictionType, restriction.IPRestrictionType)
97+
assert.Equal(t, tt.expected.IPRanges, restriction.IPRanges)
98+
}
99+
})
100+
}
101+
}

0 commit comments

Comments
 (0)