@@ -5675,4 +5675,40 @@ void keyBidstreamRespectsConfigValuesWithRemoteConfig(Vertx vertx, VertxTestCont
56755675 testContext .completeNow ();
56765676 });
56775677 }
5678+
5679+ private void assertLastUpdatedHasMillis (JsonArray buckets ) {
5680+ for (int i = 0 ; i < buckets .size (); i ++) {
5681+ JsonObject bucket = buckets .getJsonObject (i );
5682+ String lastUpdated = bucket .getString ("last_updated" );
5683+ // Verify pattern yyyy-MM-dd'T'HH:mm:ss.SSS
5684+ assertTrue (lastUpdated .matches ("\\ d{4}-\\ d{2}-\\ d{2}T\\ d{2}:\\ d{2}:\\ d{2}\\ .\\ d{3}" ),
5685+ "last_updated does not contain millisecond precision: " + lastUpdated );
5686+ }
5687+ }
5688+
5689+ @ ParameterizedTest
5690+ @ ValueSource (strings = {"v1" , "v2" })
5691+ void identityBucketsAlwaysReturnMilliseconds (String apiVersion , Vertx vertx , VertxTestContext testContext ) {
5692+ final int clientSiteId = 201 ;
5693+ fakeAuth (clientSiteId , Role .MAPPER );
5694+ setupSalts ();
5695+
5696+ // SaltEntry with a lastUpdated that has 0 milliseconds
5697+ long lastUpdatedMillis = Instant .parse ("2024-01-01T00:00:00Z" ).toEpochMilli ();
5698+ SaltEntry bucketEntry = new SaltEntry (456 , "hashed456" , lastUpdatedMillis , "salt456" , null , null , null , null );
5699+ when (saltProviderSnapshot .getModifiedSince (any ())).thenReturn (List .of (bucketEntry ));
5700+
5701+ String sinceTimestamp = "2023-12-31T00:00:00" ; // earlier timestamp
5702+
5703+ boolean isV1 = apiVersion .equals ("v1" );
5704+ String v1Param = isV1 ? "since_timestamp=" + sinceTimestamp : null ;
5705+ JsonObject req = isV1 ? null : new JsonObject ().put ("since_timestamp" , sinceTimestamp );
5706+
5707+ send (apiVersion , vertx , apiVersion + "/identity/buckets" , isV1 , v1Param , req , 200 , respJson -> {
5708+ JsonArray buckets = respJson .getJsonArray ("body" );
5709+ assertFalse (buckets .isEmpty ());
5710+ assertLastUpdatedHasMillis (buckets );
5711+ testContext .completeNow ();
5712+ });
5713+ }
56785714}
0 commit comments