@@ -88,6 +88,7 @@ describe('Configurations Controller', () => {
8888 'getAll' ,
8989 'getLatest' ,
9090 'getByVersion' ,
91+ 'updateSandboxConfig' ,
9192 ] ;
9293
9394 let mockDataAccess ;
@@ -235,4 +236,269 @@ describe('Configurations Controller', () => {
235236 expect ( result . status ) . to . equal ( 400 ) ;
236237 expect ( error ) . to . have . property ( 'message' , 'Configuration version required to be an integer' ) ;
237238 } ) ;
239+
240+ describe ( 'Sandbox Configuration Methods' , ( ) => {
241+ let mockCurrentConfig ;
242+ let mockNewConfig ;
243+
244+ beforeEach ( ( ) => {
245+ mockCurrentConfig = {
246+ getJobs : sandbox . stub ( ) . returns ( [ ] ) ,
247+ getHandlers : sandbox . stub ( ) . returns ( { } ) ,
248+ getQueues : sandbox . stub ( ) . returns ( { } ) ,
249+ getSlackRoles : sandbox . stub ( ) . returns ( { } ) ,
250+ } ;
251+
252+ mockNewConfig = {
253+ getVersion : sandbox . stub ( ) . returns ( '2' ) ,
254+ getJobs : sandbox . stub ( ) . returns ( [ ] ) ,
255+ getHandlers : sandbox . stub ( ) . returns ( { } ) ,
256+ getQueues : sandbox . stub ( ) . returns ( { } ) ,
257+ getSlackRoles : sandbox . stub ( ) . returns ( { } ) ,
258+ } ;
259+
260+ mockDataAccess . Configuration . findLatest = sandbox . stub ( ) . resolves ( mockCurrentConfig ) ;
261+ mockDataAccess . Configuration . create = sandbox . stub ( ) . resolves ( mockNewConfig ) ;
262+ } ) ;
263+
264+ describe ( 'updateSandboxConfig' , ( ) => {
265+ it ( 'should update sandbox configurations successfully' , async ( ) => {
266+ const requestContext = {
267+ data : {
268+ sandboxConfigs : {
269+ cwv : { expire : '10' } ,
270+ 'meta-tags' : { expire : '15' } ,
271+ } ,
272+ } ,
273+ } ;
274+
275+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
276+ const response = await result . json ( ) ;
277+
278+ expect ( result . status ) . to . equal ( 200 ) ;
279+ expect ( response ) . to . have . property ( 'message' , 'Sandbox configurations updated successfully' ) ;
280+ expect ( response ) . to . have . property ( 'updatedConfigs' ) ;
281+ expect ( response . updatedConfigs ) . to . deep . equal ( {
282+ cwv : { expire : '10' } ,
283+ 'meta-tags' : { expire : '15' } ,
284+ } ) ;
285+ expect ( response ) . to . have . property ( 'totalUpdated' , 2 ) ;
286+ expect ( response ) . to . have . property ( 'newVersion' , '2' ) ;
287+ expect ( mockDataAccess . Configuration . create ) . to . have . been . calledWith ( {
288+ jobs : [ ] ,
289+ handlers : {
290+ cwv : { sandbox : { expire : '10' } } ,
291+ 'meta-tags' : { sandbox : { expire : '15' } } ,
292+ } ,
293+ queues : { } ,
294+ slackRoles : { } ,
295+ } ) ;
296+ } ) ;
297+
298+ it ( 'should return bad request when sandboxConfigs is missing' , async ( ) => {
299+ const requestContext = {
300+ data : { } ,
301+ } ;
302+
303+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
304+ const error = await result . json ( ) ;
305+
306+ expect ( result . status ) . to . equal ( 400 ) ;
307+ expect ( error . message ) . to . include ( 'sandboxConfigs object is required' ) ;
308+ } ) ;
309+
310+ it ( 'should return bad request when context.data is undefined' , async ( ) => {
311+ const requestContext = { } ;
312+
313+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
314+ const error = await result . json ( ) ;
315+
316+ expect ( result . status ) . to . equal ( 400 ) ;
317+ expect ( error . message ) . to . include ( 'sandboxConfigs object is required' ) ;
318+ } ) ;
319+
320+ it ( 'should return bad request when sandboxConfigs is not an object' , async ( ) => {
321+ const requestContext = {
322+ data : {
323+ sandboxConfigs : 'invalid' ,
324+ } ,
325+ } ;
326+
327+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
328+ const error = await result . json ( ) ;
329+
330+ expect ( result . status ) . to . equal ( 400 ) ;
331+ expect ( error . message ) . to . include ( 'sandboxConfigs object is required' ) ;
332+ } ) ;
333+
334+ it ( 'should return forbidden for non-admin users' , async ( ) => {
335+ context . attributes . authInfo . withProfile ( { is_admin : false } ) ;
336+
337+ const requestContext = {
338+ data : {
339+ sandboxConfigs : {
340+ cwv : { expire : '10' } ,
341+ } ,
342+ } ,
343+ } ;
344+
345+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
346+ const error = await result . json ( ) ;
347+
348+ expect ( result . status ) . to . equal ( 403 ) ;
349+ expect ( error . message ) . to . include ( 'Only admins can update sandbox configurations' ) ;
350+ } ) ;
351+
352+ it ( 'should return not found when configuration does not exist' , async ( ) => {
353+ mockDataAccess . Configuration . findLatest . resolves ( null ) ;
354+
355+ const requestContext = {
356+ data : {
357+ sandboxConfigs : {
358+ cwv : { expire : '10' } ,
359+ } ,
360+ } ,
361+ } ;
362+
363+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
364+ const error = await result . json ( ) ;
365+
366+ expect ( result . status ) . to . equal ( 404 ) ;
367+ expect ( error . message ) . to . include ( 'Configuration not found' ) ;
368+ } ) ;
369+
370+ it ( 'should return bad request when Configuration.create throws an error' , async ( ) => {
371+ const requestContext = {
372+ data : {
373+ sandboxConfigs : {
374+ cwv : { expire : '10' } ,
375+ } ,
376+ } ,
377+ } ;
378+
379+ mockDataAccess . Configuration . create . throws ( new Error ( 'Create failed' ) ) ;
380+
381+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
382+ const error = await result . json ( ) ;
383+
384+ expect ( result . status ) . to . equal ( 400 ) ;
385+ expect ( error . message ) . to . include ( 'Error updating sandbox configuration: Create failed' ) ;
386+ } ) ;
387+
388+ it ( 'should handle when getHandlers returns null' , async ( ) => {
389+ const requestContext = {
390+ data : {
391+ sandboxConfigs : {
392+ cwv : { expire : '10' } ,
393+ } ,
394+ } ,
395+ } ;
396+
397+ // Mock getHandlers to return null to test the || {} fallback
398+ mockCurrentConfig . getHandlers . returns ( null ) ;
399+
400+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
401+ const response = await result . json ( ) ;
402+
403+ expect ( result . status ) . to . equal ( 200 ) ;
404+ expect ( response ) . to . have . property ( 'message' , 'Sandbox configurations updated successfully' ) ;
405+ expect ( mockDataAccess . Configuration . create ) . to . have . been . calledWith ( {
406+ jobs : [ ] ,
407+ handlers : {
408+ cwv : { sandbox : { expire : '10' } } ,
409+ } ,
410+ queues : { } ,
411+ slackRoles : { } ,
412+ } ) ;
413+ } ) ;
414+
415+ it ( 'should handle when audit type does not exist in handlers' , async ( ) => {
416+ const requestContext = {
417+ data : {
418+ sandboxConfigs : {
419+ newAuditType : { enabled : true } ,
420+ } ,
421+ } ,
422+ } ;
423+
424+ // Mock getHandlers to return handlers without the new audit type
425+ mockCurrentConfig . getHandlers . returns ( {
426+ cwv : { sandbox : { expire : '5' } } ,
427+ } ) ;
428+
429+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
430+ const response = await result . json ( ) ;
431+
432+ expect ( result . status ) . to . equal ( 200 ) ;
433+ expect ( response ) . to . have . property ( 'message' , 'Sandbox configurations updated successfully' ) ;
434+ expect ( mockDataAccess . Configuration . create ) . to . have . been . calledWith ( {
435+ jobs : [ ] ,
436+ handlers : {
437+ cwv : { sandbox : { expire : '5' } } ,
438+ newAuditType : { sandbox : { enabled : true } } ,
439+ } ,
440+ queues : { } ,
441+ slackRoles : { } ,
442+ } ) ;
443+ } ) ;
444+
445+ it ( 'should handle when audit type exists but has no sandbox property' , async ( ) => {
446+ const requestContext = {
447+ data : {
448+ sandboxConfigs : {
449+ lhs : { timeout : '30' } ,
450+ } ,
451+ } ,
452+ } ;
453+
454+ // Mock getHandlers to return handlers with audit type but no sandbox property
455+ mockCurrentConfig . getHandlers . returns ( {
456+ cwv : { sandbox : { expire : '5' } } ,
457+ lhs : { enabled : true } , // No sandbox property
458+ } ) ;
459+
460+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
461+ const response = await result . json ( ) ;
462+
463+ expect ( result . status ) . to . equal ( 200 ) ;
464+ expect ( response ) . to . have . property ( 'message' , 'Sandbox configurations updated successfully' ) ;
465+ expect ( mockDataAccess . Configuration . create ) . to . have . been . calledWith ( {
466+ jobs : [ ] ,
467+ handlers : {
468+ cwv : { sandbox : { expire : '5' } } ,
469+ lhs : { enabled : true , sandbox : { timeout : '30' } } ,
470+ } ,
471+ queues : { } ,
472+ slackRoles : { } ,
473+ } ) ;
474+ } ) ;
475+
476+ it ( 'should handle when getHandlers returns undefined' , async ( ) => {
477+ const requestContext = {
478+ data : {
479+ sandboxConfigs : {
480+ cwv : { expire : '10' } ,
481+ } ,
482+ } ,
483+ } ;
484+
485+ // Mock getHandlers to return undefined to test the || {} fallback
486+ mockCurrentConfig . getHandlers . returns ( undefined ) ;
487+
488+ const result = await configurationsController . updateSandboxConfig ( requestContext ) ;
489+ const response = await result . json ( ) ;
490+
491+ expect ( result . status ) . to . equal ( 200 ) ;
492+ expect ( response ) . to . have . property ( 'message' , 'Sandbox configurations updated successfully' ) ;
493+ expect ( mockDataAccess . Configuration . create ) . to . have . been . calledWith ( {
494+ jobs : [ ] ,
495+ handlers : {
496+ cwv : { sandbox : { expire : '10' } } ,
497+ } ,
498+ queues : { } ,
499+ slackRoles : { } ,
500+ } ) ;
501+ } ) ;
502+ } ) ;
503+ } ) ;
238504} ) ;
0 commit comments