Skip to content

Commit

Permalink
#85 - ResendReviewsUntilDuplicated cron + its tests (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
iakunin authored Apr 25, 2020
1 parent e68448f commit 4e68e54
Show file tree
Hide file tree
Showing 16 changed files with 299 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package dev.iakunin.codexiabot.codexia.config;

import dev.iakunin.codexiabot.codexia.cron.ResendReviewsUntilDuplicated;
import dev.iakunin.codexiabot.common.runnable.Logging;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
public class ResendReviewsUntilDuplicatedCronConfig implements SchedulingConfigurer {

private final ResendReviewsUntilDuplicated resendReviewsUntilDuplicated;

private final String cronExpression;

public ResendReviewsUntilDuplicatedCronConfig(
ResendReviewsUntilDuplicated resendReviewsUntilDuplicated,
@Value("${app.cron.codexia.resend-reviews-until-duplicated:-}") String cronExpression
) {
this.resendReviewsUntilDuplicated = resendReviewsUntilDuplicated;
this.cronExpression = cronExpression;
}

@Bean
public Runnable resendReviewsUntilDuplicatedRunnable() {
return new Logging(this.resendReviewsUntilDuplicated);
}

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addCronTask(
this.resendReviewsUntilDuplicatedRunnable(),
this.cronExpression
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.iakunin.codexiabot.codexia.cron;

import dev.iakunin.codexiabot.codexia.entity.CodexiaReviewNotification;
import dev.iakunin.codexiabot.codexia.repository.CodexiaReviewNotificationRepository;
import dev.iakunin.codexiabot.codexia.sdk.CodexiaClient;
import dev.iakunin.codexiabot.codexia.service.ReviewSender;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@AllArgsConstructor(onConstructor_={@Autowired})
// @todo #85 Remove this cron after https://github.com/yegor256/codexia/issues/98 is done
public final class ResendReviewsUntilDuplicated implements Runnable {

private final CodexiaReviewNotificationRepository codexiaReviewNotificationRepository;

private final ReviewSender reviewSender;

public void run() {
this.codexiaReviewNotificationRepository
.findAllByLastStatusExcludingResponseCode(
CodexiaReviewNotification.Status.SUCCESS,
CodexiaClient.ReviewStatus.ALREADY_EXISTS.httpStatus()
)
.stream()
.map(CodexiaReviewNotification::getCodexiaReview)
.forEach(this.reviewSender::send);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,18 @@ public interface CodexiaReviewNotificationRepository extends JpaRepository<Codex
"and m1.status = ?1"
)
Set<CodexiaReviewNotification> findAllByLastStatus(CodexiaReviewNotification.Status status);

@Query(
"select m1 " +
"from CodexiaReviewNotification m1 " +
"left join CodexiaReviewNotification m2 " +
" on (m1.codexiaReview = m2.codexiaReview and m1.id < m2.id) " +
"where m2.id is null " +
"and m1.status = ?1 " +
"and m1.responseCode <> ?2"
)
Set<CodexiaReviewNotification> findAllByLastStatusExcludingResponseCode(
CodexiaReviewNotification.Status status,
Integer responseCode
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,18 @@ class Project {
// @todo #6 replace `Date` with `ZonedDateTime`
private Date created;
}

enum ReviewStatus {
ALREADY_EXISTS(404);

private final int httpStatus;

ReviewStatus(int httpStatus) {
this.httpStatus = httpStatus;
}

public int httpStatus() {
return this.httpStatus;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
@AllArgsConstructor(onConstructor_={@Autowired})
public final class ReviewSenderImpl implements ReviewSender {

private static final int REVIEW_ALREADY_EXISTS_STATUS = 404;

private final CodexiaReviewNotificationRepository codexiaReviewNotificationRepository;

private final CodexiaClient codexiaClient;
Expand Down Expand Up @@ -72,7 +70,7 @@ private void saveExceptionalNotification(
notification
.setStatus(
// @todo #19 rewrite via custom Feign exceptions
e.status() == REVIEW_ALREADY_EXISTS_STATUS
e.status() == CodexiaClient.ReviewStatus.ALREADY_EXISTS.httpStatus()
? CodexiaReviewNotification.Status.SUCCESS
: CodexiaReviewNotification.Status.ERROR
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
"type": "java.lang.String",
"description": "Cron expression for codexia.resend-erroneous-reviews."
},
{
"name": "app.cron.codexia.resend-reviews-until-duplicated",
"type": "java.lang.String",
"description": "Cron expression for codexia.resend-reviews-until-duplicated."
},
{
"name": "app.cron.codexia.projects-health-check",
"type": "java.lang.String",
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application-prod.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ app.cron.codexia.codexia-parser=45 * * * * *
app.cron.codexia.missing-filler=0 0 0 * * *
app.cron.codexia.send-reviews=55 * * * * *
app.cron.codexia.resend-erroneous-reviews=25 * * * * *
app.cron.codexia.resend-reviews-until-duplicated=15 10 * * * *
app.cron.codexia.projects-health-check=35 * * * * *

app.cron.github.stat.lines-of-code=30 * * * * *
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package dev.iakunin.codexiabot.codexia.cron;

import com.github.database.rider.core.api.dataset.DataSet;
import com.github.database.rider.core.api.dataset.ExpectedDataSet;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
import dev.iakunin.codexiabot.AbstractIntegrationTest;
import dev.iakunin.codexiabot.util.WireMockServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;

@ContextConfiguration(initializers = ResendReviewsUntilDuplicatedIntegrationTest.Initializer.class)
public class ResendReviewsUntilDuplicatedIntegrationTest extends AbstractIntegrationTest {

@Autowired
private ResendReviewsUntilDuplicated cron;

@Test
@DataSet(
value = "db-rider/codexia/cron/resend-reviews-until-duplicated/initial/emptyDatabase.yml",
cleanBefore = true, cleanAfter = true
)
@ExpectedDataSet("db-rider/codexia/cron/resend-reviews-until-duplicated/expected/emptyDatabase.yml")
public void emptyDatabase() {
cron.run();
}

@Test
@DataSet(
value = "db-rider/codexia/cron/resend-reviews-until-duplicated/initial/oneUnsuccessfulNotification.yml",
cleanBefore = true, cleanAfter = true
)
@ExpectedDataSet("db-rider/codexia/cron/resend-reviews-until-duplicated/expected/oneUnsuccessfulNotification.yml")
public void oneUnsuccessfulNotification() {
cron.run();
}

@Test
@DataSet(
value = "db-rider/codexia/cron/resend-reviews-until-duplicated/initial/oneSuccessfulNotificationWithDuplicatedCode.yml",
cleanBefore = true, cleanAfter = true
)
@ExpectedDataSet("db-rider/codexia/cron/resend-reviews-until-duplicated/expected/oneSuccessfulNotificationWithDuplicatedCode.yml")
public void oneSuccessfulNotificationWithDuplicatedCode() {
cron.run();
}

@Test
@DataSet(
value = "db-rider/codexia/cron/resend-reviews-until-duplicated/initial/happyPath.yml",
cleanBefore = true, cleanAfter = true
)
@ExpectedDataSet("db-rider/codexia/cron/resend-reviews-until-duplicated/expected/happyPath.yml")
public void happyPath() {
WireMockServer.getInstance().stubFor(
post(urlPathMatching("/p/\\d+/post"))
.willReturn(aResponse()
.withStatus(404)
.withHeader("Content-Type", "application/text")
.withBody("Review already exists.")
)
);

cron.run();
}

@AfterEach
void after() {
WireMockServer.getInstance().resetAll();
}

static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of(
"app.codexia.base-url=" + WireMockServer.getInstance().baseUrl()
).applyTo(applicationContext.getEnvironment());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
codexia_project: []

codexia_review: []

codexia_review_notification: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
codexia_review_notification:
-
codexia_review_id: 1
status: SUCCESS
response_code: 200
response: Some response
-
codexia_review_id: 1
status: SUCCESS
response_code: 404
response: "Review already exists."
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
codexia_review_notification:
-
codexia_review_id: 1
status: SUCCESS
response_code: 404
response: Some response
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
codexia_review_notification:
-
codexia_review_id: 1
status: ERROR
response_code: 500
response: Some response
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
codexia_project: []

codexia_review: []

codexia_review_notification: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
codexia_project:
-
id: 5
uuid: "groovy: UUID.randomUUID().toString()"
external_id: 12
coordinates: "test-project1/test-repo1"
author: "some-first-author"
project_created_at: "2019-12-20 12:01:02"

codexia_review:
-
id: 1
uuid: "groovy: UUID.randomUUID().toString()"
codexia_project_id: 5
author: Review author
reason: Review reason
text: Review text

codexia_review_notification:
-
uuid: "groovy: UUID.randomUUID().toString()"
codexia_review_id: 1
status: SUCCESS
response_code: 200
response: Some response
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
codexia_project:
-
id: 5
uuid: "groovy: UUID.randomUUID().toString()"
external_id: 12
coordinates: "test-project1/test-repo1"
author: "some-first-author"
project_created_at: "2019-12-20 12:01:02"

codexia_review:
-
id: 1
uuid: "groovy: UUID.randomUUID().toString()"
codexia_project_id: 5
author: Review author
reason: Review reason
text: Review text

codexia_review_notification:
-
uuid: "groovy: UUID.randomUUID().toString()"
codexia_review_id: 1
status: SUCCESS
response_code: 404
response: Some response
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
codexia_project:
-
id: 5
uuid: "groovy: UUID.randomUUID().toString()"
external_id: 12
coordinates: "test-project1/test-repo1"
author: "some-first-author"
project_created_at: "2019-12-20 12:01:02"

codexia_review:
-
id: 1
uuid: "groovy: UUID.randomUUID().toString()"
codexia_project_id: 5
author: Review author
reason: Review reason
text: Review text

codexia_review_notification:
-
uuid: "groovy: UUID.randomUUID().toString()"
codexia_review_id: 1
status: ERROR
response_code: 500
response: Some response

1 comment on commit 4e68e54

@0pdd
Copy link

@0pdd 0pdd commented on 4e68e54 Apr 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 85-a7ac8fa2 discovered in src/main/java/dev/iakunin/codexiabot/codexia/cron/ResendReviewsUntilDuplicated.java and submitted as #89. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but we discovered it only now.

Please sign in to comment.