99 "os"
1010 "strings"
1111 "testing"
12- "time"
1312
1413 "github.com/golang/mock/gomock"
1514 "github.com/rs/zerolog"
@@ -25,6 +24,7 @@ import (
2524 "github.com/snyk/go-application-framework/pkg/local_workflows/code_workflow/sast_contract"
2625 "github.com/snyk/go-application-framework/pkg/local_workflows/content_type"
2726 "github.com/snyk/go-application-framework/pkg/local_workflows/json_schemas"
27+ testutils "github.com/snyk/go-application-framework/pkg/local_workflows/test_utils"
2828 "github.com/snyk/go-application-framework/pkg/mocks"
2929 "github.com/snyk/go-application-framework/pkg/networking"
3030 "github.com/snyk/go-application-framework/pkg/ui"
@@ -460,67 +460,6 @@ func Test_Code_UseNativeImplementation(t *testing.T) {
460460 })
461461}
462462
463- // Helper function to test key dependencies for configuration keys
464- func testOrganizationDependency (
465- t * testing.T ,
466- configKey string ,
467- dependencyKey string ,
468- configIsBoolean bool ,
469- ) {
470- t .Helper ()
471-
472- // Setup
473- ctrl := gomock .NewController (t )
474- defer ctrl .Finish ()
475-
476- config := configuration .NewWithOpts (configuration .WithCachingEnabled (10 * time .Minute ))
477- config .Set (dependencyKey , "value1" )
478-
479- // Track how many times the callback is invoked
480- callCount := 0
481- testCallback := func (c configuration.Configuration , existingValue interface {}) (interface {}, error ) {
482- callCount ++
483- // Return a value that changes on each call. This allows us to check whether the returned value comes from
484- // the cache or this callback function.
485- if configIsBoolean {
486- // Alternate between true and false
487- return callCount % 2 == 1 , nil
488- }
489- return fmt .Sprintf ("value-%d" , callCount ), nil
490- }
491-
492- // Register the dependency
493- err := config .AddKeyDependency (configKey , dependencyKey )
494- assert .NoError (t , err )
495- config .AddDefaultValue (configKey , testCallback )
496-
497- // First Get - should invoke callback
498- result1 := getValue (config , configKey , configIsBoolean )
499- assert .NotNil (t , result1 )
500- assert .Equal (t , 1 , callCount , "Callback should be invoked on first read" )
501-
502- // Second Get - should use cached value
503- result2 := getValue (config , configKey , configIsBoolean )
504- assert .Equal (t , result1 , result2 , "Cached value should be used on second read" )
505- assert .Equal (t , 1 , callCount , "Callback should not be called on second read" )
506-
507- // Change the value of the dependency - this should clear the cached value.
508- config .Set (dependencyKey , "value2" )
509-
510- // Third Get - should invoke callback again since cache was cleared
511- result3 := getValue (config , configKey , configIsBoolean )
512- assert .NotNil (t , result3 )
513- assert .NotEqual (t , result1 , result3 , "Cached value should not be used after dependency changed" )
514- assert .Equal (t , 2 , callCount , "Callback should be called again after dependency changed" )
515- }
516-
517- func getValue (config configuration.Configuration , key string , isBoolean bool ) interface {} {
518- if isBoolean {
519- return config .GetBool (key )
520- }
521- return config .Get (key )
522- }
523-
524463// setupMockEngine creates a mock engine with basic expectations
525464func setupMockEngine (t * testing.T ) * mocks.MockEngine {
526465 t .Helper ()
@@ -591,16 +530,7 @@ func setupMockEngineWithServer(t *testing.T, server *httptest.Server) (*mocks.Mo
591530 return mockEngine , config
592531}
593532
594- func Test_GetSastSettingsConfig (t * testing.T ) {
595- t .Run ("adds organization dependency and clears cache on org change" , func (t * testing.T ) {
596- testOrganizationDependency (
597- t ,
598- code_workflow .ConfigurationSastSettings ,
599- configuration .ORGANIZATION ,
600- false ,
601- )
602- })
603-
533+ func Test_getSastSettingsConfig (t * testing.T ) {
604534 t .Run ("callback returns existing value when provided" , func (t * testing.T ) {
605535 existingValue := & sast_contract.SastResponse {SastEnabled : true }
606536
@@ -625,6 +555,28 @@ func Test_GetSastSettingsConfig(t *testing.T) {
625555 assert .True (t , sastResponse .LocalCodeEngine .Enabled )
626556 })
627557
558+ t .Run ("adds organization dependency and clears cache on org change" , func (t * testing.T ) {
559+ testutils .CheckCacheRespectOrgDependency (
560+ t ,
561+ code_workflow .ConfigurationSastSettings ,
562+ func (isFirstCall bool ) any {
563+ return & sast_contract.SastResponse {
564+ SastEnabled : isFirstCall ,
565+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : isFirstCall },
566+ }
567+ },
568+ InitCodeWorkflow ,
569+ & sast_contract.SastResponse {
570+ SastEnabled : true ,
571+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : true },
572+ },
573+ & sast_contract.SastResponse {
574+ SastEnabled : false ,
575+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
576+ },
577+ )
578+ })
579+
628580 t .Run ("callback returns error when API call fails and existing value is nil" , func (t * testing.T ) {
629581 server := setupMockServerWithError (t )
630582 defer server .Close ()
@@ -637,16 +589,7 @@ func Test_GetSastSettingsConfig(t *testing.T) {
637589 })
638590}
639591
640- func Test_GetSastEnabled (t * testing.T ) {
641- t .Run ("adds organization dependency and clears cache on org change" , func (t * testing.T ) {
642- testOrganizationDependency (
643- t ,
644- code_workflow .ConfigurationSastEnabled ,
645- configuration .ORGANIZATION ,
646- true ,
647- )
648- })
649-
592+ func Test_getSastEnabled (t * testing.T ) {
650593 t .Run ("callback function returns existing value when provided" , func (t * testing.T ) {
651594 mockEngine := setupMockEngine (t )
652595 result , err := getSastEnabled (mockEngine )(mockEngine .GetConfiguration (), true )
@@ -656,17 +599,57 @@ func Test_GetSastEnabled(t *testing.T) {
656599 assert .True (t , boolResult , "Should return existing value when provided" )
657600 })
658601
659- t .Run ("callback fetches settings when existing value is nil" , func (t * testing.T ) {
660- server := setupMockServerForSastSettings ( t , true , false )
661- defer server . Close ()
602+ t .Run ("callback reads from ConfigurationSastSettings (pre-cached) when existing value is nil" , func (t * testing.T ) {
603+ mockEngine := setupMockEngine ( t )
604+ config := mockEngine . GetConfiguration ()
662605
663- mockEngine , config := setupMockEngineWithServer (t , server )
606+ // Set ConfigurationSastSettings in config
607+ sastSettings := & sast_contract.SastResponse {
608+ SastEnabled : true ,
609+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
610+ }
611+ config .Set (code_workflow .ConfigurationSastSettings , sastSettings )
664612
665613 result , err := getSastEnabled (mockEngine )(config , nil )
666614 assert .NoError (t , err )
667615 boolResult , ok := result .(bool )
668616 assert .True (t , ok , "result should be of type bool" )
669- assert .True (t , boolResult , "Should return SastEnabled from API response" )
617+ assert .True (t , boolResult , "Should return SastEnabled from ConfigurationSastSettings" )
618+ })
619+
620+ t .Run ("depends on ConfigurationSastSettings" , func (t * testing.T ) {
621+ testutils .CheckConfigCachesDependency (
622+ t ,
623+ code_workflow .ConfigurationSastEnabled ,
624+ code_workflow .ConfigurationSastSettings ,
625+ getSastEnabled ,
626+ & sast_contract.SastResponse {
627+ SastEnabled : true ,
628+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
629+ },
630+ & sast_contract.SastResponse {
631+ SastEnabled : false ,
632+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
633+ },
634+ true ,
635+ false ,
636+ )
637+ })
638+
639+ t .Run ("respects organization changes (full chain)" , func (t * testing.T ) {
640+ testutils .CheckCacheRespectOrgDependency (
641+ t ,
642+ code_workflow .ConfigurationSastEnabled ,
643+ func (isFirstCall bool ) any {
644+ return & sast_contract.SastResponse {
645+ SastEnabled : isFirstCall ,
646+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
647+ }
648+ },
649+ InitCodeWorkflow ,
650+ true ,
651+ false ,
652+ )
670653 })
671654
672655 t .Run ("callback returns false and error when API call fails and existing value is nil" , func (t * testing.T ) {
@@ -683,16 +666,7 @@ func Test_GetSastEnabled(t *testing.T) {
683666 })
684667}
685668
686- func Test_GetSlceEnabled (t * testing.T ) {
687- t .Run ("adds organization dependency and clears cache on org change" , func (t * testing.T ) {
688- testOrganizationDependency (
689- t ,
690- code_workflow .ConfigurarionSlceEnabled ,
691- configuration .ORGANIZATION ,
692- true ,
693- )
694- })
695-
669+ func Test_getSlceEnabled (t * testing.T ) {
696670 t .Run ("callback function returns existing value when provided" , func (t * testing.T ) {
697671 mockEngine := setupMockEngine (t )
698672 result , err := getSlceEnabled (mockEngine )(mockEngine .GetConfiguration (), true )
@@ -702,17 +676,57 @@ func Test_GetSlceEnabled(t *testing.T) {
702676 assert .True (t , boolResult , "Should return existing value when provided" )
703677 })
704678
705- t .Run ("callback fetches settings when existing value is nil" , func (t * testing.T ) {
706- server := setupMockServerForSastSettings ( t , false , true )
707- defer server . Close ()
679+ t .Run ("callback reads from ConfigurationSastSettings (pre-cached) when existing value is nil" , func (t * testing.T ) {
680+ mockEngine := setupMockEngine ( t )
681+ config := mockEngine . GetConfiguration ()
708682
709- mockEngine , config := setupMockEngineWithServer (t , server )
683+ // Set ConfigurationSastSettings in config
684+ sastSettings := & sast_contract.SastResponse {
685+ SastEnabled : false ,
686+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : true },
687+ }
688+ config .Set (code_workflow .ConfigurationSastSettings , sastSettings )
710689
711690 result , err := getSlceEnabled (mockEngine )(config , nil )
712691 assert .NoError (t , err )
713692 boolResult , ok := result .(bool )
714693 assert .True (t , ok , "result should be of type bool" )
715- assert .True (t , boolResult , "Should return LocalCodeEngine.Enabled from API response" )
694+ assert .True (t , boolResult , "Should return LocalCodeEngine.Enabled from ConfigurationSastSettings" )
695+ })
696+
697+ t .Run ("depends on ConfigurationSastSettings" , func (t * testing.T ) {
698+ testutils .CheckConfigCachesDependency (
699+ t ,
700+ code_workflow .ConfigurarionSlceEnabled ,
701+ code_workflow .ConfigurationSastSettings ,
702+ getSlceEnabled ,
703+ & sast_contract.SastResponse {
704+ SastEnabled : false ,
705+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : true },
706+ },
707+ & sast_contract.SastResponse {
708+ SastEnabled : false ,
709+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : false },
710+ },
711+ true ,
712+ false ,
713+ )
714+ })
715+
716+ t .Run ("respects organization changes (full chain)" , func (t * testing.T ) {
717+ testutils .CheckCacheRespectOrgDependency (
718+ t ,
719+ code_workflow .ConfigurarionSlceEnabled ,
720+ func (isFirstCall bool ) any {
721+ return & sast_contract.SastResponse {
722+ SastEnabled : false ,
723+ LocalCodeEngine : sast_contract.LocalCodeEngine {Enabled : isFirstCall },
724+ }
725+ },
726+ InitCodeWorkflow ,
727+ true ,
728+ false ,
729+ )
716730 })
717731
718732 t .Run ("callback returns false and error when API call fails and existing value is nil" , func (t * testing.T ) {
0 commit comments