Procházet zdrojové kódy

wersja po poprawkach

Adam Matuszewski před 1 rokem
rodič
revize
91d2089b8d

+ 38 - 0
NotificationSystem3/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 8 - 0
NotificationSystem3/.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 7 - 0
NotificationSystem3/.idea/encodings.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
+  </component>
+</project>

+ 14 - 0
NotificationSystem3/.idea/misc.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 8 - 0
NotificationSystem3/.idea/vcs.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 85 - 0
NotificationSystem3/pom.xml

@@ -0,0 +1,85 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>pl.dmcs</groupId>
+  <artifactId>app</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>11</maven.compiler.source>
+    <maven.compiler.target>11</maven.compiler.target>
+  </properties>
+  <name>My sample project</name>
+  <description>This is my sample project.</description>
+  <url>https://weeia.p.lodz.pl</url>
+  <dependencies>
+    <!-- JUnit dependency for testing -->
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <version>5.10.2</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- Mockito dependency for testing -->
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>5.11.0</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- Apache Commons Lang for Pair class -->
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.12.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <!-- clean lifecycle -->
+        <plugin>
+          <artifactId>maven-clean-plugin</artifactId>
+          <version>3.3.2</version>
+        </plugin>
+        <!-- default lifecycle -->
+        <plugin>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>3.3.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.12.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>3.2.5</version>
+          <configuration>
+            <argLine>-XX:+EnableDynamicAgentLoading -Djdk.instrument.traceUsage</argLine>
+          </configuration>
+        </plugin>
+        <plugin>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>3.3.0</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-install-plugin</artifactId>
+          <version>3.1.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-deploy-plugin</artifactId>
+          <version>3.1.1</version>
+        </plugin>
+        <!-- site lifecycle -->
+        <plugin>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>4.0.0-M13</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-project-info-reports-plugin</artifactId>
+          <version>3.5.0</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>

+ 30 - 0
NotificationSystem3/src/main/java/pl/dmcs/DataLoader.java

@@ -0,0 +1,30 @@
+package pl.dmcs;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DataLoader {
+    public static Pair<User, List<String>> loadData(String filePath) throws IOException {
+        BufferedReader reader = new BufferedReader(new FileReader(filePath));
+        String line = reader.readLine();
+        String[] userData = line.split(",");
+
+        User user = new User(userData[0], userData[1], userData[2]);
+        List<String> recipients = new ArrayList<>();
+
+        while ((line = reader.readLine()) != null) {
+            recipients.add(line.trim());
+        }
+
+        reader.close();
+        return Pair.of(user, recipients);
+    }
+}
+
+
+

+ 5 - 0
NotificationSystem3/src/main/java/pl/dmcs/MailService.java

@@ -0,0 +1,5 @@
+package pl.dmcs;
+
+public interface MailService {
+    void sendEmail(String sender, String recipient, String subject, String content) throws Exception;
+}

+ 7 - 0
NotificationSystem3/src/main/java/pl/dmcs/NotificationService.java

@@ -0,0 +1,7 @@
+package pl.dmcs;
+
+import java.util.List;
+
+public interface NotificationService {
+    void sendNotifications(User user, List<String> recipients, String subject, String content) throws Exception;
+}

+ 25 - 0
NotificationSystem3/src/main/java/pl/dmcs/NotificationServiceImpl.java

@@ -0,0 +1,25 @@
+package pl.dmcs;
+
+import java.util.List;
+
+public class NotificationServiceImpl implements NotificationService {
+    private final MailService mailService;
+
+    public NotificationServiceImpl(MailService mailService) {
+        this.mailService = mailService;
+    }
+
+    @Override
+    public void sendNotifications(User user, List<String> recipients, String subject, String content)  {
+        String prefixedSubject = "Powiadomienie: " + subject;
+        String prefixedContent = "Powiadomienie od " + user.getFirstName() + " " + user.getLastName() + "\n" + content;
+
+        for (String recipient : recipients) {
+            try {
+                mailService.sendEmail(user.getEmail(), recipient, prefixedSubject, prefixedContent);
+            } catch (Exception e) {
+                System.err.println("Failed to send email to: " + recipient + ". Error: " + e.getMessage());
+            }
+        }
+    }
+}

+ 25 - 0
NotificationSystem3/src/main/java/pl/dmcs/User.java

@@ -0,0 +1,25 @@
+package pl.dmcs;
+
+public class User {
+    private String firstName;
+    private String lastName;
+    private String email;
+
+    public User(String firstName, String lastName, String email) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.email = email;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+}

+ 9 - 0
NotificationSystem3/src/main/resources/META-INF/maven/archetype.xml

@@ -0,0 +1,9 @@
+<archetype>
+  <id>NotificationServiceTest.java</id>
+  <sources>
+    <source>src/main/java/App.java</source>
+  </sources>
+  <testSources>
+    <source>src/test/java/AppTest.java</source>
+  </testSources>
+</archetype>

