Skip to content
This repository has been archived by the owner on Apr 24, 2022. It is now read-only.

Commit

Permalink
[TEAMMATES#11553] Make account requests searchable in admin search pa…
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelfangjw committed Feb 13, 2022
1 parent bb36f4a commit 6454c30
Show file tree
Hide file tree
Showing 37 changed files with 1,313 additions and 20 deletions.
6 changes: 6 additions & 0 deletions solr/solr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ bin/solr create -c instructors -s 2 -rf 2
bin/solr config -c instructors -p 8983 -action set-user-property -property update.autoCreateFields -value false
curl -X POST -H 'Content-type: application/json' --data-binary '{"add-field": {"name": "courseId", "type": "string"}}' localhost:8983/solr/instructors/schema
curl -X POST -H 'Content-type: application/json' --data-binary '{"add-field": {"name": "email", "type": "string"}}' localhost:8983/solr/instructors/schema

# Create core to run account requests collection
bin/solr create -c accountrequests -s 2 -rf 2
bin/solr config -c accountrequests -p 8983 -action set-user-property -property update.autoCreateFields -value false
curl -X POST -H 'Content-type: application/json' --data-binary '{"add-field": {"name": "email", "type": "string"}}' localhost:8983/solr/accountrequests/schema
curl -X POST -H 'Content-type: application/json' --data-binary '{"add-field": {"name": "institute", "type": "string"}}' localhost:8983/solr/accountrequests/schema
17 changes: 14 additions & 3 deletions src/e2e/java/teammates/e2e/cases/AdminSearchPageE2ETest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.testng.annotations.Test;

import teammates.common.datatransfer.attributes.AccountAttributes;
import teammates.common.datatransfer.attributes.AccountRequestAttributes;
import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;
import teammates.common.datatransfer.attributes.InstructorAttributes;
import teammates.common.datatransfer.attributes.StudentAttributes;
Expand Down Expand Up @@ -43,6 +44,7 @@ public void testAll() {
AccountAttributes studentAccount = testData.accounts.get("student1InCourse1");
InstructorAttributes instructor = testData.instructors.get("instructor1OfCourse1");
AccountAttributes instructorAccount = testData.accounts.get("instructor1OfCourse1");
AccountRequestAttributes accountRequest = testData.accountRequests.get("instructor1OfCourse1");

______TS("Typical case: Search student email");
String searchContent = student.getEmail();
Expand Down Expand Up @@ -99,18 +101,27 @@ public void testAll() {
searchPage.verifyRegenerateInstructorKey(instructor, originalJoinLink);
searchPage.waitForPageToLoad();

______TS("Typical case: Search common course id");
______TS("Typical case: Search for account request by email");
searchPage.clearSearchBox();
searchContent = student.getCourse();
searchContent = accountRequest.getEmail();
searchPage.inputSearchContent(searchContent);
searchPage.clickSearchButton();
searchPage.verifyAccountRequestRowContent(accountRequest);
searchPage.verifyAccountRequestExpandedLinks(accountRequest);

______TS("Typical case: Search common search key");
searchPage.clearSearchBox();
searchContent = "Course1";
searchPage.inputSearchContent(searchContent);
searchPage.clickSearchButton();
searchPage.verifyStudentRowContent(student, studentAccount, studentDetails, studentManageAccountLink,
studentHomePageLink);
searchPage.verifyInstructorRowContent(instructor, instructorAccount, instructorManageAccountLink,
instructorHomePageLink);
searchPage.verifyAccountRequestRowContent(accountRequest);

______TS("Typical case: Expand and collapse links");
searchPage.verifyLinkExpansionButtons(student, instructor);
searchPage.verifyLinkExpansionButtons(student, instructor, accountRequest);
}

private String getExpectedStudentDetails(StudentAttributes student) {
Expand Down
102 changes: 101 additions & 1 deletion src/e2e/java/teammates/e2e/pageobjects/AdminSearchPage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package teammates.e2e.pageobjects;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;

import java.util.List;
Expand All @@ -11,6 +12,7 @@
import org.openqa.selenium.support.FindBy;

import teammates.common.datatransfer.attributes.AccountAttributes;
import teammates.common.datatransfer.attributes.AccountRequestAttributes;
import teammates.common.datatransfer.attributes.InstructorAttributes;
import teammates.common.datatransfer.attributes.StudentAttributes;
import teammates.common.util.Const;
Expand All @@ -33,8 +35,15 @@ public class AdminSearchPage extends AppPage {
private static final int INSTRUCTOR_COL_INSTITUTE = 4;
private static final int INSTRUCTOR_COL_OPTIONS = 5;

private static final int ACCOUNT_REQUEST_COL_NAME = 1;
private static final int ACCOUNT_REQUEST_COL_EMAIL = 2;
private static final int ACCOUNT_REQUEST_COL_INSTITUTE = 3;
private static final int ACCOUNT_REQUEST_COL_CREATED_AT = 4;
private static final int ACCOUNT_REQUEST_COL_REGISTERED_AT = 5;

private static final String EXPANDED_ROWS_HEADER_EMAIL = "Email";
private static final String EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK = "Course Join Link";
private static final String EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK = "Account Registration Link";
private static final String LINK_TEXT_RESET_GOOGLE_ID = "Reset Google ID";

@FindBy(id = "search-box")
Expand All @@ -49,12 +58,18 @@ public class AdminSearchPage extends AppPage {
@FindBy(id = "show-instructor-links")
private WebElement expandInstructorLinksButton;

@FindBy(id = "show-account-request-links")
private WebElement expandAccountRequestLinksButton;

@FindBy(id = "hide-student-links")
private WebElement collapseStudentLinksButton;

@FindBy(id = "hide-instructor-links")
private WebElement collapseInstructorLinksButton;

@FindBy(id = "hide-account-request-links")
private WebElement collapseAccountRequestLinksButton;

public AdminSearchPage(Browser browser) {
super(browser);
}
Expand Down Expand Up @@ -103,6 +118,11 @@ public void clickExpandInstructorLinks() {
waitForPageToLoad();
}

public void clickExpandAccountRequestLinks() {
click(expandAccountRequestLinksButton);
waitForPageToLoad();
}

public void clickCollapseStudentLinks() {
click(collapseStudentLinksButton);
waitForPageToLoad();
Expand All @@ -113,6 +133,11 @@ public void clickCollapseInstructorLinks() {
waitForPageToLoad();
}

public void clickCollapseAccountRequestLinks() {
click(collapseAccountRequestLinksButton);
waitForPageToLoad();
}

public WebElement getStudentRow(StudentAttributes student) {
String details = String.format("%s [%s] (%s)", student.getCourse(),
student.getSection() == null ? Const.DEFAULT_SECTION : student.getSection(), student.getTeam());
Expand Down Expand Up @@ -230,6 +255,44 @@ public void resetInstructorGoogleId(InstructorAttributes instructor) {
waitForElementStaleness(link);
}

public WebElement getAccountRequestRow(AccountRequestAttributes accountRequest) {
String email = accountRequest.getEmail();
String institute = accountRequest.getInstitute();
List<WebElement> rows = browser.driver.findElements(By.cssSelector("#search-table-account-request tbody tr"));
for (WebElement row : rows) {
List<WebElement> columns = row.findElements(By.tagName("td"));
if (columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1).getAttribute("innerHTML").contains(email)
&& columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1).getAttribute("innerHTML").contains(institute)) {
return row;
}
}
return null;
}

public String getAccountRequestName(WebElement accountRequestRow) {
return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_NAME);
}

public String getAccountRequestEmail(WebElement accountRequestRow) {
return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_EMAIL);
}

public String getAccountRequestInstitute(WebElement accountRequestRow) {
return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_INSTITUTE);
}

public String getAccountRequestCreatedAt(WebElement accountRequestRow) {
return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_CREATED_AT);
}

public String getAccountRequestRegisteredAt(WebElement accountRequestRow) {
return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_REGISTERED_AT);
}

