diff --git a/src/test/java/de/rwu/easydrop/api/AmazonProductDataSourceTest.java b/src/test/java/de/rwu/easydrop/api/AmazonProductDataSourceTest.java index ff472fe..d643d91 100644 --- a/src/test/java/de/rwu/easydrop/api/AmazonProductDataSourceTest.java +++ b/src/test/java/de/rwu/easydrop/api/AmazonProductDataSourceTest.java @@ -1,6 +1,16 @@ package de.rwu.easydrop.api; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.lang.reflect.Field; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -10,34 +20,36 @@ import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import de.rwu.easydrop.api.client.AmazonProductDataSource; +import de.rwu.easydrop.api.dto.ProductDTO; public class AmazonProductDataSourceTest { - private AmazonProductDataSource dataSource; + private AmazonProductDataSource demoDataSource; + + private static String demoApiKey = "my-api-key"; + private static String demoApiUrl = "https://www.example.com/api"; + private static String demoDataOrigin = "Amazon"; + private static String demoProductId = "whateverId"; @BeforeEach public void setup() { - dataSource = new AmazonProductDataSource( - "https://www.example.com/api", - "my-api-key"); + demoDataSource = new AmazonProductDataSource( + demoApiUrl, + demoApiKey); MockitoAnnotations.openMocks(this); } @Test public void testConstructor() { - // Arrange - String baseUrl = "https://www.example.com/api"; - String apiKey = "my-api-key"; - // Assert try { Field baseUrlField = AmazonProductDataSource.class.getDeclaredField("baseUrl"); baseUrlField.setAccessible(true); - Assertions.assertEquals(baseUrl, baseUrlField.get(dataSource)); + Assertions.assertEquals(demoApiUrl, baseUrlField.get(demoDataSource)); Field apiKeyField = AmazonProductDataSource.class.getDeclaredField("apiKey"); apiKeyField.setAccessible(true); - Assertions.assertEquals(apiKey, apiKeyField.get(dataSource)); + Assertions.assertEquals(demoApiKey, apiKeyField.get(demoDataSource)); } catch (NoSuchFieldException e) { Assertions.fail(); } catch (IllegalAccessException e) { @@ -51,14 +63,128 @@ public class AmazonProductDataSourceTest { String productId1 = "12345"; URL expectedUrl1 = new URL( "https://www.example.com/api/products/2020-08-26/products/12345/offers?productRegion=DE&locale=de_DE"); - URL createdUrl1 = dataSource.createApiUrl(productId1); + URL createdUrl1 = demoDataSource.createApiUrl(productId1); Assertions.assertEquals(expectedUrl1, createdUrl1); // Test case 2 String productId2 = "67890"; URL expectedUrl2 = new URL( - "https://www.example.com/api/products/2020-08-26/products/67890/offers?productRegion=DE&locale=de_DE"); - URL createdUrl2 = dataSource.createApiUrl(productId2); + "https://www.example.com/api/products/2020-08-26/" + + "products/67890/offers?productRegion=DE&locale=de_DE"); + URL createdUrl2 = demoDataSource.createApiUrl(productId2); Assertions.assertEquals(expectedUrl2, createdUrl2); } + + @Test + public void testBuildProductDTO_completeData() { + // Set up the test environment + String json = "{\"featuredOffer\": {\"availability\": \"available\"," + + "\"price\": {\"value\": {\"amount\": 10.0}}," + + "\"shippingOptions\": [{\"shippingCost\": {\"value\": {\"amount\": 2.5}}}], " + + "\"merchant\": {\"name\": \"Merchant A\"}}}"; + ProductDTO product = new ProductDTO(demoProductId, demoDataOrigin); + + // Invoke the method + ProductDTO result = demoDataSource.buildProductDTO(product, json); + + // Verify the product DTO properties + assertEquals(demoDataOrigin, result.getDataOrigin()); + assertEquals(true, result.isAvailable()); + assertEquals(10.0, result.getCurrentPrice()); + assertEquals(2.5, result.getDeliveryPrice()); + assertEquals("Merchant A", result.getMerchant()); + } + + @Test + public void testBuildProductDTO_incompleteData() { + // Set up the test environment + String json = "{\"otherOffer\": {\"availability\": \"available\"," + + "\"price\": {\"value\": {\"amount\": 10.0}}," + + "\"shippingOptions\": [{\"shippingCost\": {\"value\": {\"amount\": 2.5}}}], " + + "\"merchant\": {\"name\": \"Merchant A\"}}}"; + ProductDTO product = new ProductDTO(demoProductId, demoDataOrigin); + + // Invoke the method + ProductDTO result = demoDataSource.buildProductDTO(product, json); + + // Verify that the product DTO remains unchanged + assertEquals(demoDataOrigin, result.getDataOrigin()); + assertEquals(false, result.isAvailable()); + assertEquals(0.0, result.getCurrentPrice()); + assertEquals(0.0, result.getDeliveryPrice()); + assertEquals(null, result.getMerchant()); + } + + @Test + public void testGetProductDTOById_successfulRequest() throws IOException { + // Set up the test environment + String mockResponse = "{\"featuredOffer\": {\"availability\": \"available\"," + + "\"price\": {\"value\": {\"amount\": 10.0}}," + + "\"shippingOptions\": [{\"shippingCost\": {\"value\": {\"amount\": 2.5}}}], " + + "\"merchant\": {\"name\": \"Merchant A\"}}}"; + + AmazonProductDataSource dataSource = mock(AmazonProductDataSource.class); + URL mockURL = mock(URL.class); + when(dataSource.createApiUrl(demoProductId)).thenReturn(mockURL); + when(dataSource.buildProductDTO(any(), anyString())).thenCallRealMethod(); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mockConnection.getInputStream()).thenReturn(new ByteArrayInputStream(mockResponse.getBytes())); + when(dataSource.getProductDTOById(demoProductId)).thenCallRealMethod(); + + // Invoke the method + ProductDTO result = dataSource.getProductDTOById(demoProductId); + + // Verify the product DTO properties + assertEquals(demoProductId, result.getProductId()); + assertEquals("Amazon", result.getDataOrigin()); + assertEquals(true, result.isAvailable()); + assertEquals(10.0, result.getCurrentPrice()); + assertEquals(2.5, result.getDeliveryPrice()); + assertEquals("Merchant A", result.getMerchant()); + } + + @Test + public void testGetProductDTOById_failedRequest() throws IOException { + // Set up the test environment + + AmazonProductDataSource dataSource = mock(AmazonProductDataSource.class); + URL mockURL = mock(URL.class); + when(dataSource.createApiUrl(demoProductId)).thenReturn(mockURL); + when(dataSource.getProductDTOById(demoProductId)).thenCallRealMethod(); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_NOT_FOUND); + + // Invoke the method and verify the exception + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + dataSource.getProductDTOById(demoProductId); + }); + + // Verify the exception message + assertEquals("Nothing found: Amazon API responded with error code 404", exception.getMessage()); + } + + @Test + public void testGetProductDTOById_ioException() throws IOException { + // Set up the test environment + AmazonProductDataSource dataSource = mock(AmazonProductDataSource.class); + URL mockURL = mock(URL.class); + when(dataSource.createApiUrl(demoProductId)).thenReturn(mockURL); + when(dataSource.getProductDTOById(demoProductId)).thenCallRealMethod(); + when(dataSource.buildProductDTO(any(), anyString())).thenCallRealMethod(); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mockConnection.getInputStream()).thenThrow(new IOException()); + + // Invoke the method and verify the exception + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + dataSource.getProductDTOById(demoProductId); + }); + + // Verify the exception message + assertEquals("Couldn't fulfill Amazon API request", exception.getMessage()); + } } diff --git a/src/test/java/de/rwu/easydrop/util/ConfigTest.java b/src/test/java/de/rwu/easydrop/util/ConfigTest.java new file mode 100644 index 0000000..9aa2d09 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/util/ConfigTest.java @@ -0,0 +1,86 @@ +package de.rwu.easydrop.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.spy; + +import java.io.FileInputStream; +import java.util.NoSuchElementException; + +import javax.naming.ConfigurationException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +class ConfigTest { + @Mock + private FileInputStream mockFileInputStream; + + private Config config; + + @BeforeEach + void setUp() throws ConfigurationException { + MockitoAnnotations.openMocks(this); + config = spy(Config.getInstance()); + } + + @Test + void testGetProperty_ExistingKey() throws NoSuchElementException { + config.setProperty("API_KEY", "12345"); + + String value = config.getProperty("API_KEY"); + + assertEquals("12345", value); + } + + @Test + void testGetProperty_NonExistingKey() { + assertThrows(NoSuchElementException.class, () -> config.getProperty("NON_EXISTING_KEY")); + } + + @Test + void testSetProperty() { + config.setProperty("API_KEY", "12345"); + + assertEquals("12345", config.getProperty("API_KEY")); + } + + @Test + void testGetInstanceNull() { + config = null; + + try { + Config newConfig = Config.getInstance(); + // Check if the returned instance is not null + assertNotNull(newConfig); + } catch (ConfigurationException e) { + fail("ConfigurationException should not be thrown."); + } + } + + @Test + void testGetInstanceNotNull() { + try { + Config newConfig = Config.getInstance(); + // Check if the returned instance is not null + assertNotNull(newConfig); + } catch (ConfigurationException e) { + fail("ConfigurationException should not be thrown."); + } + } + + @Test + void testLoadConfigSuccessfully() { + try { + config.loadConfig(); + config.setProperty("WHATEVER", "SUCCESS"); + assertNotNull(config.getProperty("WHATEVER")); + } catch (ConfigurationException e) { + fail("ConfigurationException should not be thrown"); + } + } +} diff --git a/src/test/java/de/rwu/easydrop/util/FormattingUtilTest.java b/src/test/java/de/rwu/easydrop/util/FormattingUtilTest.java new file mode 100644 index 0000000..3fc600d --- /dev/null +++ b/src/test/java/de/rwu/easydrop/util/FormattingUtilTest.java @@ -0,0 +1,58 @@ +package de.rwu.easydrop.util; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class FormattingUtilTest { + + @Test + public void testConstructorIsPrivate() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + // Check for private constructor + Constructor constructor = FormattingUtil.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + + // Make sure exception is thrown when instantiating + constructor.setAccessible(true); + assertThrows(InvocationTargetException.class, () -> { + constructor.newInstance(); + }); + } + + @Test + public void testFormatEuro_positiveAmount() { + double amount = 1234.56; + String expectedFormattedAmount = "1.234,56 €"; + + String formattedAmount = FormattingUtil.formatEuro(amount); + + Assertions.assertEquals(expectedFormattedAmount, formattedAmount); + } + + @Test + public void testFormatEuro_zeroAmount() { + double amount = 0.0; + String expectedFormattedAmount = "0,00 €"; + + String formattedAmount = FormattingUtil.formatEuro(amount); + + Assertions.assertEquals(expectedFormattedAmount, formattedAmount); + } + + @Test + public void testFormatEuro_negativeAmount() { + double amount = -789.12; + String expectedFormattedAmount = "-789,12 €"; + + String formattedAmount = FormattingUtil.formatEuro(amount); + + Assertions.assertEquals(expectedFormattedAmount, formattedAmount); + } +}