From 5e9c78eb169be88bcda22f854251214241f0ef58 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Fri, 10 Jan 2025 14:17:49 +0530 Subject: [PATCH] feat : adds post validation test (#1632) * feat : adds post validation test * enhance test * fix : issue with inserting of initial data * fix issue with setting status * adds mising import * adds not blank constraint * adds more tests --- .../jooq/r2dbc/config/Initializer.java | 14 +++++++-- .../jooq/r2dbc/service/PostService.java | 8 +++-- .../db/migration/postgresql/V1__01_init.sql | 23 +++++++++++++-- .../r2dbc/repository/PostRepositoryTest.java | 29 +++++++++++++++++++ 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/Initializer.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/Initializer.java index d70fdcd48..9077d6ec6 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/Initializer.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/Initializer.java @@ -6,6 +6,7 @@ import static com.example.jooq.r2dbc.testcontainersflyway.db.tables.Tags.TAGS; import com.example.jooq.r2dbc.config.logging.Loggable; +import com.example.jooq.r2dbc.model.Status; import com.example.jooq.r2dbc.repository.PostRepository; import com.example.jooq.r2dbc.testcontainersflyway.db.tables.records.PostCommentsRecord; import com.example.jooq.r2dbc.testcontainersflyway.db.tables.records.PostsRecord; @@ -43,15 +44,22 @@ public void run(String... args) { DeleteUsingStep postsRecordDeleteUsingStep = dslContext.deleteFrom(POSTS); Mono.from(postsTagsRecordDeleteUsingStep) + .doOnError(e -> log.error("Failed to delete posts_tags", e)) .then(Mono.from(tagsRecordDeleteUsingStep)) + .doOnError(e -> log.error("Failed to delete tags", e)) .then(Mono.from(postCommentsRecordDeleteUsingStep)) + .doOnError(e -> log.error("Failed to delete post_comments", e)) .then(Mono.from(postsRecordDeleteUsingStep)) + .doOnError(e -> log.error("Failed to delete posts", e)) .then( Mono.from( dslContext .insertInto(POSTS) - .columns(POSTS.TITLE, POSTS.CONTENT) - .values("jooq test", "content of Jooq test") + .columns(POSTS.TITLE, POSTS.CONTENT, POSTS.STATUS) + .values( + "jooq test", + "content of Jooq test", + Status.PUBLISHED.name()) .returningResult(POSTS.ID))) .flatMap( postId -> @@ -94,7 +102,7 @@ public void run(String... args) { .subscribe( data -> log.debug("Retrieved data: {}", data), error -> - log.debug("Failed to retrieve posts with comments and tags", error), + log.error("Failed to retrieve posts with comments and tags", error), () -> log.debug("done")); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java index 4e9794522..8d6df373e 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java @@ -8,6 +8,7 @@ import static org.jooq.impl.DSL.select; import com.example.jooq.r2dbc.entities.Post; +import com.example.jooq.r2dbc.model.Status; import com.example.jooq.r2dbc.model.request.CreatePostCommand; import com.example.jooq.r2dbc.model.request.CreatePostComment; import com.example.jooq.r2dbc.model.response.PaginatedResult; @@ -70,8 +71,11 @@ public Mono create(CreatePostCommand createPostCommand) { var createPostSQL = dslContext .insertInto(POSTS) - .columns(POSTS.TITLE, POSTS.CONTENT) - .values(createPostCommand.title(), createPostCommand.content()) + .columns(POSTS.TITLE, POSTS.CONTENT, POSTS.STATUS) + .values( + createPostCommand.title(), + createPostCommand.content(), + Status.DRAFT.name()) .returningResult(POSTS.ID); return Flux.fromIterable(createPostCommand.tagName()) diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/db/migration/postgresql/V1__01_init.sql b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/db/migration/postgresql/V1__01_init.sql index 8ce2f4151..8016bfe1a 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/db/migration/postgresql/V1__01_init.sql +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/db/migration/postgresql/V1__01_init.sql @@ -5,9 +5,9 @@ CREATE TABLE posts( id uuid NOT NULL DEFAULT uuid_generate_v4(), - title text, - content text, - status text, + title text NOT NULL, + content text NOT NULL, + status text NOT NULL, created_at timestamptz DEFAULT NOW(), created_by text, updated_at timestamptz, @@ -47,3 +47,20 @@ CREATE tag_id ) ); + +ALTER TABLE + posts ADD CONSTRAINT check_title_not_blank CHECK( + LENGTH( + TRIM( title ) + )> 0 + ), + ADD CONSTRAINT check_content_not_blank CHECK( + LENGTH( + TRIM( content ) + )> 0 + ), + ADD CONSTRAINT check_status_not_blank CHECK( + LENGTH( + TRIM( status ) + )> 0 + ); \ No newline at end of file diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/repository/PostRepositoryTest.java b/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/repository/PostRepositoryTest.java index 4188a64e0..24f611e30 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/repository/PostRepositoryTest.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/repository/PostRepositoryTest.java @@ -18,8 +18,12 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.UUID; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest; import org.springframework.context.annotation.Import; @@ -204,6 +208,31 @@ void testOptimisticLockingOnConcurrentPostUpdates() { .verify(); } + @ParameterizedTest + @MethodSource("invalidPostProvider") + void testInsertPostWithInvalidDataShouldFail( + String title, String content, Status status, String expectedError) { + StepVerifier.create( + postRepository.save( + new Post().setTitle(title).setContent(content).setStatus(status))) + .expectErrorMatches( + throwable -> + throwable instanceof DataIntegrityViolationException + && throwable.getMessage().contains(expectedError)) + .verify(); + } + + private static Stream invalidPostProvider() { + return Stream.of( + Arguments.of(null, "content", Status.DRAFT, "title"), + Arguments.of("", "content", Status.DRAFT, "title"), + Arguments.of(" ", "content", Status.DRAFT, "title"), + Arguments.of("title", "content", null, "status"), + Arguments.of("title", "", Status.DRAFT, "content"), + Arguments.of("title", " ", Status.DRAFT, "content"), + Arguments.of("title", null, Status.DRAFT, "content")); + } + private Mono createPost() { return postRepository.save( new Post().setTitle("jooq test").setContent("content of Jooq test"));