Skip to content

Commit c0cceac

Browse files
committed
fix: added clock service to allow easy injection of clock now()
Discussed with Samir last week who agreed that it was a sensible thing to do to make testing easier ( Dont think it will fix the resolution issue on int test though )
1 parent 3a8202f commit c0cceac

File tree

6 files changed

+75
-21
lines changed

6 files changed

+75
-21
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package uk.gov.hmcts.cp.subscription.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import uk.gov.hmcts.cp.subscription.services.ClockService;
6+
7+
import java.time.Clock;
8+
9+
@Configuration
10+
public class AppConfig {
11+
12+
@Bean
13+
ClockService clockService() {
14+
return new ClockService(Clock.systemDefaultZone());
15+
}
16+
}

src/main/java/uk/gov/hmcts/cp/subscription/mappers/SubscriptionMapper.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package uk.gov.hmcts.cp.subscription.mappers;
22

3+
import org.mapstruct.Context;
34
import org.mapstruct.Mapper;
45
import org.mapstruct.Mapping;
56
import org.mapstruct.Named;
@@ -9,6 +10,7 @@
910
import uk.gov.hmcts.cp.openapi.model.NotificationEndpoint;
1011
import uk.gov.hmcts.cp.subscription.entities.ClientSubscriptionEntity;
1112
import uk.gov.hmcts.cp.subscription.model.EntityEventType;
13+
import uk.gov.hmcts.cp.subscription.services.ClockService;
1214

1315
import java.util.List;
1416

