Skip to content

Commit

Permalink
[TEAMMATES#12048] Create SQL logic for CreateNotificationAction and a…
Browse files Browse the repository at this point in the history
…dd relevant tests for v9 migration (TEAMMATES#12077)
  • Loading branch information
hhdqirui authored and domlimm committed Feb 22, 2023
1 parent b61d00d commit 6f0f999
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 14 deletions.
41 changes: 41 additions & 0 deletions src/it/java/teammates/it/storage/sqlapi/NotificationDbIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package teammates.it.storage.sqlapi;

import java.time.Instant;
import java.util.UUID;

import org.testng.annotations.Test;

import teammates.common.datatransfer.NotificationStyle;
import teammates.common.datatransfer.NotificationTargetUser;
import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.InvalidParametersException;
import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.storage.sqlapi.NotificationsDb;
import teammates.storage.sqlentity.Notification;

/**
* SUT: {@link NotificationsDb}.
*/
public class NotificationDbIT extends BaseTestCaseWithSqlDatabaseAccess {

private final NotificationsDb notificationsDb = NotificationsDb.inst();

@Test
public void testCreateNotification() throws EntityAlreadyExistsException, InvalidParametersException {
______TS("success: create notification that does not exist");
Notification newNotification = new Notification.NotificationBuilder()
.withStartTime(Instant.parse("2011-01-01T00:00:00Z"))
.withEndTime(Instant.parse("2099-01-01T00:00:00Z"))
.withStyle(NotificationStyle.DANGER)
.withTargetUser(NotificationTargetUser.GENERAL)
.withTitle("A deprecation note")
.withMessage("<p>Deprecation happens in three minutes</p>")
.build();

notificationsDb.createNotification(newNotification);

UUID notificationId = newNotification.getNotificationId();
Notification actualNotification = notificationsDb.getNotification(notificationId);
verifyEquals(newNotification, actualNotification);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import teammates.sqllogic.core.LogicStarter;
import teammates.storage.sqlentity.BaseEntity;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Notification;
import teammates.test.BaseTestCase;

/**
Expand Down Expand Up @@ -61,6 +62,11 @@ protected void verifyEquals(BaseEntity expected, BaseEntity actual) {
Course actualCourse = (Course) actual;
equalizeIrrelevantData(expectedCourse, actualCourse);
assertEquals(JsonUtils.toJson(expectedCourse), JsonUtils.toJson(actualCourse));
} else if (expected instanceof Notification) {
Notification expectedNotification = (Notification) expected;
Notification actualNotification = (Notification) actual;
equalizeIrrelevantData(expectedNotification, actualNotification);
assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));
}
}

Expand All @@ -86,4 +92,10 @@ private void equalizeIrrelevantData(Course expected, Course actual) {
expected.setUpdatedAt(actual.getUpdatedAt());
}

private void equalizeIrrelevantData(Notification expected, Notification actual) {
// Ignore time field as it is stamped at the time of creation in testing
expected.setCreatedAt(actual.getCreatedAt());
expected.setUpdatedAt(actual.getUpdatedAt());
}

}
18 changes: 18 additions & 0 deletions src/main/java/teammates/sqllogic/api/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.InvalidParametersException;
import teammates.sqllogic.core.CoursesLogic;
import teammates.sqllogic.core.NotificationsLogic;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Notification;

/**
* Provides the business logic for production usage of the system.
Expand All @@ -15,6 +17,7 @@ public class Logic {

final CoursesLogic coursesLogic = CoursesLogic.inst();
// final FeedbackSessionsLogic feedbackSessionsLogic = FeedbackSessionsLogic.inst();
final NotificationsLogic notificationsLogic = NotificationsLogic.inst();

Logic() {
// prevent initialization
Expand Down Expand Up @@ -45,4 +48,19 @@ public Course getCourse(String courseId) {
public Course createCourse(Course course) throws InvalidParametersException, EntityAlreadyExistsException {
return coursesLogic.createCourse(course);
}

/**
* Creates a notification.
*
* <p>Preconditions:</p>
* * All parameters are non-null.
*
* @return created notification
* @throws InvalidParametersException if the notification is not valid
* @throws EntityAlreadyExistsException if the notification exists in the database
*/
public Notification createNotification(Notification notification) throws
InvalidParametersException, EntityAlreadyExistsException {
return notificationsLogic.createNotification(notification);
}
}
3 changes: 3 additions & 0 deletions src/main/java/teammates/sqllogic/core/LogicStarter.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import teammates.common.util.Logger;
import teammates.storage.sqlapi.CoursesDb;
import teammates.storage.sqlapi.FeedbackSessionsDb;
import teammates.storage.sqlapi.NotificationsDb;

/**
* Setup in web.xml to register logic classes at application startup.
Expand All @@ -20,9 +21,11 @@ public class LogicStarter implements ServletContextListener {
public static void initializeDependencies() {
CoursesLogic coursesLogic = CoursesLogic.inst();
FeedbackSessionsLogic fsLogic = FeedbackSessionsLogic.inst();
NotificationsLogic notificationsLogic = NotificationsLogic.inst();

coursesLogic.initLogicDependencies(CoursesDb.inst(), fsLogic);
fsLogic.initLogicDependencies(FeedbackSessionsDb.inst(), coursesLogic);
notificationsLogic.initLogicDependencies(NotificationsDb.inst());

log.info("Initialized dependencies between logic classes");
}
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/teammates/sqllogic/core/NotificationsLogic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package teammates.sqllogic.core;

import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.InvalidParametersException;
import teammates.storage.sqlapi.NotificationsDb;
import teammates.storage.sqlentity.Notification;

/**
* Handles the logic related to notifications.
*/
public final class NotificationsLogic {

private static final NotificationsLogic instance = new NotificationsLogic();

private NotificationsDb notificationsDb;

private NotificationsLogic() {
// prevent initialization
}

public static NotificationsLogic inst() {
return instance;
}

void initLogicDependencies(NotificationsDb notificationsDb) {
this.notificationsDb = notificationsDb;
}

/**
* Creates a notification.
*
* @return the created notification
* @throws InvalidParametersException if the notification is not valid
* @throws EntityAlreadyExistsException if the notification already exists in the database.
*/
public Notification createNotification(Notification notification)
throws InvalidParametersException, EntityAlreadyExistsException {
return notificationsDb.createNotification(notification);
}
}
13 changes: 5 additions & 8 deletions src/main/java/teammates/storage/sqlapi/NotificationsDb.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package teammates.storage.sqlapi;

import java.util.UUID;

import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.common.exception.InvalidParametersException;
Expand Down Expand Up @@ -35,19 +37,14 @@ public Notification createNotification(Notification notification)
throw new InvalidParametersException(notification.getInvalidityInfo());
}

if (getNotification(notification.getNotificationId().toString()) != null) {
throw new EntityAlreadyExistsException(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS,
notification.toString()));
}

persist(notification);
return notification;
}

