diff --git a/.github/pmd-ruleset.xml b/.github/pmd-ruleset.xml
index 35916718..19dedd48 100644
--- a/.github/pmd-ruleset.xml
+++ b/.github/pmd-ruleset.xml
@@ -18,6 +18,7 @@
+
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index c0fe9c93..087c10e9 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -89,14 +89,14 @@ jobs:
gradle-version: current
- name: Gradle Build
- run: gradle build -x test -x api
+ run: gradle build -x test
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: DAST - Build and run containerised app
run: |
- docker compose -f docker/docker-compose.yml up -d
+ docker compose -f docker-compose.yml up -d
echo "Waiting for health endpoint..."
for i in {1..30}; do
diff --git a/.gitignore b/.gitignore
index 31ab8a84..97bd8192 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-gradle
+gradle/wrapper
bin/*
!bin/run-in-docker.sh
.gradle
diff --git a/docker/Dockerfile b/Dockerfile
similarity index 100%
rename from docker/Dockerfile
rename to Dockerfile
diff --git a/build.gradle b/build.gradle
index 44052908..e52fd11a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,6 +17,7 @@ version = System.getProperty('ARTEFACT_VERSION') ?: '0.0.999'
apply {
from("$rootDir/gradle/dependencies/java-core.gradle")
from("$rootDir/gradle/dependencies/spring-core.gradle")
+ from("$rootDir/gradle/dependencies/spring-db.gradle")
from("$rootDir/gradle/github/repositories.gradle")
from("$rootDir/gradle/github/java.gradle")
@@ -26,7 +27,6 @@ apply {
from("$rootDir/gradle/github/jar.gradle")
from("$rootDir/gradle/tasks/apitest.gradle")
- from("$rootDir/gradle/tasks/docker.gradle")
}
springBoot {
@@ -40,4 +40,7 @@ springBoot {
dependencies {
implementation('uk.gov.hmcts.cp:api-cp-crime-courthearing-cases-results:0.0.0-a65d290')
+
+ // Lets add this to the api because we need it to prevent its openapi NotNull errors
+ implementation("io.swagger.core.v3:swagger-annotations:2.2.41")
}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..4dbee57f
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,21 @@
+services:
+ db:
+ image: postgres:16-alpine
+ environment:
+ POSTGRES_DB: appdb
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+ ports:
+ - "5432:5432"
+
+ app:
+ build:
+ dockerfile: Dockerfile
+ environment:
+ DATASOURCE_URL: jdbc:postgresql://db:5432/appdb
+ DATASOURCE_USERNAME: postgres
+ DATASOURCE_PASSWORD: postgres
+ depends_on:
+ - db
+ ports:
+ - "8082:8082"
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
deleted file mode 100644
index c8116301..00000000
--- a/docker/docker-compose.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-services:
- app:
- container_name: app
- build:
- context: ..
- dockerfile: docker/Dockerfile
- ports:
- - "8082:8082"
- environment:
- SERVER_PORT: 8082
diff --git a/gradle/dependencies/spring-db.gradle b/gradle/dependencies/spring-db.gradle
new file mode 100644
index 00000000..dbede3e9
--- /dev/null
+++ b/gradle/dependencies/spring-db.gradle
@@ -0,0 +1,10 @@
+dependencies {
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'org.postgresql:postgresql'
+ implementation 'org.springframework.boot:spring-boot-starter-flyway'
+ implementation 'org.flywaydb:flyway-core'
+ implementation 'org.flywaydb:flyway-database-postgresql'
+ testImplementation("org.springframework.boot:spring-boot-testcontainers:4.0.0")
+ testImplementation 'org.testcontainers:postgresql:1.21.3'
+ testImplementation 'org.testcontainers:junit-jupiter:1.21.3'
+}
\ No newline at end of file
diff --git a/gradle/tasks/apitest.gradle b/gradle/tasks/apitest.gradle
index 6d23937e..63273b9a 100644
--- a/gradle/tasks/apitest.gradle
+++ b/gradle/tasks/apitest.gradle
@@ -1,4 +1,4 @@
-tasks.register('api', Test) {
+tasks.register('apiTest', Test) {
description = "Runs api tests against docker-compose stack"
group = "Verification"
@@ -13,12 +13,12 @@ tasks.register('api', Test) {
}
tasks.named('check') {
- dependsOn tasks.named('api')
+ dependsOn tasks.named('apiTest')
}
tasks.named('build') {
dependsOn tasks.named('test')
- dependsOn tasks.named('api')
+ dependsOn tasks.named('apiTest')
}
sourceSets {
@@ -30,5 +30,21 @@ sourceSets {
}
}
-dependencies {
+dockerCompose {
+ useComposeFiles = ['docker-compose.yml']
+ startedServices = ['db', 'app']
+
+ buildBeforeUp = true
+ waitForTcpPorts = true
+ upAdditionalArgs = ['--wait', '--wait-timeout', '120']
+
+ captureContainersOutput = true
+ removeOrphans = true
+ stopContainers = true
+ removeContainers = true
+
+ projectName = "app"
+
+ useDockerComposeV2 = true
+ dockerExecutable = 'docker'
}
diff --git a/gradle/tasks/docker.gradle b/gradle/tasks/docker.gradle
deleted file mode 100644
index 97085af8..00000000
--- a/gradle/tasks/docker.gradle
+++ /dev/null
@@ -1,18 +0,0 @@
-dockerCompose {
- useComposeFiles = ['docker/docker-compose.yml']
- startedServices = ['app']
-
- buildBeforeUp = true
- waitForTcpPorts = true
- upAdditionalArgs = ['--wait', '--wait-timeout', '30']
-
- captureContainersOutput = true
- removeOrphans = true
- stopContainers = true
- removeContainers = true
-
- projectName = "${rootProject.name}"
-
- useDockerComposeV2 = true
- dockerExecutable = 'docker'
-}
\ No newline at end of file
diff --git a/src/main/java/uk/gov/hmcts/cp/entities/SubscriberEntity.java b/src/main/java/uk/gov/hmcts/cp/entities/SubscriberEntity.java
new file mode 100644
index 00000000..66690929
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/entities/SubscriberEntity.java
@@ -0,0 +1,28 @@
+package uk.gov.hmcts.cp.entities;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = "subscriber")
+@Getter
+@Builder(toBuilder = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class SubscriberEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ private String name;
+}
\ No newline at end of file
diff --git a/src/main/java/uk/gov/hmcts/cp/entities/SubscriptionEntity.java b/src/main/java/uk/gov/hmcts/cp/entities/SubscriptionEntity.java
new file mode 100644
index 00000000..349c54de
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/entities/SubscriptionEntity.java
@@ -0,0 +1,34 @@
+package uk.gov.hmcts.cp.entities;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import uk.gov.hmcts.cp.model.EventType;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = "subscription")
+@Getter
+@Builder(toBuilder = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class SubscriptionEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ private UUID subscriberId;
+ @Enumerated(EnumType.STRING)
+ private EventType eventType;
+ private String notifyUrl;
+}
\ No newline at end of file
diff --git a/src/main/java/uk/gov/hmcts/cp/mappers/SubscriptionMapper.java b/src/main/java/uk/gov/hmcts/cp/mappers/SubscriptionMapper.java
new file mode 100644
index 00000000..b0ce8094
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/mappers/SubscriptionMapper.java
@@ -0,0 +1,19 @@
+package uk.gov.hmcts.cp.mappers;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.ReportingPolicy;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+import uk.gov.hmcts.cp.openapi.model.Result;
+
+import java.util.List;
+
+@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface SubscriptionMapper {
+
+ @Mapping(source = "notifyUrl", target = "resultText")
+ Result mapSubscriptionToResult(SubscriptionEntity subscription);
+
+ List mapSubscriptionsToResults(List subscriptions);
+
+}
diff --git a/src/main/java/uk/gov/hmcts/cp/model/EventType.java b/src/main/java/uk/gov/hmcts/cp/model/EventType.java
new file mode 100644
index 00000000..0a14af77
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/model/EventType.java
@@ -0,0 +1,6 @@
+package uk.gov.hmcts.cp.model;
+
+public enum EventType {
+ PCR,
+ CUSTODIAL_RESULT
+}
diff --git a/src/main/java/uk/gov/hmcts/cp/repositories/SubscriberRepository.java b/src/main/java/uk/gov/hmcts/cp/repositories/SubscriberRepository.java
new file mode 100644
index 00000000..acf9960d
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/repositories/SubscriberRepository.java
@@ -0,0 +1,11 @@
+package uk.gov.hmcts.cp.repositories;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import uk.gov.hmcts.cp.entities.SubscriberEntity;
+
+import java.util.UUID;
+
+@Repository
+public interface SubscriberRepository extends JpaRepository {
+}
diff --git a/src/main/java/uk/gov/hmcts/cp/repositories/SubscriptionRepository.java b/src/main/java/uk/gov/hmcts/cp/repositories/SubscriptionRepository.java
new file mode 100644
index 00000000..fddb0001
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/repositories/SubscriptionRepository.java
@@ -0,0 +1,14 @@
+package uk.gov.hmcts.cp.repositories;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+
+import java.util.List;
+import java.util.UUID;
+
+@Repository
+public interface SubscriptionRepository extends JpaRepository {
+
+ List getBySubscriberId(UUID subscriberId);
+}
diff --git a/src/main/java/uk/gov/hmcts/cp/services/SubscriptionService.java b/src/main/java/uk/gov/hmcts/cp/services/SubscriptionService.java
new file mode 100644
index 00000000..6fe6c468
--- /dev/null
+++ b/src/main/java/uk/gov/hmcts/cp/services/SubscriptionService.java
@@ -0,0 +1,31 @@
+package uk.gov.hmcts.cp.services;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+import uk.gov.hmcts.cp.mappers.SubscriptionMapper;
+import uk.gov.hmcts.cp.openapi.model.Result;
+import uk.gov.hmcts.cp.repositories.SubscriptionRepository;
+
+import java.util.List;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class SubscriptionService {
+
+ private final SubscriptionRepository subscriptionRepository;
+ private final SubscriptionMapper mapper;
+
+ public Result getSubscriptionById(final UUID subscriptionId) {
+ final SubscriptionEntity entity = subscriptionRepository.getReferenceById(subscriptionId);
+ return mapper.mapSubscriptionToResult(entity);
+ }
+
+ public List getSubscriptionsBySubscriber(final UUID subscriberId) {
+ final List subscriptions = subscriptionRepository.getBySubscriberId(subscriberId);
+ return mapper.mapSubscriptionsToResults(subscriptions);
+ }
+}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
new file mode 100644
index 00000000..d09414e5
--- /dev/null
+++ b/src/main/resources/application.yaml
@@ -0,0 +1,16 @@
+server:
+ port: ${SERVER_PORT:8082}
+
+spring:
+ application:
+ name: service-hmcts-springboot-demo-postgres
+ jpa:
+ open-in-view: false
+ datasource:
+ url: ${DATASOURCE_URL:jdbc:postgresql://localhost:5432/appdb}
+ username: ${DATASOURCE_USERNAME:postgres}
+ password: ${DATASOURCE_PASSWORD:postgres}
+ flyway:
+ enabled: true
+ locations: classpath:db/migration
+ baseline-on-migrate: true
diff --git a/src/main/resources/db/migration/V1.001__initial_schema.sql b/src/main/resources/db/migration/V1.001__initial_schema.sql
new file mode 100644
index 00000000..818a931c
--- /dev/null
+++ b/src/main/resources/db/migration/V1.001__initial_schema.sql
@@ -0,0 +1,15 @@
+create table subscriber (
+ id uuid primary key not null,
+ name varchar(128) not null
+);
+create unique index on subscriber (name);
+
+create table subscription (
+ id uuid primary key not null,
+ subscriber_id uuid not null,
+ event_type varchar(32) not null,
+ notify_url text not null
+);
+
+alter table subscription
+ add constraint subscription_subscriber_id_fk foreign key (subscriber_id) references subscriber (id);
\ No newline at end of file
diff --git a/src/test/java/uk/gov/hmcts/cp/config/TestContainersInitialise.java b/src/test/java/uk/gov/hmcts/cp/config/TestContainersInitialise.java
new file mode 100644
index 00000000..abd5f99a
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/config/TestContainersInitialise.java
@@ -0,0 +1,31 @@
+package uk.gov.hmcts.cp.config;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.test.util.TestPropertyValues;
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.testcontainers.containers.PostgreSQLContainer;
+
+@Slf4j
+public class TestContainersInitialise implements ApplicationContextInitializer {
+
+ private static final PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer(
+ "postgres")
+ .withDatabaseName("postgres")
+ .withUsername("postgres")
+ .withPassword("postgres");
+
+
+ @SneakyThrows
+ @Override
+ public void initialize(ConfigurableApplicationContext applicationContext) {
+ postgreSQLContainer.start();
+ TestPropertyValues.of(
+ "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
+ "spring.datasource.username=" + postgreSQLContainer.getUsername(),
+ "spring.datasource.password=" + postgreSQLContainer.getPassword()
+ ).applyTo(applicationContext.getEnvironment());
+ }
+}
+
diff --git a/src/test/java/uk/gov/hmcts/cp/controllers/integration/IntegrationTestBase.java b/src/test/java/uk/gov/hmcts/cp/integration/IntegrationTestBase.java
similarity index 64%
rename from src/test/java/uk/gov/hmcts/cp/controllers/integration/IntegrationTestBase.java
rename to src/test/java/uk/gov/hmcts/cp/integration/IntegrationTestBase.java
index 1ffe987b..b2cb2ef8 100644
--- a/src/test/java/uk/gov/hmcts/cp/controllers/integration/IntegrationTestBase.java
+++ b/src/test/java/uk/gov/hmcts/cp/integration/IntegrationTestBase.java
@@ -1,12 +1,15 @@
-package uk.gov.hmcts.cp.controllers.integration;
+package uk.gov.hmcts.cp.integration;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
+import uk.gov.hmcts.cp.config.TestContainersInitialise;
@SpringBootTest
+@ContextConfiguration(initializers = TestContainersInitialise.class)
@AutoConfigureMockMvc
@Slf4j
public abstract class IntegrationTestBase {
diff --git a/src/test/java/uk/gov/hmcts/cp/controllers/integration/RootControllerIntegrationTest.java b/src/test/java/uk/gov/hmcts/cp/integration/RootControllerIntegrationTest.java
similarity index 89%
rename from src/test/java/uk/gov/hmcts/cp/controllers/integration/RootControllerIntegrationTest.java
rename to src/test/java/uk/gov/hmcts/cp/integration/RootControllerIntegrationTest.java
index 8ae04ed5..8cb2cd84 100644
--- a/src/test/java/uk/gov/hmcts/cp/controllers/integration/RootControllerIntegrationTest.java
+++ b/src/test/java/uk/gov/hmcts/cp/integration/RootControllerIntegrationTest.java
@@ -1,4 +1,4 @@
-package uk.gov.hmcts.cp.controllers.integration;
+package uk.gov.hmcts.cp.integration;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/uk/gov/hmcts/cp/mappers/SubscriptionMapperTest.java b/src/test/java/uk/gov/hmcts/cp/mappers/SubscriptionMapperTest.java
new file mode 100644
index 00000000..2f103fd7
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/mappers/SubscriptionMapperTest.java
@@ -0,0 +1,28 @@
+package uk.gov.hmcts.cp.mappers;
+
+import org.junit.jupiter.api.Test;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+import uk.gov.hmcts.cp.openapi.model.Result;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SubscriptionMapperTest {
+
+ SubscriptionMapper mapper = new SubscriptionMapperImpl();
+
+ @Test
+ void single_subscription_should_map_to_response() {
+ SubscriptionEntity subscription = SubscriptionEntity.builder().notifyUrl("https://example").build();
+ Result result = mapper.mapSubscriptionToResult(subscription);
+ assertThat(result.getResultText()).isEqualTo("https://example");
+ }
+
+ @Test
+ void list_of_subscriptions_should_map_to_response() {
+ SubscriptionEntity subscription = SubscriptionEntity.builder().notifyUrl("https://example").build();
+ List results = mapper.mapSubscriptionsToResults(List.of(subscription));
+ assertThat(results).hasSize(1);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/hmcts/cp/repositories/RepositoryTestBase.java b/src/test/java/uk/gov/hmcts/cp/repositories/RepositoryTestBase.java
new file mode 100644
index 00000000..bdfb3cc7
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/repositories/RepositoryTestBase.java
@@ -0,0 +1,50 @@
+package uk.gov.hmcts.cp.repositories;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.test.context.ContextConfiguration;
+import uk.gov.hmcts.cp.config.TestContainersInitialise;
+import uk.gov.hmcts.cp.entities.SubscriberEntity;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+import uk.gov.hmcts.cp.model.EventType;
+
+import java.util.UUID;
+
+@SpringBootTest
+@ContextConfiguration(initializers = TestContainersInitialise.class)
+@AutoConfigureMockMvc
+@Slf4j
+public abstract class RepositoryTestBase {
+
+ @Autowired
+ protected SubscriberRepository subscriberRepository;
+
+ @Autowired
+ protected SubscriptionRepository subscriptionRepository;
+
+ protected void clearAllTables() {
+ log.info("Clearing all tables");
+ subscriptionRepository.deleteAll();
+ subscriberRepository.deleteAll();
+ }
+
+ protected SubscriberEntity insertSubscriber(String name) {
+ SubscriberEntity subscriber = SubscriberEntity.builder().name(name).build();
+ SubscriberEntity saved = subscriberRepository.save(subscriber);
+ log.info("Inserted subscriber:{}", saved.getId());
+ return saved;
+ }
+
+ protected SubscriptionEntity insertSubscription(UUID subscriberId) {
+ SubscriptionEntity subscription = SubscriptionEntity.builder()
+ .subscriberId(subscriberId)
+ .eventType(EventType.PCR)
+ .notifyUrl("https://example.com/notify")
+ .build();
+ SubscriptionEntity saved = subscriptionRepository.save(subscription);
+ log.info("Inserted subscription:{}", saved.getId());
+ return saved;
+ }
+}
diff --git a/src/test/java/uk/gov/hmcts/cp/repositories/SubscriberRepositoryTest.java b/src/test/java/uk/gov/hmcts/cp/repositories/SubscriberRepositoryTest.java
new file mode 100644
index 00000000..da9f2ba3
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/repositories/SubscriberRepositoryTest.java
@@ -0,0 +1,26 @@
+package uk.gov.hmcts.cp.repositories;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import uk.gov.hmcts.cp.entities.SubscriberEntity;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SubscriberRepositoryTest extends RepositoryTestBase {
+
+ @BeforeEach
+ void beforeEach() {
+ clearAllTables();
+ }
+
+ @Test
+ void subscriber_should_save_and_read_ok() {
+ insertSubscriber("My subscriber");
+ List subscribers = subscriberRepository.findAll();
+ assertThat(subscribers).hasSize(1);
+ assertThat(subscribers.get(0).getId()).isNotNull();
+ assertThat(subscribers.get(0).getName()).isEqualTo("My subscriber");
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/hmcts/cp/repositories/SubscriptionRepositoryTest.java b/src/test/java/uk/gov/hmcts/cp/repositories/SubscriptionRepositoryTest.java
new file mode 100644
index 00000000..7df673b5
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/repositories/SubscriptionRepositoryTest.java
@@ -0,0 +1,46 @@
+package uk.gov.hmcts.cp.repositories;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import uk.gov.hmcts.cp.entities.SubscriberEntity;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static uk.gov.hmcts.cp.model.EventType.PCR;
+
+class SubscriptionRepositoryTest extends RepositoryTestBase {
+
+ @BeforeEach
+ void beforeEach() {
+ clearAllTables();
+ }
+
+ @Test
+ void subscription_should_save_and_read_ok() {
+ SubscriberEntity subscriber = insertSubscriber("My subscriber");
+ insertSubscription(subscriber.getId());
+ List subscriptions = subscriptionRepository.findAll();
+ assertThat(subscriptions).hasSize(1);
+ assertThat(subscriptions.get(0).getId()).isNotNull();
+ assertThat(subscriptions.get(0).getEventType()).isEqualTo(PCR);
+ assertThat(subscriptions.get(0).getNotifyUrl()).isEqualTo("https://example.com/notify");
+ }
+
+ @Test
+ void fk_constraint_should_prevent_orphaned_subscription() {
+ UUID randomSubscriptionId = UUID.randomUUID();
+ assertThrows(Exception.class, () -> insertSubscription(randomSubscriptionId));
+ }
+
+ @Test
+ void query_by_subscriber_id_should_return_subscription_list() {
+ SubscriberEntity subscriber = insertSubscriber("My subscriber");
+ insertSubscription(subscriber.getId());
+ List subscriptions = subscriptionRepository.getBySubscriberId(subscriber.getId());
+ assertThat(subscriptions).hasSize(1);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/hmcts/cp/services/SubscriptionServiceTest.java b/src/test/java/uk/gov/hmcts/cp/services/SubscriptionServiceTest.java
new file mode 100644
index 00000000..0e4460e3
--- /dev/null
+++ b/src/test/java/uk/gov/hmcts/cp/services/SubscriptionServiceTest.java
@@ -0,0 +1,51 @@
+package uk.gov.hmcts.cp.services;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+import uk.gov.hmcts.cp.entities.SubscriptionEntity;
+import uk.gov.hmcts.cp.mappers.SubscriptionMapper;
+import uk.gov.hmcts.cp.mappers.SubscriptionMapperImpl;
+import uk.gov.hmcts.cp.openapi.model.Result;
+import uk.gov.hmcts.cp.repositories.SubscriptionRepository;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class SubscriptionServiceTest {
+
+ @Mock
+ SubscriptionRepository subscriptionRepository;
+ @Spy
+ SubscriptionMapper mapper = new SubscriptionMapperImpl();
+
+ @InjectMocks
+ SubscriptionService subscriptionService;
+
+ SubscriptionEntity subscriptionEntity = SubscriptionEntity.builder().notifyUrl("url").build();
+
+ UUID subscriberId = UUID.fromString("2413d0fd-8a75-4fb6-828d-1a1fb7ae7290");
+ UUID subscriptionId = UUID.fromString("ee2e6e17-7c37-45ec-a1d4-4023500fb90d");
+
+ @Test
+ void get_single_subscription_should_return_single() {
+ when(subscriptionRepository.getReferenceById(subscriptionId)).thenReturn(subscriptionEntity);
+ Result response = subscriptionService.getSubscriptionById(subscriptionId);
+ assertThat(response.getResultText()).isEqualTo("url");
+ }
+
+ @Test
+ void get_subscription_by_subscriber_id_should_return() {
+ when(subscriptionRepository.getBySubscriberId(subscriberId)).thenReturn(List.of(subscriptionEntity));
+ List response = subscriptionService.getSubscriptionsBySubscriber(subscriberId);
+ assertThat(response).hasSize(1);
+ assertThat(response.get(0).getResultText()).isEqualTo("url");
+ }
+}
\ No newline at end of file