Skip to content

Commit

Permalink
Improve test methods
Browse files Browse the repository at this point in the history
  • Loading branch information
DhiraPT committed Feb 19, 2025
1 parent 979929e commit 9908492
Showing 1 changed file with 71 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package teammates.sqlui.webapi;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -15,6 +17,7 @@
import teammates.storage.sqlentity.Account;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Instructor;
import teammates.storage.sqlentity.Student;
import teammates.ui.output.MessageOutput;
import teammates.ui.webapi.DeleteInstructorAction;
import teammates.ui.webapi.InvalidOperationException;
Expand All @@ -27,6 +30,8 @@ public class DeleteInstructorActionTest extends BaseActionTest<DeleteInstructorA
private Course course;
private Instructor instructor;
private Instructor instructor2;
private Student student;
private String studentId = "student-googleId";

@Override
protected String getActionUri() {
Expand All @@ -42,31 +47,36 @@ protected String getRequestMethod() {
void setUp() {
Mockito.reset(mockLogic);

course = new Course("course-id", "Course Name", Const.DEFAULT_TIME_ZONE, "institute");
instructor = setupInstructor("instructor-googleId", "name", "[email protected]");
instructor2 = setupInstructor("instructor2-googleId", "name2", "[email protected]");
course = getTypicalCourse();
instructor = setupInstructor("instructor-googleId", "[email protected]");
instructor2 = setupInstructor("instructor2-googleId", "[email protected]");
student = getTypicalStudent();

setupMockLogic();
}

private Instructor setupInstructor(String googleId, String name, String email) {
Account account = new Account(googleId, name, email);
InstructorPrivileges instructorPrivileges = new InstructorPrivileges();
instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, true);
private Instructor setupInstructor(String googleId, String email) {
Account account = getTypicalAccount();
account.setGoogleId(googleId);
account.setEmail(email);

Instructor instructor = new Instructor(course, name, email,
true, "", null, instructorPrivileges);
Instructor instructor = getTypicalInstructor();
instructor.setEmail(email);
instructor.setDisplayedToStudents(true);
instructor.setAccount(account);

return instructor;
}

private void setupMockLogic() {
when(mockLogic.getCourse(course.getId())).thenReturn(course);
when(mockLogic.getInstructorByGoogleId(course.getId(), instructor.getGoogleId())).thenReturn(instructor);
when(mockLogic.getInstructorByGoogleId(course.getId(), instructor2.getGoogleId())).thenReturn(instructor2);
when(mockLogic.getStudentByGoogleId(course.getId(), studentId)).thenReturn(student);
when(mockLogic.getInstructorForEmail(course.getId(), instructor.getEmail())).thenReturn(instructor);
when(mockLogic.getInstructorForEmail(course.getId(), instructor2.getEmail())).thenReturn(instructor2);
when(mockLogic.getInstructorsByCourse(course.getId())).thenReturn(List.of(instructor, instructor2));
when(mockLogic.getStudentsForCourse(course.getId())).thenReturn(List.of(student));
}

@Test
Expand All @@ -79,7 +89,9 @@ void testExecute_deleteInstructorByGoogleId_success() {
DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), instructor2.getGoogleId());
verify(mockLogic, times(1)).deleteInstructorCascade(course.getId(), instructor2.getEmail());
verify(mockLogic, times(1)).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

Expand All @@ -93,12 +105,14 @@ void testExecute_deleteInstructorByEmail_success() {
DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(1)).getInstructorForEmail(course.getId(), instructor2.getEmail());
verify(mockLogic, times(1)).deleteInstructorCascade(course.getId(), instructor2.getEmail());
verify(mockLogic, times(1)).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

@Test
void testExecute_deleteLastInstructorByGoogleId_fail() {
void testExecute_onlyOneInstructorInCourse_throwsInvalidOperationException() {
// Override the mock logic for the course to have only one instructor
when(mockLogic.getInstructorsByCourse(course.getId())).thenReturn(List.of(instructor));

Expand All @@ -113,7 +127,42 @@ void testExecute_deleteLastInstructorByGoogleId_fail() {
assertEquals("The instructor you are trying to delete is the last instructor in the course. "
+ "Deleting the last instructor from the course is not allowed.", ioe.getMessage());

verify(mockLogic, times(0)).deleteInstructorCascade(course.getId(), instructor.getEmail());
verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), instructor.getGoogleId());
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
}

@Test
void testExecute_onlyOneRegisteredInstructor_throwsInvalidOperationException() {
instructor2.setAccount(null);

String[] params = {
Const.ParamsNames.COURSE_ID, course.getId(),
Const.ParamsNames.INSTRUCTOR_ID, instructor.getGoogleId(),
};

InvalidOperationException ioe = verifyInvalidOperation(params);
assertEquals("The instructor you are trying to delete is the last instructor in the course. "
+ "Deleting the last instructor from the course is not allowed.", ioe.getMessage());

verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), instructor.getGoogleId());
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
}

