diff --git a/src/main/java/teammates/ui/constants/ApiStringConst.java b/src/main/java/teammates/ui/constants/ApiStringConst.java
new file mode 100644
index 00000000000..5158f2ac964
--- /dev/null
+++ b/src/main/java/teammates/ui/constants/ApiStringConst.java
@@ -0,0 +1,40 @@
+package teammates.ui.constants;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import teammates.common.util.FieldValidator;
+
+/**
+ * Special constants used by the back-end.
+ */
+public enum ApiStringConst {
+ // CHECKSTYLE.OFF:JavadocVariable
+ EMAIL_REGEX(escapeRegex(FieldValidator.REGEX_EMAIL));
+ // CHECKSTYLE.ON:JavadocVariable
+
+ private final Object value;
+
+ ApiStringConst(Object value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Escape regex pattern strings to ensure the pattern remains valid when converted to JS.
+ */
+ private static String escapeRegex(String regexStr) {
+ String escapedRegexStr = regexStr;
+ // Double escape backslashes
+ escapedRegexStr = escapedRegexStr.replace("\\", "\\\\");
+ // Replace possessive zero or more times quantifier *+ that the email pattern uses
+ // with greedy zero or more times quantifier *
+ // as possessive quantifiers are not supported in JavaScript
+ escapedRegexStr = escapedRegexStr.replace("*+", "*");
+ return escapedRegexStr;
+ }
+
+}
diff --git a/src/web/app/pages-static/request-page/__snapshots__/request-page.component.spec.ts.snap b/src/web/app/pages-static/request-page/__snapshots__/request-page.component.spec.ts.snap
index aab4f634f16..3167fed5fd4 100644
--- a/src/web/app/pages-static/request-page/__snapshots__/request-page.component.spec.ts.snap
+++ b/src/web/app/pages-static/request-page/__snapshots__/request-page.component.spec.ts.snap
@@ -63,16 +63,6 @@ exports[`RequestPageComponent should render correctly after form is submitted 1`
js@exampleu.edu
-
Comments |
diff --git a/src/web/app/pages-static/request-page/request-page.component.spec.ts b/src/web/app/pages-static/request-page/request-page.component.spec.ts
index 07b1c5d5dd2..9f4c3042247 100644
--- a/src/web/app/pages-static/request-page/request-page.component.spec.ts
+++ b/src/web/app/pages-static/request-page/request-page.component.spec.ts
@@ -42,7 +42,6 @@ describe('RequestPageComponent', () => {
institution: 'University of Example',
country: 'Example Republic',
email: 'js@exampleu.edu',
- homePage: 'u.exampleu.edu/jsmith',
comments: '',
};
fixture.detectChanges();
diff --git a/src/web/app/pages-static/request-page/request-page.module.ts b/src/web/app/pages-static/request-page/request-page.module.ts
index 7333207fc0b..12a9d337875 100644
--- a/src/web/app/pages-static/request-page/request-page.module.ts
+++ b/src/web/app/pages-static/request-page/request-page.module.ts
@@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
+import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
import { InstructorRequestFormComponent } from './instructor-request-form/instructor-request-form.component';
import { RequestPageComponent } from './request-page.component';
import { TeammatesRouterModule } from '../../components/teammates-router/teammates-router.module';
@@ -29,6 +30,7 @@ const routes: Routes = [
RouterModule.forChild(routes),
TeammatesRouterModule,
ReactiveFormsModule,
+ NgbAlertModule,
],
})
export class RequestPageModule { }
diff --git a/src/web/types/const.spec.ts b/src/web/types/const.spec.ts
index f5f403835ec..6bc4e7112ec 100644
--- a/src/web/types/const.spec.ts
+++ b/src/web/types/const.spec.ts
@@ -1,4 +1,4 @@
-import { ApiConst } from './api-const';
+import { ApiConst, ApiStringConst } from './api-const';
import { FeedbackQuestionType } from './api-output';
import {
DEFAULT_INSTRUCTOR_PRIVILEGE,
@@ -68,6 +68,12 @@ describe('Constants', () => {
expect(typeof ApiConst.NO_VALUE).toEqual('number');
});
+ // Here we test that the constants are strings
+ it('should generate string constants correctly', () => {
+ expect(typeof ApiStringConst.EMAIL_REGEX).toEqual('string');
+ expect(() => new RegExp(ApiStringConst.EMAIL_REGEX)).not.toThrow();
+ });
+
// Here we test that:
// 1. The string is parseable to JSON
// 2. The question type is correct
diff --git a/src/web/types/form-validator.ts b/src/web/types/form-validator.ts
index c2f44cf5beb..ea18815ca5d 100644
--- a/src/web/types/form-validator.ts
+++ b/src/web/types/form-validator.ts
@@ -1,4 +1,4 @@
-import { ApiConst } from './api-const';
+import { ApiConst, ApiStringConst } from './api-const';
/**
* Represents the root FormValidator object of all form fields.
@@ -33,4 +33,35 @@ export enum FormValidator {
* Max length for the 'E-mail Address` field.
*/
EMAIL_MAX_LENGTH = ApiConst.EMAIL_MAX_LENGTH,
+
+ /**
+ * Regex used to verify emails in the back-end.
+ */
+ EMAIL_REGEX = ApiStringConst.EMAIL_REGEX,
+
+ /**
+ * Regex used to verify names.
+ *
+ * Based on back-end's `FieldValidator.REGEX_NAME`.
+ * The back-end regex is not converted to use here as the pattern syntax is not accepted in JS.
+ */
+ NAME_REGEX = '^[a-zA-Z0-9][^|%]*$',
+
+ /**
+ * Regex used to verify country names.
+ *
+ * Based on back-end's `FieldValidator.REGEX_NAME`, but without needing to start with alphanumeric
+ * as the country is added to the end of the combined institute string.
+ */
+ COUNTRY_REGEX = '^[^|%]*$',
+
+ /**
+ * Max length for institution name in account request. (to be combined with country)
+ */
+ INSTITUTION_NAME_MAX_LENGTH = 86,
+
+ /**
+ * Max length for country in account request. (to be combined with institution name)
+ */
+ COUNTRY_NAME_MAX_LENGTH = 40,
}
|