2323import com .example .solidconnection .chat .fixture .ChatParticipantFixture ;
2424import com .example .solidconnection .chat .fixture .ChatReadStatusFixture ;
2525import com .example .solidconnection .chat .fixture .ChatRoomFixture ;
26+ import com .example .solidconnection .chat .repository .ChatMessageRepository ;
2627import com .example .solidconnection .chat .repository .ChatReadStatusRepositoryForTest ;
2728import com .example .solidconnection .common .dto .SliceResponse ;
2829import com .example .solidconnection .common .exception .CustomException ;
4344import org .springframework .data .domain .Sort ;
4445import org .springframework .messaging .simp .SimpMessagingTemplate ;
4546import org .springframework .test .context .bean .override .mockito .MockitoBean ;
47+ import org .springframework .transaction .support .TransactionSynchronization ;
48+ import org .springframework .transaction .support .TransactionSynchronizationManager ;
49+ import org .springframework .transaction .support .TransactionTemplate ;
4650
4751@ TestContainerSpringBootTest
4852@ DisplayName ("채팅 서비스 테스트" )
@@ -54,6 +58,12 @@ class ChatServiceTest {
5458 @ Autowired
5559 private ChatReadStatusRepositoryForTest chatReadStatusRepositoryForTest ;
5660
61+ @ Autowired
62+ private ChatMessageRepository chatMessageRepository ;
63+
64+ @ Autowired
65+ private TransactionTemplate transactionTemplate ;
66+
5767 @ Autowired
5868 private SiteUserFixture siteUserFixture ;
5969
@@ -418,9 +428,19 @@ void setUp() {
418428 // given
419429 final String content = "안녕하세요" ;
420430 ChatMessageSendRequest request = new ChatMessageSendRequest (content );
431+ long messageCount = chatMessageRepository .count ();
421432
422433 // when
423- chatService .sendChatMessage (request , sender .getId (), chatRoom .getId ());
434+ transactionTemplate .executeWithoutResult (status -> {
435+ chatService .sendChatMessage (request , sender .getId (), chatRoom .getId ());
436+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
437+ TransactionSynchronizationManager .registerSynchronization (new TransactionSynchronization () {
438+ @ Override
439+ public void beforeCommit (boolean readOnly ) {
440+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
441+ }
442+ });
443+ });
424444
425445 // then
426446 ArgumentCaptor <String > destinationCaptor = ArgumentCaptor .forClass (String .class );
@@ -431,7 +451,28 @@ void setUp() {
431451 assertAll (
432452 () -> assertThat (destinationCaptor .getValue ()).isEqualTo ("/topic/chat/" + chatRoom .getId ()),
433453 () -> assertThat (payloadCaptor .getValue ().content ()).isEqualTo (content ),
434- () -> assertThat (payloadCaptor .getValue ().siteUserId ()).isEqualTo (sender .getId ())
454+ () -> assertThat (payloadCaptor .getValue ().siteUserId ()).isEqualTo (sender .getId ()),
455+ () -> assertThat (chatMessageRepository .count ()).isEqualTo (messageCount + 1 )
456+ );
457+ }
458+
459+ @ Test
460+ void 트랜잭션이_롤백되면_메시지를_저장하거나_방송하지_않는다 () {
461+ // given
462+ ChatMessageSendRequest request = new ChatMessageSendRequest ("롤백 메시지" );
463+ long messageCount = chatMessageRepository .count ();
464+
465+ // when
466+ transactionTemplate .executeWithoutResult (status -> {
467+ chatService .sendChatMessage (request , sender .getId (), chatRoom .getId ());
468+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
469+ status .setRollbackOnly ();
470+ });
471+
472+ // then
473+ assertAll (
474+ () -> BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions (),
475+ () -> assertThat (chatMessageRepository .count ()).isEqualTo (messageCount )
435476 );
436477 }
437478
@@ -473,9 +514,19 @@ void setUp() {
473514 TEST_IMAGE_URL2
474515 );
475516 ChatImageSendRequest request = new ChatImageSendRequest (imageUrls );
517+ long messageCount = chatMessageRepository .count ();
476518
477519 // when
478- chatService .sendChatImage (request , sender .getId (), chatRoom .getId ());
520+ transactionTemplate .executeWithoutResult (status -> {
521+ chatService .sendChatImage (request , sender .getId (), chatRoom .getId ());
522+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
523+ TransactionSynchronizationManager .registerSynchronization (new TransactionSynchronization () {
524+ @ Override
525+ public void beforeCommit (boolean readOnly ) {
526+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
527+ }
528+ });
529+ });
479530
480531 // then
481532 ArgumentCaptor <String > destinationCaptor = ArgumentCaptor .forClass (String .class );
@@ -492,7 +543,28 @@ void setUp() {
492543 () -> assertThat (response .attachments ().get (1 ).url ()).isEqualTo (imageUrls .get (1 )),
493544 () -> assertThat (response .messageType ()).isEqualTo (MessageType .IMAGE ),
494545 () -> assertThat (response .siteUserId ()).isEqualTo (sender .getId ()),
495- () -> assertThat (response .content ()).isEmpty ()
546+ () -> assertThat (response .content ()).isEmpty (),
547+ () -> assertThat (chatMessageRepository .count ()).isEqualTo (messageCount + 1 )
548+ );
549+ }
550+
551+ @ Test
552+ void 트랜잭션이_롤백되면_이미지_메시지를_저장하거나_방송하지_않는다 () {
553+ // given
554+ ChatImageSendRequest request = new ChatImageSendRequest (List .of (TEST_IMAGE_URL ));
555+ long messageCount = chatMessageRepository .count ();
556+
557+ // when
558+ transactionTemplate .executeWithoutResult (status -> {
559+ chatService .sendChatImage (request , sender .getId (), chatRoom .getId ());
560+ BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions ();
561+ status .setRollbackOnly ();
562+ });
563+
564+ // then
565+ assertAll (
566+ () -> BDDMockito .then (simpMessagingTemplate ).shouldHaveNoInteractions (),
567+ () -> assertThat (chatMessageRepository .count ()).isEqualTo (messageCount )
496568 );
497569 }
498570
0 commit comments