@@ -20,16 +22,16 @@ public interface SubscriptionMapper {
2022
@Mapping(target = "id", expression = "java(null)")
2123
@Mapping(source = "request.eventTypes", target = "eventTypes", qualifiedByName = "mapWithSortedEventTypes")
2224
@Mapping(source = "request.notificationEndpoint", target = "notificationEndpoint", qualifiedByName = "mapFromNotificationEndpoint")
23-
@Mapping(target = "createdAt", expression = "java(java.time.OffsetDateTime.now())")
24-
@Mapping(target = "updatedAt", expression = "java(java.time.OffsetDateTime.now())")
25-
ClientSubscriptionEntity mapCreateRequestToEntity(ClientSubscriptionRequest request);
25+
@Mapping(target = "createdAt", expression = "java(clockService.now())")
26+
@Mapping(target = "updatedAt", expression = "java(clockService.now())")
27+
ClientSubscriptionEntity mapCreateRequestToEntity(@Context ClockService clockService, ClientSubscriptionRequest request);
2628

2729
@Mapping(source = "existing.id", target = "id")
2830
@Mapping(source = "request.eventTypes", target = "eventTypes", qualifiedByName = "mapWithSortedEventTypes")
2931
@Mapping(source = "request.notificationEndpoint", target = "notificationEndpoint", qualifiedByName = "mapFromNotificationEndpoint")
3032
@Mapping(source = "existing.createdAt", target = "createdAt")
31-
@Mapping(expression = "java(java.time.OffsetDateTime.now())", target = "updatedAt")
32-
ClientSubscriptionEntity mapUpdateRequestToEntity(ClientSubscriptionEntity existing, ClientSubscriptionRequest request);
33+
@Mapping(expression = "java(clockService.now())", target = "updatedAt")
34+
ClientSubscriptionEntity mapUpdateRequestToEntity(@Context ClockService clockService, ClientSubscriptionEntity existing, ClientSubscriptionRequest request);
3335

3436
@Mapping(source = "id", target = "clientSubscriptionId")
3537
ClientSubscription mapEntityToResponse(ClientSubscriptionEntity entity);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package uk.gov.hmcts.cp.subscription.services;
2+
3+
import lombok.AllArgsConstructor;
4+
import org.springframework.stereotype.Service;
5+
6+
import java.time.Clock;
7+
import java.time.OffsetDateTime;
8+
import java.time.ZoneOffset;
9+
10+
@Service
11+
@AllArgsConstructor
12+
/**
13+
* We use a ClockService to expose the clock time in a simple method to allow mocking in Tests
14+
*/
15+
public class ClockService {
16+
17+
Clock clock;
18+
19+
public OffsetDateTime now() {
20+
return clock.instant().atOffset(ZoneOffset.UTC);
21+
}
22+
}

src/main/java/uk/gov/hmcts/cp/subscription/services/SubscriptionService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@
1616
@Slf4j
1717
public class SubscriptionService {
1818

19+
private final ClockService clockService;
1920
private final SubscriptionRepository subscriptionRepository;
2021
private final SubscriptionMapper mapper;
2122

2223
public ClientSubscription saveSubscription(final ClientSubscriptionRequest request) {
23-
final ClientSubscriptionEntity entity = mapper.mapCreateRequestToEntity(request);
24+
final ClientSubscriptionEntity entity = mapper.mapCreateRequestToEntity(clockService, request);
2425
return mapper.mapEntityToResponse(subscriptionRepository.save(entity));
2526
}
2627

2728
public ClientSubscription updateSubscription(final UUID clientSubscriptionId, final ClientSubscriptionRequest request) {
2829
final ClientSubscriptionEntity existing = subscriptionRepository.getReferenceById(clientSubscriptionId);
29-
final ClientSubscriptionEntity entity = mapper.mapUpdateRequestToEntity(existing, request);
30+
final ClientSubscriptionEntity entity = mapper.mapUpdateRequestToEntity(clockService, existing, request);
3031
return mapper.mapEntityToResponse(subscriptionRepository.save(entity));
3132
}
3233

src/test/java/uk/gov/hmcts/cp/subscription/mappers/SubscriptionMapperTest.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,59 @@
11
package uk.gov.hmcts.cp.subscription.mappers;
22

33
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.mockito.Mock;
6+
import org.mockito.junit.jupiter.MockitoExtension;
47
import uk.gov.hmcts.cp.openapi.model.ClientSubscription;
58
import uk.gov.hmcts.cp.openapi.model.ClientSubscriptionRequest;
69
import uk.gov.hmcts.cp.openapi.model.NotificationEndpoint;
710
import uk.gov.hmcts.cp.subscription.entities.ClientSubscriptionEntity;
811
import uk.gov.hmcts.cp.subscription.model.EntityEventType;
12+
import uk.gov.hmcts.cp.subscription.services.ClockService;
913

1014
import java.time.OffsetDateTime;
15+
import java.time.ZoneOffset;
1116
import java.util.ArrayList;
1217
import java.util.List;
1318
import java.util.UUID;
1419

1520
import static org.assertj.core.api.Assertions.assertThat;
21+
import static org.mockito.Mockito.when;
1622
import static uk.gov.hmcts.cp.openapi.model.EventType.CUSTODIAL_RESULT;
1723
import static uk.gov.hmcts.cp.openapi.model.EventType.PCR;
1824

25+
@ExtendWith(MockitoExtension.class)
1926
class SubscriptionMapperTest {
2027

28+
private final static OffsetDateTime MOCKCREATED = OffsetDateTime.of(2025, 12, 1, 11, 30, 50, 582007048, ZoneOffset.UTC);
29+
private final static OffsetDateTime MOCKUPDATED = OffsetDateTime.of(2025, 12, 2, 12, 40, 55, 234567890, ZoneOffset.UTC);
30+
31+
@Mock
32+
ClockService clockService;
33+
2134
SubscriptionMapper mapper = new SubscriptionMapperImpl();
2235

2336
UUID clientSubscriptionId = UUID.fromString("d730c6e1-66ba-4ef0-a3dd-0b9928faa76d");
2437
NotificationEndpoint notificationEndpoint = NotificationEndpoint.builder()
2538
.webhookUrl("https://example.com")
2639
.build();
27-
OffsetDateTime createdAt = OffsetDateTime.now().minusDays(2);
28-
OffsetDateTime updatedAt = OffsetDateTime.now().minusHours(2);
2940
ClientSubscriptionEntity existing = ClientSubscriptionEntity.builder()
3041
.id(clientSubscriptionId)
3142
.notificationEndpoint(notificationEndpoint.getWebhookUrl().toString())
3243
.eventTypes(mutableLisOfEventTypes())
33-
.createdAt(createdAt)
34-
.updatedAt(updatedAt)
44+
.createdAt(MOCKCREATED)
45+
.updatedAt(MOCKCREATED)
3546
.build();
3647

3748
@Test
3849
void create_request_should_map_to_entity_with_sorted_types() {
50+
when(clockService.now()).thenReturn(MOCKCREATED);
3951
ClientSubscriptionRequest request = ClientSubscriptionRequest.builder()
4052
.notificationEndpoint(notificationEndpoint)
4153
.eventTypes(List.of(PCR, CUSTODIAL_RESULT))
4254
.build();
4355

44-
ClientSubscriptionEntity entity = mapper.mapCreateRequestToEntity(request);
56+
ClientSubscriptionEntity entity = mapper.mapCreateRequestToEntity(clockService, request);
4557

4658
assertThat(entity.getId()).isNull();
4759
assertThat(entity.getNotificationEndpoint()).isEqualTo("https://example.com");
@@ -59,14 +71,14 @@ void update_request_should_map_to_entity_with_sorted_types() {
5971
.notificationEndpoint(updatedEndpoint)
6072
.eventTypes(List.of(CUSTODIAL_RESULT))
6173
.build();
62-
63-
ClientSubscriptionEntity entity = mapper.mapUpdateRequestToEntity(existing, request);
74+
when(clockService.now()).thenReturn(MOCKUPDATED);
75+
ClientSubscriptionEntity entity = mapper.mapUpdateRequestToEntity(clockService, existing, request);
6476

6577
assertThat(entity.getId()).isEqualTo(clientSubscriptionId);
6678
assertThat(entity.getNotificationEndpoint()).isEqualTo("https://updated.com");
6779
assertThat(entity.getEventTypes().toString()).isEqualTo("[CUSTODIAL_RESULT]");
68-
assertThat(entity.getCreatedAt()).isEqualTo(createdAt);
69-
assertThat(entity.getUpdatedAt()).isAfter(updatedAt);
80+
assertThat(entity.getCreatedAt()).isEqualTo(MOCKCREATED);
81+
assertThat(entity.getUpdatedAt()).isEqualTo(MOCKUPDATED);
7082
}
7183

7284
@Test
@@ -76,8 +88,8 @@ void entity_should_map_to_response() {
7688
assertThat(subscription.getClientSubscriptionId()).isEqualTo(clientSubscriptionId);
7789
assertThat(subscription.getNotificationEndpoint()).isEqualTo(notificationEndpoint);
7890
assertThat(subscription.getEventTypes().toString()).isEqualTo("[CUSTODIAL_RESULT, PCR]");
79-
assertThat(subscription.getCreatedAt()).isEqualTo(createdAt);
80-
assertThat(subscription.getUpdatedAt()).isEqualTo(updatedAt);
91+
assertThat(subscription.getCreatedAt()).isEqualTo(MOCKCREATED);
92+
assertThat(subscription.getUpdatedAt()).isEqualTo(MOCKCREATED);
8193
}
8294

8395
private List<EntityEventType> mutableLisOfEventTypes() {

src/test/java/uk/gov/hmcts/cp/subscription/services/SubscriptionServiceTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
@ExtendWith(MockitoExtension.class)
2222
class SubscriptionServiceTest {
2323

24+
@Mock ClockService clockService;
2425
@Mock
2526
SubscriptionRepository subscriptionRepository;
2627
@Mock
@@ -38,21 +39,21 @@ class SubscriptionServiceTest {
3839

3940
@Test
4041
void save_request_should_save_new_entity() {
41-
when(mapper.mapCreateRequestToEntity(request)).thenReturn(requestEntity);
42+
when(mapper.mapCreateRequestToEntity(clockService, request)).thenReturn(requestEntity);
4243
when(subscriptionRepository.save(requestEntity)).thenReturn(savedEntity);
4344
when(mapper.mapEntityToResponse(savedEntity)).thenReturn(response);
4445

4546
ClientSubscription result = subscriptionService.saveSubscription(request);
4647

47-
verify(mapper).mapCreateRequestToEntity(request);
48+
verify(mapper).mapCreateRequestToEntity(clockService, request);
4849
verify(subscriptionRepository).save(requestEntity);
4950
assertThat(result).isEqualTo(response);
5051
}
5152

5253
@Test
5354
void update_request_should_update_existing_entity() {
5455
when(subscriptionRepository.getReferenceById(subscriptionId)).thenReturn(savedEntity);
55-
when(mapper.mapUpdateRequestToEntity(savedEntity, request)).thenReturn(requestEntity);
56+
when(mapper.mapUpdateRequestToEntity(clockService, savedEntity, request)).thenReturn(requestEntity);
5657
when(subscriptionRepository.save(requestEntity)).thenReturn(updatedEntity);
5758
when(mapper.mapEntityToResponse(updatedEntity)).thenReturn(response);
5859

0 commit comments

Comments
 (0)