1+ package com .example .log4u .domain .diary .facade ;
2+
3+ import static org .assertj .core .api .Assertions .*;
4+ import static org .mockito .BDDMockito .*;
5+
6+ import java .util .List ;
7+
8+ import org .junit .jupiter .api .DisplayName ;
9+ import org .junit .jupiter .api .Test ;
10+ import org .junit .jupiter .api .extension .ExtendWith ;
11+ import org .mockito .InjectMocks ;
12+ import org .mockito .Mock ;
13+ import org .mockito .junit .jupiter .MockitoExtension ;
14+ import org .springframework .data .domain .Slice ;
15+ import org .springframework .data .domain .SliceImpl ;
16+
17+ import com .example .log4u .common .dto .PageResponse ;
18+ import com .example .log4u .domain .diary .SortType ;
19+ import com .example .log4u .domain .diary .VisibilityType ;
20+ import com .example .log4u .domain .diary .dto .DiaryRequestDto ;
21+ import com .example .log4u .domain .diary .dto .DiaryResponseDto ;
22+ import com .example .log4u .domain .diary .entity .Diary ;
23+ import com .example .log4u .domain .diary .service .DiaryService ;
24+ import com .example .log4u .domain .hashtag .service .HashtagService ;
25+ import com .example .log4u .domain .like .service .LikeService ;
26+ import com .example .log4u .domain .map .service .MapService ;
27+ import com .example .log4u .domain .media .entity .Media ;
28+ import com .example .log4u .domain .media .service .MediaService ;
29+ import com .example .log4u .fixture .DiaryFixture ;
30+ import com .example .log4u .fixture .MediaFixture ;
31+
32+ @ ExtendWith (MockitoExtension .class )
33+ class DiaryFacadeTest {
34+
35+ @ Mock
36+ private DiaryService diaryService ;
37+
38+ @ Mock
39+ private MediaService mediaService ;
40+
41+ @ Mock
42+ private MapService mapService ;
43+
44+ @ Mock
45+ private LikeService likeService ;
46+
47+ @ Mock
48+ private HashtagService hashtagService ;
49+
50+ @ InjectMocks
51+ private DiaryFacade diaryFacade ;
52+
53+ @ Test
54+ @ DisplayName ("다이어리 생성 성공" )
55+ void createDiary () {
56+ // given
57+ Long userId = 1L ;
58+ DiaryRequestDto request = DiaryFixture .createDiaryRequestDtoFixture ();
59+ Diary diary = DiaryFixture .createDiaryFixture ();
60+ String thumbnailUrl = "https://example.com/thumbnail.jpg" ;
61+
62+ given (mediaService .extractThumbnailUrl (request .mediaList ())).willReturn (thumbnailUrl );
63+ given (diaryService .saveDiary (userId , request , thumbnailUrl )).willReturn (diary );
64+
65+ // when
66+ diaryFacade .createDiary (userId , request );
67+
68+ // then
69+ verify (mediaService ).extractThumbnailUrl (request .mediaList ());
70+ verify (diaryService ).saveDiary (userId , request , thumbnailUrl );
71+ verify (mediaService ).saveMedia (diary .getDiaryId (), request .mediaList ());
72+ verify (hashtagService ).saveOrUpdateHashtag (diary .getDiaryId (), request .hashtagList ());
73+ verify (mapService ).increaseRegionDiaryCount (request .location ().latitude (), request .location ().longitude ());
74+ }
75+
76+ @ Test
77+ @ DisplayName ("다이어리 삭제 성공" )
78+ void deleteDiary () {
79+ // given
80+ Long userId = 1L ;
81+ Long diaryId = 1L ;
82+ Diary diary = DiaryFixture .createDiaryFixture ();
83+
84+ given (diaryService .getDiaryAfterValidateOwnership (diaryId , userId )).willReturn (diary );
85+
86+ // when
87+ diaryFacade .deleteDiary (userId , diaryId );
88+
89+ // then
90+ verify (diaryService ).getDiaryAfterValidateOwnership (diaryId , userId );
91+ verify (mediaService ).deleteMediaByDiaryId (diaryId );
92+ verify (hashtagService ).deleteHashtagsByDiaryId (diaryId );
93+ verify (diaryService ).deleteDiary (diary );
94+ }
95+
96+ @ Test
97+ @ DisplayName ("다이어리 수정 성공" )
98+ void updateDiary () {
99+ // given
100+ Long userId = 1L ;
101+ Long diaryId = 1L ;
102+ DiaryRequestDto request = DiaryFixture .createDiaryRequestDtoFixture ();
103+ Diary diary = DiaryFixture .createDiaryFixture ();
104+ String newThumbnailUrl = "https://example.com/new-thumbnail.jpg" ;
105+
106+ given (diaryService .getDiaryAfterValidateOwnership (diaryId , userId )).willReturn (diary );
107+ given (mediaService .extractThumbnailUrl (request .mediaList ())).willReturn (newThumbnailUrl );
108+
109+ // when
110+ diaryFacade .updateDiary (userId , diaryId , request );
111+
112+ // then
113+ verify (diaryService ).getDiaryAfterValidateOwnership (diaryId , userId );
114+ verify (mediaService ).updateMediaByDiaryId (diaryId , request .mediaList ());
115+ verify (hashtagService ).saveOrUpdateHashtag (diaryId , request .hashtagList ());
116+ verify (mediaService ).extractThumbnailUrl (request .mediaList ());
117+ verify (diaryService ).updateDiary (diary , request , newThumbnailUrl );
118+ }
119+
120+ @ Test
121+ @ DisplayName ("다이어리 단건 조회 성공" )
122+ void getDiary () {
123+ // given
124+ Long userId = 1L ;
125+ Long diaryId = 1L ;
126+ Diary diary = DiaryFixture .createPublicDiaryFixture (diaryId , 2L ); // 다른 사용자의 공개 다이어리
127+ List <Media > mediaList = List .of (MediaFixture .createMediaFixture (10L , diaryId ));
128+ List <String > hashtagList = List .of ("여행" , "맛집" );
129+ boolean isLiked = true ;
130+
131+ given (diaryService .getDiaryAfterValidateAccess (diaryId , userId )).willReturn (diary );
132+ given (likeService .isLiked (userId , diaryId )).willReturn (isLiked );
133+ given (mediaService .getMediaByDiaryId (diaryId )).willReturn (mediaList );
134+ given (hashtagService .getHashtagsByDiaryId (diaryId )).willReturn (hashtagList );
135+
136+ // when
137+ DiaryResponseDto result = diaryFacade .getDiary (userId , diaryId );
138+
139+ // then
140+ assertThat (result ).isNotNull ();
141+ assertThat (result .diaryId ()).isEqualTo (diaryId );
142+ assertThat (result .userId ()).isEqualTo (2L );
143+ assertThat (result .visibility ()).isEqualTo (VisibilityType .PUBLIC .name ());
144+ assertThat (result .mediaList ()).hasSize (1 );
145+ assertThat (result .hashtagList ()).containsExactly ("여행" , "맛집" );
146+ assertThat (result .isLiked ()).isTrue ();
147+ }
148+
149+ @ Test
150+ @ DisplayName ("다이어리 목록 조회 성공" )
151+ void getDiariesByCursor () {
152+ // given
153+ Long userId = 1L ;
154+ Long targetUserId = 2L ;
155+ Long cursorId = null ;
156+ int size = 10 ;
157+
158+ List <DiaryResponseDto > dtoList = List .of (
159+ DiaryResponseDto .of (
160+ DiaryFixture .createPublicDiaryFixture (1L , targetUserId ),
161+ List .of (MediaFixture .createMediaFixture (1L , 1L )),
162+ List .of ("여행" , "맛집" ),
163+ false
164+ ),
165+ DiaryResponseDto .of (
166+ DiaryFixture .createPublicDiaryFixture (2L , targetUserId ),
167+ List .of (MediaFixture .createMediaFixture (2L , 2L )),
168+ List .of ("일상" ),
169+ true
170+ ),
171+ DiaryResponseDto .of (
172+ DiaryFixture .createPublicDiaryFixture (3L , targetUserId ),
173+ List .of (MediaFixture .createMediaFixture (3L , 3L )),
174+ List .of ("제주도" , "여행" , "사진" ),
175+ false
176+ )
177+ );
178+
179+ Slice <DiaryResponseDto > dtoSlice = new SliceImpl <>(dtoList );
180+ PageResponse <DiaryResponseDto > pageResponse = PageResponse .of (dtoSlice , 3L );
181+
182+ given (diaryService .getDiaryResponseDtoSlice (userId , targetUserId , cursorId , size )).willReturn (dtoSlice );
183+
184+ // when
185+ PageResponse <DiaryResponseDto > result = diaryFacade .getDiariesByCursor (userId , targetUserId , cursorId , size );
186+
187+ // then
188+ assertThat (result .list ()).hasSize (3 );
189+ assertThat (result .pageInfo ().nextCursor ()).isEqualTo (3L );
190+ }
191+
192+ @ Test
193+ @ DisplayName ("다이어리 검색 성공" )
194+ void searchDiariesByCursor () {
195+ // given
196+ String keyword = "여행" ;
197+ SortType sort = SortType .LATEST ;
198+ Long cursorId = null ;
199+ int size = 10 ;
200+
201+ List <DiaryResponseDto > dtoList = List .of (
202+ DiaryResponseDto .of (
203+ DiaryFixture .createPublicDiaryFixture (1L , 1L ),
204+ List .of (MediaFixture .createMediaFixture (1L , 1L )),
205+ List .of ("여행" , "맛집" ),
206+ false
207+ ),
208+ DiaryResponseDto .of (
209+ DiaryFixture .createPublicDiaryFixture (2L , 2L ),
210+ List .of (MediaFixture .createMediaFixture (2L , 2L )),
211+ List .of ("여행" , "제주도" ),
212+ false
213+ )
214+ );
215+
216+ Slice <DiaryResponseDto > dtoSlice = new SliceImpl <>(dtoList );
217+ PageResponse <DiaryResponseDto > pageResponse = PageResponse .of (dtoSlice , 2L );
218+
219+ given (diaryService .searchDiariesByCursor (keyword , sort , cursorId , size )).willReturn (dtoSlice );
220+
221+ // when
222+ PageResponse <DiaryResponseDto > result = diaryFacade .searchDiariesByCursor (keyword , sort , cursorId , size );
223+
224+ // then
225+ assertThat (result .list ()).hasSize (2 );
226+ assertThat (result .pageInfo ().nextCursor ()).isEqualTo (2L );
227+ }
228+ }
0 commit comments