public String getAccountRequestRegistrationLink(WebElement accountRequestRow) {
return getExpandedRowInputValue(accountRequestRow, EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK);
}

public int getNumExpandedRows(WebElement row) {
String xpath = "following-sibling::tr[1]/td/ul/li";
return row.findElements(By.xpath(xpath)).size();
Expand Down Expand Up @@ -333,31 +396,68 @@ public void verifyInstructorExpandedLinks(InstructorAttributes instructor) {
assertNotEquals("", actualJoinLink);
}

public void verifyLinkExpansionButtons(StudentAttributes student, InstructorAttributes instructor) {
public void verifyAccountRequestRowContent(AccountRequestAttributes accountRequest) {
WebElement accountRequestRow = getAccountRequestRow(accountRequest);
String actualName = getAccountRequestName(accountRequestRow);
String actualEmail = getAccountRequestEmail(accountRequestRow);
String actualInstitute = getAccountRequestInstitute(accountRequestRow);
String actualCreatedAt = getAccountRequestCreatedAt(accountRequestRow);
String actualRegisteredAt = getAccountRequestRegisteredAt(accountRequestRow);

assertEquals(accountRequest.getName(), actualName);
assertEquals(accountRequest.getEmail(), actualEmail);
assertEquals(accountRequest.getInstitute(), actualInstitute);
assertFalse(actualCreatedAt.isBlank());
if (actualRegisteredAt == null) {
assertEquals("Not Registered Yet", actualRegisteredAt);
} else {
assertFalse(actualCreatedAt.isBlank());
}
}

public void verifyAccountRequestExpandedLinks(AccountRequestAttributes accountRequest) {
clickExpandAccountRequestLinks();
WebElement accountRequestRow = getAccountRequestRow(accountRequest);
String actualRegistrationLink = getAccountRequestRegistrationLink(accountRequestRow);

assertFalse(actualRegistrationLink.isBlank());
}

public void verifyLinkExpansionButtons(StudentAttributes student,
InstructorAttributes instructor, AccountRequestAttributes accountRequest) {
WebElement studentRow = getStudentRow(student);
WebElement instructorRow = getInstructorRow(instructor);
WebElement accountRequestRow = getAccountRequestRow(accountRequest);

clickExpandStudentLinks();
clickExpandInstructorLinks();
clickExpandAccountRequestLinks();
int numExpandedStudentRows = getNumExpandedRows(studentRow);
int numExpandedInstructorRows = getNumExpandedRows(instructorRow);
int numExpandedAccountRequestRows = getNumExpandedRows(accountRequestRow);
assertNotEquals(numExpandedStudentRows, 0);
assertNotEquals(numExpandedInstructorRows, 0);
assertNotEquals(numExpandedAccountRequestRows, 0);

clickCollapseInstructorLinks();
numExpandedStudentRows = getNumExpandedRows(studentRow);
numExpandedInstructorRows = getNumExpandedRows(instructorRow);
numExpandedAccountRequestRows = getNumExpandedRows(accountRequestRow);
assertNotEquals(numExpandedStudentRows, 0);
assertEquals(numExpandedInstructorRows, 0);
assertNotEquals(numExpandedAccountRequestRows, 0);

clickExpandInstructorLinks();
clickCollapseStudentLinks();
clickCollapseAccountRequestLinks();
waitUntilAnimationFinish();

numExpandedStudentRows = getNumExpandedRows(studentRow);
numExpandedInstructorRows = getNumExpandedRows(instructorRow);
numExpandedAccountRequestRows = getNumExpandedRows(accountRequestRow);
assertEquals(numExpandedStudentRows, 0);
assertNotEquals(numExpandedInstructorRows, 0);
assertEquals(numExpandedAccountRequestRows, 0);
}

public void verifyRegenerateStudentKey(StudentAttributes student, String originalJoinLink) {
Expand Down
7 changes: 7 additions & 0 deletions src/e2e/java/teammates/e2e/util/TestDataValidityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ public void checkTestDataValidity() throws IOException {
.add("Invalid response recipient email: " + response.getRecipient());
}
});

dataBundle.accountRequests.forEach((id, accountRequest) -> {
if (!isValidTestEmail(accountRequest.getEmail())) {
errors.computeIfAbsent(pathString, k -> new ArrayList<>())
.add("Invalid account request email: " + accountRequest.getEmail());
}
});
});
}

