diff --git a/src/main/java/org/patinanetwork/codebloom/api/submission/SubmissionController.java b/src/main/java/org/patinanetwork/codebloom/api/submission/SubmissionController.java index 91a1cf069..f1d028e51 100644 --- a/src/main/java/org/patinanetwork/codebloom/api/submission/SubmissionController.java +++ b/src/main/java/org/patinanetwork/codebloom/api/submission/SubmissionController.java @@ -264,12 +264,11 @@ public ResponseEntity> getCurrentPotd(final HttpServletReq AuthenticationObject authenticationObject = protector.validateSession(request); User user = authenticationObject.getUser(); - POTD potd = potdRepository.getCurrentPOTD(); - - if (potd == null || !isSameDay(potd.getCreatedAt())) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(ApiResponder.failure("Sorry, no problem of the day today!")); - } + POTD potd = potdRepository + .getCurrentPOTD() + .filter(p -> isSameDay(p.getCreatedAt())) + .orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, no problem of the day today!")); boolean alreadyCompleted = questionRepository .getQuestionBySlugAndUserId(potd.getSlug(), user.getId()) @@ -303,12 +302,11 @@ public ResponseEntity> getCurrentPotd(final HttpServletReq public ResponseEntity> getCurrentPotdEmbed() { FakeLag.sleep(750); - POTD potd = potdRepository.getCurrentPOTD(); - - if (potd == null || !isSameDay(potd.getCreatedAt())) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(ApiResponder.failure("Sorry, no problem of the day today!")); - } + POTD potd = potdRepository + .getCurrentPOTD() + .filter(p -> isSameDay(p.getCreatedAt())) + .orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, no problem of the day today!")); return ResponseEntity.ok() .body(ApiResponder.success("Problem of the day has been fetched!", PotdDto.fromPOTD(potd))); diff --git a/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepository.java b/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepository.java index 38d368604..d8e894fef 100644 --- a/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepository.java +++ b/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepository.java @@ -1,14 +1,15 @@ package org.patinanetwork.codebloom.common.db.repos.potd; import java.util.ArrayList; +import java.util.Optional; import org.patinanetwork.codebloom.common.db.models.potd.POTD; public interface POTDRepository { POTD createPOTD(POTD potd); - POTD getPOTDById(String id); + Optional getPOTDById(String id); - POTD getCurrentPOTD(); + Optional getCurrentPOTD(); ArrayList getAllPOTDS(); diff --git a/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDSqlRepository.java b/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDSqlRepository.java index 5cd2506c3..ae8dbf2ef 100644 --- a/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDSqlRepository.java +++ b/src/main/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDSqlRepository.java @@ -5,6 +5,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Optional; import java.util.UUID; import javax.sql.DataSource; import org.patinanetwork.codebloom.common.db.models.potd.POTD; @@ -56,7 +57,7 @@ public POTD createPOTD(final POTD potd) { } @Override - public POTD getPOTDById(final String id) { + public Optional getPOTDById(final String id) { String sql = "SELECT id, \"title\", \"slug\", \"multiplier\", \"createdAt\" FROM \"POTD\" WHERE id = ?"; try (Connection conn = ds.getConnection(); @@ -64,14 +65,14 @@ public POTD getPOTDById(final String id) { stmt.setObject(1, UUID.fromString(id)); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { - return mapRowToPOTD(rs); + return Optional.of(mapRowToPOTD(rs)); } } } catch (SQLException e) { throw new RuntimeException("Failed to get POTD by id", e); } - return null; + return Optional.empty(); } @Override @@ -118,7 +119,7 @@ public void deletePOTD(final String id) { } @Override - public POTD getCurrentPOTD() { + public Optional getCurrentPOTD() { String sql = """ SELECT "id", "title", "slug", "multiplier", "createdAt" FROM "POTD" @@ -130,11 +131,11 @@ public POTD getCurrentPOTD() { PreparedStatement stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery()) { if (rs.next()) { - return mapRowToPOTD(rs); + return Optional.of(mapRowToPOTD(rs)); } } catch (SQLException e) { throw new RuntimeException("Failed to get current POTD", e); } - return null; + return Optional.empty(); } } diff --git a/src/main/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandler.java b/src/main/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandler.java index bb0ba749b..6975b172d 100644 --- a/src/main/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandler.java +++ b/src/main/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandler.java @@ -109,7 +109,7 @@ public static Predicate distinctByKey(final Function keyExt public ArrayList handleSubmissions( final List leetcodeSubmissions, final User user, boolean fast) { ArrayList acceptedSubmissions = new ArrayList<>(); - POTD potd = potdRepository.getCurrentPOTD(); + Optional potd = potdRepository.getCurrentPOTD(); var questionMap = leetcodeSubmissions.parallelStream() .filter(distinctByKey(LeetcodeSubmission::getTitleSlug)) @@ -154,14 +154,10 @@ public ArrayList handleSubmissions( .getQuestionBySlugAndUserId(leetcodeSubmission.getTitleSlug(), user.getId()) .isPresent(); - float multiplier; - if (potd == null - || !isValid(potd.getCreatedAt()) - || !Objects.equals(potd.getSlug(), leetcodeSubmission.getTitleSlug())) { - multiplier = 1.0f; - } else { - multiplier = potd.getMultiplier(); - } + float multiplier = potd.filter(currentPotd -> isValid(currentPotd.getCreatedAt()) + && Objects.equals(currentPotd.getSlug(), leetcodeSubmission.getTitleSlug())) + .map(POTD::getMultiplier) + .orElse(1.0f); QuestionBank bankQuestion = questionMap.get(leetcodeSubmission.getTitleSlug()); diff --git a/src/main/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetter.java b/src/main/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetter.java index e08ed1b07..20f06d80d 100644 --- a/src/main/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetter.java +++ b/src/main/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetter.java @@ -1,5 +1,6 @@ package org.patinanetwork.codebloom.scheduled.potd; +import java.util.Optional; import org.patinanetwork.codebloom.common.db.models.potd.POTD; import org.patinanetwork.codebloom.common.db.repos.potd.POTDRepository; import org.patinanetwork.codebloom.common.leetcode.LeetcodeClient; @@ -35,8 +36,9 @@ public void setPotd() { return; } - POTD currentPotd = potdRepository.getCurrentPOTD(); - if (currentPotd != null && currentPotd.getTitle().equals(leetcodePotd.getTitle())) { + Optional potd = potdRepository.getCurrentPOTD(); + + if (potd.map(p -> p.getTitle().equals(leetcodePotd.getTitle())).orElse(false)) { // It's already the latest POTD, don't want to do it again. LOGGER.info("POTD has already been set before, will not be doing it again."); return; diff --git a/src/test/java/org/patinanetwork/codebloom/api/submission/SubmissionControllerTest.java b/src/test/java/org/patinanetwork/codebloom/api/submission/SubmissionControllerTest.java index 0b2a6eaf7..037046ed7 100644 --- a/src/test/java/org/patinanetwork/codebloom/api/submission/SubmissionControllerTest.java +++ b/src/test/java/org/patinanetwork/codebloom/api/submission/SubmissionControllerTest.java @@ -213,7 +213,7 @@ void testGetCurrentPotdSuccess() { when(auth.getUser()).thenReturn(user); when(user.getId()).thenReturn("abcdefg123456"); - when(potdRepository.getCurrentPOTD()).thenReturn(potd); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.of(potd)); when(potd.getCreatedAt()).thenReturn(LocalDateTime.now()); when(potd.getSlug()).thenReturn("two-sum"); @@ -240,19 +240,19 @@ void testGetCurrentPotdFailure() { when(protector.validateSession(request)).thenReturn(auth); when(auth.getUser()).thenReturn(user); - when(potdRepository.getCurrentPOTD()).thenReturn(null); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.empty()); - ResponseEntity> response = submissionController.getCurrentPotd(request); + ResponseStatusException ex = + assertThrows(ResponseStatusException.class, () -> submissionController.getCurrentPotd(request)); - assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); - assertFalse(response.getBody().isSuccess()); + assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); } @Test void testGetCurrentPotdEmbedSuccess() { POTD potd = mock(POTD.class); - when(potdRepository.getCurrentPOTD()).thenReturn(potd); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.of(potd)); when(potd.getCreatedAt()).thenReturn(LocalDateTime.now()); ResponseEntity> response = submissionController.getCurrentPotdEmbed(); @@ -265,12 +265,12 @@ void testGetCurrentPotdEmbedSuccess() { @Test void testGetCurrentPotdEmbedFailure() { - when(potdRepository.getCurrentPOTD()).thenReturn(null); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.empty()); - ResponseEntity> response = submissionController.getCurrentPotdEmbed(); + ResponseStatusException ex = + assertThrows(ResponseStatusException.class, () -> submissionController.getCurrentPotdEmbed()); - assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); - assertFalse(response.getBody().isSuccess()); + assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); } @Test diff --git a/src/test/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepositoryTest.java b/src/test/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepositoryTest.java index e21cef644..17dae0fde 100644 --- a/src/test/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepositoryTest.java +++ b/src/test/java/org/patinanetwork/codebloom/common/db/repos/potd/POTDRepositoryTest.java @@ -1,10 +1,12 @@ package org.patinanetwork.codebloom.common.db.repos.potd; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; @@ -55,24 +57,24 @@ void testCreatePOTD() { @Test @Order(2) void testGetPOTDById() { - POTD fetched = potdRepository.getPOTDById(testPOTD.getId()); - assertNotNull(fetched); - assertTrue(testPOTD.equals(fetched)); + Optional fetched = potdRepository.getPOTDById(testPOTD.getId()); + assertTrue(fetched.isPresent()); + assertTrue(Optional.of(testPOTD).equals(fetched)); } @Test @Order(3) void testGetCurrentPOTD() { - POTD current = potdRepository.getCurrentPOTD(); - assertNotNull(current); - assertTrue(testPOTD.equals(current)); + Optional current = potdRepository.getCurrentPOTD(); + assertTrue(current.isPresent()); + assertTrue(Optional.of(testPOTD).equals(current)); } @Test @Order(4) void testGetAllPOTDS() { List all = potdRepository.getAllPOTDS(); - assertNotNull(all); + assertFalse(all.isEmpty()); assertTrue(all.contains(testPOTD)); } @@ -81,7 +83,7 @@ void testGetAllPOTDS() { void testUpdatePOTD() { testPOTD.setTitle("Updated Title"); potdRepository.updatePOTD(testPOTD); - POTD updated = potdRepository.getPOTDById(testPOTD.getId()); - assertEquals("Updated Title", updated.getTitle()); + Optional updated = potdRepository.getPOTDById(testPOTD.getId()); + assertEquals("Updated Title", updated.get().getTitle()); } } diff --git a/src/test/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandlerTest.java b/src/test/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandlerTest.java index bab773acf..98cc90d42 100644 --- a/src/test/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandlerTest.java +++ b/src/test/java/org/patinanetwork/codebloom/common/submissions/SubmissionsHandlerTest.java @@ -93,7 +93,7 @@ private LeetcodeQuestion leetcodeQuestion(String slug, String difficulty, float @BeforeEach void commonStubs() { when(leaderboardRepository.getRecentLeaderboardMetadata()).thenReturn(Optional.of(leaderboard)); - when(potdRepository.getCurrentPOTD()).thenReturn(null); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.empty()); when(questionRepository.createQuestion(any(Question.class))).thenAnswer(inv -> { Question q = inv.getArgument(0); @@ -339,14 +339,14 @@ void appliesPotdMultiplier() { .multiplier(2.0f) .createdAt(LocalDateTime.now()) .build(); - when(potdRepository.getCurrentPOTD()).thenReturn(potd); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.of(potd)); LeetcodeSubmission sub = acceptedSubmission(700, "two-sum", LocalDateTime.of(2025, 6, 1, 12, 0)); when(questionRepository.questionExistsBySubmissionId("700")).thenReturn(false); when(questionRepository.getQuestionBySlugAndUserId("two-sum", USER_ID)).thenReturn(Optional.empty()); when(leetcodeClient.findQuestionBySlug("two-sum")).thenReturn(leetcodeQuestion("two-sum", "Easy", 50f)); - when(potdRepository.getCurrentPOTD()).thenReturn(null); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.empty()); handler.handleSubmissions( List.of(acceptedSubmission(701, "two-sum", LocalDateTime.of(2025, 6, 1, 12, 0))), user, false); @@ -358,7 +358,7 @@ void appliesPotdMultiplier() { q.setId("q-potd"); return q; }); - when(potdRepository.getCurrentPOTD()).thenReturn(potd); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.of(potd)); ArrayList potdResult = handler.handleSubmissions(List.of(sub), user, false); diff --git a/src/test/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetterTest.java b/src/test/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetterTest.java index 535f711cd..23119b72c 100644 --- a/src/test/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetterTest.java +++ b/src/test/java/org/patinanetwork/codebloom/scheduled/potd/PotdSetterTest.java @@ -1,8 +1,10 @@ package org.patinanetwork.codebloom.scheduled.potd; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; +import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -31,7 +33,7 @@ void testPotdSetterSetPotdWherePotdIsNull() { @Test void testPotdSetterSetPotdWherePotdIsFoundButStillCurrentPotd() { POTD potd = new POTD("Example title", "Example slug", QuestionDifficulty.Easy); - org.patinanetwork.codebloom.common.db.models.potd.POTD dbPotd = org.patinanetwork + Optional dbPotd = Optional.of(org.patinanetwork .codebloom .common .db @@ -44,7 +46,7 @@ void testPotdSetterSetPotdWherePotdIsFoundButStillCurrentPotd() { .multiplier(1.3f) .slug(potd.getTitleSlug()) .title(potd.getTitle()) - .build(); + .build()); when(leetcodeClient.getPotd()).thenReturn(potd); when(potdRepository.getCurrentPOTD()).thenReturn(dbPotd); @@ -59,7 +61,7 @@ void testPotdSetterSetPotdWherePotdIsFoundButStillCurrentPotd() { void testPotdSetterSetPotdWherePotdIsFoundButNoCurrentPotdYet() { POTD potd = new POTD("Example title", "Example slug", QuestionDifficulty.Easy); when(leetcodeClient.getPotd()).thenReturn(potd); - when(potdRepository.getCurrentPOTD()).thenReturn(null); + when(potdRepository.getCurrentPOTD()).thenReturn(Optional.empty()); potdSetter.setPotd(); @@ -77,7 +79,7 @@ void testPotdSetterSetPotdWherePotdIsFoundButNoCurrentPotdYet() { @Test void testPotdSetterSetPotdWherePotdIsFoundAndDoesntMatchOldPotd() { POTD potd = new POTD("Example title", "Example slug", QuestionDifficulty.Easy); - org.patinanetwork.codebloom.common.db.models.potd.POTD oldDbPotd = org.patinanetwork + Optional oldDbPotd = Optional.of(org.patinanetwork .codebloom .common .db @@ -90,7 +92,7 @@ void testPotdSetterSetPotdWherePotdIsFoundAndDoesntMatchOldPotd() { .multiplier(1.3f) .slug("old slug") .title("old title") - .build(); + .build()); when(leetcodeClient.getPotd()).thenReturn(potd); when(potdRepository.getCurrentPOTD()).thenReturn(oldDbPotd); @@ -105,6 +107,5 @@ void testPotdSetterSetPotdWherePotdIsFoundAndDoesntMatchOldPotd() { assertNotNull(dbPotd); assertEquals(potd.getTitle(), dbPotd.getTitle()); assertEquals(potd.getTitleSlug(), dbPotd.getSlug()); - assertEquals(potd.getDifficulty(), potd.getDifficulty()); } }