/**
* Gets a notification by its unique ID.
*/
public Notification getNotification(String notificationId) {
public Notification getNotification(UUID notificationId) {
assert notificationId != null;

return HibernateUtil.getSessionFactory().getCurrentSession().get(Notification.class, notificationId);
Expand All @@ -66,7 +63,7 @@ public Notification updateNotification(Notification notification)
throw new InvalidParametersException(notification.getInvalidityInfo());
}

if (getNotification(notification.getNotificationId().toString()) == null) {
if (getNotification(notification.getNotificationId()) == null) {
throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);
}

Expand All @@ -78,7 +75,7 @@ public Notification updateNotification(Notification notification)
*
* <p>Fails silently if there is no such notification.
*/
public void deleteNotification(String notificationId) {
public void deleteNotification(UUID notificationId) {
assert notificationId != null;

Notification notification = getNotification(notificationId);
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/teammates/storage/sqlentity/Notification.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public class Notification extends BaseEntity {
* Instantiates a new notification from {@code NotificationBuilder}.
*/
public Notification(NotificationBuilder builder) {
this.setNotificationId(builder.notificationId);
this.setStartTime(builder.startTime);
this.setEndTime(builder.endTime);
this.setStyle(builder.style);
Expand Down Expand Up @@ -111,6 +112,10 @@ public UUID getNotificationId() {
return notificationId;
}

public void setNotificationId(UUID notificationId) {
this.notificationId = notificationId;
}

public Instant getStartTime() {
return startTime;
}
Expand Down Expand Up @@ -236,6 +241,7 @@ public boolean equals(Object other) {
*/
public static class NotificationBuilder {

private UUID notificationId;
private Instant startTime;
private Instant endTime;
private NotificationStyle style;
Expand All @@ -244,8 +250,9 @@ public static class NotificationBuilder {
private String message;
private boolean shown;

public NotificationBuilder(String title) {
this.title = title;
public NotificationBuilder withNotificationId(UUID notificationId) {
this.notificationId = notificationId;
return this;
}

public NotificationBuilder withStartTime(Instant startTime) {
Expand All @@ -268,6 +275,11 @@ public NotificationBuilder withTargetUser(NotificationTargetUser targetUser) {
return this;
}

public NotificationBuilder withTitle(String title) {
this.title = title;
return this;
}

public NotificationBuilder withMessage(String message) {
this.message = message;
return this;
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/teammates/ui/output/NotificationData.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import teammates.common.datatransfer.NotificationStyle;
import teammates.common.datatransfer.NotificationTargetUser;
import teammates.common.datatransfer.attributes.NotificationAttributes;
import teammates.storage.sqlentity.Notification;

/**
* The API output format of a notification.
Expand Down Expand Up @@ -31,6 +32,18 @@ public NotificationData(NotificationAttributes notificationAttributes) {
this.shown = notificationAttributes.isShown();
}

public NotificationData(Notification notification) {
this.notificationId = notification.getNotificationId().toString();
this.startTimestamp = notification.getStartTime().toEpochMilli();
this.endTimestamp = notification.getEndTime().toEpochMilli();
this.createdAt = notification.getCreatedAt().toEpochMilli();
this.style = notification.getStyle();
this.targetUser = notification.getTargetUser();
this.title = notification.getTitle();
this.message = notification.getMessage();
this.shown = notification.isShown();
}

public String getNotificationId() {
return this.notificationId;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package teammates.ui.webapi;

import java.time.Instant;
import java.util.UUID;

import org.apache.http.HttpStatus;

import teammates.common.datatransfer.attributes.NotificationAttributes;
import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.Logger;
import teammates.storage.sqlentity.Notification;
import teammates.ui.output.NotificationData;
import teammates.ui.request.InvalidHttpRequestBodyException;
import teammates.ui.request.NotificationCreateRequest;
Expand All @@ -26,7 +25,7 @@ public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOpera
Instant startTime = Instant.ofEpochMilli(notificationRequest.getStartTimestamp());
Instant endTime = Instant.ofEpochMilli(notificationRequest.getEndTimestamp());

NotificationAttributes newNotification = NotificationAttributes.builder(UUID.randomUUID().toString())
Notification newNotification = new Notification.NotificationBuilder()
.withStartTime(startTime)
.withEndTime(endTime)
.withStyle(notificationRequest.getStyle())
Expand All @@ -36,7 +35,7 @@ public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOpera
.build();

try {
return new JsonResult(new NotificationData(logic.createNotification(newNotification)));
return new JsonResult(new NotificationData(sqlLogic.createNotification(newNotification)));
} catch (InvalidParametersException e) {
throw new InvalidHttpRequestBodyException(e);
} catch (EntityAlreadyExistsException e) {
Expand Down
Loading

0 comments on commit 6f0f999

Please sign in to comment.