+ 15 - 0
NotificationSystem3/src/main/resources/archetype-resources/pom.xml

@@ -0,0 +1,15 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>$org.example</groupId>
+  <artifactId>$NotificationServiceTest.java</artifactId>
+  <version>$1.0-SNAPSHOT</version>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 13 - 0
NotificationSystem3/src/main/resources/archetype-resources/src/main/java/App.java

@@ -0,0 +1,13 @@
+package $org.example;
+
+/**
+ * Hello world!
+ *
+ */
+public class App 
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World!" );
+    }
+}

+ 38 - 0
NotificationSystem3/src/main/resources/archetype-resources/src/test/java/AppTest.java

@@ -0,0 +1,38 @@
+package $org.example;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}

+ 3 - 0
NotificationSystem3/src/main/resources/notifications.csv

@@ -0,0 +1,3 @@
+Jan,Kowalski,jan.kowalski@example.com
+recipient1@example.com
+recipient2@example.com

+ 75 - 0
NotificationSystem3/src/test/java/pl/dmcs/DataLoaderTest.java

@@ -0,0 +1,75 @@
+package pl.dmcs;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class DataLoaderTest {
+
+    @TempDir
+    Path tempDir;
+
+    private File createTempFileWithData(String userData, List<String> recipients) throws IOException {
+        File tempFile = tempDir.resolve("testdata.csv").toFile();
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) {
+            writer.write(userData);
+            writer.write("\n");
+            for (String recipient : recipients) {
+                writer.write(recipient);
+                writer.write("\n");
+            }
+        }
+        return tempFile;
+    }
+
+    private void assertUserData(User expectedUser, List<String> expectedRecipients, Pair<User, List<String>> result) {
+        User actualUser = result.getLeft();
+        List<String> actualRecipients = result.getRight();
+
+        assertEquals(expectedUser.getFirstName(), actualUser.getFirstName());
+        assertEquals(expectedUser.getLastName(), actualUser.getLastName());
+        assertEquals(expectedUser.getEmail(), actualUser.getEmail());
+        assertEquals(expectedRecipients, actualRecipients);
+    }
+
+    @Test
+    public void testLoadData() throws IOException {
+        File tempFile = createTempFileWithData("John,Doe,john.doe@example.com",
+                Arrays.asList("recipient1@example.com", "recipient2@example.com", "recipient3@example.com"));
+
+        User expectedUser = new User("John", "Doe", "john.doe@example.com");
+        List<String> expectedRecipients = Arrays.asList("recipient1@example.com", "recipient2@example.com", "recipient3@example.com");
+
+        Pair<User, List<String>> result = DataLoader.loadData(tempFile.getAbsolutePath());
+        assertUserData(expectedUser, expectedRecipients, result);
+    }
+
+    @Test
+    public void testLoadDataEmptyRecipients() throws IOException {
+        File tempFile = createTempFileWithData("John,Doe,john.doe@example.com", Collections.emptyList());
+
+        User expectedUser = new User("John", "Doe", "john.doe@example.com");
+        List<String> expectedRecipients = Collections.emptyList();
+
+        Pair<User, List<String>> result = DataLoader.loadData(tempFile.getAbsolutePath());
+        assertUserData(expectedUser, expectedRecipients, result);
+    }
+
+    @Test
+    public void testLoadDataInvalidFile() {
+        assertThrows(IOException.class, () -> {
+            DataLoader.loadData("invalid/path/to/file.csv");
+        });
+    }
+}

+ 110 - 0
NotificationSystem3/src/test/java/pl/dmcs/NotificationServiceTest.java

