Skip to content

Commit

Permalink
Merge branch 'db-migrate-DeleteInstructorActionTest' of https://githu…
Browse files Browse the repository at this point in the history
…b.com/DhiraPT/teammates into db-migrate-DeleteInstructorActionTest
  • Loading branch information
DhiraPT committed Mar 1, 2025
2 parents 46e8c53 + e21f154 commit bf22591
Show file tree
Hide file tree
Showing 12 changed files with 708 additions and 27 deletions.
13 changes: 2 additions & 11 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,12 @@ In order for the back-end to properly work, you need to have a running database

The details on how to run them locally can be found [here (for local Datastore emulator)](#running-the-datastore-emulator) and [here (for full-text search service)](search.md).

If you have access to Docker, we have a Docker compose definition to run those services:
If you have access to Docker, we recommend using Docker Compose v2 to run those services:

```sh
docker compose up -d
```
If the above command does not work, you may not have the updated v2 version of Docker. You may want to try this instead:

```sh
docker-compose up -d
```
For more information on Docker, you may wish to refer to the [Docker Documentation](https://docs.docker.com/compose/reference/).

### Starting the dev server
Expand Down Expand Up @@ -239,16 +235,11 @@ The Datastore emulator will be running in the port specified in the `build.prope

<panel header="**Using Docker-based tooling**">

We have a Docker compose definition to run dependent services, including local Datastore emulator. Run it under the `datastore` service name and bind to the container port `8484`:
Docker Compose v2 is used to run dependent services, including local Datastore emulator. Run it under the `datastore` service name and bind to the container port `8484`:

```sh
docker compose run -p 8484:8484 datastore
```
If the above command does not work, you may want to try this instead:

```sh
docker-compose run -p 8484:8484 datastore
```

**Verification:** Should receive an "Ok" response in the browser at `http://localhost:8484`.
</panel>
Expand Down
9 changes: 1 addition & 8 deletions docs/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,11 @@ This document will assume Solr version `8.11.1`.

## Setting up Solr using Docker

If you have access to Docker, this method is straightforward and recommended.

We have provided a Docker compose definition to run dependent services, including Solr. Run it under the `solr` service name and bind to the container port `8983`:
If you have access to Docker, we recommend using Docker Compose v2 to run the dependent services, including Solr. Run it under the `solr` service name and bind to the container port `8983`:

```sh
docker compose run -p 8983:8983 solr
```
If the above command does not work, you may want to try this instead:

```sh
docker-compose run -p 8983:8983 solr
```

**Verification:** the Solr admin console should be accessible in `http://localhost:8983`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* Deletes an existing account request.
*/
class DeleteAccountRequestAction extends AdminOnlyAction {
public class DeleteAccountRequestAction extends AdminOnlyAction {

@Override
public JsonResult execute() throws InvalidOperationException {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/teammates/ui/webapi/GetTimeZonesAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* Action: get supported time zones.
*/
class GetTimeZonesAction extends Action {
public class GetTimeZonesAction extends Action {

@Override
AuthType getMinAuthLevel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* Gets usage statistics for a specified time period.
*/
class GetUsageStatisticsAction extends Action {
public class GetUsageStatisticsAction extends Action {

private static final Duration MAX_SEARCH_WINDOW = Duration.ofDays(184L); // covering six whole months

Expand Down
192 changes: 192 additions & 0 deletions src/test/java/teammates/sqlui/webapi/CreateNotificationActionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package teammates.sqlui.webapi;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.when;

import java.util.UUID;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import teammates.common.datatransfer.NotificationStyle;
import teammates.common.datatransfer.NotificationTargetUser;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.Const;
import teammates.storage.sqlentity.Notification;
import teammates.ui.output.NotificationData;
import teammates.ui.request.InvalidHttpRequestBodyException;
import teammates.ui.request.NotificationCreateRequest;
import teammates.ui.webapi.CreateNotificationAction;

/**
* SUT: {@link CreateNotificationAction}.
*/
public class CreateNotificationActionTest extends BaseActionTest<CreateNotificationAction> {
private static final String GOOGLE_ID = "user-googleId";
private static final String INVALID_TITLE = "";
NotificationCreateRequest testReq;
private Notification testNotification;

@Override
String getActionUri() {
return Const.ResourceURIs.NOTIFICATION;
}

@Override
String getRequestMethod() {
return POST;
}

@BeforeMethod
void setUp() {
loginAsAdmin();
testNotification = getTypicalNotificationWithId();
}

@Test
void testExecute_addNotification_success() throws Exception {
long startTime = testNotification.getStartTime().toEpochMilli();
long endTime = testNotification.getEndTime().toEpochMilli();
NotificationStyle style = testNotification.getStyle();
NotificationTargetUser targetUser = testNotification.getTargetUser();
String title = testNotification.getTitle();
String message = testNotification.getMessage();

when(mockLogic.createNotification(isA(Notification.class))).thenAnswer(invocation -> invocation.getArgument(0));

NotificationCreateRequest req = getTypicalCreateRequest();
CreateNotificationAction action = getAction(req);
NotificationData res = (NotificationData) action.execute().getOutput();

when(mockLogic.getNotification(UUID.fromString(res.getNotificationId()))).thenReturn(testNotification);

Notification createdNotification = mockLogic.getNotification(UUID.fromString(res.getNotificationId()));

// check that notification returned has same properties as notification created
assertEquals(createdNotification.getStartTime().toEpochMilli(), res.getStartTimestamp());
assertEquals(createdNotification.getEndTime().toEpochMilli(), res.getEndTimestamp());
assertEquals(createdNotification.getStyle(), res.getStyle());
assertEquals(createdNotification.getTargetUser(), res.getTargetUser());
assertEquals(createdNotification.getTitle(), res.getTitle());
assertEquals(createdNotification.getMessage(), res.getMessage());

// check DB correctly processed request
assertEquals(startTime, createdNotification.getStartTime().toEpochMilli());
assertEquals(endTime, createdNotification.getEndTime().toEpochMilli());
assertEquals(style, createdNotification.getStyle());
assertEquals(targetUser, createdNotification.getTargetUser());
assertEquals(title, createdNotification.getTitle());
assertEquals(message, createdNotification.getMessage());
}

@Test
void testSpecificAccessControl_admin_canAccess() {
verifyCanAccess();
}

@Test
void testSpecificAccessControl_instructor_cannotAccess() {
logoutUser();
loginAsInstructor(GOOGLE_ID);
verifyCannotAccess();
}

@Test
void testSpecificAccessControl_student_cannotAccess() {
logoutUser();
loginAsStudent(GOOGLE_ID);
verifyCannotAccess();
}

@Test
void testSpecificAccessControl_loggedOut_cannotAccess() {
logoutUser();
verifyCannotAccess();
}

@Test
void testExecute_invalidStyle_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setStyle(null);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Notification style cannot be null", ex.getMessage());
}

@Test
void testExecute_invalidTargetUser_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setTargetUser(null);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Notification target user cannot be null", ex.getMessage());
}

@Test
void testExecute_invalidTitle_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setTitle(null);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Notification title cannot be null", ex.getMessage());
}

@Test
void testExecute_invalidMessage_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setMessage(null);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Notification message cannot be null", ex.getMessage());
}

@Test
void testExecute_negativeStartTimestamp_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setStartTimestamp(-1);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Start timestamp should be greater than zero", ex.getMessage());
}

@Test
void testExecute_negativeEndTimestamp_throwsInvalidHttpParameterException() {
testReq = getTypicalCreateRequest();
testReq.setEndTimestamp(-1);

InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("End timestamp should be greater than zero", ex.getMessage());
}

@Test
void testExecute_invalidParameter_throwsInvalidHttpParameterException() throws Exception {
testReq = getTypicalCreateRequest();
testReq.setTitle(INVALID_TITLE);

when(mockLogic.createNotification(any())).thenThrow(new InvalidParametersException("Invalid title"));
InvalidHttpRequestBodyException ex = verifyHttpRequestBodyFailure(testReq);

assertEquals("Invalid title", ex.getMessage());
}

private NotificationCreateRequest getTypicalCreateRequest() {
NotificationCreateRequest req = new NotificationCreateRequest();

req.setStartTimestamp(testNotification.getStartTime().toEpochMilli());
req.setEndTimestamp(testNotification.getEndTime().toEpochMilli());
req.setStyle(testNotification.getStyle());
req.setTargetUser(testNotification.getTargetUser());
req.setTitle(testNotification.getTitle());
req.setMessage(testNotification.getMessage());

return req;
}

}
Loading

0 comments on commit bf22591

Please sign in to comment.