Expand Down
24 changes: 23 additions & 1 deletion src/e2e/resources/data/AdminSearchPageE2ETest.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"googleId": "tm.e2e.ASearch.student1",
"email": "ASearch.student1@gmail.tmt",
"course": "tm.e2e.ASearch.course1",
"name": "Student1 in course1",
"name": "Student1 in Course1",
"comments": "comment for student1InCourse1",
"team": "Team 1.1",
"section": "Section 1"
Expand Down Expand Up @@ -132,5 +132,27 @@
"isClosingEmailEnabled": true,
"isPublishedEmailEnabled": true
}
},
"accountRequests": {
"instructor1OfCourse1": {
"name": "Instructor1 of Course1",
"email": "ASearch.instructor1@gmail.tmt",
"institute": "TEAMMATES Test Institute 1",
"createdAt": "2011-01-01T00:00:00Z",
"registeredAt": "1970-02-14T00:00:00Z"
},
"instructor2OfCourse1": {
"name": "Instructor2 of Course1",
"email": "ASearch.instructor2@gmail.tmt",
"institute": "TEAMMATES Test Institute 1",
"createdAt": "2011-01-01T00:00:00Z",
"registeredAt": "1970-02-14T00:00:00Z"
},
"unregisteredInstructor1": {
"name": "Typical Instructor Name",
"email": "ASearch.unregisteredinstructor1@gmail.tmt",
"institute": "TEAMMATES Test Institute 1",
"createdAt": "2011-01-01T00:00:00Z"
}
}
}
3 changes: 3 additions & 0 deletions src/main/java/teammates/common/util/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ public static class ResourceURIs {
public static final String SESSION_STATS = URI_PREFIX + "/session/stats";
public static final String SESSION_SUBMITTED_GIVER_SET = URI_PREFIX + "/session/submitted/giverset";
public static final String SESSIONS = URI_PREFIX + "/sessions";
public static final String SEARCH_ACCOUNT_REQUESTS = URI_PREFIX + "/search/accountrequests";
public static final String SEARCH_INSTRUCTORS = URI_PREFIX + "/search/instructors";
public static final String SEARCH_STUDENTS = URI_PREFIX + "/search/students";
public static final String BIN_SESSION = URI_PREFIX + "/bin/session";
Expand Down Expand Up @@ -403,6 +404,8 @@ public static class TaskQueue {

public static final String SEARCH_INDEXING_QUEUE_NAME = "search-indexing-queue";
public static final String INSTRUCTOR_SEARCH_INDEXING_WORKER_URL = URI_PREFIX + "/instructorSearchIndexing";
public static final String ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL =
URI_PREFIX + "/accountRequestSearchIndexing";
public static final String STUDENT_SEARCH_INDEXING_WORKER_URL = URI_PREFIX + "/studentSearchIndexing";
}

Expand Down
20 changes: 20 additions & 0 deletions src/main/java/teammates/logic/api/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -1469,4 +1469,24 @@ public AccountRequestAttributes getAccountRequest(String email, String institute
return accountRequestsLogic.getAccountRequest(email, institute);
}

/**
* This is used by admin to search account requests in the whole system.
*
* @return A list of {@link AccountRequestAttributes} or {@code null} if no match found.
*/
public List<AccountRequestAttributes> searchAccountRequestsInWholeSystem(String queryString)
throws SearchServiceException {
assert queryString != null;

return accountRequestsLogic.searchAccountRequestsInWholeSystem(queryString);
}

/**
* Creates or updates search document for the given account request.
*
* @see AccountRequestsLogic#putDocument(AccountRequestAttributes)
*/
public void putAccountRequestDocument(AccountRequestAttributes accountRequest) throws SearchServiceException {
accountRequestsLogic.putDocument(accountRequest);
}
}
15 changes: 15 additions & 0 deletions src/main/java/teammates/logic/api/TaskQueuer.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ public void scheduleInstructorForSearchIndexing(String courseId, String email) {
paramMap, null);
}

