@@ -239,4 +239,83 @@ void testRefreshFromCalculation(int lastRotationDaysAgo, int refreshFromDaysFrom
239239
240240 assertThat (actual .refreshFrom ()).isEqualTo (expected );
241241 }
242+
243+ @ Test
244+ void rotateSaltsPopulatePreviousSaltsOnRotation () throws Exception {
245+ final Duration [] minAges = {
246+ Duration .ofDays (90 ),
247+ Duration .ofDays (60 ),
248+ Duration .ofDays (30 )
249+ };
250+
251+ var lessThan90Days = daysEarlier (60 ).toEpochMilli ();
252+ var exactly90Days = daysEarlier (90 ).toEpochMilli ();
253+ var over90Days = daysEarlier (120 ).toEpochMilli ();
254+ var lastSnapshot = SnapshotBuilder .start ()
255+ .withEntries (
256+ new SaltEntry (1 , "1" , lessThan90Days , "salt1" , null , null , null , null ),
257+ new SaltEntry (3 , "2" , exactly90Days , "salt2" , null , null , null , null ),
258+ new SaltEntry (5 , "3" , over90Days , "salt3" , null , null , null , null )
259+ )
260+ .build (daysEarlier (1 ), daysLater (6 ));
261+
262+ var result = saltRotation .rotateSalts (lastSnapshot , minAges , 1 , targetDate );
263+ assertTrue (result .hasSnapshot ());
264+
265+ var salts = result .getSnapshot ().getAllRotatingSalts ();
266+ assertEquals ("salt1" , salts [0 ].previousSalt ());
267+ assertEquals ("salt2" , salts [1 ].previousSalt ());
268+ assertEquals ("salt3" , salts [2 ].previousSalt ());
269+ }
270+
271+ @ Test
272+ void rotateSaltsPreservePreviousSaltsLessThan90DaysOld () throws Exception {
273+ final Duration [] minAges = {
274+ Duration .ofDays (60 ),
275+ };
276+
277+ var notValidForRotation1 = daysEarlier (40 ).toEpochMilli ();
278+ var notValidForRotation2 = daysEarlier (50 ).toEpochMilli ();
279+ var validForRotation = daysEarlier (70 );
280+ var lastSnapshot = SnapshotBuilder .start ()
281+ .withEntries (
282+ new SaltEntry (1 , "1" , notValidForRotation1 , "salt1" , null , "previousSalt1" , null , null ),
283+ new SaltEntry (2 , "2" , notValidForRotation2 , "salt2" , null , null , null , null )
284+ )
285+ .withEntries (1 , validForRotation )
286+ .build (daysEarlier (1 ), daysLater (6 ));
287+
288+ var result = saltRotation .rotateSalts (lastSnapshot , minAges , 1 , targetDate );
289+ assertTrue (result .hasSnapshot ());
290+
291+ var salts = result .getSnapshot ().getAllRotatingSalts ();
292+ assertEquals ("previousSalt1" , salts [0 ].previousSalt ());
293+ assertNull (salts [1 ].previousSalt ());
294+ }
295+
296+ @ Test
297+ void rotateSaltsRemovePreviousSaltsOver90DaysOld () throws Exception {
298+ final Duration [] minAges = {
299+ Duration .ofDays (100 ),
300+ };
301+
302+ var exactly90Days = daysEarlier (90 ).toEpochMilli ();
303+ var over90Days = daysEarlier (100 ).toEpochMilli ();
304+ var validForRotation = daysEarlier (120 );
305+ var lastSnapshot = SnapshotBuilder .start ()
306+ .withEntries (
307+ new SaltEntry (1 , "1" , exactly90Days , "salt1" , null , "90DaysOld" , null , null ),
308+ new SaltEntry (2 , "2" , over90Days , "salt2" , null , "over90DaysOld" , null , null )
309+ )
310+ .withEntries (1 , validForRotation )
311+ .build (daysEarlier (1 ), daysLater (6 ));
312+
313+ var result = saltRotation .rotateSalts (lastSnapshot , minAges , 0.5 , targetDate );
314+ assertTrue (result .hasSnapshot ());
315+
316+ var salts = result .getSnapshot ().getAllRotatingSalts ();
317+ assertNull (salts [0 ].previousSalt ());
318+ assertNull (salts [1 ].previousSalt ());
319+ }
320+
242321}
0 commit comments