Skip to content

Commit

Permalink
Merge branch 'master' into combine-account-requests
Browse files Browse the repository at this point in the history
  • Loading branch information
mingyuanc authored Jul 30, 2024
2 parents 35471f2 + ea30a05 commit 3e6daf8
Show file tree
Hide file tree
Showing 46 changed files with 1,270 additions and 87 deletions.
74 changes: 46 additions & 28 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,49 @@ jobs:
permissions:
pull-requests: write
steps:
- uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
})
const isTitleValid = /^\[#\d+\] /.test(pr.data.title)
const isDescriptionValid = /([Ff]ix(es|ed)?|[Cc]lose(s|d)?|[Rr]esolve(s|d)?|[Pp]art [Oo]f) #\d+/.test(pr.data.body)
if (isTitleValid && isDescriptionValid) {
return
}
let body = `Hi @${pr.data.user.login}, thank you for your interest in contributing to TEAMMATES!
However, your PR does not appear to follow our [contribution guidelines](https://teammates.github.io/teammates/process.html#step-4-submit-a-pr):\n\n`
if (!isTitleValid) {
body += "- Title must start with the issue number the PR is fixing in square brackets, e.g. `[#<issue-number>]`\n"
}
if (!isDescriptionValid) {
body += "- Description must reference the issue number the PR is fixing, e.g. `Fixes #<issue-number>` (or `Part of #<issue-number>` if the PR does not address the issue fully)\n"
}
body += "\nPlease address the above before we proceed to review your PR."
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body,
})
- uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
})
const isTitleValid = /^\[#\d+\] /.test(pr.data.title)
const isDescriptionValid = /([Ff]ix(es|ed)?|[Cc]lose(s|d)?|[Rr]esolve(s|d)?|[Pp]art [Oo]f) #\d+/.test(pr.data.body)
const descriptionRegex = /(?:[Ff]ix(?:es|ed)?|[Cc]lose(?:s|d)?|[Rr]esolve(?:s|d)?|[Pp]art [Oo]f) #(\d+)/
const extractIssueNumber = (description) => {
const match = description.match(descriptionRegex)
return match ? parseInt(match[1]) : null
};
const issueNumber = extractIssueNumber(pr.data.body)
let isIssueOpen = false
if (issueNumber) {
const issue = await github.rest.issues.get({
owner: 'TEAMMATES',
repo: 'teammates',
issue_number: issueNumber
})
isIssueOpen = issue.data.state === 'open'
if (isTitleValid && isDescriptionValid && isIssueOpen) {
return
}
}
let body = `Hi @${pr.data.user.login}, thank you for your interest in contributing to TEAMMATES!
However, your PR does not appear to follow our [contribution guidelines](https://teammates.github.io/teammates/process.html#step-4-submit-a-pr):\n\n`
if (!isTitleValid) {
body += "- Title must start with the issue number the PR is fixing in square brackets, e.g. `[#<issue-number>]`\n"
}
if (!isDescriptionValid) {
body += "- Description must reference the issue number the PR is fixing, e.g. `Fixes #<issue-number>` (or `Part of #<issue-number>` if the PR does not address the issue fully)\n"
}
if (!isIssueOpen && issueNumber) {
body += "- The issue referenced in the description (#" + issueNumber + ") is not open.\n"
}
body += "\nPlease address the above before we proceed to review your PR."
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body,
})
Original file line number Diff line number Diff line change
@@ -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() + "]");
}
}
Original file line number Diff line number Diff line change
@@ -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")));
}
}
Original file line number Diff line number Diff line change
@@ -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": {}
}
1 change: 1 addition & 0 deletions src/e2e/resources/testng-e2e-sql.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<class name="teammates.e2e.cases.sql.InstructorNotificationsPageE2ETest" />
<class name="teammates.e2e.cases.sql.StudentCourseDetailsPageE2ETest" />
<class name="teammates.e2e.cases.sql.RequestPageE2ETest" />
<class name="teammates.e2e.cases.sql.InstructorCourseStudentDetailsEditPageE2ETest" />
</classes>
</test>
</suite>
Loading

0 comments on commit 3e6daf8

Please sign in to comment.