/**
* Schedules for the search indexing of the account request identified by {@code email} and {@code institute}.
*
* @param email the email associated with the account request
* @param institute the institute associated with the account request
*/
public void scheduleAccountRequestForSearchIndexing(String email, String institute) {
Map<String, String> paramMap = new HashMap<>();
paramMap.put(ParamsNames.INSTRUCTOR_EMAIL, email);
paramMap.put(ParamsNames.INSTRUCTOR_INSTITUTION, institute);

addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL,
paramMap, null);
}

/**
* Schedules for the search indexing of the student identified by {@code courseId} and {@code email}.
*
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/teammates/logic/core/AccountRequestsLogic.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package teammates.logic.core;

import java.util.List;

import teammates.common.datatransfer.attributes.AccountRequestAttributes;
import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.exception.SearchServiceException;
import teammates.storage.api.AccountRequestsDb;

/**
Expand Down Expand Up @@ -78,4 +81,23 @@ public AccountRequestAttributes getAccountRequestForRegistrationKey(String regis
return accountRequestsDb.getAccountRequestForRegistrationKey(registrationKey);
}

/**
* Creates or updates search document for the given account request.
*
* @param accountRequest the account request to be put into documents
*/
public void putDocument(AccountRequestAttributes accountRequest) throws SearchServiceException {
accountRequestsDb.putDocument(accountRequest);
}

/**
* Searches for account requests in the whole system.
*
* @return A list of {@link AccountRequestAttributes} or {@code null} if no match found.
*/
public List<AccountRequestAttributes> searchAccountRequestsInWholeSystem(String queryString)
throws SearchServiceException {
return accountRequestsDb.searchAccountRequestsInWholeSystem(queryString);
}

}
Loading

0 comments on commit 6454c30

Please sign in to comment.