@@ -44,10 +44,11 @@ describe('useMetricDetectorLimit', () => {
44
44
SubscriptionStore . init ( ) ;
45
45
} ) ;
46
46
47
- it ( 'returns no limits when feature flag is disabled' , ( ) => {
47
+ it ( 'handles feature flag is disabled' , ( ) => {
48
48
const wrapper = createWrapper ( mockOrganizationWithoutFeature ) ;
49
- MockApiClient . addMockResponse ( {
49
+ const detectorsRequest = MockApiClient . addMockResponse ( {
50
50
url : '/organizations/org-slug/detectors/' ,
51
+ headers : { 'X-Hits' : '5' } ,
51
52
body : [ ] ,
52
53
} ) ;
53
54
@@ -60,23 +61,43 @@ describe('useMetricDetectorLimit', () => {
60
61
isLoading : false ,
61
62
isError : false ,
62
63
} ) ;
64
+
65
+ expect ( detectorsRequest ) . not . toHaveBeenCalled ( ) ;
63
66
} ) ;
64
67
65
- it ( 'handles no subscription data (defaults to 0)' , ( ) => {
68
+ it ( 'handles no subscription data' , async ( ) => {
66
69
const wrapper = createWrapper ( mockOrganization ) ;
67
70
68
71
SubscriptionStore . set ( mockOrganization . slug , null as any ) ;
69
72
const detectorsRequest = MockApiClient . addMockResponse ( {
70
73
url : '/organizations/org-slug/detectors/' ,
74
+ headers : { 'X-Hits' : '2' } ,
71
75
body : [ ] ,
72
76
} ) ;
73
77
74
78
const { result} = renderHook ( ( ) => useMetricDetectorLimit ( ) , { wrapper} ) ;
75
79
76
- expect ( result . current . detectorLimit ) . toBe ( 0 ) ;
77
- expect ( result . current . isLoading ) . toBe ( true ) ;
80
+ await waitFor ( ( ) => {
81
+ expect ( result . current ?. isLoading ) . toBe ( false ) ;
82
+ } ) ;
78
83
79
- expect ( detectorsRequest ) . toHaveBeenCalled ( ) ;
84
+ expect ( result . current ) . toEqual ( {
85
+ hasReachedLimit : false ,
86
+ detectorLimit : - 1 ,
87
+ detectorCount : 2 ,
88
+ isLoading : false ,
89
+ isError : false ,
90
+ } ) ;
91
+
92
+ expect ( detectorsRequest ) . toHaveBeenCalledWith (
93
+ '/organizations/org-slug/detectors/' ,
94
+ expect . objectContaining ( {
95
+ query : expect . objectContaining ( {
96
+ query : 'type:metric' ,
97
+ per_page : 0 ,
98
+ } ) ,
99
+ } )
100
+ ) ;
80
101
} ) ;
81
102
82
103
it ( 'handles detectors count is below limit' , async ( ) => {
@@ -96,11 +117,8 @@ describe('useMetricDetectorLimit', () => {
96
117
97
118
const detectorsRequest = MockApiClient . addMockResponse ( {
98
119
url : '/organizations/org-slug/detectors/' ,
99
- body : [
100
- { id : '1' , name : 'Detector 1' } ,
101
- { id : '2' , name : 'Detector 2' } ,
102
- { id : '3' , name : 'Detector 3' } ,
103
- ] ,
120
+ headers : { 'X-Hits' : '3' } ,
121
+ body : [ ] ,
104
122
} ) ;
105
123
106
124
const { result} = renderHook ( ( ) => useMetricDetectorLimit ( ) , { wrapper} ) ;
@@ -117,7 +135,15 @@ describe('useMetricDetectorLimit', () => {
117
135
isError : false ,
118
136
} ) ;
119
137
120
- expect ( detectorsRequest ) . toHaveBeenCalledTimes ( 1 ) ;
138
+ expect ( detectorsRequest ) . toHaveBeenCalledWith (
139
+ '/organizations/org-slug/detectors/' ,
140
+ expect . objectContaining ( {
141
+ query : expect . objectContaining ( {
142
+ query : 'type:metric' ,
143
+ per_page : 0 ,
144
+ } ) ,
145
+ } )
146
+ ) ;
121
147
} ) ;
122
148
123
149
it ( 'handles detectors count equals limit' , async ( ) => {
@@ -137,11 +163,44 @@ describe('useMetricDetectorLimit', () => {
137
163
138
164
MockApiClient . addMockResponse ( {
139
165
url : '/organizations/org-slug/detectors/' ,
140
- body : [
141
- { id : '1' , name : 'Detector 1' } ,
142
- { id : '2' , name : 'Detector 2' } ,
143
- { id : '3' , name : 'Detector 3' } ,
144
- ] ,
166
+ headers : { 'X-Hits' : '3' } ,
167
+ body : [ ] ,
168
+ } ) ;
169
+
170
+ const { result} = renderHook ( ( ) => useMetricDetectorLimit ( ) , { wrapper} ) ;
171
+
172
+ await waitFor ( ( ) => {
173
+ expect ( result . current . isLoading ) . toBe ( false ) ;
174
+ } ) ;
175
+
176
+ expect ( result . current ) . toEqual ( {
177
+ hasReachedLimit : true ,
178
+ detectorLimit : 3 ,
179
+ detectorCount : 3 ,
180
+ isLoading : false ,
181
+ isError : false ,
182
+ } ) ;
183
+ } ) ;
184
+
185
+ it ( 'handles detector limit is -1' , async ( ) => {
186
+ const wrapper = createWrapper ( mockOrganization ) ;
187
+
188
+ const subscription = SubscriptionFixture ( {
189
+ organization : mockOrganization ,
190
+ planDetails : {
191
+ ...SubscriptionFixture ( {
192
+ organization : mockOrganization ,
193
+ } ) . planDetails ,
194
+ metricDetectorLimit : - 1 ,
195
+ } ,
196
+ } ) ;
197
+
198
+ SubscriptionStore . set ( mockOrganization . slug , subscription ) ;
199
+
200
+ const detectorsRequest = MockApiClient . addMockResponse ( {
201
+ url : '/organizations/org-slug/detectors/' ,
202
+ headers : { 'X-Hits' : '10' } ,
203
+ body : [ ] ,
145
204
} ) ;
146
205
147
206
const { result} = renderHook ( ( ) => useMetricDetectorLimit ( ) , { wrapper} ) ;
@@ -150,11 +209,15 @@ describe('useMetricDetectorLimit', () => {
150
209
expect ( result . current . isLoading ) . toBe ( false ) ;
151
210
} ) ;
152
211
153
- expect ( result . current . hasReachedLimit ) . toBe ( true ) ;
154
- expect ( result . current . detectorLimit ) . toBe ( 3 ) ;
155
- expect ( result . current . detectorCount ) . toBe ( 3 ) ;
156
- expect ( result . current . isLoading ) . toBe ( false ) ;
157
- expect ( result . current . isError ) . toBe ( false ) ;
212
+ expect ( result . current ) . toEqual ( {
213
+ hasReachedLimit : false ,
214
+ detectorLimit : - 1 ,
215
+ detectorCount : 10 ,
216
+ isLoading : false ,
217
+ isError : false ,
218
+ } ) ;
219
+
220
+ expect ( detectorsRequest ) . toHaveBeenCalled ( ) ;
158
221
} ) ;
159
222
160
223
it ( 'handles detectors API error gracefully' , async ( ) => {
@@ -183,10 +246,48 @@ describe('useMetricDetectorLimit', () => {
183
246
expect ( result . current . isLoading ) . toBe ( false ) ;
184
247
} ) ;
185
248
186
- expect ( result . current . isError ) . toBe ( true ) ;
187
- expect ( result . current . detectorLimit ) . toBe ( 20 ) ;
188
- expect ( result . current . detectorCount ) . toBe ( 0 ) ;
189
- expect ( result . current . hasReachedLimit ) . toBe ( false ) ;
190
- expect ( result . current . isLoading ) . toBe ( false ) ;
249
+ expect ( result . current ) . toEqual ( {
250
+ hasReachedLimit : false ,
251
+ detectorLimit : 20 ,
252
+ detectorCount : - 1 ,
253
+ isLoading : false ,
254
+ isError : true ,
255
+ } ) ;
256
+ } ) ;
257
+
258
+ it ( 'handles missing X-Hits header as error' , async ( ) => {
259
+ const wrapper = createWrapper ( mockOrganization ) ;
260
+
261
+ const subscription = SubscriptionFixture ( {
262
+ organization : mockOrganization ,
263
+ planDetails : {
264
+ ...SubscriptionFixture ( {
265
+ organization : mockOrganization ,
266
+ } ) . planDetails ,
267
+ metricDetectorLimit : 5 ,
268
+ } ,
269
+ } ) ;
270
+
271
+ SubscriptionStore . set ( mockOrganization . slug , subscription ) ;
272
+
273
+ MockApiClient . addMockResponse ( {
274
+ url : '/organizations/org-slug/detectors/' ,
275
+ body : [ ] ,
276
+ // No X-Hits header
277
+ } ) ;
278
+
279
+ const { result} = renderHook ( ( ) => useMetricDetectorLimit ( ) , { wrapper} ) ;
280
+
281
+ await waitFor ( ( ) => {
282
+ expect ( result . current . isLoading ) . toBe ( false ) ;
283
+ } ) ;
284
+
285
+ expect ( result . current ) . toEqual ( {
286
+ hasReachedLimit : false ,
287
+ detectorLimit : 5 ,
288
+ detectorCount : - 1 ,
289
+ isLoading : false ,
290
+ isError : true ,
291
+ } ) ;
191
292
} ) ;
192
293
} ) ;
0 commit comments