diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventChannel.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventChannel.java index e67e360..215547e 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventChannel.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventChannel.java @@ -8,11 +8,4 @@ *

Decreases coupling and enables testing of event types.

* */ public interface EventChannel { - - /** - * Getter method for enum name. - * - * @return String name of enum. - * */ - String getName(); } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java index a4a2bad..79e4f7b 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java @@ -32,9 +32,20 @@ public final class EventManager { * @param subscriber the {@link EventSubscriber} object to add. * @param eventChannel the {@link EventChannel} type this subscriber should subscribe to. * - * + * @throws IllegalArgumentException if subscriber is already subscribed to event channel, + * or if parameters are null. */ - public void addSubscriber(final EventSubscriber subscriber, final EventChannel eventChannel) { + public void addSubscriber(final EventSubscriber subscriber, final EventChannel eventChannel) + throws IllegalArgumentException { + if (subscriber == null || eventChannel == null) { + throw new IllegalArgumentException("Parameters cannot be null!"); + } + + List subscribers = subscriberMap.get(eventChannel); + if (subscribers != null && subscribers.contains(subscriber)) { + throw new IllegalArgumentException("Subscriber already subscribed to event channel!"); + } + subscriberMap.computeIfAbsent(eventChannel, k -> new ArrayList<>()).add(subscriber); } @@ -49,9 +60,9 @@ public void addSubscriber(final EventSubscriber subscriber, final EventChannel e */ public void invokeEvent(final EventData data) throws IllegalArgumentException { - if (data == null || !subscriberMap.containsKey(data.channel())) { + if (data == null || data.data() == null) { throw new IllegalArgumentException( - "No subscriber listening to this event!" + "Data cannot be null!" ); } else { for (EventSubscriber e : subscriberMap.get(data.channel())) { diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java index ace4933..215ff37 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java @@ -51,12 +51,4 @@ public enum EventType implements EventChannel { * */ SELECT_STOCK_FOR_MINIGAME; - - /** - * {@inheritDoc} - * */ - @Override - public String getName() { - return this.name(); - } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/Validator.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/Validator.java index b31108e..a9969db 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/Validator.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/Validator.java @@ -63,6 +63,12 @@ public enum Validator { * */ VALID_POSITIVE_INT(VALID_INT.validationRule.and(s -> Integer.parseInt(s) >= 0), "Number is not positive!"), + + /** + * Rule that checks if a string represents a valid week. (Greater than 1). + * */ + VALID_WEEK(VALID_POSITIVE_INT.validationRule.and(s -> + Integer.parseInt(s) > 0), "Invalid week"), /** * Rule that checks if string is not empty, * and if it can be parsed into a {@link LocalDate} object. diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManagerTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManagerTest.java index 716e96e..4852d1c 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManagerTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManagerTest.java @@ -1,99 +1,176 @@ package edu.ntnu.idi.idatt2003.g40.mappe.service.event; -import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewData; -import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewEnum; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class EventManagerTest { private enum TestEventTypes implements EventChannel { + /** + * Test event type 1. + * */ TEST_TYPE_1, + + /** + * Test event type 2. + * */ TEST_TYPE_2, + + /** + * Test event type 3 (Used by both subscribers). + * */ TEST_TYPE_3; - @Override - public String getName() { - return this.name(); - } } - private GenericEventPublisher testEventPublisher; - private GenericEventPublisher testEventPublisher2; - private GenericEventPublisher testEventPublisher3; - - private GenericEventSubscriber testEventSubscriber; - private GenericEventSubscriber testEventSubscriber2; - private EventManager testEventManager; + private SampleEventSubscriber sampleEventSubscriber1; + private SampleEventSubscriber sampleEventSubscriber2; @BeforeEach void setUp() { testEventManager = new EventManager(); - testEventSubscriber = new GenericEventSubscriber(); - testEventSubscriber2 = new GenericEventSubscriber(); + sampleEventSubscriber1 = new SampleEventSubscriber(); + sampleEventSubscriber2 = new SampleEventSubscriber(); + + testEventManager.addSubscriber(sampleEventSubscriber1, TestEventTypes.TEST_TYPE_1); + testEventManager.addSubscriber(sampleEventSubscriber1, TestEventTypes.TEST_TYPE_3); + + testEventManager.addSubscriber(sampleEventSubscriber2, TestEventTypes.TEST_TYPE_2); + testEventManager.addSubscriber(sampleEventSubscriber2, TestEventTypes.TEST_TYPE_3); + } - testEventPublisher = new GenericEventPublisher(testEventManager, TestEventTypes.TEST_TYPE_1); - testEventPublisher2 = new GenericEventPublisher(testEventManager, TestEventTypes.TEST_TYPE_2); - testEventPublisher3 = new GenericEventPublisher(testEventManager, TestEventTypes.TEST_TYPE_3); + @Test + void addingSubscriberNullParametersThrowsException() { + assertThrows(IllegalArgumentException.class, + () -> testEventManager.addSubscriber( + null, + TestEventTypes.TEST_TYPE_2)); + + assertThrows(IllegalArgumentException.class, + () -> testEventManager.addSubscriber( + sampleEventSubscriber1, + null)); + + // Will only throw exception if sample event subscriber 1 is duplicate. + assertDoesNotThrow( + () -> testEventManager.addSubscriber( + sampleEventSubscriber1, + TestEventTypes.TEST_TYPE_2)); - testEventManager.addSubscriber(testEventSubscriber, TestEventTypes.TEST_TYPE_1); - testEventManager.addSubscriber(testEventSubscriber2, TestEventTypes.TEST_TYPE_2); + } + + @Test + void addingDuplicateSubscriberForSameChannelThrowsException() { + assertDoesNotThrow( + () -> testEventManager.addSubscriber( + sampleEventSubscriber1, + TestEventTypes.TEST_TYPE_2)); + + assertThrows(IllegalArgumentException.class, + () -> testEventManager.addSubscriber( + sampleEventSubscriber1, + TestEventTypes.TEST_TYPE_1)); } @Test void firedEventCaughtByCorrectSubscriber() { - assertFalse(testEventSubscriber.invokedEvent); - testEventPublisher.fireEvent(); - assertTrue(testEventSubscriber.invokedEvent); + String dataToSend = "Data for type 1"; + + assertFalse(sampleEventSubscriber1.getInvoked()); + assertNull(sampleEventSubscriber1.getLastReceivedData()); + + EventData eventData = new EventData<>( + TestEventTypes.TEST_TYPE_1, + dataToSend + ); + testEventManager.invokeEvent(eventData); + + assertTrue(sampleEventSubscriber1.getInvoked()); + assertEquals(dataToSend, sampleEventSubscriber1.getLastReceivedData()); } @Test void firedEventNotCaughtByIncorrectSubscriber() { - assertFalse(testEventSubscriber.invokedEvent); - testEventPublisher2.fireEvent(); - assertFalse(testEventSubscriber.invokedEvent); + String dataToSend = "Data for type 1"; + + assertFalse(sampleEventSubscriber1.getInvoked()); + assertNull(sampleEventSubscriber1.getLastReceivedData()); + assertFalse(sampleEventSubscriber2.getInvoked()); + assertNull(sampleEventSubscriber2.getLastReceivedData()); + + EventData eventData = new EventData<>( + TestEventTypes.TEST_TYPE_2, + dataToSend + ); + testEventManager.invokeEvent(eventData); + + assertFalse(sampleEventSubscriber1.getInvoked()); + assertNull(sampleEventSubscriber1.getLastReceivedData()); + + assertTrue(sampleEventSubscriber2.getInvoked()); + assertEquals(dataToSend, sampleEventSubscriber2.getLastReceivedData()); } @Test - void firedEventThrowsErrorWhenNoSubscribers() { - assertFalse(testEventSubscriber.invokedEvent); - assertThrows(IllegalArgumentException.class, () -> { - testEventPublisher3.fireEvent(); - }); - assertFalse(testEventSubscriber.invokedEvent); - } + void firedEventsWithMultipleSubscribersCaughtByAllSubscribers() { + String dataToSend = "Data for type 1"; - private class GenericEventPublisher implements EventPublisher { + assertFalse(sampleEventSubscriber1.getInvoked()); + assertNull(sampleEventSubscriber1.getLastReceivedData()); + assertFalse(sampleEventSubscriber2.getInvoked()); + assertNull(sampleEventSubscriber2.getLastReceivedData()); - private final ViewData viewData; - private final EventData eventData; - private final EventManager eventManager; + EventData eventData = new EventData<>( + TestEventTypes.TEST_TYPE_3, + dataToSend + ); + testEventManager.invokeEvent(eventData); - public GenericEventPublisher(final EventManager eventManager, final TestEventTypes eventType) { - viewData = new ViewData(ViewEnum.IN_GAME); - eventData = new EventData(eventType, viewData); - this.eventManager = eventManager; - } + assertTrue(sampleEventSubscriber1.getInvoked()); + assertEquals(dataToSend, sampleEventSubscriber1.getLastReceivedData()); - public void fireEvent() { - invoke(eventData, eventManager); - } + assertTrue(sampleEventSubscriber2.getInvoked()); + assertEquals(dataToSend, sampleEventSubscriber2.getLastReceivedData()); + } - @Override - public void invoke(EventData data, EventManager eventManager) { - eventManager.invokeEvent(data); - } + @Test + void firedEventThrowsErrorWhenDataIsNull() { + + EventData invalidEventData = new EventData<>( + TestEventTypes.TEST_TYPE_1, + null + ); + + assertThrows(IllegalArgumentException.class, + () -> testEventManager.invokeEvent(null)); + + assertThrows(IllegalArgumentException.class, + () -> testEventManager.invokeEvent(invalidEventData)); } - private class GenericEventSubscriber implements EventSubscriber { - public boolean invokedEvent = false; + private static class SampleEventSubscriber implements EventSubscriber { + private boolean invokedEvent = false; + private Object lastReceivedData = null; @Override - public void handleEvent(EventData data) { + public void handleEvent(final EventData data) { invokedEvent = true; + lastReceivedData = data.data(); + } + + private boolean getInvoked() { + return invokedEvent; + } + + private Object getLastReceivedData() { + return lastReceivedData; } } } \ No newline at end of file