@@ -0,0 +1,110 @@
+package pl.dmcs;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.*;
+
+public class NotificationServiceTest {
+
+    private MailService mailServiceMock;
+    private NotificationService notificationService;
+
+    @BeforeEach
+    public void setUp() {
+        mailServiceMock = mock(MailService.class, withSettings().withoutAnnotations().defaultAnswer(CALLS_REAL_METHODS));
+        notificationService = new NotificationServiceImpl(mailServiceMock);
+    }
+
+    private void sendAndVerifyNotifications(User user, List<String> recipients, String subject, String content) throws Exception {
+        notificationService.sendNotifications(user, recipients, subject, content);
+
+        String expectedSubject = "Powiadomienie: " + subject;
+        String expectedContent = "Powiadomienie od " + user.getFirstName() + " " + user.getLastName() + "\n" + content;
+
+        for (String recipient : recipients) {
+            verify(mailServiceMock).sendEmail(user.getEmail(), recipient, expectedSubject, expectedContent);
+        }
+    }
+
+    @Test
+    public void testSendNotifications() throws Exception {
+        User user = new User("Jan", "Kowalski", "jan.kowalski@example.com");
+        List<String> recipients = Arrays.asList("recipient1@example.com", "recipient2@example.com");
+        String subject = "Testowy temat";
+        String content = "Treść wiadomości";
+
+        sendAndVerifyNotifications(user, recipients, subject, content);
+    }
+
+    @Test
+    public void testSendNotificationsFromCSV() throws Exception {
+        String filePath = "src/test/resources/notifications.csv";
+
+        Pair<User, List<String>> data = DataLoader.loadData(filePath);
+        User user = data.getLeft();
+        List<String> recipients = data.getRight();
+        String subject = "Testowy temat";
+        String content = "Treść wiadomości";
+
+        sendAndVerifyNotifications(user, recipients, subject, content);
+
+        for (String recipient : recipients) {
+            System.out.println("Sent email to: " + recipient);
+            System.out.println("Subject: " + "Powiadomienie: " + subject);
+            System.out.println("Content: " + "Powiadomienie od " + user.getFirstName() + " " + user.getLastName() + "\n" + content);
+        }
+    }
+
+    @Test
+    public void testSendNotificationsWithException() throws Exception {
+        MailService mailServiceMock = mock(MailService.class);
+        NotificationService notificationService = new NotificationServiceImpl(mailServiceMock);
+
+        User user = new User("Jan", "Kowalski", "jan.kowalski@example.com");
+        List<String> recipients = Arrays.asList("recipient1@example.com", "recipient2@example.com");
+        String subject = "Testowy temat";
+        String content = "Treść wiadomości";
+
+        doThrow(new RuntimeException("Email sending failed"))
+                .when(mailServiceMock).sendEmail(anyString(), eq("recipient1@example.com"), anyString(), anyString());
+
+        notificationService.sendNotifications(user, recipients, subject, content);
+
+        String expectedSubject = "Powiadomienie: Testowy temat";
+        String expectedContent = "Powiadomienie od Jan Kowalski\nTreść wiadomości";
+
+        verify(mailServiceMock).sendEmail(user.getEmail(), "recipient1@example.com", expectedSubject, expectedContent);
+        verify(mailServiceMock).sendEmail(user.getEmail(), "recipient2@example.com", expectedSubject, expectedContent);
+    }
+
+    @Test
+    public void testPartialFailuresStillSendToOthers() throws Exception {
+        User user = new User("Jan", "Kowalski", "jan.kowalski@example.com");
+        List<String> recipients = Arrays.asList("recipient1@example.com", "recipient2@example.com", "recipient3@example.com");
+        String subject = "Testowy temat";
+        String content = "Treść wiadomości";
+
+        doThrow(new RuntimeException("Email sending failed"))
+                .when(mailServiceMock).sendEmail(anyString(), eq("recipient1@example.com"), anyString(), anyString());
+
+        doNothing()
+                .when(mailServiceMock).sendEmail(anyString(), eq("recipient2@example.com"), anyString(), anyString());
+        doNothing()
+                .when(mailServiceMock).sendEmail(anyString(), eq("recipient3@example.com"), anyString(), anyString());
+
+        notificationService.sendNotifications(user, recipients, subject, content);
+
+        String expectedSubject = "Powiadomienie: " + subject;
+        String expectedContent = "Powiadomienie od " + user.getFirstName() + " " + user.getLastName() + "\n" + content;
+
+        verify(mailServiceMock).sendEmail(user.getEmail(), "recipient1@example.com", expectedSubject, expectedContent);
+        verify(mailServiceMock).sendEmail(user.getEmail(), "recipient2@example.com", expectedSubject, expectedContent);
+        verify(mailServiceMock).sendEmail(user.getEmail(), "recipient3@example.com", expectedSubject, expectedContent);
+    }
+
+}

+ 9 - 0
NotificationSystem3/src/test/resources/DoPoprawy

@@ -0,0 +1,9 @@
+1. Drugi test na innych danych na sztywno.
+2. Odrębne testy dla każdej klasy.
++3. Test dla DataLoader. --dodany
+4. Test typu end to end.
+5. Wyrzucanie konkretnego wyjątku (To już na 5, więc można odpuścic).
+6. Sprawdzić jaka wiadomość została wysłana
++7. W przypadku niepowodzenie wysłania maila dla jednego odbiorcy, pozostali powinni otrzymać maile, sprawdzić ilość i treści. -- dodany dodatkowy test oraz modyfikacja do klasy notificationserviceimpl
+8. Ewentualnie można usunąć serwis dla Notification (zawrzeć to jako zwykłą klasę)
++9. Przeprowadzenie refaktoryzacji. (refaktoryzowane testy dla notificationserviceimpl sprawdzic czy mozna cos jeszcze zrefaktoryzowac)

+ 3 - 0
NotificationSystem3/src/test/resources/notifications.csv

@@ -0,0 +1,3 @@
+Jan,Kowalski,jan.kowalski@example.com
+recipient1@example.com
+recipient2@example.com