@@ -12,7 +12,7 @@ governing permissions and limitations under the License.
1212
1313const { setCurrentOrgId, context } = require ( '@adobe/aio-lib-ims' )
1414const { setStore } = require ( '@adobe/aio-lib-core-config' )
15- const { initSdk, getOutputFormat, columnWithArray, disableCliAuth, enableCliAuth, formatDuration } = require ( '../src/cloudmanager-helpers' )
15+ const { initSdk, getOutputFormat, columnWithArray, disableCliAuth, enableCliAuth, formatDuration, executeWithRetries } = require ( '../src/cloudmanager-helpers' )
1616const { init } = require ( '@adobe/aio-lib-cloudmanager' )
1717const { setDecodedToken, resetDecodedToken } = require ( 'jsonwebtoken' )
1818
@@ -133,3 +133,66 @@ test('formatDuration -- only finished', async () => {
133133 finishedAt : '2021-05-01' ,
134134 } ) ) . toEqual ( '' )
135135} )
136+
137+ describe ( 'executeWithRetries' , ( ) => {
138+ afterEach ( ( ) => {
139+ jest . restoreAllMocks ( )
140+ } )
141+
142+ test ( 'should not retry when no 401, 403 thrown' , async ( ) => {
143+ const mockFn = jest . fn ( ) . mockResolvedValue ( 'success' )
144+
145+ executeWithRetries ( mockFn )
146+
147+ expect ( mockFn . mock . calls . length ) . toEqual ( 1 )
148+ } )
149+
150+ test ( 'should retry when 401 thrown' , async ( ) => {
151+ const mockFn = jest . fn ( )
152+ . mockRejectedValueOnce ( { sdkDetails : { response : { status : 401 } } } )
153+ . mockResolvedValue ( 'success' )
154+
155+ await executeWithRetries ( mockFn )
156+
157+ expect ( mockFn . mock . calls . length ) . toEqual ( 2 )
158+ } )
159+
160+ test ( 'should retry when 403 thrown' , async ( ) => {
161+ const mockFn = jest . fn ( )
162+ . mockRejectedValueOnce ( { sdkDetails : { response : { status : 401 } } } )
163+ . mockResolvedValue ( 'success' )
164+
165+ await executeWithRetries ( mockFn )
166+
167+ expect ( mockFn . mock . calls . length ) . toEqual ( 2 )
168+ } )
169+
170+ test ( 'should throw error when no 401, 403 thrown' , async ( ) => {
171+ const mockFn = jest . fn ( )
172+ . mockRejectedValue ( new Error ( ) )
173+
174+ await expect ( executeWithRetries ( mockFn ) ) . rejects . toThrow ( )
175+
176+ expect ( mockFn . mock . calls . length ) . toEqual ( 1 )
177+ } )
178+
179+ test ( 'should retry 5 times and throw exception' , async ( ) => {
180+ const mockFn = jest . fn ( ) . mockRejectedValue ( { sdkDetails : { response : { status : 401 } } } )
181+
182+ await expect ( executeWithRetries ( mockFn ) ) . rejects . toThrow ( '[CloudManagerCLI:MAX_RETRY_REACHED] Max retries' )
183+
184+ expect ( mockFn . mock . calls . length ) . toEqual ( 5 )
185+ } )
186+
187+ test ( 'should reset retry counter after 1 hour' , async ( ) => {
188+ jest . spyOn ( Date , 'now' )
189+ . mockReturnValueOnce ( new Date ( Date . UTC ( 2024 , 11 , 1 , 0 , 0 , 0 ) ) )
190+ . mockReturnValueOnce ( new Date ( Date . UTC ( 2024 , 11 , 1 , 0 , 0 , 0 ) ) )
191+ . mockReturnValue ( new Date ( Date . UTC ( 2024 , 11 , 1 , 1 , 0 , 0 ) ) )
192+ const mockFn = jest . fn ( ) . mockRejectedValue ( { sdkDetails : { response : { status : 401 } } } )
193+
194+ await expect ( executeWithRetries ( mockFn ) ) . rejects . toThrow ( '[CloudManagerCLI:MAX_RETRY_REACHED] Max retries' )
195+
196+ expect ( mockFn . mock . calls . length ) . toEqual ( 6 )
197+ } )
198+ } )
0 commit comments