@@ -1774,6 +1774,8 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
17741774 expected * gwproto.GetFeatureFlagsResponse
17751775 expectedErr error
17761776 clampTest bool // when true, verify RequestedAt is clamped (not exact match with timeNow)
1777+ // when true, RequestedAt is stamped by the server and checked against the current time
1778+ expectRequestedAtNow bool
17771779 }{
17781780 {
17791781 desc : "err: environment api key not found" ,
@@ -1900,10 +1902,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
19001902 FeatureFlagsId : "" ,
19011903 Features : []* featureproto.Feature {},
19021904 ArchivedFeatureFlagIds : make ([]string , 0 ),
1903- RequestedAt : timeNow .Unix (),
19041905 ForceUpdate : false ,
19051906 },
1906- expectedErr : nil ,
1907+ expectedErr : nil ,
1908+ expectRequestedAtNow : true ,
19071909 },
19081910 {
19091911 desc : "success: with no tag and no feature flags ID" ,
@@ -1936,10 +1938,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
19361938 multiFeatures [2 ],
19371939 },
19381940 ArchivedFeatureFlagIds : make ([]string , 0 ),
1939- RequestedAt : timeNow .Unix (),
19401941 ForceUpdate : true ,
19411942 },
1942- expectedErr : nil ,
1943+ expectedErr : nil ,
1944+ expectRequestedAtNow : true ,
19431945 },
19441946 {
19451947 desc : "success: with no tag and with same feature flags ID" ,
@@ -2006,10 +2008,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
20062008 multiFeatures [2 ],
20072009 },
20082010 ArchivedFeatureFlagIds : []string {multiFeatures [4 ].Id },
2009- RequestedAt : timeNow .Unix (),
20102011 ForceUpdate : false ,
20112012 },
2012- expectedErr : nil ,
2013+ expectedErr : nil ,
2014+ expectRequestedAtNow : true ,
20132015 },
20142016 {
20152017 desc : "success: with tag and no feature flags ID" ,
@@ -2037,11 +2039,11 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
20372039 expected : & gwproto.GetFeatureFlagsResponse {
20382040 FeatureFlagsId : singleFeatureID ,
20392041 Features : singleFeature ,
2040- RequestedAt : timeNow .Unix (),
20412042 ArchivedFeatureFlagIds : make ([]string , 0 ),
20422043 ForceUpdate : true ,
20432044 },
2044- expectedErr : nil ,
2045+ expectedErr : nil ,
2046+ expectRequestedAtNow : true ,
20452047 },
20462048 {
20472049 desc : "success: with tag and same feature flags ID" ,
@@ -2103,10 +2105,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
21032105 FeatureFlagsId : singleFeatureID ,
21042106 Features : singleFeature ,
21052107 ArchivedFeatureFlagIds : make ([]string , 0 ),
2106- RequestedAt : timeNow .Unix (),
21072108 ForceUpdate : true ,
21082109 },
2109- expectedErr : nil ,
2110+ expectedErr : nil ,
2111+ expectRequestedAtNow : true ,
21102112 },
21112113 {
21122114 // With the 10-minute featureFlagDiffGracePeriod default, the
@@ -2141,10 +2143,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
21412143 FeatureFlagsId : singleFeatureID ,
21422144 Features : []* featureproto.Feature {multiFeatures [0 ]},
21432145 ArchivedFeatureFlagIds : []string {multiFeatures [4 ].Id },
2144- RequestedAt : timeNow .Unix (),
21452146 ForceUpdate : false ,
21462147 },
2147- expectedErr : nil ,
2148+ expectedErr : nil ,
2149+ expectRequestedAtNow : true ,
21482150 },
21492151 {
21502152 desc : "success: diff includes features with UpdatedAt equal to RequestedAt" ,
@@ -2174,10 +2176,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
21742176 FeatureFlagsId : singleFeatureID ,
21752177 Features : singleFeature ,
21762178 ArchivedFeatureFlagIds : make ([]string , 0 ),
2177- RequestedAt : timeNow .Unix (),
21782179 ForceUpdate : false ,
21792180 },
2180- expectedErr : nil ,
2181+ expectedErr : nil ,
2182+ expectRequestedAtNow : true ,
21812183 },
21822184 {
21832185 desc : "success: future requestedAt is clamped to now in None response" ,
@@ -2240,10 +2242,10 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
22402242 FeatureFlagsId : singleFeatureID ,
22412243 Features : singleFeature ,
22422244 ArchivedFeatureFlagIds : make ([]string , 0 ),
2243- RequestedAt : timeNow .Unix (),
22442245 ForceUpdate : true ,
22452246 },
2246- expectedErr : nil ,
2247+ expectedErr : nil ,
2248+ expectRequestedAtNow : true ,
22472249 },
22482250 }
22492251 for _ , p := range patterns {
@@ -2265,6 +2267,11 @@ func TestGrpcGetFeatureFlags(t *testing.T) {
22652267 assert .Less (t , actual .RequestedAt , p .input .RequestedAt ,
22662268 "%s: RequestedAt should be clamped below the future input value" , p .desc )
22672269 } else {
2270+ if p .expectRequestedAtNow {
2271+ require .NotNil (t , actual , "%s" , p .desc )
2272+ assert .InDelta (t , time .Now ().Unix (), actual .RequestedAt , 5 , "%s" , p .desc )
2273+ p .expected .RequestedAt = actual .RequestedAt
2274+ }
22682275 assert .Equal (t , p .expected , actual , "%s" , p .desc )
22692276 }
22702277 })
@@ -2359,6 +2366,7 @@ func TestGrpcGetEvaluationsValidation(t *testing.T) {
23592366 "authorization" : []string {"test-key" },
23602367 })
23612368 actual , err := gs .GetEvaluations (ctx , p .input )
2369+ assertEvaluationsCreatedAtNow (t , p .expected , actual , p .desc )
23622370 assert .Equal (t , p .expected , actual , "%s" , p .desc )
23632371 assert .Equal (t , p .expectedErr , err , "%s" , p .desc )
23642372 })
@@ -2410,6 +2418,7 @@ func TestGrpcGetEvaluationsZeroFeature(t *testing.T) {
24102418 "authorization" : []string {"test-key" },
24112419 })
24122420 actual , err := gs .GetEvaluations (ctx , p .input )
2421+ assertEvaluationsCreatedAtNow (t , p .expected , actual , p .desc )
24132422 assert .Equal (t , p .expected , actual , "%s" , p .desc )
24142423 assert .Equal (t , p .expected .State , actual .State , "%s" , p .desc )
24152424 assert .Equal (t , p .expectedErr , err , "%s" , p .desc )
@@ -4948,12 +4957,27 @@ func newUUID(t *testing.T) string {
49484957 return id .String ()
49494958}
49504959
4960+ // assertEvaluationsCreatedAtNow checks the server-stamped CreatedAt against the
4961+ // current time, then copies it into expected so the whole response can be compared.
4962+ func assertEvaluationsCreatedAtNow (
4963+ t * testing.T ,
4964+ expected , actual * gwproto.GetEvaluationsResponse ,
4965+ desc string ,
4966+ ) {
4967+ t .Helper ()
4968+ if expected == nil || expected .Evaluations == nil || actual == nil || actual .Evaluations == nil {
4969+ return
4970+ }
4971+ assert .InDelta (t , time .Now ().Unix (), actual .Evaluations .CreatedAt , 5 , "%s" , desc )
4972+ expected .Evaluations .CreatedAt = actual .Evaluations .CreatedAt
4973+ }
4974+
4975+ // CreatedAt is left unset because the server stamps it at request time.
49514976func emptyUserEvaluations (t * testing.T ) * featureproto.UserEvaluations {
49524977 t .Helper ()
49534978 return & featureproto.UserEvaluations {
49544979 Id : "no_evaluations" ,
49554980 Evaluations : []* featureproto.Evaluation {},
4956- CreatedAt : time .Now ().Unix (),
49574981 ArchivedFeatureIds : []string {},
49584982 ForceUpdate : false ,
49594983 }
0 commit comments