Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create SQL logic for CreateNotificationAction and add relevant tests for v9 migration #12077

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