diff --git a/MyLocalChat/src/main/java/app/Main.java b/MyLocalChat/src/main/java/app/Main.java index aabc42a..1f8a986 100644 --- a/MyLocalChat/src/main/java/app/Main.java +++ b/MyLocalChat/src/main/java/app/Main.java @@ -1,16 +1,17 @@ package app; -import fassade.ChatService; +import server.ChatServer; import ui.Chat; public class Main { - - public static void main(String[] args) { - ChatService service = new ChatService(); - - // Zwei Fenster erstellen - Chat omarChat = new Chat("Omar", "Obai", service, 550, 100); - Chat obaiChat = new Chat("Obai", "Omar", service, 100, 100); - } - -} + public static void main(String[] args) { + new Thread(() -> ChatServer.startServer()).start(); + + try { Thread.sleep(1000); } catch (InterruptedException e) {} + + javax.swing.SwingUtilities.invokeLater(() -> { + new Chat("Obai", 100, 100); + new Chat("Omar", 550, 100); + }); + } +} \ No newline at end of file diff --git a/MyLocalChat/src/main/java/domain/User.java b/MyLocalChat/src/main/java/domain/User.java index 3920a90..19292a6 100644 --- a/MyLocalChat/src/main/java/domain/User.java +++ b/MyLocalChat/src/main/java/domain/User.java @@ -3,6 +3,7 @@ package domain; import java.util.List; public class User { + private static int nextUserId = 1000; private int userId; private final String username; @@ -12,6 +13,7 @@ public class User { private UserChatRoom chatRoom; private UserGruppenRoom gruppenRoom; + public User(String username) { this.userId = nextUserId++; this.username = username; diff --git a/MyLocalChat/src/main/java/domain/UserChatRoom.java b/MyLocalChat/src/main/java/domain/UserChatRoom.java index 3e5f480..7ccf869 100644 --- a/MyLocalChat/src/main/java/domain/UserChatRoom.java +++ b/MyLocalChat/src/main/java/domain/UserChatRoom.java @@ -5,12 +5,13 @@ import java.util.List; import java.util.Objects; public class UserChatRoom { - private List chatRooms; // Bessere Namensgebung: chatRooms statt chatsRooms + private List chatRooms; public UserChatRoom() { this.chatRooms = new ArrayList<>(); } + public boolean addChat(ChatRoom chatRoom) { Objects.requireNonNull(chatRoom, "ChatRoom darf nicht null sein"); diff --git a/MyLocalChat/src/main/java/fassade/ChatService.java b/MyLocalChat/src/main/java/fassade/ChatService.java index 85c7b24..695ee30 100644 --- a/MyLocalChat/src/main/java/fassade/ChatService.java +++ b/MyLocalChat/src/main/java/fassade/ChatService.java @@ -19,13 +19,14 @@ public class ChatService { usersById = new HashMap<>(); } - public void createUser(String userName) { + public boolean createUser(String userName) { if (users.containsKey(userName)) throw new IllegalArgumentException("User existiert bereits: " + userName); User tempUser = new User(userName); users.put(userName, tempUser); usersById.put(tempUser.getUserId(), tempUser); + return true; } private User getUser(String userName) { diff --git a/MyLocalChat/src/main/java/server/ChatServer.java b/MyLocalChat/src/main/java/server/ChatServer.java new file mode 100644 index 0000000..73350de --- /dev/null +++ b/MyLocalChat/src/main/java/server/ChatServer.java @@ -0,0 +1,69 @@ +package server; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class ChatServer { + private static List clientWriters = new ArrayList<>(); + + public static void startServer() { + System.out.println("🚀 Starte LocalChat server..."); + + try (ServerSocket serverSocket = new ServerSocket(12345)) { + System.out.println("✅ server läuft auf Port 12345"); + + while (true) { + Socket clientSocket = serverSocket.accept(); + System.out.println("🔗 Neuer Client verbunden"); + new Thread(new ClientHandler(clientSocket)).start(); + } + } catch (IOException e) { + System.out.println("❌ server Fehler: " + e.getMessage()); + } + } + + private static class ClientHandler implements Runnable { + private Socket socket; + private PrintWriter out; + private String username; + + public ClientHandler(Socket socket) { + this.socket = socket; + } + + public void run() { + try { + out = new PrintWriter(socket.getOutputStream(), true); + BufferedReader in = new BufferedReader( + new InputStreamReader(socket.getInputStream())); + + // Username vom Client empfangen + username = in.readLine(); + System.out.println("👤 " + username + " ist beigetreten"); + + clientWriters.add(out); + broadcast("🌟 " + username + " hat den Chat betreten"); + + // Nachrichten empfangen und verteilen + String message; + while ((message = in.readLine()) != null) { + System.out.println("📩 " + username + ": " + message); + broadcast(username + ": " + message); + } + } catch (IOException e) { + System.out.println("❌ " + username + " hat den Chat verlassen"); + } finally { + clientWriters.remove(out); + broadcast("👋 " + username + " hat den Chat verlassen"); + try { socket.close(); } catch (IOException e) {} + } + } + } + + private static void broadcast(String message) { + for (PrintWriter writer : clientWriters) { + writer.println(message); + } + } +} \ No newline at end of file diff --git a/MyLocalChat/src/main/java/ui/Chat.java b/MyLocalChat/src/main/java/ui/Chat.java index 7431889..4fe06cd 100644 --- a/MyLocalChat/src/main/java/ui/Chat.java +++ b/MyLocalChat/src/main/java/ui/Chat.java @@ -3,54 +3,67 @@ package ui; import javax.swing.*; import java.awt.*; import java.awt.event.*; -import fassade.ChatService; +import java.io.*; +import java.net.*; public class Chat extends JFrame { - private ChatService service; + private PrintWriter out; private String username; - private int roomId; private JTextArea chatArea; private JTextField messageField; - private JButton sendButton; - public Chat(String username, String otherUser, ChatService service, int x, int y) { - this.service = service; + public Chat(String username, int x, int y) { this.username = username; - - // User erstellen - service.createUser(username); - service.createUser(otherUser); - - // Chatroom erstellen - this.roomId = service.createChatRoom(username, otherUser); - setupGUI(); + connectToServer(); setLocation(x, y); setVisible(true); } + private void connectToServer() { + try { + Socket socket = new Socket("localhost", 12345); + out = new PrintWriter(socket.getOutputStream(), true); + + // Username zum Server senden + out.println(username); + + // Thread für eingehende Nachrichten + new Thread(() -> { + try { + BufferedReader in = new BufferedReader( + new InputStreamReader(socket.getInputStream())); + + String message; + while ((message = in.readLine()) != null) { + chatArea.append(message + "\n"); + } + } catch (IOException e) { + chatArea.append("❌ Verbindung zum Server verloren\n"); + } + }).start(); + + } catch (IOException e) { + JOptionPane.showMessageDialog(this, "❌ Server nicht erreichbar!"); + } + } + private void setupGUI() { - setTitle("Chat - " + username); + setTitle("💬 " + username); setSize(400, 500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); - // Chat-Anzeige chatArea = new JTextArea(); chatArea.setEditable(false); - JScrollPane scrollPane = new JScrollPane(chatArea); - add(scrollPane, BorderLayout.CENTER); + add(new JScrollPane(chatArea), BorderLayout.CENTER); - // Eingabe-Bereich JPanel inputPanel = new JPanel(new BorderLayout()); messageField = new JTextField(); - sendButton = new JButton("Senden"); + JButton sendButton = new JButton("📤"); - // Send-Button Action sendButton.addActionListener(e -> sendMessage()); - - // Enter-Taste zum Senden messageField.addActionListener(e -> sendMessage()); inputPanel.add(messageField, BorderLayout.CENTER); @@ -58,32 +71,13 @@ public class Chat extends JFrame { inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(inputPanel, BorderLayout.SOUTH); - - // Initiale Nachricht - chatArea.append("Chat gestartet mit " + username + "\n"); } private void sendMessage() { String message = messageField.getText().trim(); - if (!message.isEmpty()) { - try { - service.sendMessage(roomId, username, message); - messageField.setText(""); - refreshChat(); - } catch (Exception e) { - JOptionPane.showMessageDialog(this, "Fehler: " + e.getMessage()); - } - } - } - - private void refreshChat() { - try { - chatArea.setText(""); - for (String message : service.showMessage(roomId)) { - chatArea.append(message + "\n"); - } - } catch (Exception e) { - chatArea.append("Fehler beim Laden: " + e.getMessage() + "\n"); + if (!message.isEmpty() && out != null) { + out.println(message); + messageField.setText(""); } } } \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/ChatRoomTest.java b/MyLocalChat/src/test/java/test/ChatRoomTest.java index 244c2f6..ad4417d 100644 --- a/MyLocalChat/src/test/java/test/ChatRoomTest.java +++ b/MyLocalChat/src/test/java/test/ChatRoomTest.java @@ -15,10 +15,9 @@ public class ChatRoomTest { User user2 = new User("User2"); ChatRoom room = new ChatRoom(user1, user2); - - - assertNotNull(room.getCreatedAt()); - assertTrue(room.getRoomId() >= 1000); + assertEquals(user1, room.getUser1()); + assertEquals(user2, room.getUser2()); + assertTrue(room.getMessages().isEmpty()); } @Test @@ -27,7 +26,7 @@ public class ChatRoomTest { User user2 = new User("User2"); ChatRoom room = new ChatRoom(user1, user2); - Message message = new Message(user1, "Hallo!"); + Message message = new Message(user1, "Hello"); room.addMessage(message); assertEquals(1, room.getMessages().size()); @@ -40,33 +39,12 @@ public class ChatRoomTest { User user2 = new User("User2"); ChatRoom room = new ChatRoom(user1, user2); - room.addMessage(new Message(user1, "Nachricht 1")); - room.addMessage(new Message(user2, "Nachricht 2")); + room.addMessage(new Message(user1, "Hi")); + room.addMessage(new Message(user2, "Hello")); List messages = room.showMessages(); assertEquals(2, messages.size()); - assertTrue(messages.get(0).contains("Nachricht 1")); - assertTrue(messages.get(1).contains("Nachricht 2")); + assertTrue(messages.get(0).contains("Hi")); + assertTrue(messages.get(1).contains("Hello")); } - - @Test - public void testAddParticipant() { - User user1 = new User("User1"); - User user2 = new User("User2"); - User user3 = new User("User3"); - ChatRoom room = new ChatRoom(user1, user2); - - - } - - @Test - public void testAddDuplicateParticipant() { - User user1 = new User("User1"); - User user2 = new User("User2"); - ChatRoom room = new ChatRoom(user1, user2); - - - } - - } \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/ChatServiceTest.java b/MyLocalChat/src/test/java/test/ChatServiceTest.java new file mode 100644 index 0000000..97cfc83 --- /dev/null +++ b/MyLocalChat/src/test/java/test/ChatServiceTest.java @@ -0,0 +1,70 @@ +package test; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.Before; +import domain.*; +import fassade.ChatService; + +import java.util.List; + +public class ChatServiceTest { + + private ChatService service; + + @Before + public void setUp() { + service = new ChatService(); + } + + @Test + public void testCreateUser() { + assertTrue(service.createUser("TestUser")); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateDuplicateUser() { + service.createUser("TestUser"); + service.createUser("TestUser"); // Should throw exception + } + + @Test + public void testCreateChatRoom() { + service.createUser("User1"); + service.createUser("User2"); + + int roomId = service.createChatRoom("User1", "User2"); + assertTrue(roomId > 0); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateChatRoomNonExistentUsers() { + service.createChatRoom("NonExistent1", "NonExistent2"); + } + + @Test + public void testSendAndReceiveMessages() { + service.createUser("User1"); + service.createUser("User2"); + int roomId = service.createChatRoom("User1", "User2"); + + service.sendMessage(roomId, "User1", "Hello"); + service.sendMessage(roomId, "User2", "Hi there"); + + List messages = service.showMessage(roomId); + assertEquals(2, messages.size()); + assertTrue(messages.get(0).contains("Hello")); + assertTrue(messages.get(1).contains("Hi there")); + } + + @Test + public void testAddContact() { + service.createUser("User1"); + service.createUser("User2"); + + assertTrue(service.addContact("User2", "User1")); + List contacts = service.getUserContacts("User1"); + assertEquals(1, contacts.size()); + assertTrue(contacts.get(0).contains("User2")); + } +} \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/ExceptionTest.java b/MyLocalChat/src/test/java/test/ExceptionTest.java new file mode 100644 index 0000000..3d5f3cc --- /dev/null +++ b/MyLocalChat/src/test/java/test/ExceptionTest.java @@ -0,0 +1,39 @@ +package test; + +import org.junit.Test; +import org.junit.Before; +import fassade.ChatService; + +public class ExceptionTest { + + private ChatService service; + + @Before + public void setUp() { + service = new ChatService(); + } + + @Test(expected = IllegalArgumentException.class) + public void testSendMessageToNonExistentRoom() { + service.sendMessage(9999, "User1", "Test"); + } + + @Test(expected = IllegalArgumentException.class) + public void testSendMessageNonExistentUser() { + service.createUser("User1"); + service.createUser("User2"); + int roomId = service.createChatRoom("User1", "User2"); + service.sendMessage(roomId, "NonExistent", "Test"); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNonExistentContact() { + service.createUser("User1"); + service.addContact("NonExistent", "User1"); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetUserContactsNonExistentUser() { + service.getUserContacts("NonExistent"); + } +} \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/GruppenRoomTest.java b/MyLocalChat/src/test/java/test/GruppenRoomTest.java new file mode 100644 index 0000000..c1fdf87 --- /dev/null +++ b/MyLocalChat/src/test/java/test/GruppenRoomTest.java @@ -0,0 +1,48 @@ +package test; + +import static org.junit.Assert.*; +import org.junit.Test; + +import domain.*; + +public class GruppenRoomTest { + + @Test + public void testGruppenRoomCreation() { + User creator = new User("Creator"); + GruppenRoom group = new GruppenRoom(creator, "TestGroup", "Description"); + + assertEquals("TestGroup", group.getName()); + assertEquals("Description", group.getDescription()); + assertEquals(creator, group.getCreator()); + assertTrue(group.getParticipants().contains(creator)); + } + + @Test + public void testAddParticipant() { + User creator = new User("Creator"); + User newUser = new User("NewUser"); + GruppenRoom group = new GruppenRoom(creator, "TestGroup", "Description"); + + assertTrue(group.addParticipant(newUser)); + assertTrue(group.getParticipants().contains(newUser)); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddDuplicateParticipant() { + User creator = new User("Creator"); + GruppenRoom group = new GruppenRoom(creator, "TestGroup", "Description"); + group.addParticipant(creator); // Should throw exception + } + + @Test + public void testAddAdmin() { + User creator = new User("Creator"); + User admin = new User("Admin"); + GruppenRoom group = new GruppenRoom(creator, "TestGroup", "Description"); + group.addParticipant(admin); + + assertTrue(group.addAdmin(creator, admin)); + assertTrue(group.getAdmins().contains(admin)); + } +} \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/IntegrationTest.java b/MyLocalChat/src/test/java/test/IntegrationTest.java new file mode 100644 index 0000000..5243fc2 --- /dev/null +++ b/MyLocalChat/src/test/java/test/IntegrationTest.java @@ -0,0 +1,66 @@ +package test; + +import static org.junit.Assert.*; +import org.junit.Test; +import fassade.ChatService; +import domain.*; +import java.util.List; + +public class IntegrationTest { + + @Test + public void testCompleteChatWorkflow() { + ChatService service = new ChatService(); + + // Create users + service.createUser("Alice"); + service.createUser("Bob"); + + // Create chat room + int roomId = service.createChatRoom("Alice", "Bob"); + + // Exchange messages + service.sendMessage(roomId, "Alice", "Hi Bob!"); + service.sendMessage(roomId, "Bob", "Hello Alice!"); + service.sendMessage(roomId, "Alice", "How are you?"); + + // Verify messages + List messages = service.showMessage(roomId); + assertEquals(3, messages.size()); + assertTrue(messages.get(0).contains("Hi Bob")); + assertTrue(messages.get(1).contains("Hello Alice")); + assertTrue(messages.get(2).contains("How are you")); + + // Test contacts + service.addContact("Bob", "Alice"); + List contacts = service.getUserContacts("Alice"); + assertEquals(1, contacts.size()); + assertTrue(contacts.get(0).contains("Bob")); + } + + @Test + public void testGroupChatWorkflow() { + ChatService service = new ChatService(); + + service.createUser("Admin"); + service.createUser("User1"); + service.createUser("User2"); + + // Create group + int groupId = service.createGruppenRoom("Admin", "DevTeam", "Development Team"); + + // Add participants + service.addParticipantToGroup(groupId, "Admin", "User1"); + service.addParticipantToGroup(groupId, "Admin", "User2"); + + // Send group messages + service.sendGroupMessage(groupId, "Admin", "Welcome everyone!"); + service.sendGroupMessage(groupId, "User1", "Thanks for adding me!"); + + // Verify group messages + List messages = service.getGroupMessages(groupId); + assertEquals(2, messages.size()); + assertTrue(messages.get(0).contains("Welcome")); + assertTrue(messages.get(1).contains("Thanks")); + } +} \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/MessageTest.java b/MyLocalChat/src/test/java/test/MessageTest.java index 8b67963..51ef018 100644 --- a/MyLocalChat/src/test/java/test/MessageTest.java +++ b/MyLocalChat/src/test/java/test/MessageTest.java @@ -2,22 +2,30 @@ package test; import static org.junit.Assert.*; import org.junit.Test; -import java.time.LocalDateTime; -import domain.*; +import domain.*; public class MessageTest { @Test public void testMessageCreation() { User sender = new User("Sender"); - Message message = new Message(sender, "Testnachricht"); + Message message = new Message(sender, "Test message"); assertEquals(sender, message.getSender()); - assertEquals("Testnachricht", message.getContent()); + assertEquals("Test message", message.getContent()); assertNotNull(message.getTimestamp()); - assertTrue(message.getTimestamp().isBefore(LocalDateTime.now().plusSeconds(1))); - assertTrue(message.getTimestamp().isAfter(LocalDateTime.now().minusSeconds(1))); + } + + @Test + public void testMessageToString() { + User sender = new User("TestUser"); + Message message = new Message(sender, "Hello World"); + + String result = message.toString(); + assertTrue(result.contains("TestUser")); + assertTrue(result.contains("Hello World")); + assertTrue(result.contains(":")); } @Test @@ -27,25 +35,9 @@ public class MessageTest { Message message = new Message(sender1, "Original"); message.setSender(sender2); - message.setContent("Geändert"); + message.setContent("Changed"); assertEquals(sender2, message.getSender()); - assertEquals("Geändert", message.getContent()); - } - - @Test - public void testMessageToString() { - User sender = new User("TestSender"); - Message message = new Message(sender, "Testinhalt"); - - String toString = message.toString(); - assertTrue(toString.contains("TestSender")); - assertTrue(toString.contains("Testinhalt")); - assertTrue(toString.contains("timestamp")); - } - - @Test(expected = IllegalArgumentException.class) - public void testMessageWithNullSender() { - new Message(null, "Test"); + assertEquals("Changed", message.getContent()); } } \ No newline at end of file diff --git a/MyLocalChat/src/test/java/test/UserTest.java b/MyLocalChat/src/test/java/test/UserTest.java index d42f518..229a106 100644 --- a/MyLocalChat/src/test/java/test/UserTest.java +++ b/MyLocalChat/src/test/java/test/UserTest.java @@ -1,17 +1,10 @@ package test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.Assert.*; +import org.junit.Test; + import domain.*; -import org.junit.jupiter.api.Test; - - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - - public class UserTest { @Test @@ -20,11 +13,10 @@ public class UserTest { assertEquals("TestUser", user.getUsername()); assertTrue(user.isOnline()); assertEquals(UserInfo.VERFÜGBAR, user.getUserInfo()); - assertTrue(user.getUserId() >= 1000); } @Test - public void testUserStatusChange() { + public void testUserStatusChanges() { User user = new User("TestUser"); user.setOnline(false); assertFalse(user.isOnline()); @@ -34,21 +26,20 @@ public class UserTest { } @Test - public void testUserIdUniqueness() { + public void testUserContacts() { User user1 = new User("User1"); User user2 = new User("User2"); - User user3 = new User("User3"); - assertNotEquals(user1.getUserId(), user2.getUserId()); - assertNotEquals(user2.getUserId(), user3.getUserId()); - assertNotEquals(user1.getUserId(), user3.getUserId()); + assertTrue(user1.getUserContacts().addContact(user2)); + assertEquals(1, user1.getUserContacts().showAllContacts().size()); } @Test - public void testUserToString() { - User user = new User("TestUser"); - String toString = user.toString(); - assertTrue(toString.contains("TestUser")); - assertTrue(toString.contains("VERFÜGBAR")); + public void testUserEquals() { + User user1 = new User("SameUser"); + User user2 = new User("SameUser"); + + assertNotEquals(user1, user2); // Different objects + assertEquals(user1, user1); // Same object } } \ No newline at end of file