11const { when } = require ( 'jest-when' )
22const Variables = require ( '../../../../lib/plugins/variables' )
3+ const NopCommand = require ( '../../../../lib/nopcommand' )
34
45describe ( 'Variables' , ( ) => {
56 let github
@@ -10,13 +11,13 @@ describe('Variables', () => {
1011 return variables
1112 }
1213
13- function configure ( ) {
14- const log = { debug : console . debug , error : console . error }
14+ function configure ( nop = false ) {
15+ const log = { debug : jest . fn ( ) , error : console . error }
1516 const errors = [ ]
16- return new Variables ( undefined , github , { owner : org , repo } , [ { name : 'test' , value : 'test' } ] , log , errors )
17+ return new Variables ( nop , github , { owner : org , repo } , [ { name : 'test' , value : 'test' } ] , log , errors )
1718 }
1819
19- beforeAll ( ( ) => {
20+ beforeEach ( ( ) => {
2021 github = {
2122 request : jest . fn ( ) . mockReturnValue ( Promise . resolve ( true ) )
2223 }
@@ -76,4 +77,194 @@ describe('Variables', () => {
7677 )
7778 } )
7879 } )
80+
81+ describe ( 'noop mode' , ( ) => {
82+ describe ( 'sync' , ( ) => {
83+ it ( 'should return NopCommands and not make mutating API calls when nop is true' , async ( ) => {
84+ const plugin = configure ( true )
85+
86+ when ( github . request )
87+ . calledWith ( 'GET /repos/:org/:repo/actions/variables' , { org, repo } )
88+ . mockResolvedValue ( {
89+ data : {
90+ variables : [ { name : 'EXISTING_VAR' , value : 'existing-value' } ]
91+ }
92+ } )
93+
94+ const result = await plugin . sync ( )
95+
96+ // Should have made GET call to fetch existing variables
97+ expect ( github . request ) . toHaveBeenCalledWith ( 'GET /repos/:org/:repo/actions/variables' , { org, repo } )
98+
99+ // Should NOT have made any mutating calls (POST, PATCH, DELETE)
100+ expect ( github . request ) . not . toHaveBeenCalledWith (
101+ expect . stringMatching ( / ^ ( P O S T | P A T C H | D E L E T E ) / ) ,
102+ expect . anything ( )
103+ )
104+
105+ // Result should contain NopCommands
106+ expect ( Array . isArray ( result ) ) . toBe ( true )
107+ expect ( result . length ) . toBeGreaterThan ( 0 )
108+ result . forEach ( cmd => expect ( cmd ) . toBeInstanceOf ( NopCommand ) )
109+ } )
110+
111+ it ( 'should return flat NopCommand array when updating variable value via sync' , async ( ) => {
112+ const log = { debug : jest . fn ( ) , error : console . error }
113+ const errors = [ ]
114+ const plugin = new Variables ( true , github , { owner : org , repo } , [ { name : 'TEST' , value : 'new-value' } ] , log , errors )
115+
116+ when ( github . request )
117+ . calledWith ( 'GET /repos/:org/:repo/actions/variables' , { org, repo } )
118+ . mockResolvedValue ( {
119+ data : {
120+ variables : [ { name : 'TEST' , value : 'old-value' } ]
121+ }
122+ } )
123+
124+ const result = await plugin . sync ( )
125+
126+ // Should have made GET call
127+ expect ( github . request ) . toHaveBeenCalledWith ( 'GET /repos/:org/:repo/actions/variables' , { org, repo } )
128+
129+ // Should NOT have made any mutating calls
130+ expect ( github . request ) . not . toHaveBeenCalledWith (
131+ expect . stringMatching ( / ^ ( P O S T | P A T C H | D E L E T E ) / ) ,
132+ expect . anything ( )
133+ )
134+
135+ // Result should be a flat array of NopCommands (not nested)
136+ expect ( Array . isArray ( result ) ) . toBe ( true )
137+ result . forEach ( cmd => {
138+ expect ( cmd ) . toBeInstanceOf ( NopCommand )
139+ expect ( Array . isArray ( cmd ) ) . toBe ( false )
140+ } )
141+ } )
142+ } )
143+
144+ describe ( 'add' , ( ) => {
145+ it ( 'should return NopCommand and not make API call when nop is true' , async ( ) => {
146+ const plugin = configure ( true )
147+ const variable = { name : 'NEW_VAR' , value : 'new-value' }
148+
149+ const result = await plugin . add ( variable )
150+
151+ expect ( result ) . toBeInstanceOf ( NopCommand )
152+ expect ( result . plugin ) . toBe ( 'Variables' )
153+ expect ( github . request ) . not . toHaveBeenCalled ( )
154+ } )
155+
156+ it ( 'should make API call when nop is false' , async ( ) => {
157+ const plugin = configure ( false )
158+ const variable = { name : 'NEW_VAR' , value : 'new-value' }
159+
160+ await plugin . add ( variable )
161+
162+ expect ( github . request ) . toHaveBeenCalledWith (
163+ 'POST /repos/:org/:repo/actions/variables' ,
164+ expect . objectContaining ( {
165+ org,
166+ repo,
167+ name : 'NEW_VAR' ,
168+ value : 'new-value'
169+ } )
170+ )
171+ } )
172+ } )
173+
174+ describe ( 'remove' , ( ) => {
175+ it ( 'should return NopCommand and not make API call when nop is true' , async ( ) => {
176+ const plugin = configure ( true )
177+ const existing = { name : 'EXISTING_VAR' , value : 'existing-value' }
178+
179+ const result = await plugin . remove ( existing )
180+
181+ expect ( result ) . toBeInstanceOf ( NopCommand )
182+ expect ( result . plugin ) . toBe ( 'Variables' )
183+ expect ( github . request ) . not . toHaveBeenCalled ( )
184+ } )
185+
186+ it ( 'should make API call when nop is false' , async ( ) => {
187+ const plugin = configure ( false )
188+ const existing = { name : 'EXISTING_VAR' , value : 'existing-value' }
189+
190+ await plugin . remove ( existing )
191+
192+ expect ( github . request ) . toHaveBeenCalledWith (
193+ 'DELETE /repos/:org/:repo/actions/variables/:variable_name' ,
194+ expect . objectContaining ( {
195+ org,
196+ repo,
197+ variable_name : 'EXISTING_VAR'
198+ } )
199+ )
200+ } )
201+ } )
202+
203+ describe ( 'update' , ( ) => {
204+ it ( 'should return single NopCommand for single operation with nop true' , async ( ) => {
205+ const plugin = configure ( true )
206+ const existing = { name : 'VAR1' , value : 'old-value' }
207+ const updated = { name : 'VAR1' , value : 'new-value' }
208+
209+ const result = await plugin . update ( existing , updated )
210+
211+ expect ( result ) . toBeInstanceOf ( NopCommand )
212+ expect ( result . plugin ) . toBe ( 'Variables' )
213+ expect ( github . request ) . not . toHaveBeenCalled ( )
214+ } )
215+
216+ it ( 'should return single NopCommand when adding new variable in update with nop true' , async ( ) => {
217+ const plugin = configure ( true )
218+ const existing = [ ]
219+ const updated = [ { name : 'NEW_VAR' , value : 'new-value' } ]
220+
221+ const result = await plugin . update ( existing , updated )
222+
223+ expect ( result ) . toBeInstanceOf ( NopCommand )
224+ expect ( github . request ) . not . toHaveBeenCalled ( )
225+ } )
226+
227+ it ( 'should return single NopCommand when deleting variable in update with nop true' , async ( ) => {
228+ const plugin = configure ( true )
229+ const existing = [ { name : 'OLD_VAR' , value : 'old-value' } ]
230+ const updated = [ ]
231+
232+ const result = await plugin . update ( existing , updated )
233+
234+ expect ( result ) . toBeInstanceOf ( NopCommand )
235+ expect ( github . request ) . not . toHaveBeenCalled ( )
236+ } )
237+
238+ it ( 'should return multiple NopCommands for multiple operations with nop true' , async ( ) => {
239+ const plugin = configure ( true )
240+ const existing = [ { name : 'UPDATE_VAR' , value : 'old' } , { name : 'DELETE_VAR' , value : 'delete-me' } ]
241+ const updated = [ { name : 'UPDATE_VAR' , value : 'new' } , { name : 'ADD_VAR' , value : 'added' } ]
242+
243+ const result = await plugin . update ( existing , updated )
244+
245+ expect ( Array . isArray ( result ) ) . toBe ( true )
246+ expect ( result ) . toHaveLength ( 3 ) // 1 update + 1 add + 1 delete
247+ result . forEach ( cmd => expect ( cmd ) . toBeInstanceOf ( NopCommand ) )
248+ expect ( github . request ) . not . toHaveBeenCalled ( )
249+ } )
250+
251+ it ( 'should make API calls when nop is false' , async ( ) => {
252+ const plugin = configure ( false )
253+ const existing = [ { name : 'VAR1' , value : 'old-value' } ]
254+ const updated = [ { name : 'VAR1' , value : 'new-value' } ]
255+
256+ await plugin . update ( existing , updated )
257+
258+ expect ( github . request ) . toHaveBeenCalledWith (
259+ 'PATCH /repos/:org/:repo/actions/variables/:variable_name' ,
260+ expect . objectContaining ( {
261+ org,
262+ repo,
263+ variable_name : 'VAR1' ,
264+ value : 'new-value'
265+ } )
266+ )
267+ } )
268+ } )
269+ } )
79270} )
0 commit comments