From 13a1891efd4d44dc71597b2a7cd2dac08bed18e8 Mon Sep 17 00:00:00 2001 From: Wei Qing <48304907+weiquu@users.noreply.github.com> Date: Wed, 10 Jul 2024 23:28:34 +0800 Subject: [PATCH 1/2] [#12048] Migrate InstructorCourseStudentDetailsEditPageE2ETest (#13069) * migrate * get name from section and team * update team * fix data issues --------- Co-authored-by: Ching Ming Yuan Co-authored-by: domoberzin <74132255+domoberzin@users.noreply.github.com> --- ...orCourseStudentDetailsEditPageE2ETest.java | 71 ++++++++++ ...ructorCourseStudentDetailsEditPageSql.java | 81 ++++++++++++ ...ourseStudentDetailsEditPageE2ETestSql.json | 123 ++++++++++++++++++ src/e2e/resources/testng-e2e-sql.xml | 1 + 4 files changed, 276 insertions(+) create mode 100644 src/e2e/java/teammates/e2e/cases/sql/InstructorCourseStudentDetailsEditPageE2ETest.java create mode 100644 src/e2e/java/teammates/e2e/pageobjects/InstructorCourseStudentDetailsEditPageSql.java create mode 100644 src/e2e/resources/data/InstructorCourseStudentDetailsEditPageE2ETestSql.json diff --git a/src/e2e/java/teammates/e2e/cases/sql/InstructorCourseStudentDetailsEditPageE2ETest.java b/src/e2e/java/teammates/e2e/cases/sql/InstructorCourseStudentDetailsEditPageE2ETest.java new file mode 100644 index 00000000000..7d097199be4 --- /dev/null +++ b/src/e2e/java/teammates/e2e/cases/sql/InstructorCourseStudentDetailsEditPageE2ETest.java @@ -0,0 +1,71 @@ +package teammates.e2e.cases.sql; + +import org.testng.annotations.Test; + +import teammates.common.util.AppUrl; +import teammates.common.util.Const; +import teammates.e2e.pageobjects.InstructorCourseStudentDetailsEditPageSql; +import teammates.e2e.util.TestProperties; +import teammates.storage.sqlentity.Course; +import teammates.storage.sqlentity.Student; +import teammates.storage.sqlentity.Team; + +/** + * SUT: {@link Const.WebPageURIs#INSTRUCTOR_COURSE_STUDENT_DETAILS_EDIT_PAGE}. + */ +public class InstructorCourseStudentDetailsEditPageE2ETest extends BaseE2ETestCase { + private Student student; + private Student otherStudent; + private Course course; + + @Override + protected void prepareTestData() { + testData = removeAndRestoreDataBundle( + loadSqlDataBundle("/InstructorCourseStudentDetailsEditPageE2ETestSql.json")); + + student = testData.students.get("ICSDetEdit.jose.tmms"); + otherStudent = testData.students.get("ICSDetEdit.benny.c"); + course = testData.courses.get("ICSDetEdit.CS2104"); + } + + @Test + @Override + public void testAll() { + AppUrl editPageUrl = createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_COURSE_STUDENT_DETAILS_EDIT_PAGE) + .withCourseId(course.getId()) + .withStudentEmail(student.getEmail()); + InstructorCourseStudentDetailsEditPageSql editPage = + loginToPage(editPageUrl, InstructorCourseStudentDetailsEditPageSql.class, + testData.instructors.get("ICSDetEdit.instr").getGoogleId()); + + ______TS("verify loaded data"); + editPage.verifyStudentDetails(student); + + ______TS("edit student details"); + Team otherTeam = testData.teams.get("tm.e2e.ICSDetEdit.CS2104-SectionB-Team100"); + student.setName("edited name"); + student.setTeam(otherTeam); + student.setComments("edited comment"); + editPage.editStudentDetails(student); + + editPage.verifyStatusMessage("Student has been updated"); + verifyPresentInDatabase(student); + + ______TS("cannot edit to an existing email"); + editPage = getNewPageInstance(editPageUrl, InstructorCourseStudentDetailsEditPageSql.class); + editPage.editStudentEmailAndResendLinks(otherStudent.getEmail()); + + editPage.verifyStatusMessage("Trying to update to an email that is already in use"); + + ______TS("edit email and resend links"); + String newEmail = TestProperties.TEST_EMAIL; + student.setEmail(newEmail); + student.setGoogleId(null); + editPage.editStudentEmailAndResendLinks(newEmail); + + editPage.verifyStatusMessage("Student has been updated and email sent"); + verifyPresentInDatabase(student); + verifyEmailSent(newEmail, "TEAMMATES: Summary of course [" + + course.getName() + "][Course ID: " + course.getId() + "]"); + } +} diff --git a/src/e2e/java/teammates/e2e/pageobjects/InstructorCourseStudentDetailsEditPageSql.java b/src/e2e/java/teammates/e2e/pageobjects/InstructorCourseStudentDetailsEditPageSql.java new file mode 100644 index 00000000000..ddeba90b1f5 --- /dev/null +++ b/src/e2e/java/teammates/e2e/pageobjects/InstructorCourseStudentDetailsEditPageSql.java @@ -0,0 +1,81 @@ +package teammates.e2e.pageobjects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +import teammates.storage.sqlentity.Student; + +/** + * Represents the instructor course student details edit page of the website. + */ +public class InstructorCourseStudentDetailsEditPageSql extends AppPage { + + @FindBy (id = "course-id") + private WebElement courseId; + + @FindBy (id = "student-name") + private WebElement studentNameTextbox; + + @FindBy (id = "section-name") + private WebElement sectionNameTextbox; + + @FindBy (id = "team-name") + private WebElement teamNameTextbox; + + @FindBy (id = "new-student-email") + private WebElement studentEmailTextbox; + + @FindBy (id = "comments") + private WebElement commentsTextbox; + + @FindBy (id = "btn-submit") + private WebElement submitButton; + + public InstructorCourseStudentDetailsEditPageSql(Browser browser) { + super(browser); + } + + @Override + protected boolean containsExpectedPageContents() { + return getPageTitle().contains("Edit Student Details"); + } + + public void verifyIsCorrectPage(String expectedCourseId, String expectedStudentEmail) { + assertEquals(expectedCourseId, courseId.getText()); + assertEquals(expectedStudentEmail, studentEmailTextbox.getAttribute("value")); + } + + public void verifyStudentDetails(Student student) { + assertEquals(student.getCourse().getId(), courseId.getText()); + assertEquals(student.getName(), studentNameTextbox.getAttribute("value")); + if (student.getSection() == null) { + assertEquals("None", sectionNameTextbox.getAttribute("value")); + } else { + assertEquals(student.getSection().getName(), sectionNameTextbox.getAttribute("value")); + } + assertEquals(student.getTeam().getName(), teamNameTextbox.getAttribute("value")); + assertEquals(student.getEmail(), studentEmailTextbox.getAttribute("value")); + if (student.getComments() != null) { + assertEquals(student.getComments(), commentsTextbox.getAttribute("value")); + } + } + + public void editStudentDetails(Student newStudent) { + fillTextBox(studentNameTextbox, newStudent.getName()); + fillTextBox(sectionNameTextbox, newStudent.getSection().getName()); + fillTextBox(teamNameTextbox, newStudent.getTeam().getName()); + if (newStudent.getComments() != null) { + fillTextBox(commentsTextbox, newStudent.getComments()); + } + clickAndConfirm(submitButton); + } + + public void editStudentEmailAndResendLinks(String newEmail) { + fillTextBox(studentEmailTextbox, newEmail); + click(submitButton); + click(waitForElementPresence(By.id("btn-resend-links"))); + } +} diff --git a/src/e2e/resources/data/InstructorCourseStudentDetailsEditPageE2ETestSql.json b/src/e2e/resources/data/InstructorCourseStudentDetailsEditPageE2ETestSql.json new file mode 100644 index 00000000000..c72fabfb3be --- /dev/null +++ b/src/e2e/resources/data/InstructorCourseStudentDetailsEditPageE2ETestSql.json @@ -0,0 +1,123 @@ +{ + "accounts": { + "ICSDetEdit.instr": { + "id": "00000000-0000-4000-8000-000000000001", + "googleId": "tm.e2e.ICSDetEdit.instr", + "name": "Teammates Test", + "email": "ICSDetEdit.instr@gmail.tmt" + }, + "José Gómez": { + "id": "00000000-0000-4000-8000-000000000002", + "googleId": "tm.e2e.ICSDetEdit.jose.tmms", + "name": "José Gómez", + "email": "ICSDetEdit.jose.tmms@gmail.tmt" + } + }, + "accountRequests": {}, + "courses": { + "ICSDetEdit.CS2104": { + "id": "tm.e2e.ICSDetEdit.CS2104", + "name": "Programming Language Concepts", + "institute": "TEAMMATES Test Institute 1", + "timeZone": "UTC" + } + }, + "sections": { + "tm.e2e.ICSDetEdit.CS2104-SectionA": { + "id": "00000000-0000-4000-8000-000000000201", + "course": { + "id": "tm.e2e.ICSDetEdit.CS2104" + }, + "name": "Section A" + }, + "tm.e2e.ICSDetEdit.CS2104-SectionB": { + "id": "00000000-0000-4000-8000-000000000202", + "course": { + "id": "tm.e2e.ICSDetEdit.CS2104" + }, + "name": "Section B" + } + }, + "teams": { + "tm.e2e.ICSDetEdit.CS2104-SectionA-Team1": { + "id": "00000000-0000-4000-8000-000000000301", + "section": { + "id": "00000000-0000-4000-8000-000000000201" + }, + "name": "Team 1" + }, + "tm.e2e.ICSDetEdit.CS2104-SectionB-Team100": { + "id": "00000000-0000-4000-8000-000000000302", + "section": { + "id": "00000000-0000-4000-8000-000000000202" + }, + "name": "Team 100" + } + }, + "deadlineExtensions": {}, + "instructors": { + "ICSDetEdit.instr": { + "id": "00000000-0000-4000-8000-000000000501", + "course": { + "id": "tm.e2e.ICSDetEdit.CS2104" + }, + "account": { + "id": "00000000-0000-4000-8000-000000000001" + }, + "name": "Teammates Test", + "email": "ICSDetEdit.instr@gmail.tmt", + "role": "INSTRUCTOR_PERMISSION_ROLE_COOWNER", + "isDisplayedToStudents": false, + "displayName": "Co-owner", + "privileges": { + "courseLevel": { + "canViewStudentInSections": true, + "canSubmitSessionInSections": true, + "canModifySessionCommentsInSections": true, + "canModifyCourse": true, + "canViewSessionInSections": true, + "canModifySession": true, + "canModifyStudent": true, + "canModifyInstructor": true + }, + "sectionLevel": {}, + "sessionLevel": {} + } + } + }, + "students": { + "ICSDetEdit.jose.tmms": { + "id": "00000000-0000-4000-8000-000000000601", + "account": { + "id": "00000000-0000-4000-8000-000000000002" + }, + "course": { + "id": "tm.e2e.ICSDetEdit.CS2104" + }, + "team": { + "id": "00000000-0000-4000-8000-000000000301" + }, + "email": "ICSDetEdit.jose.tmms@gmail.tmt", + "name": "José Gómez", + "comments": "This student's name is José Gómez" + }, + "ICSDetEdit.benny.c": { + "id": "00000000-0000-4000-8000-000000000602", + "course": { + "id": "tm.e2e.ICSDetEdit.CS2104" + }, + "team": { + "id": "00000000-0000-4000-8000-000000000301" + }, + "email": "ICSDetEdit.benny.c.tmms@gmail.tmt", + "name": "Benny Charles", + "comments": "This student's name is Benny Charles" + } + }, + "feedbackSessions": {}, + "feedbackQuestions": {}, + "feedbackResponses": {}, + "feedbackResponseComments": {}, + "notifications": {}, + "readNotifications": {} +} diff --git a/src/e2e/resources/testng-e2e-sql.xml b/src/e2e/resources/testng-e2e-sql.xml index 7bd113b3dbc..b3b8fe5bc6f 100644 --- a/src/e2e/resources/testng-e2e-sql.xml +++ b/src/e2e/resources/testng-e2e-sql.xml @@ -23,6 +23,7 @@ + From 3f5f68dc971ebabc2eb0f5d8541a24b36d716807 Mon Sep 17 00:00:00 2001 From: Francisco Savala <99670885+franciscoSavala@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:53:36 -0300 Subject: [PATCH 2/2] [#13104] Accounts request form: auto-unify country names (#13117) * Added unified countries for InstructorRequestForm * Added tests for InstructorRequestForm for unified countries * Fixed lint errors for InstructorRequestForm * Added countries and moved countrymapping * Tests Fixed --------- Co-authored-by: Francisco Savala Co-authored-by: Wei Qing <48304907+weiquu@users.noreply.github.com> Co-authored-by: Ching Ming Yuan Co-authored-by: domoberzin <74132255+domoberzin@users.noreply.github.com> --- .../instructor-request-form.component.spec.ts | 20 +++++++++++++++++++ .../instructor-request-form.component.ts | 17 ++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts index a0c9bbac2f2..ff055296c3c 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts @@ -114,4 +114,24 @@ describe('InstructorRequestFormComponent', () => { expect(accountService.createAccountRequest).toHaveBeenCalledTimes(1); expect(accountService.createAccountRequest).toHaveBeenCalledWith(expect.objectContaining(typicalCreateRequest)); }); + + it('should auto-unify country when applicable', () => { + jest.spyOn(accountService, 'createAccountRequest').mockReturnValue( + new Observable((subscriber) => { subscriber.next(); })); + const unitedStatesModel: InstructorRequestFormModel = { + ...typicalModel, + country: 'españa', + }; + const unitedStatesCreateRequest: AccountCreateRequest = { + ...typicalCreateRequest, + instructorInstitution: `${unitedStatesModel.institution}, Spain`, + }; + fillFormWith(unitedStatesModel); + component.onSubmit(); + + expect(accountService.createAccountRequest).toHaveBeenCalledTimes(1); + expect(accountService.createAccountRequest).toHaveBeenCalledWith( + expect.objectContaining(unitedStatesCreateRequest)); + }); + }); diff --git a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts index 7caa14e3bd9..a5fd36e8e38 100644 --- a/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts +++ b/src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts @@ -115,11 +115,24 @@ export class InstructorRequestFormComponent { const name = this.name.value!.trim(); const email = this.email.value!.trim(); const comments = this.comments.value!.trim(); - + // Country Mapping + const countryMapping: { [key: string]: string } = { + 'united states': 'USA', + us: 'USA', + america: 'USA', + uk: 'United Kingdom', + deutschland: 'Germany', + 'united arab emirates': 'UAE', + españa: 'Spain', + méxico: 'Mexico', + belgië: 'Belgium', + holland: 'Netherlands', + }; // Combine country and institution const country = this.country.value!.trim(); + const mappedCountry = countryMapping[country.toLowerCase()] || country; const institution = this.institution.value!.trim(); - const combinedInstitution = `${institution}, ${country}`; + const combinedInstitution = `${institution}, ${mappedCountry}`; const requestData: AccountCreateRequest = { instructorEmail: email,