diff --git a/Jenkinsfile_nightly b/Jenkinsfile_nightly index 68586ed58..01469d575 100644 --- a/Jenkinsfile_nightly +++ b/Jenkinsfile_nightly @@ -94,6 +94,7 @@ withNightlyPipeline(type, product, component) { env.IA_CASE_DOCUMENTS_API_URL = "http://ia-case-documents-api-aat.service.core-compute-aat.internal/" env.IA_CASE_NOTIFICATIONS_API_URL = "http://ia-case-notifications-api-aat.service.core-compute-aat.internal/" + env.IA_TIMED_EVENT_SERVICE_URL = "http://ia-timed-event-service-aat.service.core-compute-aat.internal/" env.IA_IDAM_REDIRECT_URI = "https://ia-bail-case-api-aat.service.core-compute-aat.internal/oauth2/callback" env.CCD_URL = "http://ccd-data-store-api-aat.service.core-compute-aat.internal" env.CCD_GW_URL = "http://dm-store-aat.service.core-compute-aat.internal" diff --git a/Jenkinsfile_parameterized b/Jenkinsfile_parameterized index d2617753e..7efd12be7 100644 --- a/Jenkinsfile_parameterized +++ b/Jenkinsfile_parameterized @@ -73,6 +73,7 @@ withParameterizedPipeline(params.TYPE, params.PRODUCT_NAME, params.APP, params.E env.IA_CASE_DOCUMENTS_API_URL = "http://ia-case-documents-api-aat.service.core-compute-aat.internal/" env.IA_CASE_NOTIFICATIONS_API_URL = "http://ia-case-notifications-api-aat.service.core-compute-aat.internal/" + env.IA_TIMED_EVENT_SERVICE_URL = "http://ia-timed-event-service-aat.service.core-compute-aat.internal/" env.IA_IDAM_REDIRECT_URI = "https://ia-bail-case-api-aat.service.core-compute-aat.internal/oauth2/callback" env.CCD_URL = "http://ccd-data-store-api-aat.service.core-compute-aat.internal" env.CCD_GW_URL = "http://dm-store-aat.service.core-compute-aat.internal" diff --git a/charts/ia-bail-case-api/Chart.yaml b/charts/ia-bail-case-api/Chart.yaml index 056b819b9..dd59fd386 100644 --- a/charts/ia-bail-case-api/Chart.yaml +++ b/charts/ia-bail-case-api/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 description: A Helm chart for Bail Case API App name: ia-bail-case-api home: https://github.com/hmcts/ia-bail-case-api -version: 0.0.22 +version: 0.0.23 maintainers: - name: Immigration & Asylum Team email: ImmigrationandAsylum@HMCTS.NET diff --git a/charts/ia-bail-case-api/values.preview.template.yaml b/charts/ia-bail-case-api/values.preview.template.yaml index 50a6f7a49..d5ba9d1a0 100644 --- a/charts/ia-bail-case-api/values.preview.template.yaml +++ b/charts/ia-bail-case-api/values.preview.template.yaml @@ -14,4 +14,7 @@ java: IA_CASE_DOCUMENTS_API_URL: "http://ia-case-documents-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal/" IA_CASE_NOTIFICATIONS_API_URL: "http://ia-case-notifications-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal/" CASE_DOCUMENT_AM_URL: "http://ccd-case-document-am-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal" - LOCATION_REF_DATA_URL: "http://rd-location-ref-api-aat.service.core-compute-aat.internal" + LOCATION_REF_DATA_URL: "http://rd-location-ref-api-aat.service.core-compute-aat.internal" + IA_TIMED_EVENT_SERVICE_URL: "https://ia-timed-event-service-pr-183.preview.platform.hmcts.net/" + IA_TIMED_EVENT_SERVICE_ENABLED: "true" + diff --git a/charts/ia-bail-case-api/values.yaml b/charts/ia-bail-case-api/values.yaml index 0b97e4c7d..3ec50bd0f 100644 --- a/charts/ia-bail-case-api/values.yaml +++ b/charts/ia-bail-case-api/values.yaml @@ -19,6 +19,8 @@ java: IA_CASE_NOTIFICATIONS_API_URL: "http://ia-case-notifications-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal/" CASE_DOCUMENT_AM_URL: "http://ccd-case-document-am-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal" COMMON_DATA_API: http://rd-commondata-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal + IA_TIMED_EVENT_SERVICE_URL: "http://ia-timed-event-service-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal/" + IA_TIMED_EVENT_SERVICE_ENABLED: "false" keyVaults: ia: resourceGroup: ia diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/Event.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/Event.java index 90298089c..4e93dd3c1 100644 --- a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/Event.java +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/Event.java @@ -38,6 +38,7 @@ public enum Event { UPLOAD_DOCUMENTS("uploadDocuments"), UPLOAD_SIGNED_DECISION_NOTICE("uploadSignedDecisionNotice"), VIEW_PREVIOUS_APPLICATIONS("viewPreviousApplications"), + TEST_TIMED_EVENT_SCHEDULE("testTimedEventSchedule"), UPLOAD_HEARING_RECORDING("uploadHearingRecording"), @JsonEnumDefaultValue diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSavedConfirmation.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSavedConfirmation.java index 64cd7c282..bc4847e5d 100644 --- a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSavedConfirmation.java +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSavedConfirmation.java @@ -41,7 +41,7 @@ public PostSubmitCallbackResponse handle(Callback callback) { + "the 'Next step' dropdown list from your case details page.\n\n" + "#### Not ready to submit your application yet?\n" + "You can return to the case details page to make changes from the ‘Next step’ dropdown list." - ); + ); return postSubmitResponse; } diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmation.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmation.java index e2cfab297..9961ef05a 100644 --- a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmation.java +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmation.java @@ -1,7 +1,9 @@ package uk.gov.hmcts.reform.bailcaseapi.domain.handlers.postsubmit; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import uk.gov.hmcts.reform.bailcaseapi.domain.DateProvider; import uk.gov.hmcts.reform.bailcaseapi.domain.UserDetailsHelper; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.BailCase; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.BailCaseFieldDefinition; @@ -12,8 +14,13 @@ import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.callback.Callback; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.callback.PostSubmitCallbackResponse; import uk.gov.hmcts.reform.bailcaseapi.domain.handlers.PostSubmitCallbackHandler; +import uk.gov.hmcts.reform.bailcaseapi.domain.service.Scheduler; import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.CcdCaseAssignment; import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.ProfessionalOrganisationRetriever; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; + +import java.time.ZoneId; +import java.time.ZonedDateTime; @Slf4j @Component @@ -23,15 +30,24 @@ public class BailApplicationSubmittedConfirmation implements PostSubmitCallbackH private final CcdCaseAssignment ccdCaseAssignment; private UserDetails userDetails; private UserDetailsHelper userDetailsHelper; + private final boolean timedEventServiceEnabled; + private final DateProvider dateProvider; + private final Scheduler scheduler; public BailApplicationSubmittedConfirmation(ProfessionalOrganisationRetriever professionalOrganisationRetriever, CcdCaseAssignment ccdCaseAssignment, UserDetails userDetails, - UserDetailsHelper userDetailsHelper) { + UserDetailsHelper userDetailsHelper, + @Value("${featureFlag.timedEventServiceEnabled}") boolean timedEventServiceEnabled, + DateProvider dateProvider, + Scheduler scheduler) { this.professionalOrganisationRetriever = professionalOrganisationRetriever; this.ccdCaseAssignment = ccdCaseAssignment; this.userDetails = userDetails; this.userDetailsHelper = userDetailsHelper; + this.timedEventServiceEnabled = timedEventServiceEnabled; + this.dateProvider = dateProvider; + this.scheduler = scheduler; } @Override @@ -54,7 +70,7 @@ public PostSubmitCallbackResponse handle(Callback callback) { postSubmitResponse.setConfirmationBody( "### What happens next\n\n" - + "All parties will be notified that the application has been submitted." + + "All parties will be notified that the application has been submitted." ); postSubmitResponse.setConfirmationHeader("# You have submitted this application"); @@ -73,9 +89,27 @@ public PostSubmitCallbackResponse handle(Callback callback) { ); ccdCaseAssignment.assignAccessToCase(callback); - ccdCaseAssignment.revokeAccessToCase(callback, organisationIdentifier); + // TODO: uncomment revokeAccessToCase + // ccdCaseAssignment.revokeAccessToCase(callback, organisationIdentifier); + } + if (timedEventServiceEnabled) { + log.info("Triggering event to test timed event service schedule feature"); + int scheduleDelayInMinutes = 1; + ZonedDateTime scheduledDate = ZonedDateTime.of( + dateProvider.nowWithTime(), + ZoneId.systemDefault() + ).plusMinutes(scheduleDelayInMinutes); + scheduler.schedule( + new TimedEvent( + "", + Event.TEST_TIMED_EVENT_SCHEDULE, + scheduledDate, + "IA", + "Bail", + callback.getCaseDetails().getId() + ) + ); } - return postSubmitResponse; } } diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/presubmit/DecisionTypeAppender.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/presubmit/DecisionTypeAppender.java index 9486908e8..cbe2ea8f2 100644 --- a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/presubmit/DecisionTypeAppender.java +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/presubmit/DecisionTypeAppender.java @@ -10,8 +10,6 @@ import uk.gov.hmcts.reform.bailcaseapi.domain.BailCaseUtils; import uk.gov.hmcts.reform.bailcaseapi.domain.DateProvider; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.BailCase; -import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ListingEvent; -import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ListingHearingCentre; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.CaseDetails; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.DecisionType; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.Event; diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/service/Scheduler.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/service/Scheduler.java new file mode 100644 index 000000000..ebbddaf98 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/domain/service/Scheduler.java @@ -0,0 +1,10 @@ +package uk.gov.hmcts.reform.bailcaseapi.domain.service; + +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; + +public interface Scheduler { + + TimedEvent schedule(TimedEvent timedEvent); + + boolean deleteSchedule(String timedEventId); +} diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/AsylumCaseServiceResponseException.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/AsylumCaseServiceResponseException.java new file mode 100644 index 000000000..1c56c5f17 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/AsylumCaseServiceResponseException.java @@ -0,0 +1,11 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients; + +public class AsylumCaseServiceResponseException extends RuntimeException { + + public AsylumCaseServiceResponseException( + String message, + Throwable cause + ) { + super(message, cause); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventMessageConverterCustomizer.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventMessageConverterCustomizer.java new file mode 100644 index 000000000..72789024e --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventMessageConverterCustomizer.java @@ -0,0 +1,34 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.ObjectProvider; + +import java.util.function.Consumer; + +public class TimedEventMessageConverterCustomizer implements ObjectProvider { + @Override + public T getObject() throws BeansException { + return null; + } + + @Override + public T getObject(Object... args) throws BeansException { + return null; + } + + @Override + public T getIfAvailable() throws BeansException { + return null; + } + + @Override + public T getIfUnique() throws BeansException { + return null; + } + + @Override + public void forEach(Consumer action) { + // do nothing + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceApi.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceApi.java new file mode 100644 index 000000000..6c4c12ce7 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceApi.java @@ -0,0 +1,62 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients; + +import com.fasterxml.jackson.databind.ObjectMapper; +import feign.Feign; +import feign.codec.Decoder; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; +import org.springframework.cloud.openfeign.support.SpringDecoder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Scope; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.bind.annotation.*; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.config.DisableHystrixFeignConfiguration; + +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static uk.gov.hmcts.reform.bailcaseapi.infrastructure.config.ServiceTokenGeneratorConfiguration.SERVICE_AUTHORIZATION; + +@FeignClient( + name = "timed-event-service-api", + url = "${timed-event-service.url}", + configuration = {TimedEventServiceApi.Configuration.class, DisableHystrixFeignConfiguration.class} +) +public interface TimedEventServiceApi { + + @PostMapping(value = "/timed-event", produces = "application/json", consumes = "application/json") + TimedEvent submitTimedEvent( + @RequestHeader(AUTHORIZATION) String userToken, + @RequestHeader(SERVICE_AUTHORIZATION) String s2sToken, + @RequestBody TimedEvent content + ); + + @DeleteMapping(value = "/timed-event/{id}", produces = "application/json", consumes = "application/json") + void deleteTimedEvent( + @RequestHeader(AUTHORIZATION) String userToken, + @RequestHeader(SERVICE_AUTHORIZATION) String s2sToken, + @PathVariable("id") String jobKey + ); + + + class Configuration { + + @Bean + public Decoder decoder(ObjectMapper objectMapper) { + HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper); + return new ResponseEntityDecoder(new SpringDecoder(() -> new HttpMessageConverters(jacksonConverter), new TimedEventMessageConverterCustomizer<>())); + } + + @Bean + @Scope("prototype") + public Feign.Builder feignBuilder() { + return Feign.builder(); + } + + } + + + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceScheduler.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceScheduler.java new file mode 100644 index 000000000..d2620c86f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceScheduler.java @@ -0,0 +1,76 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients; + +import feign.FeignException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; +import uk.gov.hmcts.reform.bailcaseapi.domain.service.Scheduler; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.security.AccessTokenProvider; + +@Service +@Slf4j +public class TimedEventServiceScheduler implements Scheduler { + + private final AuthTokenGenerator serviceAuthTokenGenerator; + private final AccessTokenProvider accessTokenProvider; + private final TimedEventServiceApi timedEventServiceApi; + + public TimedEventServiceScheduler( + AuthTokenGenerator serviceAuthTokenGenerator, + @Qualifier("requestUser") AccessTokenProvider accessTokenProvider, + TimedEventServiceApi timedEventServiceApi + ) { + this.serviceAuthTokenGenerator = serviceAuthTokenGenerator; + this.accessTokenProvider = accessTokenProvider; + this.timedEventServiceApi = timedEventServiceApi; + } + + @Override + public TimedEvent schedule(TimedEvent timedEvent) { + + String serviceAuthorizationToken = serviceAuthTokenGenerator.generate(); + String accessToken = accessTokenProvider.getAccessToken(); + + try { + + return timedEventServiceApi.submitTimedEvent( + accessToken, + serviceAuthorizationToken, + timedEvent + ); + + } catch (FeignException e) { + + throw new AsylumCaseServiceResponseException( + String.format( + "Couldn't schedule timed event for caseId: %d, event: %s", + timedEvent.getCaseId(), + timedEvent.getEvent() + ), + e + ); + } + } + + public boolean deleteSchedule(String timedEventId) { + String serviceAuthorizationToken = serviceAuthTokenGenerator.generate(); + String accessToken = accessTokenProvider.getAccessToken(); + + try { + timedEventServiceApi.deleteTimedEvent( + accessToken, + serviceAuthorizationToken, + timedEventId + ); + } catch (FeignException ex) { + log.warn("The schedule with id {} could not be deleted. This should not happen and may cause problems. " + + "Check that the schedule ID is correct.", + timedEventId); + return false; + } + + return true; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/model/TimedEvent.java b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/model/TimedEvent.java new file mode 100644 index 000000000..55bcc17f6 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/model/TimedEvent.java @@ -0,0 +1,22 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.Event; + +import java.time.ZonedDateTime; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class TimedEvent { + + private String id; + private Event event; + private ZonedDateTime scheduledDateTime; + private String jurisdiction; + private String caseType; + private long caseId; + +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index b127446db..c9e42ba3e 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -75,6 +75,7 @@ security: caseworker-ia-system: - "clearLegalRepresentativeDetails" - "caseListing" + - "testTimedEventSchedule" caseworker-caa: - "nocRequest" - "clearLegalRepresentativeDetails" @@ -118,6 +119,7 @@ security: - "imaStatus" - "forceCaseToHearing" - "changeTribunalCentre" + - "testTimedEventSchedule" - "uploadHearingRecording" caseworker-ia-homeofficebail: - "startApplication" @@ -213,8 +215,12 @@ prof.ref.data.path.org.users: ${PROF_REF_DATA_ORG_USERS_PATH:/refdata/external/v prof.ref.data.path.org.organisation: ${PROF_REF_DATA_ORG_ORGANISATION_PATH:/refdata/external/v1/organisations} location.ref.data.url: ${LOCATION_REF_DATA_URL:http://localhost:8991} +timed-event-service: + url: ${IA_TIMED_EVENT_SERVICE_URL:http://127.0.0.1:8095} + featureFlag: isDocumentGenerationEnabled: ${IA_DOCUMENT_GENERATION_ENABLED:true} + timedEventServiceEnabled: ${IA_TIMED_EVENT_SERVICE_ENABLED:false} launchDarkly: sdkKey: ${LAUNCH_DARKLY_SDK_KEY:sdk-key} diff --git a/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/EventTest.java b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/EventTest.java index 2104de87d..5e74dc821 100644 --- a/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/EventTest.java +++ b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/entities/ccd/EventTest.java @@ -38,12 +38,13 @@ void has_correct_values() { assertEquals("caseListing", Event.CASE_LISTING.toString()); assertEquals("imaStatus", Event.IMA_STATUS.toString()); assertEquals("changeTribunalCentre", Event.CHANGE_TRIBUNAL_CENTRE.toString()); + assertEquals("testTimedEventSchedule", Event.TEST_TIMED_EVENT_SCHEDULE.toString()); assertEquals("unknown", Event.UNKNOWN.toString()); assertEquals("uploadHearingRecording", Event.UPLOAD_HEARING_RECORDING.toString()); } @Test void fail_if_changes_needed_after_modifying_class() { - assertEquals(35, Event.values().length); + assertEquals(36, Event.values().length); } } diff --git a/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmationTest.java b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmationTest.java index 72b3de446..291c9194f 100644 --- a/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmationTest.java +++ b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/domain/handlers/postsubmit/BailApplicationSubmittedConfirmationTest.java @@ -3,19 +3,23 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Optional; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import uk.gov.hmcts.reform.bailcaseapi.domain.DateProvider; import uk.gov.hmcts.reform.bailcaseapi.domain.UserDetailsHelper; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.BailCase; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.BailCaseFieldDefinition; @@ -27,39 +31,60 @@ import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.callback.Callback; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.callback.PostSubmitCallbackResponse; import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ref.OrganisationEntityResponse; +import uk.gov.hmcts.reform.bailcaseapi.domain.service.Scheduler; import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.CcdCaseAssignment; import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.ProfessionalOrganisationRetriever; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; @MockitoSettings(strictness = Strictness.LENIENT) public class BailApplicationSubmittedConfirmationTest { - @Mock private Callback callback; + @Mock + private Callback callback; - @Mock private CaseDetails caseDetails; + @Mock + private CaseDetails caseDetails; - @Mock private BailCase bailCase; + @Mock + private BailCase bailCase; - @Mock private ProfessionalOrganisationRetriever professionalOrganisationRetriever; + @Mock + private ProfessionalOrganisationRetriever professionalOrganisationRetriever; - @Mock private CcdCaseAssignment ccdCaseAssignment; + @Mock + private CcdCaseAssignment ccdCaseAssignment; - @Mock private OrganisationPolicy organisationPolicy; + @Mock + private OrganisationPolicy organisationPolicy; - @Mock private OrganisationEntityResponse organisationEntityResponse; + @Mock + private OrganisationEntityResponse organisationEntityResponse; - @Mock private UserDetails userDetails; + @Mock + private UserDetails userDetails; - @Mock private UserDetailsHelper userDetailsHelper; + @Mock + private UserDetailsHelper userDetailsHelper; + private boolean timedEventServiceEnabled; + @Mock + private DateProvider dateProvider; + @Mock + private Scheduler scheduler; private BailApplicationSubmittedConfirmation bailApplicationSubmittedConfirmation; @BeforeEach public void setUp() { bailApplicationSubmittedConfirmation = - new BailApplicationSubmittedConfirmation(professionalOrganisationRetriever, - ccdCaseAssignment, - userDetails, - userDetailsHelper); + new BailApplicationSubmittedConfirmation( + professionalOrganisationRetriever, + ccdCaseAssignment, + userDetails, + userDetailsHelper, + false, + dateProvider, + scheduler + ); when(callback.getEvent()).thenReturn(Event.SUBMIT_APPLICATION); } @@ -85,6 +110,7 @@ void should_set_header_body() { assertNotNull(response.getConfirmationHeader(), "Confirmation Header is null"); assertThat(response.getConfirmationHeader().get()).isEqualTo("# You have submitted this application"); + verify(scheduler, never()).schedule(any(TimedEvent.class)); } @Test @@ -143,7 +169,7 @@ void should_assign_and_revoke_access_to_case_when_user_is_Lr() { bailApplicationSubmittedConfirmation.handle(callback); verify(ccdCaseAssignment, times(1)).assignAccessToCase(callback); - verify(ccdCaseAssignment, times(1)).revokeAccessToCase(callback, organisationIdentifier); + // TODO: verify(ccdCaseAssignment, times(1)).revokeAccessToCase(callback, organisationIdentifier); } @Test @@ -162,4 +188,46 @@ void should_not_assign_and_revoke_access_to_case_when_user_is_not_LR() { verify(ccdCaseAssignment, never()).assignAccessToCase(callback); verify(ccdCaseAssignment, never()).revokeAccessToCase(any(), anyString()); } + + @Test + void testTestTimedEventScheduleEvent() { + bailApplicationSubmittedConfirmation = + new BailApplicationSubmittedConfirmation( + professionalOrganisationRetriever, + ccdCaseAssignment, + userDetails, + userDetailsHelper, + true, + dateProvider, + scheduler + ); + long caseId = 1234L; + String organisationIdentifier = "someOrgIdentifier"; + + when(callback.getCaseDetails()).thenReturn(caseDetails); + when(caseDetails.getCaseData()).thenReturn(bailCase); + when(callback.getCaseDetails().getId()).thenReturn(caseId); + when(userDetailsHelper.getLoggedInUserRoleLabel(any())).thenReturn(UserRoleLabel.LEGAL_REPRESENTATIVE); + when(bailCase.read(BailCaseFieldDefinition.LOCAL_AUTHORITY_POLICY, OrganisationPolicy.class)).thenReturn( + Optional.of(organisationPolicy)); + when(professionalOrganisationRetriever.retrieve()).thenReturn(organisationEntityResponse); + when(organisationEntityResponse.getOrganisationIdentifier()).thenReturn(organisationIdentifier); + LocalDateTime someTime = LocalDateTime.of(2024, 10, 10, 10, 10, 10); + when(dateProvider.nowWithTime()).thenReturn(someTime); + ZonedDateTime someTimeDelayed = ZonedDateTime.of( + someTime, + ZoneId.systemDefault() + ).plusMinutes(1); + bailApplicationSubmittedConfirmation.handle(callback); + verify(dateProvider).nowWithTime(); + TimedEvent timedEvent = new TimedEvent( + "", + Event.TEST_TIMED_EVENT_SCHEDULE, + someTimeDelayed, + "IA", + "Bail", + callback.getCaseDetails().getId() + ); + verify(scheduler).schedule(refEq(timedEvent)); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceSchedulerTest.java b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceSchedulerTest.java new file mode 100644 index 000000000..8263e41d4 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/bailcaseapi/infrastructure/clients/TimedEventServiceSchedulerTest.java @@ -0,0 +1,106 @@ +package uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients; + +import feign.FeignException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; +import uk.gov.hmcts.reform.bailcaseapi.domain.entities.ccd.Event; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.clients.model.TimedEvent; +import uk.gov.hmcts.reform.bailcaseapi.infrastructure.security.AccessTokenProvider; + +import java.time.ZonedDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class TimedEventServiceSchedulerTest { + + TimedEventServiceScheduler timedEventServiceScheduler; + @Mock + private AuthTokenGenerator serviceAuthTokenGenerator; + @Mock + private AccessTokenProvider accessTokenProvider; + @Mock + private TimedEventServiceApi timedEventServiceApi; + private String s2sToken = "someS2sToken"; + private String authToken = "authToken"; + + @BeforeEach + public void setup() { + when(serviceAuthTokenGenerator.generate()).thenReturn(s2sToken); + when(accessTokenProvider.getAccessToken()).thenReturn(authToken); + + timedEventServiceScheduler = + new TimedEventServiceScheduler(serviceAuthTokenGenerator, accessTokenProvider, timedEventServiceApi); + } + + + @Test + void should_invoke_timed_event_api() { + + TimedEvent timedEvent = new TimedEvent( + "someId", + Event.CASE_LISTING, + ZonedDateTime.now(), + "", + "", + 1234 + ); + + when(timedEventServiceApi.submitTimedEvent(authToken, s2sToken, timedEvent)).thenReturn(timedEvent); + + assertEquals(timedEvent, timedEventServiceScheduler.schedule(timedEvent)); + } + + @Test + void should_rethrow_exception_from_api() { + + TimedEvent timedEvent = new TimedEvent( + "someId", + Event.CASE_LISTING, + ZonedDateTime.now(), + "", + "", + 1234 + ); + + when(timedEventServiceApi.submitTimedEvent(authToken, s2sToken, timedEvent)).thenThrow(FeignException.class); + + assertThatThrownBy(() -> timedEventServiceScheduler.schedule(timedEvent)) + .isInstanceOf(AsylumCaseServiceResponseException.class) + .hasCauseInstanceOf(FeignException.class); + } + + @Test + void should_invoke_delete_api_successfully() { + // Given + doNothing().when(timedEventServiceApi).deleteTimedEvent(authToken, s2sToken, "1234567"); + + // When + boolean result = timedEventServiceScheduler.deleteSchedule("1234567"); + + // Then + verify(timedEventServiceApi).deleteTimedEvent(authToken, s2sToken, "1234567"); + assertThat(result).isTrue(); + } + + @Test + void should_invoke_delete_api_with_failure() { + // Given + doThrow(FeignException.class).when(timedEventServiceApi).deleteTimedEvent(authToken, s2sToken, "1234567"); + + // When + boolean result = timedEventServiceScheduler.deleteSchedule("1234567"); + + // Then + verify(timedEventServiceApi).deleteTimedEvent(authToken, s2sToken, "1234567"); + assertThat(result).isFalse(); + } + +}