diff --git a/cookiecutter.json b/cookiecutter.json index c1dfb38..df9ab44 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -3,8 +3,10 @@ "app_title": "{{cookiecutter.app_name.capitalize()}}", "domain": "{{cookiecutter.domain}}", "domain_capitalized": "{{cookiecutter.domain.capitalize()}}", + "domain_uppercase": "{{cookiecutter.domain.upper()}}", "domain_plural": "{%- if cookiecutter.app_name.endswith('y') -%}{{cookiecutter.domain.replace('y','')}}ies{% else %}{{cookiecutter.domain.lower()}}s{% endif %}", "domain_plural_capitalized": "{{cookiecutter.domain_plural.capitalize()}}", + "domain_plural_uppercase": "{{cookiecutter.domain_plural.upper()}}", "group_id": "org.{{cookiecutter.domain}}", "artifact_id": "{{cookiecutter.domain}}", "package_name": "{{cookiecutter.domain}}" diff --git a/{{cookiecutter.app_name}}/jpa-adapter/pom.xml b/{{cookiecutter.app_name}}/jpa-adapter/pom.xml new file mode 100644 index 0000000..4053b6a --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/pom.xml @@ -0,0 +1,77 @@ + + + + {{cookiecutter.group_id}} + {{cookiecutter.artifact_id}}-parent + 1.0-SNAPSHOT + + 4.0.0 + jpa-adapter + + + + {{cookiecutter.group_id}} + domain-api + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.liquibase + liquibase-core + + + org.springframework.data + spring-data-envers + + + org.postgresql + postgresql + + + net.lbruun.springboot + preliquibase-spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + com.h2database + h2 + test + + + + + + com.societegenerale.commons + arch-unit-maven-plugin + + + + com.societegenerale.commons.plugin.rules.NoJunitAssertRuleTest + com.societegenerale.commons.plugin.rules.NoPowerMockRuleTest + com.societegenerale.commons.plugin.rules.NoTestIgnoreRuleTest + com.societegenerale.commons.plugin.rules.NoTestIgnoreWithoutCommentRuleTest + + com.societegenerale.commons.plugin.rules.NoStandardStreamRuleTest + com.societegenerale.commons.plugin.rules.NoJodaTimeRuleTest + com.societegenerale.commons.plugin.rules.NoJavaUtilDateRuleTest + com.societegenerale.commons.plugin.rules.NoPrefixForInterfacesRuleTest + com.societegenerale.commons.plugin.rules.NoPublicFieldRuleTest + com.societegenerale.commons.plugin.rules.NoInjectedFieldTest + com.societegenerale.commons.plugin.rules.NoAutowiredFieldTest + + + + + + + diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/config/JpaAdapterConfig.java b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/config/JpaAdapterConfig.java new file mode 100644 index 0000000..4f172be --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/config/JpaAdapterConfig.java @@ -0,0 +1,23 @@ +package {{cookiecutter.package_name}}.repository.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import {{cookiecutter.package_name}}.domain.port.Obtain{{cookiecutter.domain_capitalized}}; +import {{cookiecutter.package_name}}.repository.{{cookiecutter.domain_capitalized}}Repository; +import {{cookiecutter.package_name}}.repository.dao.{{cookiecutter.domain_capitalized}}Dao; + +@Configuration +@EntityScan("{{cookiecutter.package_name}}.repository.entity") +@EnableJpaRepositories( + basePackages = "{{cookiecutter.package_name}}.repository.dao", + repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class) +public class JpaAdapterConfig { + + @Bean + public Obtain{{cookiecutter.domain_capitalized}} get{{cookiecutter.domain_capitalized}}Repository({{cookiecutter.domain_capitalized}}Dao {{cookiecutter.domain}}Dao) { + return new {{cookiecutter.domain_capitalized}}Repository({{cookiecutter.domain}}Dao); + } +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/dao/{{cookiecutter.domain_capitalized}}Dao.java b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/dao/{{cookiecutter.domain_capitalized}}Dao.java new file mode 100644 index 0000000..5a71255 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/dao/{{cookiecutter.domain_capitalized}}Dao.java @@ -0,0 +1,14 @@ +package {{cookiecutter.package_name}}.repository.dao; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.history.RevisionRepository; +import org.springframework.stereotype.Repository; +import {{cookiecutter.package_name}}.repository.entity.{{cookiecutter.domain_capitalized}}Entity; + +@Repository +public interface {{cookiecutter.domain_capitalized}}Dao + extends JpaRepository<{{cookiecutter.domain_capitalized}}Entity, Long>, RevisionRepository<{{cookiecutter.domain_capitalized}}Entity, Long, Long> { + + Optional<{{cookiecutter.domain_capitalized}}Entity> findByCode(Long code); +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/EnversRevisionEntity.java b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/EnversRevisionEntity.java new file mode 100644 index 0000000..6af7556 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/EnversRevisionEntity.java @@ -0,0 +1,34 @@ +package {{cookiecutter.package_name}}.repository.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Table(name = "REVISION_INFO", schema = "{{cookiecutter.domain_uppercase}}_AUDIT") +@Entity +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@SequenceGenerator( + schema = "{{cookiecutter.domain_uppercase}}_AUDIT", + name = "SEQ_REVISION_INFO", + sequenceName = "{{cookiecutter.domain_uppercase}}_AUDIT.SEQ_REVISION_INFO", + allocationSize = 1) +public class EnversRevisionEntity { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_REVISION_INFO") + @Column(name = "REV") + private Long rev; + + @Column(name = "TIMESTAMP") + private Long code; +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/{{cookiecutter.domain_capitalized}}Entity.java b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/{{cookiecutter.domain_capitalized}}Entity.java new file mode 100644 index 0000000..3c1d673 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/entity/{{cookiecutter.domain_capitalized}}Entity.java @@ -0,0 +1,45 @@ +package {{cookiecutter.package_name}}.repository.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.envers.Audited; +import {{cookiecutter.package_name}}.domain.model.{{cookiecutter.domain_capitalized}}; + +@Table(name = "T_{{cookiecutter.domain_uppercase}}") +@Entity +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Audited +public class {{cookiecutter.domain_capitalized}}Entity { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_T_{{cookiecutter.domain_uppercase}}") + @SequenceGenerator( + name = "SEQ_T_{{cookiecutter.domain_uppercase}}", + sequenceName = "SEQ_T_{{cookiecutter.domain_uppercase}}", + allocationSize = 1, + initialValue = 1) + @Column(name = "TECH_ID") + private Long techId; + + @Column(name = "CODE") + private Long code; + + @Column(name = "DESCRIPTION") + private String description; + + public {{cookiecutter.domain_capitalized}} toModel() { + return {{cookiecutter.domain_capitalized}}.builder().code(code).description(description).build(); + } +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}Repository.java b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}Repository.java new file mode 100644 index 0000000..a9084cf --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}Repository.java @@ -0,0 +1,29 @@ +package {{cookiecutter.package_name}}.repository; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import {{cookiecutter.package_name}}.domain.model.{{cookiecutter.domain_capitalized}}; +import {{cookiecutter.package_name}}.domain.port.Obtain{{cookiecutter.domain_capitalized}}; +import {{cookiecutter.package_name}}.repository.dao.{{cookiecutter.domain_capitalized}}Dao; +import {{cookiecutter.package_name}}.repository.entity.{{cookiecutter.domain_capitalized}}Entity; + +public class {{cookiecutter.domain_capitalized}}Repository implements Obtain{{cookiecutter.domain_capitalized}} { + + private final {{cookiecutter.domain_capitalized}}Dao {{cookiecutter.domain}}Dao; + + public {{cookiecutter.domain_capitalized}}Repository({{cookiecutter.domain_capitalized}}Dao {{cookiecutter.domain}}Dao) { + this.{{cookiecutter.domain}}Dao = {{cookiecutter.domain}}Dao; + } + + @Override + public List<{{cookiecutter.domain_capitalized}}> getAll{{cookiecutter.domain_plural_capitalized}}() { + return {{cookiecutter.domain}}Dao.findAll().stream().map({{cookiecutter.domain_capitalized}}Entity::toModel).collect(Collectors.toList()); + } + + @Override + public Optional<{{cookiecutter.domain_capitalized}}> get{{cookiecutter.domain_capitalized}}ByCode(Long code) { + var {{cookiecutter.domain}}Entity = {{cookiecutter.domain}}Dao.findByCode(code); + return {{cookiecutter.domain}}Entity.map({{cookiecutter.domain_capitalized}}Entity::toModel); + } +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/application.yaml b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/application.yaml new file mode 100644 index 0000000..ce5094b --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/application.yaml @@ -0,0 +1,27 @@ +spring: + datasource: + driver-class-name: ${database.driver-class-name:org.postgresql.Driver} + url: ${database.url} + username: ${database.username} + password: ${database.password} + jpa: + generate-ddl: false + hibernate: + ddl-auto: none + database-platform: org.hibernate.dialect.PostgreSQLDialect + show-sql: ${database.show_sql:false} + properties: + hibernate: + default_schema: ${database.default_schema:{{cookiecutter.domain_uppercase}}} + show_sql: ${database.show_sql:false} + use_sql_comments: ${database.use_sql_comments:false} + format_sql: ${database.format_sql:false} + org: + hibernate: + envers: + default_schema: ${database.default_audit_schema:{{cookiecutter.domain_uppercase}}_AUDIT} + store_data_at_delete: true + liquibase: + enabled: true + liquibase-schema: ${database.liquibase_schema:LIQUIBASE} + default-schema: ${database.default_schema:{{cookiecutter.domain_uppercase}}} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/db.changelog-master.yaml b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/db.changelog-master.yaml new file mode 100644 index 0000000..859d7d1 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/db.changelog-master.yaml @@ -0,0 +1,5 @@ +databaseChangeLog: + - include: + file: db/changelog/includes/240720211408009-create-revision.yaml + - include: + file: db/changelog/includes/110720212155010-create-{{cookiecutter.domain}}.yaml \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/110720212155010-create-{{cookiecutter.domain}}.yaml b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/110720212155010-create-{{cookiecutter.domain}}.yaml new file mode 100644 index 0000000..34ec4de --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/110720212155010-create-{{cookiecutter.domain}}.yaml @@ -0,0 +1,77 @@ +databaseChangeLog: + - changeSet: + id: create-table-t_{{cookiecutter.domain}} + author: Paul WILLIAMS + changes: + - createTable: + tableName: T_{{cookiecutter.domain_uppercase}} + columns: + - column: + name: TECH_ID + type: BIGINT + constraints: + primaryKey: true + nullable: false + - column: + name: CODE + type: BIGINT + constraints: + nullable: false + - column: + name: DESCRIPTION + type: VARCHAR(255) + constraints: + nullable: false + createSequence: + sequenceName: SEQ_T_{{cookiecutter.domain_uppercase}} + startValue: 1 + incrementBy: 1 + rollback: + - dropSequence: + sequenceName: SEQ_T_{{cookiecutter.domain_uppercase}} + - dropTable: + tableName: T_{{cookiecutter.domain_uppercase}} + - changeSet: + id: create-table-t_{{cookiecutter.domain}}_aud + author: Paul WILLIAMS + changes: + - createTable: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + tableName: T_{{cookiecutter.domain_uppercase}}_AUD + columns: + - column: + name: TECH_ID + type: BIGINT + constraints: + nullable: false + - column: + name: CODE + type: BIGINT + constraints: + nullable: false + - column: + name: DESCRIPTION + type: VARCHAR(255) + constraints: + nullable: false + - column: + name: REV + type: BIGINT + constraints: + nullable: false + foreignKeyName: FK_T_{{cookiecutter.domain_uppercase}}_AUD_REV + references: {{cookiecutter.domain_uppercase}}_AUDIT.REVINFO(REV) + - column: + name: REVTYPE + type: INTEGER + constraints: + nullable: false + - addPrimaryKey: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + tableName: T_{{cookiecutter.domain_uppercase}}_AUD + columnNames: TECH_ID, REV + rollback: + - dropTable: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + tableName: T_{{cookiecutter.domain_uppercase}}_AUD + cascadeConstraints: true diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/240720211408009-create-revision.yaml b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/240720211408009-create-revision.yaml new file mode 100644 index 0000000..3a599a3 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/db/changelog/includes/240720211408009-create-revision.yaml @@ -0,0 +1,34 @@ +databaseChangeLog: + - changeSet: + id: create-table-t_{{cookiecutter.domain}}_audit + author: Anup Baranwal + changes: + - createTable: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + tableName: REVINFO + columns: + - column: + name: REV + type: BIGINT + constraints: + primaryKey: true + nullable: false + autoIncrement: true + - column: + name: REVTSTMP + type: BIGINT + constraints: + nullable: false + createSequence: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + sequenceName: SEQ_REVISION_INFO + startValue: 1 + incrementBy: 1 + rollback: + - dropTable: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + tableName: REVINFO + cascadeConstraints: true + - dropSequence: + schemaName: {{cookiecutter.domain_uppercase}}_AUDIT + sequenceName: SEQ_REVISION_INFO \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/preliquibase/default.sql b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/preliquibase/default.sql new file mode 100644 index 0000000..e2af544 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/main/resources/preliquibase/default.sql @@ -0,0 +1,3 @@ +CREATE SCHEMA IF NOT EXISTS ${spring.liquibase.liquibase-schema:LIQUIBASE}; +CREATE SCHEMA IF NOT EXISTS ${spring.liquibase.default-schema:{{cookiecutter.domain_uppercase}}}; +CREATE SCHEMA IF NOT EXISTS ${spring.jpa.properties.org.hibernate.envers:{{cookiecutter.domain_uppercase}}_AUDIT}; \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaAdapterApplication.java b/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaAdapterApplication.java new file mode 100644 index 0000000..501370c --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaAdapterApplication.java @@ -0,0 +1,22 @@ +package {{cookiecutter.package_name}}.repository; + +import net.lbruun.springboot.preliquibase.PreLiquibaseAutoConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Import; +import {{cookiecutter.package_name}}.repository.config.JpaAdapterConfig; + +@SpringBootApplication +public class {{cookiecutter.domain_capitalized}}JpaAdapterApplication { + + public static void main(String[] args) { + SpringApplication.run({{cookiecutter.domain_capitalized}}JpaAdapterApplication.class, args); + } + + @TestConfiguration + @Import(JpaAdapterConfig.class) + @ImportAutoConfiguration({PreLiquibaseAutoConfiguration.class}) + static class {{cookiecutter.domain_capitalized}}JpaTestConfig {} +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaTest.java b/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaTest.java new file mode 100644 index 0000000..1104973 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/test/java/{{cookiecutter.package_name}}/repository/{{cookiecutter.domain_capitalized}}JpaTest.java @@ -0,0 +1,80 @@ +package {{cookiecutter.package_name}}.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import {{cookiecutter.package_name}}.domain.model.{{cookiecutter.domain_capitalized}}; +import {{cookiecutter.package_name}}.domain.port.Obtain{{cookiecutter.domain_capitalized}}; + +@ExtendWith(SpringExtension.class) +@DataJpaTest +@ActiveProfiles("test") +public class {{cookiecutter.domain_capitalized}}JpaTest { + + @Autowired private Obtain{{cookiecutter.domain_capitalized}} obtain{{cookiecutter.domain_capitalized}}; + + @Test + @DisplayName("should start the application") + public void startup() { + assertThat(Boolean.TRUE).isTrue(); + } + + @Sql(scripts = {"/sql/data.sql"}) + @Test + @DisplayName( + "given {{cookiecutter.domain_plural}} exist in database when asked should return all {{cookiecutter.domain_plural}} from database") + public void shouldGiveMe{{cookiecutter.domain_plural_capitalized}}WhenAskedGiven{{cookiecutter.domain_capitalized}}ExistsInDatabase() { + // Given from @Sql + // When + var {{cookiecutter.domain_plural}} = obtain{{cookiecutter.domain_capitalized}}.getAll{{cookiecutter.domain_plural_capitalized}}(); + // Then + assertThat({{cookiecutter.domain_plural}}) + .isNotNull() + .extracting("description") + .contains("Twinkle twinkle little star"); + } + + @Test + @DisplayName("given no {{cookiecutter.domain_plural}} exists in database when asked should return empty") + public void shouldGiveNo{{cookiecutter.domain_capitalized}}WhenAskedGiven{{cookiecutter.domain_plural_capitalized}}DoNotExistInDatabase() { + // When + var {{cookiecutter.domain_plural}} = obtain{{cookiecutter.domain_capitalized}}.getAll{{cookiecutter.domain_plural_capitalized}}(); + // Then + assertThat({{cookiecutter.domain_plural}}).isNotNull().isEmpty(); + } + + @Sql(scripts = {"/sql/data.sql"}) + @Test + @DisplayName( + "given {{cookiecutter.domain_plural}} exists in database when asked for {{cookiecutter.domain}} by id should return the {{cookiecutter.domain}}") + public void shouldGiveThe{{cookiecutter.domain_capitalized}}WhenAskedByIdGivenThat{{cookiecutter.domain_capitalized}}ByThatIdExistsInDatabase() { + // Given from @Sql + // When + var {{cookiecutter.domain}} = obtain{{cookiecutter.domain_capitalized}}.get{{cookiecutter.domain_capitalized}}ByCode(1L); + // Then + assertThat({{cookiecutter.domain}}) + .isNotNull() + .isNotEmpty() + .get() + .isEqualTo({{cookiecutter.domain_capitalized}}.builder().code(1L).description("Twinkle twinkle little star").build()); + } + + @Sql(scripts = {"/sql/data.sql"}) + @Test + @DisplayName( + "given {{cookiecutter.domain_plural}} exists in database when asked for {{cookiecutter.domain}} by id that does not exist should give empty") + public void shouldGiveNo{{cookiecutter.domain_capitalized}}WhenAskedByIdGivenThat{{cookiecutter.domain_capitalized}}ByThatIdDoesNotExistInDatabase() { + // Given from @Sql + // When + var {{cookiecutter.domain}} = obtain{{cookiecutter.domain_capitalized}}.get{{cookiecutter.domain_capitalized}}ByCode(-1000L); + // Then + assertThat({{cookiecutter.domain}}).isEmpty(); + } +} diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/application-test.yml b/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/application-test.yml new file mode 100644 index 0000000..5ed6901 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/application-test.yml @@ -0,0 +1,5 @@ +database: + url: jdbc:h2:mem:testdb;MODE=PostgreSQL; + driver-class-name: org.h2.Driver + username: '' + password: '' \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/sql/data.sql b/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/sql/data.sql new file mode 100644 index 0000000..82645a2 --- /dev/null +++ b/{{cookiecutter.app_name}}/jpa-adapter/src/test/resources/sql/data.sql @@ -0,0 +1,2 @@ +INSERT INTO {{cookiecutter.domain_uppercase}}.T_{{cookiecutter.domain_uppercase}}(TECH_ID, CODE, DESCRIPTION) VALUES +(1000, 1, 'Twinkle twinkle little star'); \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/pom.xml b/{{cookiecutter.app_name}}/pom.xml index af650ec..bf39b5e 100644 --- a/{{cookiecutter.app_name}}/pom.xml +++ b/{{cookiecutter.app_name}}/pom.xml @@ -36,8 +36,8 @@ domain-api domain - @@ -54,7 +54,17 @@ domain ${project.version} + + packagename + jpa-adapter + ${project.version} + + + net.lbruun.springboot + preliquibase-spring-boot-starter + ${pre-liquibase.version} + org.junit junit-bom