Skip to content

Commit

Permalink
[#11329] Release V8.0.0 (#11343)
Browse files Browse the repository at this point in the history
  • Loading branch information
wkurniawan07 authored Aug 7, 2021
1 parent 389d40b commit 9ff5424
Show file tree
Hide file tree
Showing 27 changed files with 175 additions and 129 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ about: Report a bug or defect in the application

<!-- Issue title: [brief description of bug] -->

- **Environment**: <!-- The environment in which you encountered the bug, e.g. live server at `V7.0.0`, `master` branch at commit 1234567. -->
- **Environment**: <!-- The environment in which you encountered the bug, e.g. live server at `V8.0.0`, `master` branch at commit 1234567. -->

**Steps to reproduce**

Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ about: Request a new or a change to existing user-facing feature

<!-- Issue title: [brief description of feature/enhancement] -->

- **Environment**: <!-- The environment in which the said feature/enhancement is absent, e.g. live server at `V7.0.0`, `master` branch at commit 1234567. -->
- **Environment**: <!-- The environment in which the said feature/enhancement is absent, e.g. live server at `V8.0.0`, `master` branch at commit 1234567. -->

**Description of feature/enhancement**

Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ dependencies {
// For using Gmail API
testImplementation("com.google.apis:google-api-services-gmail:v1-rev20200601-1.30.9")
// For using JMeter APIs
testImplementation("org.apache.jmeter:ApacheJMeter_core:5.3") {
testImplementation("org.apache.jmeter:ApacheJMeter_core:5.4.1") {
exclude group: "org.apache.jmeter", module: "bom"
}
testImplementation("org.apache.jmeter:ApacheJMeter_http:5.3") {
testImplementation("org.apache.jmeter:ApacheJMeter_http:5.4.1") {
exclude group: "org.apache.jmeter", module: "bom"
}

Expand Down
12 changes: 5 additions & 7 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ This type of request will be processed as follows:
1. Request forwarded to the `WebApiServlet` and subsequent actions are the same as user-invoked AJAX requests.

GAE server sends such automated requests through two different configurations:
- Cron jobs: These are jobs that are automatically scheduled for a specified period of time, e.g. scheduling feedback session opening reminders. It is configured in `cron.xml`.
- Task queue workers: These are hybrids of user-invoked and GAE-invoked in that they are queued by users (i.e. users request for the tasks to be added to queue), but executed by GAE (i.e. GAE determines when and which tasks in the queue are executed at any point of time). This is typically used for tasks that may take a long time to finish and can exceed the 1 minute standard request processing limit imposed by GAE. It is configured in `queue.xml` as well as the `TaskQueue` nested class of the [Const](../src/main/java/teammates/common/util/Const.java) class.
- Cron jobs: These are jobs that are automatically scheduled for a specified period of time, e.g. scheduling feedback session opening reminders. It is configured in `cron.yaml`.
- Task queue workers: These are hybrids of user-invoked and GAE-invoked in that they are queued by users (i.e. users request for the tasks to be added to queue), but executed by GAE (i.e. GAE determines when and which tasks in the queue are executed at any point of time). This is typically used for tasks that may take a long time to finish and might be blocking user's interaction. It is configured in `queue.yaml` as well as the `TaskQueue` nested class of the [Const](../src/main/java/teammates/common/util/Const.java) class.

### Template Method pattern

Expand All @@ -119,7 +119,7 @@ On designing API endpoints (for AJAX requests):
- Some fields are required be hidden in the API response, mostly for data privacy purposes. Whenever required, there should be methods in the request output objects catered for this.
- API endpoints should not be concerned with how data is presented.
- Case study 1: some endpoint will pass timezone information via two information: timezone ID and UNIX epoch milliseconds. It is up to the front-end on how to make use of those two pieces of information.
- Case study 2: CSV file for session result or student list is just a different way of presenting the same information in the web page. Due to this, when downloding CSV, the web page will request the same information as that used when displaying in web page and do the necessary conversion to CSV.
- Case study 2: CSV file for session result or student list is just a different way of presenting the same information in the web page. Due to this, when downloading CSV, the web page will request the same information as that used when displaying in web page and do the necessary conversion to CSV.

On data exchange between front-end and back-end:

Expand Down Expand Up @@ -284,11 +284,9 @@ The E2E component has no knowledge of the internal workings of the application a

Package overview:

- **`e2e.util`**: Contains helpers needed for running E2E tests.
- **`e2e.util`**: Contains helpers needed for running E2E tests. Also contains the test cases for the said infrastructure/helpers.
- **`e2e.pageobjects`**: Contains abstractions of the pages as they appear on a Browser (i.e. SUTs).
- **`e2e.cases`**: Contains test cases.
- **`.util`**: Component test cases for testing the test helpers.
- **`.e2e`**: System test cases for testing the application as a whole.
- **`e2e.cases`**: Contains system test cases for testing the application as a whole.

## Client Component

Expand Down
6 changes: 3 additions & 3 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,17 @@ The steps for adding a student is almost identical to the steps for adding instr
- Where appropriate, change the reference to "instructor" to "student".
- `Students` → `Enroll` to add students for the course.
**Alternative**: Run the test cases, they create several student and instructor accounts in the datastore. Use one of them to log in.
**Alternative**: Run the E2E test cases, they create several student and instructor accounts in the database. Use one of them to log in.
### Logging in without UI
In dev server, it is also possible to "log in" without UI (e.g. when only testing API endpoints). In order to do that, you need to submit the following API call:
```sh
POST http://localhost:8080/[email protected]&isAdmin=on
POST http://localhost:8080/[email protected]
```
where `[email protected]` and `isAdmin=on` can be replaced as appropriate.
where `[email protected]` can be replaced as appropriate.
The back-end server will return cookies which will subsequently be used to authenticate your requests.
Expand Down
11 changes: 2 additions & 9 deletions docs/e2e-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,15 @@ If you are testing against a production server (staging server or live server),
1. Edit `src/e2e/resources/test.properties` as instructed is in its comments.
* In particular, you will need a legitimate Gmail account to be used for testing.

1. You need to setup a `Gmail API`<sup>1</sup> as follows:
1. If you are testing email sending, you need to setup a `Gmail API` as follows:
* [Obtain a Gmail API credentials](https://github.com/TEAMMATES/teammates-ops/blob/master/platform-guide.md#setting-up-gmail-api-credentials) and download it.
* Copy the file to `src/e2e/resources/gmail-api` (create the `gmail-api` folder) of your project and rename it to `client_secret.json`.
* It is also possible to use the Gmail API credentials from any other Google Cloud Platform project for this purpose.
* Run `EmailAccountTest` to confirm that the setup works. For the first run, it is expected that you will need to grant access from the test Gmail account to the above API.

1. Login manually to TEAMMATES on the browser used for testing to add cookie with login details to the browser profile.
* This profile will be added to the web driver so that E2E tests will start with user already logged in.
* This is required as Google does not allow login by automated software.

1. Run the full test suite or any subset of it as how you would have done it in dev server.
* Do note that the GAE daily quota is usually not enough to run the full test suite, in particular for accounts with no billing enabled.

<sup>1</sup> This setup is necessary because our test suite uses the Gmail API to access the Gmail account used for testing (the account is specified in `test.properties`) to confirm that the account receives the expected emails from TEAMMATES.
This is needed only when testing against a production server because no actual emails are sent by the dev server and therefore delivery of emails is not tested when testing against the dev server.

## Creating E2E tests

As E2E tests should be written from the end user perspective, each test case should reflect some user workflow.
Expand Down Expand Up @@ -135,4 +128,4 @@ All Page Object classes inherit from `AppPage` which contains methods that are c
We bundle together everything as one test case instead of having multiple test cases. The advantage is that the time for the whole test class will be reduced because we minimize repetitive per-method setup/teardown. The downside is that it increases the time spent on re-running failed tests as the whole class has to be re-run. We opt for this approach because we expect tests to pass more frequently than to fail.

**Why is there one JSON file for each test case?**
Each test case has its own JSON file and the data inside has a unique prefix to prevent clashes in the database that may cause test failure, since tests are run concurrently.
Each test case has its own JSON file and the data inside has a unique prefix to prevent clashes in the database that may cause test failure, since tests are run concurrently.
2 changes: 1 addition & 1 deletion docs/performance-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To see a sample implementation of a test case, you can refer to `StudentProfileL

If you want to use your own copy of [JMeter](https://jmeter.apache.org/download_jmeter.cgi), update the `test.jmeter.*` properties in `src/lnp/resources/test.properties` accordingly.

First, open the terminal and navigate to the root of project folder. Start the backend server, i.e. `./gradlew appengineRun`, before running the performance tests.
First, open the terminal and navigate to the root of project folder. Start the backend server, i.e. `./gradlew serverRun`, before running the performance tests.

For more details about how to set up and run your local server, please refer to [Developer Guide](https://github.com/TEAMMATES/teammates/blob/master/docs/development.md).

Expand Down
1 change: 0 additions & 1 deletion docs/setting-up.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ More information can be found at [this documentation](https://help.github.com/ar
These tools are necessary regardless of whether you are developing front-end or back-end:
1. Install Java JDK 11.
1. Install Python 3 (recommended) or Python 2.7.
If you want to develop front-end, you need to install the following:
Expand Down
4 changes: 2 additions & 2 deletions src/client/resources/client.template.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
# This is the URL of the database the script will run against.
# For staging server, the URL should be the URL of the application.
# e.g. client.target.url=http\://localhost\:8484
# e.g. client.target.url=https\://7-0-0-dot-teammates-john.appspot.com
# e.g. client.target.url=https\://8-0-0-dot-teammates-john.appspot.com
client.target.url=http\://localhost\:8484

# This is the URL of the API back-end that the script will be run against.
# Note that most of the time, this URL will not be used as scripts will use the database URL (defined previously) instead.
# This URL will be used for other back-end operations that need connection to other services such as search service.
# The backdoor key and CSRF key will be the keys that are used in the specified API back-end.
# e.g. client.api.url=https\://localhost\:8080
# e.g. client.api.url=https\://7-0-0-dot-teammates-john.appspot.com
# e.g. client.api.url=https\://8-0-0-dot-teammates-john.appspot.com
client.api.url=
client.backdoor.key=
client.csrf.key=
2 changes: 1 addition & 1 deletion src/e2e/resources/test.template.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# This is the url of the app we are testing against.
# e.g. test.app.url=http\://localhost\:8080
# e.g. test.app.url=https\://7-0-0-dot-teammates-john.appspot.com
# e.g. test.app.url=https\://8-0-0-dot-teammates-john.appspot.com
# Note: the '.' in the url has been replaced by -dot- to support https connection for the staging server.
test.app.url=http\://localhost\:8080

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ protected Map<String, FeedbackSessionAttributes> generateFeedbackSessions() {
FeedbackSessionAttributes session = FeedbackSessionAttributes
.builder(FEEDBACK_SESSION_NAME, COURSE_ID)
.withCreatorEmail(INSTRUCTOR_EMAIL)
.withStartTime(Instant.now())
.withStartTime(Instant.now().plusMillis(100))
.withEndTime(Instant.now().plusSeconds(500))
.withSessionVisibleFromTime(Instant.now())
.withResultsVisibleFromTime(Instant.now())
Expand Down
4 changes: 2 additions & 2 deletions src/lnp/resources/test.template.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

# This is the url of the app we are testing against.
# e.g. test.app.url=http\://localhost\:8080
# e.g. test.app.url=https\://7-0-0-dot-teammates-john.appspot.com
# e.g. test.app.url=https\://8-0-0-dot-teammates-john.appspot.com
# Note: the '.' in the url has been replaced by -dot- to support https connection for the staging server.
test.app.url=http\://localhost\:8080

# This is the domain of the app we are testing against.
# e.g. test.app.domain=localhost
# e.g. test.app.domain=7-0-0-dot-teammates-john.appspot.com
# e.g. test.app.domain=8-0-0-dot-teammates-john.appspot.com
test.app.domain=localhost

# This is the port of the app we are testing against.
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/teammates/storage/search/SearchManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ abstract class SearchManager<T extends EntityAttributes<?>> {
if (StringHelper.isEmpty(searchServiceHost)) {
this.client = null;
} else {
this.client = new HttpSolrClient.Builder(searchServiceHost).build();
this.client = new HttpSolrClient.Builder(searchServiceHost)
.withConnectionTimeout(2000) // timeout for connecting to Solr server
.withSocketTimeout(5000) // timeout for reading data
.build();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,23 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import teammates.common.util.Config;

/**
* Filter to add web security headers.
*/
public class WebSecurityHeaderFilter implements Filter {

private static final String IMG_SRC_CSP = Config.isDevServer()
? "'self' data: http: https:"
: "'self' data: https:";

private static final String CSP_POLICY = String.join("; ", Arrays.asList(
"default-src 'none'",
"script-src 'self' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://cdn.jsdelivr.net/",
"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/",
"frame-src 'self' docs.google.com https://www.google.com/recaptcha/",
"img-src 'self' data: http: https:",
"img-src " + IMG_SRC_CSP,
"font-src 'self' https://cdn.jsdelivr.net/",
"connect-src 'self'",
"manifest-src 'self'",
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/build.template.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ app.region=us-central1

# This is the version number of the app.
# Use dashes instead of dots because GAE does not allow dots in version number.
# e.g. app.version = 7-0-0
app.version = 7-0-0
# e.g. app.version = 8-0-0
app.version = 8-0-0

# This is the URL for the front-end dev server.
# This should be used only during development mode where the dev server needs to be whitelisted for CORS.
Expand Down
Loading

0 comments on commit 9ff5424

Please sign in to comment.