1+ /*
2+ Copyright 2025 Adobe. All rights reserved.
3+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+ you may not use this file except in compliance with the License. You may obtain a copy
5+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
7+ Unless required by applicable law or agreed to in writing, software distributed under
8+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+ OF ANY KIND, either express or implied. See the License for the specific language
10+ governing permissions and limitations under the License.
11+ */
12+
13+ // Mock modules before requiring the main file
14+ const mockOpenWhiskInstance = {
15+ actions : {
16+ invoke : jest . fn ( )
17+ } ,
18+ rules : {
19+ disable : jest . fn ( ) ,
20+ enable : jest . fn ( )
21+ }
22+ } ;
23+
24+ jest . mock ( 'openwhisk' , ( ) => {
25+ return jest . fn ( ( ) => mockOpenWhiskInstance ) ;
26+ } ) ;
27+
28+ jest . mock ( 'dotenv' , ( ) => ( {
29+ config : jest . fn ( )
30+ } ) ) ;
31+
32+ jest . mock ( 'commander' , ( ) => {
33+ const mockProgram = {
34+ option : jest . fn ( ) . mockReturnThis ( ) ,
35+ parse : jest . fn ( ) . mockReturnThis ( ) ,
36+ opts : jest . fn ( ) . mockReturnValue ( { keys : 'en,fr' } )
37+ } ;
38+ return { program : mockProgram } ;
39+ } ) ;
40+ // Store original process.env
41+ const originalEnv = process . env ;
42+
43+ describe ( 'Refresh PDP Tool Tests' , ( ) => {
44+ let mainModule ;
45+
46+ beforeEach ( ( ) => {
47+ // Reset process.env before each test
48+ process . env = { ...originalEnv } ;
49+ process . env . AIO_RUNTIME_NAMESPACE = 'test-namespace' ;
50+ process . env . AIO_RUNTIME_AUTH = 'test-auth' ;
51+
52+ // Clear all mocks
53+ jest . clearAllMocks ( ) ;
54+ jest . resetModules ( ) ;
55+
56+ // Reset mock functions
57+ mockOpenWhiskInstance . actions . invoke . mockReset ( ) ;
58+ mockOpenWhiskInstance . rules . disable . mockReset ( ) ;
59+ mockOpenWhiskInstance . rules . enable . mockReset ( ) ;
60+
61+ // Mock exit and console
62+ process . exit = jest . fn ( ) ;
63+ console . log = jest . fn ( ) ;
64+ console . error = jest . fn ( ) ;
65+ } ) ;
66+
67+ afterEach ( ( ) => {
68+ process . env = originalEnv ;
69+ } ) ;
70+
71+ describe ( 'Environment Variables' , ( ) => {
72+ it ( 'should exit if AIO_RUNTIME_NAMESPACE is missing' , ( ) => {
73+ delete process . env . AIO_RUNTIME_NAMESPACE ;
74+ require ( '../tools/refresh-pdps' ) ;
75+
76+ expect ( process . exit ) . toHaveBeenCalledWith ( 1 ) ;
77+ expect ( console . log ) . toHaveBeenCalledWith (
78+ 'Missing required environment variables AIO_RUNTIME_AUTH and AIO_RUNTIME_NAMESPACE'
79+ ) ;
80+ } ) ;
81+
82+ it ( 'should exit if AIO_RUNTIME_AUTH is missing' , ( ) => {
83+ delete process . env . AIO_RUNTIME_AUTH ;
84+ require ( '../tools/refresh-pdps' ) ;
85+
86+ expect ( process . exit ) . toHaveBeenCalledWith ( 1 ) ;
87+ expect ( console . log ) . toHaveBeenCalledWith (
88+ 'Missing required environment variables AIO_RUNTIME_AUTH and AIO_RUNTIME_NAMESPACE'
89+ ) ;
90+ } ) ;
91+ } ) ;
92+
93+ describe ( 'checkState function' , ( ) => {
94+ beforeEach ( ( ) => {
95+ mainModule = require ( '../tools/refresh-pdps' ) ;
96+ } ) ;
97+
98+ it ( 'should return state value for given locale' , async ( ) => {
99+ const expectedState = { value : 'false' } ;
100+ mockOpenWhiskInstance . actions . invoke . mockResolvedValueOnce ( expectedState ) ;
101+
102+ const result = await mainModule . checkState ( 'en' ) ;
103+
104+ expect ( mockOpenWhiskInstance . actions . invoke ) . toHaveBeenCalledWith ( {
105+ name : 'state-manager' ,
106+ params : { key : 'en' , op : 'get' } ,
107+ blocking : true ,
108+ result : true
109+ } ) ;
110+ expect ( result ) . toBe ( 'false' ) ;
111+ } ) ;
112+
113+ it ( 'should handle errors when checking state' , async ( ) => {
114+ mockOpenWhiskInstance . actions . invoke . mockRejectedValueOnce ( new Error ( 'API Error' ) ) ;
115+ await expect ( mainModule . checkState ( 'en' ) ) . rejects . toThrow ( 'API Error' ) ;
116+ } ) ;
117+ } ) ;
118+
119+ describe ( 'flushStoreState function' , ( ) => {
120+ beforeEach ( ( ) => {
121+ mainModule = require ( '../tools/refresh-pdps' ) ;
122+ } ) ;
123+
124+ it ( 'should invoke delete operation for given locale' , async ( ) => {
125+ await mainModule . flushStoreState ( 'en' ) ;
126+
127+ expect ( mockOpenWhiskInstance . actions . invoke ) . toHaveBeenCalledWith ( {
128+ name : 'state-manager' ,
129+ params : { key : 'en' , op : 'delete' } ,
130+ blocking : true ,
131+ result : true
132+ } ) ;
133+ } ) ;
134+
135+ it ( 'should handle errors when flushing state' , async ( ) => {
136+ mockOpenWhiskInstance . actions . invoke . mockRejectedValueOnce ( new Error ( 'Delete Error' ) ) ;
137+ await expect ( mainModule . flushStoreState ( 'en' ) ) . rejects . toThrow ( 'Delete Error' ) ;
138+ } ) ;
139+ } ) ;
140+
141+ describe ( 'main function' , ( ) => {
142+ beforeEach ( ( ) => {
143+ mainModule = require ( '../tools/refresh-pdps' ) ;
144+ mockOpenWhiskInstance . rules . disable . mockResolvedValue ( { } ) ;
145+ mockOpenWhiskInstance . rules . enable . mockResolvedValue ( { } ) ;
146+ mockOpenWhiskInstance . actions . invoke
147+ . mockResolvedValueOnce ( { value : 'false' } )
148+ . mockResolvedValueOnce ( { } )
149+ . mockResolvedValueOnce ( { } )
150+ . mockResolvedValueOnce ( { value : 'true' } ) ;
151+
152+ jest . useFakeTimers ( ) ;
153+ } ) ;
154+
155+ afterEach ( ( ) => {
156+ jest . useRealTimers ( ) ;
157+ } ) ;
158+
159+ it ( 'should successfully complete the state management cycle' , async ( ) => {
160+ const mainPromise = mainModule . main ( ) ;
161+ jest . runAllTimers ( ) ;
162+ await mainPromise ;
163+
164+ expect ( mockOpenWhiskInstance . rules . disable ) . toHaveBeenCalledWith ( {
165+ name : 'poll_every_minute'
166+ } ) ;
167+ expect ( mockOpenWhiskInstance . rules . enable ) . toHaveBeenCalledWith ( {
168+ name : 'poll_every_minute'
169+ } ) ;
170+ expect ( process . exit ) . toHaveBeenCalledWith ( 0 ) ;
171+ } ) ;
172+
173+ it ( 'should timeout if running state never becomes true' , async ( ) => {
174+ mockOpenWhiskInstance . actions . invoke . mockResolvedValue ( { value : 'false' } ) ;
175+
176+ const timeout = 1500 ; // to simulate in the test env
177+ const mainPromise = mainModule . main ( timeout ) ;
178+ jest . advanceTimersByTime ( 1500 ) ;
179+ await mainPromise ;
180+
181+ expect ( console . error ) . toHaveBeenCalledWith (
182+ 'Timeout: running state did not become true within 30 minutes.'
183+ ) ;
184+ expect ( process . exit ) . toHaveBeenCalledWith ( 1 ) ;
185+ } ) ;
186+ } ) ;
187+ } ) ;
0 commit comments