11package com .mongodb .samplemflix .integration ;
22
3+ import static org .junit .jupiter .api .Assertions .assertEquals ;
34import static org .junit .jupiter .api .Assertions .assertFalse ;
45import static org .junit .jupiter .api .Assertions .assertNotNull ;
56import static org .junit .jupiter .api .Assertions .assertTrue ;
67
78import com .mongodb .client .MongoCollection ;
89import com .mongodb .samplemflix .model .Movie ;
910import com .mongodb .samplemflix .service .MovieService ;
11+ import java .time .LocalDate ;
1012import java .util .ArrayList ;
1113import java .util .Arrays ;
1214import java .util .Collections ;
1315import java .util .List ;
16+ import java .util .TimeZone ;
17+ import org .bson .BsonDateTime ;
1418import org .bson .Document ;
19+ import org .bson .types .ObjectId ;
1520import org .junit .jupiter .api .AfterAll ;
1621import org .junit .jupiter .api .BeforeAll ;
1722import org .junit .jupiter .api .DisplayName ;
2025import org .springframework .beans .factory .annotation .Autowired ;
2126import org .springframework .boot .test .context .SpringBootTest ;
2227import org .springframework .data .mongodb .core .MongoTemplate ;
28+ import org .springframework .data .mongodb .core .query .Criteria ;
29+ import org .springframework .data .mongodb .core .query .Query ;
2330import org .springframework .test .context .ActiveProfiles ;
2431
2532/**
@@ -223,6 +230,58 @@ void testSearchMoviesByPlot_WithPagination() {
223230 }
224231 }
225232
233+ // ==================== RELEASED FIELD ROUND-TRIP TESTS ====================
234+
235+ @ Test
236+ @ DisplayName ("Should read BSON DateTime at midnight UTC as the correct LocalDate without date shift" )
237+ void testReleasedFieldRoundTrip_NoDateShift () {
238+ if (!isSearchEnabled ()) {
239+ System .out .println ("Skipping test - Search not enabled" );
240+ return ;
241+ }
242+
243+ // The test movies were inserted with known BSON DateTime values at midnight UTC:
244+ // "Test Space Adventure" -> 2024-01-01T00:00:00Z (1704067200000)
245+ // "Test Mystery Movie" -> 2024-03-31T00:00:00Z (1711843200000)
246+ // "Test Adventure Quest" -> 2024-12-31T00:00:00Z (1735603200000)
247+ // A JVM timezone west of UTC could shift these dates backward by one day
248+ // (e.g. 2024-01-01 -> 2023-12-31). Cycle through multiple timezones to
249+ // verify the native LocalDateCodec always interprets BSON DateTime in UTC.
250+
251+ List <String > timezones = List .of (
252+ "America/New_York" ,
253+ "America/Los_Angeles" ,
254+ "Asia/Tokyo" ,
255+ "Europe/London" ,
256+ "Pacific/Auckland"
257+ );
258+
259+ TimeZone originalTz = TimeZone .getDefault ();
260+ try {
261+ for (String zoneId : timezones ) {
262+ TimeZone .setDefault (TimeZone .getTimeZone (zoneId ));
263+
264+ Movie spaceAdventure = findTestMovieByTitle ("Test Space Adventure" );
265+ assertEquals (LocalDate .of (2024 , 1 , 1 ), spaceAdventure .getReleased (),
266+ "2024-01-01T00:00:00Z shifted in " + zoneId );
267+
268+ Movie mystery = findTestMovieByTitle ("Test Mystery Movie" );
269+ assertEquals (LocalDate .of (2024 , 3 , 31 ), mystery .getReleased (),
270+ "2024-03-31T00:00:00Z shifted in " + zoneId );
271+
272+ Movie adventureQuest = findTestMovieByTitle ("Test Adventure Quest" );
273+ assertEquals (LocalDate .of (2024 , 12 , 31 ), adventureQuest .getReleased (),
274+ "2024-12-31T00:00:00Z shifted in " + zoneId );
275+ }
276+ } finally {
277+ TimeZone .setDefault (originalTz );
278+ }
279+ }
280+
281+ private Movie findTestMovieByTitle (String title ) {
282+ return mongoTemplate .findOne (new Query (Criteria .where ("title" ).is (title )), Movie .class );
283+ }
284+
226285 // ==================== HELPER METHODS ====================
227286
228287 private boolean isSearchEnabled () {
@@ -239,16 +298,19 @@ private void createTestMovies() {
239298 new Document ()
240299 .append ("title" , "Test Space Adventure" )
241300 .append ("year" , 2024 )
301+ .append ("released" , new BsonDateTime (1704067200000L )) // 1st of Jan 2024 in UTC
242302 .append ("plot" , "An epic space adventure across the galaxy" )
243303 .append ("genres" , Arrays .asList ("Sci-Fi" , "Adventure" )),
244304 new Document ()
245305 .append ("title" , "Test Mystery Movie" )
246306 .append ("year" , 2024 )
307+ .append ("released" , new BsonDateTime (1711843200000L )) // 31 of March 2024 in UTC
247308 .append ("plot" , "A detective solves a mysterious crime" )
248309 .append ("genres" , Arrays .asList ("Mystery" , "Thriller" )),
249310 new Document ()
250311 .append ("title" , "Test Adventure Quest" )
251312 .append ("year" , 2024 )
313+ .append ("released" , new BsonDateTime (1735603200000L )) // 31 December 2024 in UTC
252314 .append ("plot" , "Heroes embark on a dangerous adventure" )
253315 .append ("genres" , Arrays .asList ("Adventure" , "Fantasy" ))
254316 );
0 commit comments