@Test
void testExecute_onlyOneInstructorDisplayedToStudents_throwsInvalidOperationException() {
instructor2.setDisplayedToStudents(false);

String[] params = {
Const.ParamsNames.COURSE_ID, course.getId(),
Const.ParamsNames.INSTRUCTOR_ID, instructor.getGoogleId(),
};

InvalidOperationException ioe = verifyInvalidOperation(params);
assertEquals("The instructor you are trying to delete is the last instructor in the course. "
+ "Deleting the last instructor from the course is not allowed.", ioe.getMessage());

verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), instructor.getGoogleId());
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
}

@Test
Expand All @@ -128,7 +177,9 @@ void testExecute_instructorDeleteOwnRoleByGoogleId_success() {
DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), instructor.getGoogleId());
verify(mockLogic, times(1)).deleteInstructorCascade(course.getId(), instructor.getEmail());
verify(mockLogic, times(1)).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

Expand All @@ -141,36 +192,34 @@ void testExecute_deleteNonExistentInstructorByGoogleId_failSilently() {
Const.ParamsNames.INSTRUCTOR_ID, "fake-googleId",
};

assertNull(mockLogic.getInstructorByGoogleId(course.getId(), "fake-googleId"));

DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(0)).deleteInstructorCascade(course.getId(), instructor.getEmail());
verify(mockLogic, times(1)).getInstructorByGoogleId(course.getId(), "fake-googleId");
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

@Test
void testExecute_deleteNonExistentInstructorByEmail_failSilently() {
String fakeInstructorEmail = "fake-instructoremail@tm.tmt";
String fakeInstructorEmail = "fake-instructoremail@teammates.tmt";
when(mockLogic.getInstructorForEmail(course.getId(), fakeInstructorEmail)).thenReturn(null);

String[] params = {
Const.ParamsNames.COURSE_ID, course.getId(),
Const.ParamsNames.INSTRUCTOR_EMAIL, fakeInstructorEmail,
};

assertNull(mockLogic.getInstructorForEmail(course.getId(), fakeInstructorEmail));

DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(0)).deleteInstructorCascade(course.getId(), fakeInstructorEmail);
verify(mockLogic, times(1)).getInstructorForEmail(course.getId(), fakeInstructorEmail);
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

@Test
void testExecute_courseDoesNotExist_failSilently() {
void testExecute_nonExistentCourse_failSilently() {
String nonExistentCourseId = "non-existent-course-id";
when(mockLogic.getCourse(nonExistentCourseId)).thenReturn(null);

Expand All @@ -182,7 +231,8 @@ void testExecute_courseDoesNotExist_failSilently() {
DeleteInstructorAction action = getAction(params);
MessageOutput actionOutput = (MessageOutput) getJsonResult(action).getOutput();

verify(mockLogic, times(0)).deleteInstructorCascade(nonExistentCourseId, instructor.getEmail());
verify(mockLogic, times(1)).getInstructorByGoogleId(nonExistentCourseId, instructor.getGoogleId());
verify(mockLogic, never()).deleteInstructorCascade(any(), any());
assertEquals("Instructor is successfully deleted.", actionOutput.getMessage());
}

Expand Down Expand Up @@ -272,7 +322,7 @@ void testSpecificAccessControl_instructorInDifferentCourse_cannotAccess() {

@Test
void testSpecificAccessControl_student_cannotAccess() {
loginAsStudent("student-googleId");
loginAsStudent(studentId);

String[] params = {
Const.ParamsNames.COURSE_ID, course.getId(),
Expand Down

0 comments on commit 9908492

Please sign in to comment.