diff --git a/README.md b/README.md index 5fdc622f..932258d4 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,6 @@ A JavaFX-based chat client using [ntfy](https://docs.ntfy.sh/) for backend messa 2. Start with: ```bash ./mvnw clean javafx:run + +## Author +Created for Lab 3 - Network Programming - Younes Ahmad diff --git a/src/main/java/com/example/model/ChatModel.java b/src/main/java/com/example/model/ChatModel.java index 8a819af0..d70144d1 100644 --- a/src/main/java/com/example/model/ChatModel.java +++ b/src/main/java/com/example/model/ChatModel.java @@ -48,6 +48,10 @@ public void connect() { } public void sendMessage(String text) throws Exception { + if (text == null || text.trim().isEmpty()) { + throw new IllegalArgumentException("Message cannot be empty"); + } + NtfyMessage message = new NtfyMessage(topic, text); networkClient.send(baseUrl, message); } diff --git a/src/main/java/com/example/model/NtfyMessage.java b/src/main/java/com/example/model/NtfyMessage.java index 49ef3259..a4f6fbb3 100644 --- a/src/main/java/com/example/model/NtfyMessage.java +++ b/src/main/java/com/example/model/NtfyMessage.java @@ -9,7 +9,7 @@ public record NtfyMessage( String event, String topic, String message, - String attachment // Nytt fält för filer + String attachment ) { public NtfyMessage(String topic, String message) { this(null, null, "message", topic, message, null); diff --git a/src/test/java/com/example/model/ChatModelTest.java b/src/test/java/com/example/model/ChatModelTest.java index a2e9ff5e..dafb58eb 100644 --- a/src/test/java/com/example/model/ChatModelTest.java +++ b/src/test/java/com/example/model/ChatModelTest.java @@ -1,5 +1,6 @@ package com.example.model; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.DisplayName; @@ -7,30 +8,50 @@ class ChatModelTest { - @Test - @DisplayName("NtfyMessage should be created with topic and message") - void testMessageCreation() { - NtfyMessage message = new NtfyMessage("testTopic", "Hello"); + private ChatModel model; - assertEquals("testTopic", message.topic()); - assertEquals("Hello", message.message()); - assertNotNull(message); + @BeforeEach + void setup() { + model = new ChatModel(); } @Test - @DisplayName("NtfyMessage should have event type") - void testMessageEvent() { - NtfyMessage message = new NtfyMessage("topic", "msg"); + @DisplayName("Should have empty message list initially") + void testInitialState() { + assertNotNull(model.getMessages()); + assertTrue(model.getMessages().isEmpty()); + } - assertEquals("message", message.event()); + @Test + @DisplayName("Should return observable list of messages") + void testGetMessages() { + assertNotNull(model.getMessages()); + assertEquals(0, model.getMessages().size()); } @Test - @DisplayName("NtfyMessage with attachment should store filename") - void testMessageWithAttachment() { - NtfyMessage message = new NtfyMessage("topic", "File sent", "test.pdf"); + @DisplayName("Should allow adding messages to list") + void testAddMessageToList() { + NtfyMessage message = new NtfyMessage("testTopic", "Test message"); + model.getMessages().add(message); - assertEquals("test.pdf", message.attachment()); - assertEquals("File sent", message.message()); + assertEquals(1, model.getMessages().size()); + assertEquals("Test message", model.getMessages().get(0).message()); + } + + @Test + @DisplayName("Should maintain message order") + void testMessageOrder() { + NtfyMessage msg1 = new NtfyMessage("topic", "First"); + NtfyMessage msg2 = new NtfyMessage("topic", "Second"); + NtfyMessage msg3 = new NtfyMessage("topic", "Third"); + + model.getMessages().add(msg1); + model.getMessages().add(msg2); + model.getMessages().add(msg3); + + assertEquals("First", model.getMessages().get(0).message()); + assertEquals("Second", model.getMessages().get(1).message()); + assertEquals("Third", model.getMessages().get(2).message()); } } \ No newline at end of file diff --git a/src/test/java/com/example/model/NtfyMesageTest.java b/src/test/java/com/example/model/NtfyMesageTest.java index 57443e83..746e313a 100644 --- a/src/test/java/com/example/model/NtfyMesageTest.java +++ b/src/test/java/com/example/model/NtfyMesageTest.java @@ -1,6 +1,5 @@ package com.example.model; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.DisplayName; @@ -8,85 +7,77 @@ class NtfyMessageTest { - private final ObjectMapper objectMapper = new ObjectMapper(); - @Test - @DisplayName("Should create message with convenience constructor") - void testConvenienceConstructor() { + @DisplayName("Should create message with topic and message text") + void testCreateMessage() { NtfyMessage message = new NtfyMessage("testTopic", "Hello World"); assertEquals("testTopic", message.topic()); assertEquals("Hello World", message.message()); + assertNotNull(message); + } + + @Test + @DisplayName("Should set default event type to 'message'") + void testDefaultEventType() { + NtfyMessage message = new NtfyMessage("testTopic", "Test"); + assertEquals("message", message.event()); + } + + @Test + @DisplayName("Should handle null id and time for new messages") + void testNewMessageHasNullIdAndTime() { + NtfyMessage message = new NtfyMessage("testTopic", "Test"); + assertNull(message.id()); assertNull(message.time()); } @Test - @DisplayName("Should deserialize JSON to NtfyMessage") - void testDeserialization() throws Exception { - String json = """ - { - "id": "abc123", - "time": 1234567890, - "event": "message", - "topic": "testTopic", - "message": "Hello World" - } - """; - - NtfyMessage message = objectMapper.readValue(json, NtfyMessage.class); + @DisplayName("Should create message with all fields using canonical constructor") + void testFullConstructor() { + NtfyMessage message = new NtfyMessage( + "abc123", // id + 1234567890L, // time + "message", // event + "testTopic", // topic + "Hello", // message + null // attachment + ); - assertNotNull(message); assertEquals("abc123", message.id()); - assertEquals(1234567890, message.time()); + assertEquals(1234567890L, message.time()); assertEquals("message", message.event()); assertEquals("testTopic", message.topic()); - assertEquals("Hello World", message.message()); + assertEquals("Hello", message.message()); } @Test - @DisplayName("Should serialize NtfyMessage to JSON") - void testSerialization() throws Exception { - NtfyMessage message = new NtfyMessage("testTopic", "Hello World"); + @DisplayName("Should accept empty message text") + void testEmptyMessage() { + NtfyMessage message = new NtfyMessage("testTopic", ""); - String json = objectMapper.writeValueAsString(message); - - assertNotNull(json); - assertTrue(json.contains("\"topic\":\"testTopic\"")); - assertTrue(json.contains("\"message\":\"Hello World\"")); - assertTrue(json.contains("\"event\":\"message\"")); + assertEquals("", message.message()); + assertEquals("testTopic", message.topic()); } @Test - @DisplayName("Should ignore unknown fields during deserialization") - void testIgnoreUnknownFields() throws Exception { - String json = """ - { - "id": "xyz789", - "time": 9876543210, - "event": "message", - "topic": "testTopic", - "message": "Test", - "expires": 1761905659, - "unknownField": "should be ignored" - } - """; - - NtfyMessage message = objectMapper.readValue(json, NtfyMessage.class); + @DisplayName("Should create message with attachment") + void testMessageWithAttachment() { + NtfyMessage message = new NtfyMessage("testTopic", "File sent", "test.pdf"); - assertNotNull(message); - assertEquals("xyz789", message.id()); - assertEquals("Test", message.message()); + assertEquals("testTopic", message.topic()); + assertEquals("File sent", message.message()); + assertEquals("test.pdf", message.attachment()); } @Test - @DisplayName("Should handle null values") - void testNullValues() { - NtfyMessage message = new NtfyMessage("topic", "message"); + @DisplayName("Should handle special characters in message") + void testSpecialCharacters() { + String specialMessage = "Hello! 🌸 @user #topic"; + NtfyMessage message = new NtfyMessage("testTopic", specialMessage); - assertNull(message.id()); - assertNull(message.time()); - assertNull(message.attachment()); + assertEquals(specialMessage, message.message()); } } \ No newline at end of file