From dd991f6fb1379a0160510ff892d5d8fd41a0c6f9 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 19:56:18 +0000 Subject: [PATCH] Add comprehensive unit tests for core and application layers Add 12 new test files and extend existing ArticleTest with tests for: - Core: User, Comment, Tag, FollowRelation, ArticleFavorite, AuthorizationService - Application: Util, Page, CursorPageParameter, CursorPager, DateTimeCursor - Service: ArticleCommandService (with mocked repository) Tests cover constructors, equality, edge cases, and error conditions. Co-Authored-By: unknown <> --- src/test/java/io/spring/UtilTest.java | 29 ++++ .../application/CursorPageParameterTest.java | 77 +++++++++++ .../spring/application/CursorPagerTest.java | 110 +++++++++++++++ .../application/DateTimeCursorTest.java | 55 ++++++++ .../java/io/spring/application/PageTest.java | 60 ++++++++ .../article/ArticleCommandServiceTest.java | 109 +++++++++++++++ .../io/spring/core/article/ArticleTest.java | 120 ++++++++++++++++ .../java/io/spring/core/article/TagTest.java | 44 ++++++ .../io/spring/core/comment/CommentTest.java | 39 ++++++ .../core/favorite/ArticleFavoriteTest.java | 42 ++++++ .../service/AuthorizationServiceTest.java | 64 +++++++++ .../spring/core/user/FollowRelationTest.java | 42 ++++++ .../java/io/spring/core/user/UserTest.java | 129 ++++++++++++++++++ .../service/DefaultJwtServiceTest.java | 3 +- 14 files changed, 922 insertions(+), 1 deletion(-) create mode 100644 src/test/java/io/spring/UtilTest.java create mode 100644 src/test/java/io/spring/application/CursorPageParameterTest.java create mode 100644 src/test/java/io/spring/application/CursorPagerTest.java create mode 100644 src/test/java/io/spring/application/DateTimeCursorTest.java create mode 100644 src/test/java/io/spring/application/PageTest.java create mode 100644 src/test/java/io/spring/application/article/ArticleCommandServiceTest.java create mode 100644 src/test/java/io/spring/core/article/TagTest.java create mode 100644 src/test/java/io/spring/core/comment/CommentTest.java create mode 100644 src/test/java/io/spring/core/favorite/ArticleFavoriteTest.java create mode 100644 src/test/java/io/spring/core/service/AuthorizationServiceTest.java create mode 100644 src/test/java/io/spring/core/user/FollowRelationTest.java create mode 100644 src/test/java/io/spring/core/user/UserTest.java diff --git a/src/test/java/io/spring/UtilTest.java b/src/test/java/io/spring/UtilTest.java new file mode 100644 index 000000000..b92ebde81 --- /dev/null +++ b/src/test/java/io/spring/UtilTest.java @@ -0,0 +1,29 @@ +package io.spring; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class UtilTest { + + @Test + public void should_return_true_for_null() { + assertThat(Util.isEmpty(null), is(true)); + } + + @Test + public void should_return_true_for_empty_string() { + assertThat(Util.isEmpty(""), is(true)); + } + + @Test + public void should_return_false_for_non_empty_string() { + assertThat(Util.isEmpty("hello"), is(false)); + } + + @Test + public void should_return_false_for_whitespace_string() { + assertThat(Util.isEmpty(" "), is(false)); + } +} diff --git a/src/test/java/io/spring/application/CursorPageParameterTest.java b/src/test/java/io/spring/application/CursorPageParameterTest.java new file mode 100644 index 000000000..8084ed113 --- /dev/null +++ b/src/test/java/io/spring/application/CursorPageParameterTest.java @@ -0,0 +1,77 @@ +package io.spring.application; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class CursorPageParameterTest { + + @Test + public void should_create_with_valid_parameters() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 10, CursorPager.Direction.NEXT); + + assertThat(param.getCursor(), is("cursor")); + assertThat(param.getLimit(), is(10)); + assertThat(param.getDirection(), is(CursorPager.Direction.NEXT)); + } + + @Test + public void should_return_true_for_next_direction() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 10, CursorPager.Direction.NEXT); + + assertThat(param.isNext(), is(true)); + } + + @Test + public void should_return_false_for_prev_direction() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 10, CursorPager.Direction.PREV); + + assertThat(param.isNext(), is(false)); + } + + @Test + public void should_return_query_limit_as_limit_plus_one() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 10, CursorPager.Direction.NEXT); + + assertThat(param.getQueryLimit(), is(11)); + } + + @Test + public void should_cap_limit_at_max() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 2000, CursorPager.Direction.NEXT); + + assertThat(param.getLimit(), is(1000)); + assertThat(param.getQueryLimit(), is(1001)); + } + + @Test + public void should_ignore_negative_limit() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", -5, CursorPager.Direction.NEXT); + + assertThat(param.getLimit(), is(20)); + } + + @Test + public void should_ignore_zero_limit() { + CursorPageParameter param = + new CursorPageParameter<>("cursor", 0, CursorPager.Direction.NEXT); + + assertThat(param.getLimit(), is(20)); + } + + @Test + public void should_accept_null_cursor() { + CursorPageParameter param = + new CursorPageParameter<>(null, 10, CursorPager.Direction.NEXT); + + assertThat(param.getCursor(), nullValue()); + } +} diff --git a/src/test/java/io/spring/application/CursorPagerTest.java b/src/test/java/io/spring/application/CursorPagerTest.java new file mode 100644 index 000000000..32621d34d --- /dev/null +++ b/src/test/java/io/spring/application/CursorPagerTest.java @@ -0,0 +1,110 @@ +package io.spring.application; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import io.spring.application.data.ArticleData; +import io.spring.application.data.ProfileData; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +public class CursorPagerTest { + + @Test + public void should_indicate_has_next_when_direction_is_next_and_has_extra() { + List data = createArticleDataList(2); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, true); + + assertThat(pager.hasNext(), is(true)); + assertThat(pager.hasPrevious(), is(false)); + } + + @Test + public void should_not_indicate_has_next_when_direction_is_next_and_no_extra() { + List data = createArticleDataList(2); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, false); + + assertThat(pager.hasNext(), is(false)); + assertThat(pager.hasPrevious(), is(false)); + } + + @Test + public void should_indicate_has_previous_when_direction_is_prev_and_has_extra() { + List data = createArticleDataList(2); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.PREV, true); + + assertThat(pager.hasNext(), is(false)); + assertThat(pager.hasPrevious(), is(true)); + } + + @Test + public void should_not_indicate_has_previous_when_direction_is_prev_and_no_extra() { + List data = createArticleDataList(2); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.PREV, false); + + assertThat(pager.hasNext(), is(false)); + assertThat(pager.hasPrevious(), is(false)); + } + + @Test + public void should_return_start_cursor_from_first_element() { + List data = createArticleDataList(3); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, false); + + assertThat(pager.getStartCursor(), notNullValue()); + assertThat(pager.getStartCursor().toString(), is(data.get(0).getCursor().toString())); + } + + @Test + public void should_return_end_cursor_from_last_element() { + List data = createArticleDataList(3); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, false); + + assertThat(pager.getEndCursor(), notNullValue()); + assertThat(pager.getEndCursor().toString(), is(data.get(2).getCursor().toString())); + } + + @Test + public void should_return_null_cursors_for_empty_data() { + List data = new ArrayList<>(); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, false); + + assertThat(pager.getStartCursor(), nullValue()); + assertThat(pager.getEndCursor(), nullValue()); + } + + @Test + public void should_return_data_list() { + List data = createArticleDataList(2); + CursorPager pager = new CursorPager<>(data, CursorPager.Direction.NEXT, false); + + assertThat(pager.getData().size(), is(2)); + } + + private List createArticleDataList(int count) { + List list = new ArrayList<>(); + for (int i = 0; i < count; i++) { + DateTime time = new DateTime().plusMinutes(i); + ArticleData articleData = + new ArticleData( + "id-" + i, + "slug-" + i, + "title-" + i, + "desc-" + i, + "body-" + i, + false, + 0, + time, + time, + Arrays.asList("tag"), + new ProfileData("user-" + i, "username-" + i, "bio", "image", false)); + list.add(articleData); + } + return list; + } +} diff --git a/src/test/java/io/spring/application/DateTimeCursorTest.java b/src/test/java/io/spring/application/DateTimeCursorTest.java new file mode 100644 index 000000000..14cf7aa7a --- /dev/null +++ b/src/test/java/io/spring/application/DateTimeCursorTest.java @@ -0,0 +1,55 @@ +package io.spring.application; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.junit.jupiter.api.Test; + +public class DateTimeCursorTest { + + @Test + public void should_return_millis_as_string() { + DateTime dateTime = new DateTime(1000000L, DateTimeZone.UTC); + DateTimeCursor cursor = new DateTimeCursor(dateTime); + + assertThat(cursor.toString(), is("1000000")); + } + + @Test + public void should_return_data() { + DateTime dateTime = new DateTime(1000000L, DateTimeZone.UTC); + DateTimeCursor cursor = new DateTimeCursor(dateTime); + + assertThat(cursor.getData(), is(dateTime)); + } + + @Test + public void should_parse_valid_cursor_string() { + DateTime result = DateTimeCursor.parse("1000000"); + + assertThat(result, notNullValue()); + assertThat(result.getMillis(), is(1000000L)); + assertThat(result.getZone(), is(DateTimeZone.UTC)); + } + + @Test + public void should_return_null_for_null_cursor() { + DateTime result = DateTimeCursor.parse(null); + + assertThat(result, nullValue()); + } + + @Test + public void should_roundtrip_through_toString_and_parse() { + DateTime original = new DateTime(DateTimeZone.UTC); + DateTimeCursor cursor = new DateTimeCursor(original); + String serialized = cursor.toString(); + DateTime parsed = DateTimeCursor.parse(serialized); + + assertThat(parsed.getMillis(), is(original.getMillis())); + } +} diff --git a/src/test/java/io/spring/application/PageTest.java b/src/test/java/io/spring/application/PageTest.java new file mode 100644 index 000000000..1192f0e19 --- /dev/null +++ b/src/test/java/io/spring/application/PageTest.java @@ -0,0 +1,60 @@ +package io.spring.application; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class PageTest { + + @Test + public void should_use_default_values() { + Page page = new Page(0, 0); + + assertThat(page.getOffset(), is(0)); + assertThat(page.getLimit(), is(20)); + } + + @Test + public void should_set_valid_offset_and_limit() { + Page page = new Page(10, 50); + + assertThat(page.getOffset(), is(10)); + assertThat(page.getLimit(), is(50)); + } + + @Test + public void should_cap_limit_at_max() { + Page page = new Page(0, 200); + + assertThat(page.getLimit(), is(100)); + } + + @Test + public void should_ignore_negative_offset() { + Page page = new Page(-5, 20); + + assertThat(page.getOffset(), is(0)); + } + + @Test + public void should_ignore_negative_limit() { + Page page = new Page(0, -10); + + assertThat(page.getLimit(), is(20)); + } + + @Test + public void should_accept_limit_at_boundary() { + Page page = new Page(0, 100); + + assertThat(page.getLimit(), is(100)); + } + + @Test + public void should_accept_limit_of_one() { + Page page = new Page(0, 1); + + assertThat(page.getLimit(), is(1)); + } +} diff --git a/src/test/java/io/spring/application/article/ArticleCommandServiceTest.java b/src/test/java/io/spring/application/article/ArticleCommandServiceTest.java new file mode 100644 index 000000000..7c68e3a10 --- /dev/null +++ b/src/test/java/io/spring/application/article/ArticleCommandServiceTest.java @@ -0,0 +1,109 @@ +package io.spring.application.article; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +import io.spring.core.article.Article; +import io.spring.core.article.ArticleRepository; +import io.spring.core.user.User; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +public class ArticleCommandServiceTest { + + private ArticleRepository articleRepository; + private ArticleCommandService articleCommandService; + + @BeforeEach + public void setUp() { + articleRepository = Mockito.mock(ArticleRepository.class); + articleCommandService = new ArticleCommandService(articleRepository); + } + + @Test + public void should_create_article_and_save() { + User creator = new User("e@e.com", "creator", "pass", "", ""); + NewArticleParam param = + NewArticleParam.builder() + .title("Test Title") + .description("Test Description") + .body("Test Body") + .tagList(Arrays.asList("java", "spring")) + .build(); + + Article article = articleCommandService.createArticle(param, creator); + + assertThat(article, notNullValue()); + assertThat(article.getTitle(), is("Test Title")); + assertThat(article.getDescription(), is("Test Description")); + assertThat(article.getBody(), is("Test Body")); + assertThat(article.getUserId(), is(creator.getId())); + assertThat(article.getSlug(), is("test-title")); + verify(articleRepository).save(any(Article.class)); + } + + @Test + public void should_update_article_and_save() { + User creator = new User("e@e.com", "creator", "pass", "", ""); + Article article = + new Article( + "Original Title", + "Original Desc", + "Original Body", + Arrays.asList("java"), + creator.getId()); + + UpdateArticleParam updateParam = new UpdateArticleParam("New Title", "New Body", "New Desc"); + + Article updated = articleCommandService.updateArticle(article, updateParam); + + assertThat(updated.getTitle(), is("New Title")); + assertThat(updated.getBody(), is("New Body")); + assertThat(updated.getDescription(), is("New Desc")); + assertThat(updated.getSlug(), is("new-title")); + verify(articleRepository).save(article); + } + + @Test + public void should_create_article_with_empty_tag_list() { + User creator = new User("e@e.com", "creator", "pass", "", ""); + NewArticleParam param = + NewArticleParam.builder() + .title("No Tags") + .description("Desc") + .body("Body") + .tagList(Arrays.asList()) + .build(); + + Article article = articleCommandService.createArticle(param, creator); + + assertThat(article.getTags().size(), is(0)); + verify(articleRepository).save(any(Article.class)); + } + + @Test + public void should_not_update_article_fields_when_empty() { + User creator = new User("e@e.com", "creator", "pass", "", ""); + Article article = + new Article( + "Original Title", + "Original Desc", + "Original Body", + Arrays.asList("java"), + creator.getId()); + + UpdateArticleParam updateParam = new UpdateArticleParam("", "", ""); + + Article updated = articleCommandService.updateArticle(article, updateParam); + + assertThat(updated.getTitle(), is("Original Title")); + assertThat(updated.getDescription(), is("Original Desc")); + assertThat(updated.getBody(), is("Original Body")); + verify(articleRepository).save(article); + } +} diff --git a/src/test/java/io/spring/core/article/ArticleTest.java b/src/test/java/io/spring/core/article/ArticleTest.java index 3e5bdb329..753887859 100644 --- a/src/test/java/io/spring/core/article/ArticleTest.java +++ b/src/test/java/io/spring/core/article/ArticleTest.java @@ -1,9 +1,13 @@ package io.spring.core.article; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import java.util.Arrays; +import java.util.Collections; +import org.joda.time.DateTime; import org.junit.jupiter.api.Test; public class ArticleTest { @@ -37,4 +41,120 @@ public void should_handle_commas() { Article article = new Article("what?the.hell,w", "desc", "body", Arrays.asList("java"), "123"); assertThat(article.getSlug(), is("what-the-hell-w")); } + + @Test + public void should_create_article_with_all_fields() { + Article article = new Article("title", "desc", "body", Arrays.asList("java", "spring"), "123"); + + assertThat(article.getId(), notNullValue()); + assertThat(article.getTitle(), is("title")); + assertThat(article.getDescription(), is("desc")); + assertThat(article.getBody(), is("body")); + assertThat(article.getUserId(), is("123")); + assertThat(article.getTags().size(), is(2)); + assertThat(article.getCreatedAt(), notNullValue()); + assertThat(article.getUpdatedAt(), notNullValue()); + } + + @Test + public void should_generate_unique_ids() { + Article a1 = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + Article a2 = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + + assertThat(a1.getId(), not(a2.getId())); + } + + @Test + public void should_deduplicate_tags() { + Article article = + new Article("title", "desc", "body", Arrays.asList("java", "java", "spring"), "123"); + + assertThat(article.getTags().size(), is(2)); + } + + @Test + public void should_create_article_with_empty_tags() { + Article article = new Article("title", "desc", "body", Collections.emptyList(), "123"); + + assertThat(article.getTags().size(), is(0)); + } + + @Test + public void should_update_title_and_slug() { + Article article = new Article("Old Title", "desc", "body", Arrays.asList("java"), "123"); + DateTime originalUpdatedAt = article.getUpdatedAt(); + + article.update("New Title", "", ""); + + assertThat(article.getTitle(), is("New Title")); + assertThat(article.getSlug(), is("new-title")); + assertThat(article.getDescription(), is("desc")); + assertThat(article.getBody(), is("body")); + } + + @Test + public void should_update_description() { + Article article = new Article("title", "old desc", "body", Arrays.asList("java"), "123"); + + article.update("", "new desc", ""); + + assertThat(article.getDescription(), is("new desc")); + assertThat(article.getTitle(), is("title")); + assertThat(article.getBody(), is("body")); + } + + @Test + public void should_update_body() { + Article article = new Article("title", "desc", "old body", Arrays.asList("java"), "123"); + + article.update("", "", "new body"); + + assertThat(article.getBody(), is("new body")); + assertThat(article.getTitle(), is("title")); + assertThat(article.getDescription(), is("desc")); + } + + @Test + public void should_not_update_when_all_empty() { + Article article = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + DateTime originalUpdatedAt = article.getUpdatedAt(); + + article.update("", "", ""); + + assertThat(article.getTitle(), is("title")); + assertThat(article.getDescription(), is("desc")); + assertThat(article.getBody(), is("body")); + assertThat(article.getUpdatedAt(), is(originalUpdatedAt)); + } + + @Test + public void should_update_all_fields_at_once() { + Article article = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + + article.update("new title", "new desc", "new body"); + + assertThat(article.getTitle(), is("new title")); + assertThat(article.getDescription(), is("new desc")); + assertThat(article.getBody(), is("new body")); + assertThat(article.getSlug(), is("new-title")); + } + + @Test + public void should_preserve_created_at_on_update() { + DateTime createdAt = new DateTime(2020, 1, 1, 0, 0); + Article article = new Article("title", "desc", "body", Arrays.asList("java"), "123", createdAt); + + article.update("new title", "", ""); + + assertThat(article.getCreatedAt(), is(createdAt)); + } + + @Test + public void should_have_equality_based_on_id() { + Article a1 = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + Article a2 = new Article("title", "desc", "body", Arrays.asList("java"), "123"); + + assertThat(a1.equals(a2), is(false)); + assertThat(a1.equals(a1), is(true)); + } } diff --git a/src/test/java/io/spring/core/article/TagTest.java b/src/test/java/io/spring/core/article/TagTest.java new file mode 100644 index 000000000..df562cf86 --- /dev/null +++ b/src/test/java/io/spring/core/article/TagTest.java @@ -0,0 +1,44 @@ +package io.spring.core.article; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class TagTest { + + @Test + public void should_create_tag_with_name() { + Tag tag = new Tag("java"); + + assertThat(tag.getId(), notNullValue()); + assertThat(tag.getName(), is("java")); + } + + @Test + public void should_generate_unique_ids() { + Tag tag1 = new Tag("java"); + Tag tag2 = new Tag("python"); + + assertThat(tag1.getId(), not(tag2.getId())); + } + + @Test + public void should_have_equality_based_on_name() { + Tag tag1 = new Tag("java"); + Tag tag2 = new Tag("java"); + + assertThat(tag1.equals(tag2), is(true)); + assertThat(tag1.hashCode(), is(tag2.hashCode())); + } + + @Test + public void should_not_be_equal_with_different_names() { + Tag tag1 = new Tag("java"); + Tag tag2 = new Tag("python"); + + assertThat(tag1.equals(tag2), is(false)); + } +} diff --git a/src/test/java/io/spring/core/comment/CommentTest.java b/src/test/java/io/spring/core/comment/CommentTest.java new file mode 100644 index 000000000..1b9e8bb88 --- /dev/null +++ b/src/test/java/io/spring/core/comment/CommentTest.java @@ -0,0 +1,39 @@ +package io.spring.core.comment; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class CommentTest { + + @Test + public void should_create_comment_with_all_fields() { + Comment comment = new Comment("comment body", "user-id-1", "article-id-1"); + + assertThat(comment.getId(), notNullValue()); + assertThat(comment.getBody(), is("comment body")); + assertThat(comment.getUserId(), is("user-id-1")); + assertThat(comment.getArticleId(), is("article-id-1")); + assertThat(comment.getCreatedAt(), notNullValue()); + } + + @Test + public void should_generate_unique_ids_for_different_comments() { + Comment comment1 = new Comment("body1", "user1", "article1"); + Comment comment2 = new Comment("body2", "user2", "article2"); + + assertThat(comment1.getId(), not(comment2.getId())); + } + + @Test + public void should_have_equality_based_on_id() { + Comment comment1 = new Comment("body", "user1", "article1"); + Comment comment2 = new Comment("body", "user1", "article1"); + + assertThat(comment1.equals(comment2), is(false)); + assertThat(comment1.equals(comment1), is(true)); + } +} diff --git a/src/test/java/io/spring/core/favorite/ArticleFavoriteTest.java b/src/test/java/io/spring/core/favorite/ArticleFavoriteTest.java new file mode 100644 index 000000000..2fc326729 --- /dev/null +++ b/src/test/java/io/spring/core/favorite/ArticleFavoriteTest.java @@ -0,0 +1,42 @@ +package io.spring.core.favorite; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class ArticleFavoriteTest { + + @Test + public void should_create_article_favorite() { + ArticleFavorite favorite = new ArticleFavorite("article-1", "user-1"); + + assertThat(favorite.getArticleId(), is("article-1")); + assertThat(favorite.getUserId(), is("user-1")); + } + + @Test + public void should_have_equality_based_on_all_fields() { + ArticleFavorite fav1 = new ArticleFavorite("article-1", "user-1"); + ArticleFavorite fav2 = new ArticleFavorite("article-1", "user-1"); + + assertThat(fav1.equals(fav2), is(true)); + assertThat(fav1.hashCode(), is(fav2.hashCode())); + } + + @Test + public void should_not_be_equal_with_different_article_id() { + ArticleFavorite fav1 = new ArticleFavorite("article-1", "user-1"); + ArticleFavorite fav2 = new ArticleFavorite("article-2", "user-1"); + + assertThat(fav1.equals(fav2), is(false)); + } + + @Test + public void should_not_be_equal_with_different_user_id() { + ArticleFavorite fav1 = new ArticleFavorite("article-1", "user-1"); + ArticleFavorite fav2 = new ArticleFavorite("article-1", "user-2"); + + assertThat(fav1.equals(fav2), is(false)); + } +} diff --git a/src/test/java/io/spring/core/service/AuthorizationServiceTest.java b/src/test/java/io/spring/core/service/AuthorizationServiceTest.java new file mode 100644 index 000000000..3c9ec92a9 --- /dev/null +++ b/src/test/java/io/spring/core/service/AuthorizationServiceTest.java @@ -0,0 +1,64 @@ +package io.spring.core.service; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import io.spring.core.article.Article; +import io.spring.core.comment.Comment; +import io.spring.core.user.User; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class AuthorizationServiceTest { + + @Test + public void article_owner_should_be_authorized_to_write_article() { + User user = new User("e@e.com", "user", "pass", "", ""); + Article article = new Article("title", "desc", "body", Arrays.asList("java"), user.getId()); + + assertThat(AuthorizationService.canWriteArticle(user, article), is(true)); + } + + @Test + public void non_owner_should_not_be_authorized_to_write_article() { + User owner = new User("owner@e.com", "owner", "pass", "", ""); + User other = new User("other@e.com", "other", "pass", "", ""); + Article article = new Article("title", "desc", "body", Arrays.asList("java"), owner.getId()); + + assertThat(AuthorizationService.canWriteArticle(other, article), is(false)); + } + + @Test + public void article_owner_should_be_authorized_to_write_comment() { + User articleOwner = new User("owner@e.com", "owner", "pass", "", ""); + User commenter = new User("commenter@e.com", "commenter", "pass", "", ""); + Article article = + new Article("title", "desc", "body", Arrays.asList("java"), articleOwner.getId()); + Comment comment = new Comment("comment body", commenter.getId(), article.getId()); + + assertThat(AuthorizationService.canWriteComment(articleOwner, article, comment), is(true)); + } + + @Test + public void comment_owner_should_be_authorized_to_write_comment() { + User articleOwner = new User("owner@e.com", "owner", "pass", "", ""); + User commenter = new User("commenter@e.com", "commenter", "pass", "", ""); + Article article = + new Article("title", "desc", "body", Arrays.asList("java"), articleOwner.getId()); + Comment comment = new Comment("comment body", commenter.getId(), article.getId()); + + assertThat(AuthorizationService.canWriteComment(commenter, article, comment), is(true)); + } + + @Test + public void non_owner_should_not_be_authorized_to_write_comment() { + User articleOwner = new User("owner@e.com", "owner", "pass", "", ""); + User commenter = new User("commenter@e.com", "commenter", "pass", "", ""); + User stranger = new User("stranger@e.com", "stranger", "pass", "", ""); + Article article = + new Article("title", "desc", "body", Arrays.asList("java"), articleOwner.getId()); + Comment comment = new Comment("comment body", commenter.getId(), article.getId()); + + assertThat(AuthorizationService.canWriteComment(stranger, article, comment), is(false)); + } +} diff --git a/src/test/java/io/spring/core/user/FollowRelationTest.java b/src/test/java/io/spring/core/user/FollowRelationTest.java new file mode 100644 index 000000000..d1d4c3eb2 --- /dev/null +++ b/src/test/java/io/spring/core/user/FollowRelationTest.java @@ -0,0 +1,42 @@ +package io.spring.core.user; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class FollowRelationTest { + + @Test + public void should_create_follow_relation() { + FollowRelation relation = new FollowRelation("user-1", "user-2"); + + assertThat(relation.getUserId(), is("user-1")); + assertThat(relation.getTargetId(), is("user-2")); + } + + @Test + public void should_have_equality_based_on_all_fields() { + FollowRelation relation1 = new FollowRelation("user-1", "user-2"); + FollowRelation relation2 = new FollowRelation("user-1", "user-2"); + + assertThat(relation1.equals(relation2), is(true)); + assertThat(relation1.hashCode(), is(relation2.hashCode())); + } + + @Test + public void should_not_be_equal_with_different_user_ids() { + FollowRelation relation1 = new FollowRelation("user-1", "user-2"); + FollowRelation relation2 = new FollowRelation("user-3", "user-2"); + + assertThat(relation1.equals(relation2), is(false)); + } + + @Test + public void should_not_be_equal_with_different_target_ids() { + FollowRelation relation1 = new FollowRelation("user-1", "user-2"); + FollowRelation relation2 = new FollowRelation("user-1", "user-3"); + + assertThat(relation1.equals(relation2), is(false)); + } +} diff --git a/src/test/java/io/spring/core/user/UserTest.java b/src/test/java/io/spring/core/user/UserTest.java new file mode 100644 index 000000000..c98c18b9a --- /dev/null +++ b/src/test/java/io/spring/core/user/UserTest.java @@ -0,0 +1,129 @@ +package io.spring.core.user; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +public class UserTest { + + @Test + public void should_create_user_with_all_fields() { + User user = new User("test@example.com", "testuser", "password", "bio", "image.png"); + + assertThat(user.getId(), notNullValue()); + assertThat(user.getEmail(), is("test@example.com")); + assertThat(user.getUsername(), is("testuser")); + assertThat(user.getPassword(), is("password")); + assertThat(user.getBio(), is("bio")); + assertThat(user.getImage(), is("image.png")); + } + + @Test + public void should_generate_unique_ids() { + User user1 = new User("a@b.com", "user1", "pass", "", ""); + User user2 = new User("c@d.com", "user2", "pass", "", ""); + + assertThat(user1.getId(), not(user2.getId())); + } + + @Test + public void should_update_email_when_not_empty() { + User user = new User("old@example.com", "user", "pass", "bio", "img"); + + user.update("new@example.com", "", "", "", ""); + + assertThat(user.getEmail(), is("new@example.com")); + assertThat(user.getUsername(), is("user")); + assertThat(user.getPassword(), is("pass")); + assertThat(user.getBio(), is("bio")); + assertThat(user.getImage(), is("img")); + } + + @Test + public void should_update_username_when_not_empty() { + User user = new User("e@e.com", "oldname", "pass", "bio", "img"); + + user.update("", "newname", "", "", ""); + + assertThat(user.getUsername(), is("newname")); + assertThat(user.getEmail(), is("e@e.com")); + } + + @Test + public void should_update_password_when_not_empty() { + User user = new User("e@e.com", "user", "oldpass", "bio", "img"); + + user.update("", "", "newpass", "", ""); + + assertThat(user.getPassword(), is("newpass")); + } + + @Test + public void should_update_bio_when_not_empty() { + User user = new User("e@e.com", "user", "pass", "oldbio", "img"); + + user.update("", "", "", "newbio", ""); + + assertThat(user.getBio(), is("newbio")); + } + + @Test + public void should_update_image_when_not_empty() { + User user = new User("e@e.com", "user", "pass", "bio", "oldimg"); + + user.update("", "", "", "", "newimg"); + + assertThat(user.getImage(), is("newimg")); + } + + @Test + public void should_not_update_fields_when_null() { + User user = new User("e@e.com", "user", "pass", "bio", "img"); + + user.update(null, null, null, null, null); + + assertThat(user.getEmail(), is("e@e.com")); + assertThat(user.getUsername(), is("user")); + assertThat(user.getPassword(), is("pass")); + assertThat(user.getBio(), is("bio")); + assertThat(user.getImage(), is("img")); + } + + @Test + public void should_not_update_fields_when_empty_string() { + User user = new User("e@e.com", "user", "pass", "bio", "img"); + + user.update("", "", "", "", ""); + + assertThat(user.getEmail(), is("e@e.com")); + assertThat(user.getUsername(), is("user")); + assertThat(user.getPassword(), is("pass")); + assertThat(user.getBio(), is("bio")); + assertThat(user.getImage(), is("img")); + } + + @Test + public void should_update_all_fields_at_once() { + User user = new User("e@e.com", "user", "pass", "bio", "img"); + + user.update("new@e.com", "newuser", "newpass", "newbio", "newimg"); + + assertThat(user.getEmail(), is("new@e.com")); + assertThat(user.getUsername(), is("newuser")); + assertThat(user.getPassword(), is("newpass")); + assertThat(user.getBio(), is("newbio")); + assertThat(user.getImage(), is("newimg")); + } + + @Test + public void should_have_equality_based_on_id() { + User user1 = new User("e@e.com", "user", "pass", "bio", "img"); + User user2 = new User("e@e.com", "user", "pass", "bio", "img"); + + assertThat(user1.equals(user2), is(false)); + assertThat(user1.equals(user1), is(true)); + } +} diff --git a/src/test/java/io/spring/infrastructure/service/DefaultJwtServiceTest.java b/src/test/java/io/spring/infrastructure/service/DefaultJwtServiceTest.java index 12929118a..b2261705e 100644 --- a/src/test/java/io/spring/infrastructure/service/DefaultJwtServiceTest.java +++ b/src/test/java/io/spring/infrastructure/service/DefaultJwtServiceTest.java @@ -13,7 +13,8 @@ public class DefaultJwtServiceTest { @BeforeEach public void setUp() { - jwtService = new DefaultJwtService("123123123123123123123123123123123123123123123123123123123123", 3600); + jwtService = + new DefaultJwtService("123123123123123123123123123123123123123123123123123123123123", 3600); } @Test