99import com .itasocialacademy .oitassist .competition .exceptions .CompetitionNotFoundException ;
1010import com .itasocialacademy .oitassist .competition .exceptions .StageNotFoundException ;
1111import com .itasocialacademy .oitassist .core .exceptions .AuthorizationException ;
12+ import com .itasocialacademy .oitassist .core .service .interfaces .EmailService ;
13+ import com .itasocialacademy .oitassist .participation .dao .dto .event .InvitationRequestEvent ;
1214import com .itasocialacademy .oitassist .participation .dao .dto .request .CreateInvitationRequest ;
1315import com .itasocialacademy .oitassist .participation .dao .dto .request .RejectEnrollmentRequest ;
1416import com .itasocialacademy .oitassist .participation .dao .dto .response .CreateInvitationResponse ;
2527import com .itasocialacademy .oitassist .participation .mapper .ParticipationMapper ;
2628import com .itasocialacademy .oitassist .participation .mapper .interfaces .ProcessInvitationMapper ;
2729import com .itasocialacademy .oitassist .participation .saver .InvitationRequestsSaver ;
30+ import com .itasocialacademy .oitassist .participation .sender .AsyncEmailSender ;
2831import com .itasocialacademy .oitassist .security .api .interfaces .SecurityFacade ;
2932import com .itasocialacademy .oitassist .user .api .dto .UserAuthDetails ;
33+ import com .itasocialacademy .oitassist .user .api .dto .UserProfileDetails ;
3034import com .itasocialacademy .oitassist .user .api .interfaces .UserFacade ;
3135import com .itasocialacademy .oitassist .user .dao .enums .Role ;
3236import org .hibernate .exception .ConstraintViolationException ;
3337import org .junit .jupiter .api .BeforeEach ;
3438import org .junit .jupiter .api .Test ;
3539import org .junit .jupiter .api .extension .ExtendWith ;
40+ import org .mockito .ArgumentCaptor ;
3641import org .mockito .InjectMocks ;
3742import org .mockito .Mock ;
3843import org .mockito .junit .jupiter .MockitoExtension ;
4651import static org .mockito .Mockito .*;
4752
4853@ ExtendWith (MockitoExtension .class )
49- public class InvitationServiceTest {
54+ class InvitationServiceTest {
5055 @ Mock
5156 private ParticipationRepository participationRepository ;
5257 @ Mock
@@ -63,6 +68,10 @@ public class InvitationServiceTest {
6368 private ProcessInvitationMapper processInvitationMapper ;
6469 @ Mock
6570 private CompetitionFacade competitionFacade ;
71+ @ Mock
72+ private AsyncEmailSender sender ;
73+ @ Mock
74+ private EmailService emailService ;
6675
6776 @ InjectMocks
6877 private InvitationServiceImpl invitationService ;
@@ -91,11 +100,13 @@ void setUp() {
91100
92101 competitionDetail = CompetitionDetail .builder ()
93102 .id (2L )
103+ .title ("Olympiad" )
94104 .competitionStatus (CompetitionStatus .ENROLLMENT )
95105 .build ();
96106
97107 stageDetail = StageDetail .builder ()
98108 .id (3L )
109+ .title ("First stage" )
99110 .competitionId (2L )
100111 .scope (StageScope .DISTRICT )
101112 .build ();
@@ -498,4 +509,54 @@ private static ProcessInvitationResponse getProcessInvitationResponse(RequestSta
498509 .status (status )
499510 .build ();
500511 }
512+
513+ // ---- emailSending part ----
514+
515+ @ Test
516+ void sendEnrollmentRequest_withSucceededInvitations_shouldScheduleInvitationEmail () {
517+ when (securityFacade .getCurrentUserId ()).thenReturn (Optional .of (4L ));
518+ when (invitationRepository .findByStudentIdInAndCompetitionIdAndStageIdAndStatus (
519+ List .of (10L ), 2L , 3L , RequestStatus .PENDING )).thenReturn (List .of ());
520+ when (participationRepository .findAllByUserIdInAndCompetitionIdAndStageId (List .of (10L ), 2L , 3L ))
521+ .thenReturn (List .of ());
522+ when (invitationRequestsSaver .saveSingleInvitation (10L , createInvitationRequest )).thenReturn (invitation );
523+ when (userFacade .findByIds (List .of (10L ))).thenReturn (List .of (validUser ));
524+ when (competitionFacade .findCompetitionById (2L )).thenReturn (Optional .of (competitionDetail ));
525+ when (competitionFacade .findStageById (3L )).thenReturn (Optional .of (stageDetail ));
526+ when (userFacade .findProfilesByIds (List .of (10L ))).thenReturn (
527+ List .of (new UserProfileDetails (10L , "Test" , "test@mail.com" )));
528+ when (invitationRequestsSaver .saveSingleInvitation (10L , createInvitationRequest )).thenReturn (invitation );
529+ invitationService .sendEnrollmentRequest (createInvitationRequest );
530+
531+ ArgumentCaptor <InvitationRequestEvent > eventCaptor = ArgumentCaptor .forClass (InvitationRequestEvent .class );
532+ verify (sender ).sendInvitationEmail (eventCaptor .capture ());
533+
534+ InvitationRequestEvent event = eventCaptor .getValue ();
535+ assertEquals ("Olympiad" , event .competitionTitle ());
536+ assertEquals ("First stage" , event .stageTitle ());
537+ assertEquals (1 , event .users ().size ());
538+ assertEquals ("test@mail.com" , event .users ().getFirst ().email ());
539+ }
540+
541+ @ Test
542+ void sendEnrollmentRequest_whenAllStudentsFail_shouldNotScheduleInvitationEmail () {
543+ UserAuthDetails orgUser = new UserAuthDetails (10L , "email1@mail.com" , "password1" , Role .ORG );
544+ when (securityFacade .getCurrentUserId ()).thenReturn (Optional .of (4L ));
545+ when (competitionFacade .findCompetitionById (2L )).thenReturn (Optional .of (competitionDetail ));
546+ when (competitionFacade .findStageById (3L )).thenReturn (Optional .of (stageDetail ));
547+ when (userFacade .findByIds (List .of (10L ))).thenReturn (List .of (orgUser ));
548+
549+ invitationService .sendEnrollmentRequest (createInvitationRequest );
550+
551+ verify (sender , never ()).sendInvitationEmail (any ());
552+ }
553+
554+ @ Test
555+ void sendInvitationEmail_noRecipients_shouldSendNothing () {
556+ InvitationRequestEvent event = new InvitationRequestEvent ("Olympiad" , "District Stage" , List .of ());
557+
558+ sender .sendInvitationEmail (event );
559+
560+ verifyNoInteractions (emailService );
561+ }
501562}
0 commit comments