diff --git a/.vscode/settings.json b/.vscode/settings.json index b72b3e1..d861443 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,6 @@ "connectionId": "LocalSonarQube", "projectKey": "EasyDrop" }, - "java.debug.settings.onBuildFailureProceed": true + "java.debug.settings.onBuildFailureProceed": true, + "java.checkstyle.configuration": "${workspaceFolder}\\config\\custom-checkstyle.xml" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5498b1c..a8f50bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,12 @@ ### Added -- Added script for local UML generation (#56) - -### Removed - -- Document stage from CI run (#56) +- Script for local UML generation (#56) +- Transaction fulfillment API classes (#71) + - `AmazonSeller` + - `AmazonPurchaser` + - `EbaySeller` + - `EbayPurchaser` ## 0.2.0 diff --git a/config/custom-checkstyle.xml b/config/custom-checkstyle.xml index 71d9e97..21428fc 100644 --- a/config/custom-checkstyle.xml +++ b/config/custom-checkstyle.xml @@ -44,6 +44,11 @@ https://www.oracle.com/java/technologies/javase/codeconventions-contents.html + + + + + diff --git a/config/suppressions.xml b/config/suppressions.xml new file mode 100644 index 0000000..4067d19 --- /dev/null +++ b/config/suppressions.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/de/rwu/easydrop/api/client/AbstractDataSource.java b/src/main/java/de/rwu/easydrop/api/client/AbstractDataSource.java index 7751c10..4b58d66 100644 --- a/src/main/java/de/rwu/easydrop/api/client/AbstractDataSource.java +++ b/src/main/java/de/rwu/easydrop/api/client/AbstractDataSource.java @@ -42,7 +42,7 @@ public abstract class AbstractDataSource implements DataSource { protected abstract ProductDTO buildProductDTO(ProductDTO product, String json); /** - * Overridable standard implementation. + * Pulls product data from a remote data source. */ @Override public ProductDTO getProductDTOById(final String productIdentifier) diff --git a/src/main/java/de/rwu/easydrop/api/client/AbstractDataWriter.java b/src/main/java/de/rwu/easydrop/api/client/AbstractDataWriter.java new file mode 100644 index 0000000..fd7a615 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/AbstractDataWriter.java @@ -0,0 +1,81 @@ +package de.rwu.easydrop.api.client; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import de.rwu.easydrop.api.dto.ProductDTO; +import de.rwu.easydrop.exception.DataWriterException; +import de.rwu.easydrop.util.FormattingUtil; + +/** + * Writes data to a remote API. + * + * @since 0.3.0 + */ +public abstract class AbstractDataWriter { + + /** + * Returns the data source's API key. + * + * @return Data source API key + */ + protected abstract String getApiKey(); + + /** + * Returns the target API's name. + * + * @return Data target API name + */ + protected abstract String getDataTarget(); + + /** + * Creates an URL object to connect to the API with. + * + * @param productIdentifier Product identifier + * @return URL object + * @throws MalformedURLException + */ + protected abstract URL createApiUrl(String productIdentifier) throws MalformedURLException; + + /** + * Sends a put request to the API. + * + * @param dto Product data transfer object + * @param apiType API Type, like Purchase or Sales + */ + protected void sendPutRequest(final ProductDTO dto, final String apiType) { + String apiKey = getApiKey(); + String dataTarget = getDataTarget(); + + if (!dataTarget.equals(dto.getDataOrigin())) { + throw new DataWriterException( + "Product data source and target " + apiType + " API are incompatible."); + } + + try { + String urlReadyIdentifier = FormattingUtil.urlEncode(dto.getProductId()); + URL apiUrl = createApiUrl(urlReadyIdentifier); + + HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection(); + connection.setRequestMethod("PUT"); + connection.setRequestProperty("Credential", apiKey); + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + throw new DataWriterException( + dataTarget + + " " + + apiType + + " API responded with error code " + + responseCode); + } + } catch (IOException e) { + throw new DataWriterException( + "Couldn't fulfill " + + dataTarget + + " API request"); + } + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/AbstractPurchaser.java b/src/main/java/de/rwu/easydrop/api/client/AbstractPurchaser.java new file mode 100644 index 0000000..67700a0 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/AbstractPurchaser.java @@ -0,0 +1,19 @@ +package de.rwu.easydrop.api.client; + +import de.rwu.easydrop.api.dto.ProductDTO; + +/** + * Abstract construct to provide access to a purchase API. + * + * @since 0.3.0 + */ +public abstract class AbstractPurchaser extends AbstractDataWriter { + /** + * Sends a buy request to the Amazon API. + * + * @param dto + */ + public void purchaseProduct(final ProductDTO dto) { + sendPutRequest(dto, "Purchase"); + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/AbstractSeller.java b/src/main/java/de/rwu/easydrop/api/client/AbstractSeller.java new file mode 100644 index 0000000..8d659d7 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/AbstractSeller.java @@ -0,0 +1,19 @@ +package de.rwu.easydrop.api.client; + +import de.rwu.easydrop.api.dto.ProductDTO; + +/** + * Abstract construct to provide access to a sales API. + * + * @since 0.3.0 + */ +public abstract class AbstractSeller extends AbstractDataWriter { + /** + * Sends a sell request to the Amazon API. + * + * @param dto + */ + public void sellProduct(final ProductDTO dto) { + sendPutRequest(dto, "Sales"); + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/AmazonPurchaser.java b/src/main/java/de/rwu/easydrop/api/client/AmazonPurchaser.java new file mode 100644 index 0000000..283ed61 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/AmazonPurchaser.java @@ -0,0 +1,67 @@ +package de.rwu.easydrop.api.client; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Sends a buy request to the Amazon API. + * + * @since 0.3.0 + */ +public final class AmazonPurchaser extends AbstractPurchaser { + /** + * Name of this data source. + */ + private static final String DATA_TARGET = "Amazon"; + /** + * Base URL to the Amazon Purchase API. + */ + private String baseUrl; + /** + * Access credential. + */ + private String apiKey; + /** + * Product region parameter required for data writes. + */ + private static final String PRODUCT_REGION = "DE"; + /** + * Locale parameter required for data writes. + */ + private static final String LOCALE = "de_DE"; + + /** + * Sets up instance with Base URL and API Key. + * + * @param newBaseUrl + * @param newApiKey + */ + public AmazonPurchaser(final String newBaseUrl, final String newApiKey) { + this.baseUrl = newBaseUrl; + this.apiKey = newApiKey; + } + + /** + * @param productId ASIN + */ + @Override + protected URL createApiUrl(final String productId) throws MalformedURLException { + return new URL(baseUrl + + "/products/2020-08-26/products/" + + productId + + "/buy?productRegion=" + + PRODUCT_REGION + + "&locale=" + + LOCALE); + } + + @Override + protected String getApiKey() { + return this.apiKey; + } + + @Override + protected String getDataTarget() { + return DATA_TARGET; + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/AmazonSeller.java b/src/main/java/de/rwu/easydrop/api/client/AmazonSeller.java new file mode 100644 index 0000000..8a47d51 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/AmazonSeller.java @@ -0,0 +1,67 @@ +package de.rwu.easydrop.api.client; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Sends a sell request to the Amazon API. + * + * @since 0.3.0 + */ +public final class AmazonSeller extends AbstractSeller { + /** + * Name of this data source. + */ + private static final String DATA_TARGET = "Amazon"; + /** + * Base URL to the Amazon Purchase API. + */ + private String baseUrl; + /** + * Access credential. + */ + private String apiKey; + /** + * Product region parameter required for data writes. + */ + private static final String PRODUCT_REGION = "DE"; + /** + * Locale parameter required for data writes. + */ + private static final String LOCALE = "de_DE"; + + /** + * Sets up instance with Base URL and API Key. + * + * @param newBaseUrl + * @param newApiKey + */ + public AmazonSeller(final String newBaseUrl, final String newApiKey) { + this.baseUrl = newBaseUrl; + this.apiKey = newApiKey; + } + + /** + * @param productId ASIN + */ + @Override + protected URL createApiUrl(final String productId) throws MalformedURLException { + return new URL(baseUrl + + "/products/2020-08-26/products/" + + productId + + "/sell?productRegion=" + + PRODUCT_REGION + + "&locale=" + + LOCALE); + } + + @Override + protected String getApiKey() { + return apiKey; + } + + @Override + protected String getDataTarget() { + return DATA_TARGET; + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/EbayPurchaser.java b/src/main/java/de/rwu/easydrop/api/client/EbayPurchaser.java new file mode 100644 index 0000000..d9f69f8 --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/EbayPurchaser.java @@ -0,0 +1,52 @@ +package de.rwu.easydrop.api.client; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Sends a buy request to the eBay API. + * + * @since 0.3.0 + */ +public final class EbayPurchaser extends AbstractPurchaser { + /** + * Name of this data source. + */ + private static final String DATA_TARGET = "eBay"; + /** + * Base URL to the eBay Purchase API. + */ + private String baseUrl; + /** + * Access credential. + */ + private String apiKey; + + /** + * Sets up instance with Base URL and API Key. + * + * @param newBaseUrl + * @param newApiKey + */ + public EbayPurchaser(final String newBaseUrl, final String newApiKey) { + this.baseUrl = newBaseUrl; + this.apiKey = newApiKey; + } + + @Override + protected URL createApiUrl(final String searchQuery) throws MalformedURLException { + return new URL(baseUrl + + "/buy/" + + searchQuery); + } + + @Override + protected String getApiKey() { + return apiKey; + } + + @Override + protected String getDataTarget() { + return DATA_TARGET; + } +} diff --git a/src/main/java/de/rwu/easydrop/api/client/EbaySeller.java b/src/main/java/de/rwu/easydrop/api/client/EbaySeller.java new file mode 100644 index 0000000..805ee5d --- /dev/null +++ b/src/main/java/de/rwu/easydrop/api/client/EbaySeller.java @@ -0,0 +1,52 @@ +package de.rwu.easydrop.api.client; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Sends a sell request to the eBay API. + * + * @since 0.3.0 + */ +public final class EbaySeller extends AbstractSeller { + /** + * Name of this data source. + */ + private static final String DATA_TARGET = "eBay"; + /** + * Base URL to the eBay Purchase API. + */ + private String baseUrl; + /** + * Access credential. + */ + private String apiKey; + + /** + * Sets up instance with Base URL and API Key. + * + * @param newBaseUrl + * @param newApiKey + */ + public EbaySeller(final String newBaseUrl, final String newApiKey) { + this.baseUrl = newBaseUrl; + this.apiKey = newApiKey; + } + + @Override + protected URL createApiUrl(final String searchQuery) throws MalformedURLException { + return new URL(baseUrl + + "/sell/" + + searchQuery); + } + + @Override + protected String getApiKey() { + return this.apiKey; + } + + @Override + protected String getDataTarget() { + return DATA_TARGET; + } +} diff --git a/src/main/java/de/rwu/easydrop/exception/DataWriterException.java b/src/main/java/de/rwu/easydrop/exception/DataWriterException.java new file mode 100644 index 0000000..6c1757e --- /dev/null +++ b/src/main/java/de/rwu/easydrop/exception/DataWriterException.java @@ -0,0 +1,27 @@ +package de.rwu.easydrop.exception; + +/** + * Exception that signifies a communication problem with a writer API. + * + * @since 0.3.0 + */ +public class DataWriterException extends RuntimeException { + /** + * Throws an exception that signifies the data of a Product are invalid. + * + * @param message + */ + public DataWriterException(final String message) { + super(message); + } + + /** + * Throws an exception that signifies the data of a Product are invalid. + * + * @param message + * @param cause + */ + public DataWriterException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/AbstractDataWriterTest.java b/src/test/java/de/rwu/easydrop/api/client/AbstractDataWriterTest.java new file mode 100644 index 0000000..edc8ad8 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/AbstractDataWriterTest.java @@ -0,0 +1,121 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +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.doCallRealMethod; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import de.rwu.easydrop.api.dto.ProductDTO; +import de.rwu.easydrop.exception.DataWriterException; + +class AbstractDataWriterTest { + private static String demoProductId = "whateverId"; + + @Mock + private HttpURLConnection mockConnection; + @Mock + private URL mockUrl; + + private AbstractDataWriter writer; + + @BeforeEach + void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + writer = new AbstractDataWriter() { + @Override + protected String getApiKey() { + return "testApiKey"; + } + + @Override + protected String getDataTarget() { + return "Test"; + } + + @Override + protected URL createApiUrl(String productIdentifier) throws MalformedURLException { + return mockUrl; + } + }; + } + + @Test + void sendPutRequest_wrongDataSource_throwsException() { + ProductDTO dto = new ProductDTO(demoProductId, "Amazon"); + + DataWriterException e = assertThrows(DataWriterException.class, () -> { + writer.sendPutRequest(dto, "testApiType"); + }); + + assertEquals("Product data source and target testApiType API are incompatible.", e.getMessage()); + } + + @Test + void sendPutRequest_badResponseCode_throwsException() throws IOException { + // Set up DTO + ProductDTO dto = new ProductDTO(demoProductId, "Test"); + + // Set up Mocks + AbstractDataWriter mockWriter = mock(AbstractDataWriter.class); + doCallRealMethod().when(mockWriter).sendPutRequest(any(), anyString()); + when(mockUrl.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); + + DataWriterException e = assertThrows(DataWriterException.class, () -> { + writer.sendPutRequest(dto, "Sales"); + }); + + assertEquals("Test Sales API responded with error code 400", e.getMessage()); + } + + @Test + void sendPutRequest_ioException_throwsException() throws IOException { + // Set up DTO + ProductDTO dto = new ProductDTO(demoProductId, "Test"); + + // Set up Mocks + AbstractDataWriter mockWriter = mock(AbstractDataWriter.class); + doCallRealMethod().when(mockWriter).sendPutRequest(any(), anyString()); + when(mockUrl.openConnection()).thenThrow(new IOException()); + + DataWriterException e = assertThrows(DataWriterException.class, () -> { + writer.sendPutRequest(dto, "testApiType"); + }); + + assertEquals("Couldn't fulfill Test API request", e.getMessage()); + } + + @Test + void sendPutRequest_successfulRequest() throws IOException { + // Set up DTO + ProductDTO dto = new ProductDTO(demoProductId, "test"); + + // Set up Mocks + AbstractDataWriter mockWriter = mock(AbstractDataWriter.class); + URL mockURL = mock(URL.class); + when(mockWriter.createApiUrl(demoProductId)).thenReturn(mockURL); + doCallRealMethod().when(mockWriter).sendPutRequest(any(), anyString()); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mockWriter.getDataTarget()).thenReturn("test"); + + assertDoesNotThrow(() -> { + mockWriter.sendPutRequest(dto, "Purchase"); + }); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/AbstractPurchaserTest.java b/src/test/java/de/rwu/easydrop/api/client/AbstractPurchaserTest.java new file mode 100644 index 0000000..f252264 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/AbstractPurchaserTest.java @@ -0,0 +1,38 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.Test; + +import de.rwu.easydrop.api.dto.ProductDTO; + +class AbstractPurchaserTest { + private AbstractPurchaser mockPurchaser = mock(AbstractPurchaser.class); + + @Test + void purchaseProduct_CorrectApiTypeInException() throws IOException { + // Set up DTO + ProductDTO dto = new ProductDTO("12345", "test"); + + // Set up mocks + URL mockURL = mock(URL.class); + when(mockPurchaser.createApiUrl("12345")).thenReturn(mockURL); + doCallRealMethod().when(mockPurchaser).purchaseProduct(any()); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mockPurchaser.getDataTarget()).thenReturn("test"); + + assertDoesNotThrow(() -> { + mockPurchaser.purchaseProduct(dto); + }); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/AbstractSellerTest.java b/src/test/java/de/rwu/easydrop/api/client/AbstractSellerTest.java new file mode 100644 index 0000000..eb7e595 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/AbstractSellerTest.java @@ -0,0 +1,38 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.Test; + +import de.rwu.easydrop.api.dto.ProductDTO; + +class AbstractSellerTest { + private AbstractSeller mockSeller = mock(AbstractSeller.class); + + @Test + void purchaseProduct_CorrectApiTypeInException() throws IOException { + // Set up DTO + ProductDTO dto = new ProductDTO("12345", "test"); + + // Set up mocks + URL mockURL = mock(URL.class); + when(mockSeller.createApiUrl("12345")).thenReturn(mockURL); + doCallRealMethod().when(mockSeller).sellProduct(any()); + HttpURLConnection mockConnection = mock(HttpURLConnection.class); + when(mockURL.openConnection()).thenReturn(mockConnection); + when(mockConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mockSeller.getDataTarget()).thenReturn("test"); + + assertDoesNotThrow(() -> { + mockSeller.sellProduct(dto); + }); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/AmazonPurchaserTest.java b/src/test/java/de/rwu/easydrop/api/client/AmazonPurchaserTest.java new file mode 100644 index 0000000..ec1e1d6 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/AmazonPurchaserTest.java @@ -0,0 +1,84 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; + +import de.rwu.easydrop.api.dto.ProductDTO; +import de.rwu.easydrop.exception.DataWriterException; + +class AmazonPurchaserTest { + private AmazonPurchaser demoPurchaser; + + private static String demoApiKey = "my-api-key"; + private static String demoApiUrl = "https://www.example.com/api"; + private static String demoDataTarget = "Amazon"; + + @BeforeEach + void setup() { + demoPurchaser = new AmazonPurchaser( + demoApiUrl, + demoApiKey); + MockitoAnnotations.openMocks(this); + } + + @Test + void testConstructor() { + // Assert + try { + Field baseUrlField = AmazonPurchaser.class.getDeclaredField("baseUrl"); + baseUrlField.setAccessible(true); + Assertions.assertEquals(demoApiUrl, baseUrlField.get(demoPurchaser)); + + Field apiKeyField = AmazonPurchaser.class.getDeclaredField("apiKey"); + apiKeyField.setAccessible(true); + Assertions.assertEquals(demoApiKey, apiKeyField.get(demoPurchaser)); + } catch (NoSuchFieldException e) { + Assertions.fail(); + } catch (IllegalAccessException e) { + Assertions.fail(); + } + } + + @Test + void testCreateApiUrl() throws MalformedURLException { + // Test case 1 + String productId1 = "12345"; + URL expectedUrl1 = new URL( + "https://www.example.com/api/products/2020-08-26/products/" + + productId1 + + "/buy?productRegion=DE&locale=de_DE"); + URL createdUrl1 = demoPurchaser.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/" + + productId2 + + "/buy?productRegion=DE&locale=de_DE"); + URL createdUrl2 = demoPurchaser.createApiUrl(productId2); + Assertions.assertEquals(expectedUrl2, createdUrl2); + } + + @Test + void getDataTarget_ReturnsExpectedDataOrigin() { + String dataTarget = demoPurchaser.getDataTarget(); + assertEquals(demoDataTarget, dataTarget); + } + + @Test + void getApiKey_ReturnsExpectedApiKey() { + String apiKey = demoPurchaser.getApiKey(); + assertEquals(demoApiKey, apiKey); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/AmazonSellerTest.java b/src/test/java/de/rwu/easydrop/api/client/AmazonSellerTest.java new file mode 100644 index 0000000..06176cc --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/AmazonSellerTest.java @@ -0,0 +1,80 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; + +class AmazonSellerTest { + private AmazonSeller demoSeller; + + private static String demoApiKey = "my-api-key"; + private static String demoApiUrl = "https://www.example.com/api"; + private static String demoDataTarget = "Amazon"; + + @BeforeEach + void setup() { + demoSeller = new AmazonSeller( + demoApiUrl, + demoApiKey); + MockitoAnnotations.openMocks(this); + } + + @Test + void testConstructor() { + // Assert + try { + Field baseUrlField = AmazonSeller.class.getDeclaredField("baseUrl"); + baseUrlField.setAccessible(true); + Assertions.assertEquals(demoApiUrl, baseUrlField.get(demoSeller)); + + Field apiKeyField = AmazonSeller.class.getDeclaredField("apiKey"); + apiKeyField.setAccessible(true); + Assertions.assertEquals(demoApiKey, apiKeyField.get(demoSeller)); + } catch (NoSuchFieldException e) { + Assertions.fail(); + } catch (IllegalAccessException e) { + Assertions.fail(); + } + } + + @Test + void testCreateApiUrl() throws MalformedURLException { + // Test case 1 + String productId1 = "12345"; + URL expectedUrl1 = new URL( + "https://www.example.com/api/products/2020-08-26/products/" + + productId1 + + "/sell?productRegion=DE&locale=de_DE"); + URL createdUrl1 = demoSeller.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/" + + productId2 + + "/sell?productRegion=DE&locale=de_DE"); + URL createdUrl2 = demoSeller.createApiUrl(productId2); + Assertions.assertEquals(expectedUrl2, createdUrl2); + } + + @Test + void getDataTarget_ReturnsExpectedDataOrigin() { + String dataTarget = demoSeller.getDataTarget(); + assertEquals(demoDataTarget, dataTarget); + } + + @Test + void getApiKey_ReturnsExpectedApiKey() { + String apiKey = demoSeller.getApiKey(); + assertEquals(demoApiKey, apiKey); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/EbayPurchaserTest.java b/src/test/java/de/rwu/easydrop/api/client/EbayPurchaserTest.java new file mode 100644 index 0000000..238e2c5 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/EbayPurchaserTest.java @@ -0,0 +1,77 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; + +class EbayPurchaserTest { + private EbayPurchaser demoPurchaser; + + private static String demoApiKey = "my-api-key"; + private static String demoApiUrl = "https://www.example.com/api"; + private static String demoDataTarget = "eBay"; + + @BeforeEach + void setup() { + demoPurchaser = new EbayPurchaser( + demoApiUrl, + demoApiKey); + MockitoAnnotations.openMocks(this); + } + + @Test + void testConstructor() { + // Assert + try { + Field baseUrlField = EbayPurchaser.class.getDeclaredField("baseUrl"); + baseUrlField.setAccessible(true); + Assertions.assertEquals(demoApiUrl, baseUrlField.get(demoPurchaser)); + + Field apiKeyField = EbayPurchaser.class.getDeclaredField("apiKey"); + apiKeyField.setAccessible(true); + Assertions.assertEquals(demoApiKey, apiKeyField.get(demoPurchaser)); + } catch (NoSuchFieldException e) { + Assertions.fail(); + } catch (IllegalAccessException e) { + Assertions.fail(); + } + } + + @Test + void testCreateApiUrl() throws MalformedURLException { + // Test case 1 + String productId1 = "12345"; + URL expectedUrl1 = new URL( + "https://www.example.com/api/buy/" + + productId1); + URL createdUrl1 = demoPurchaser.createApiUrl(productId1); + Assertions.assertEquals(expectedUrl1, createdUrl1); + + // Test case 2 + String productId2 = "67890"; + URL expectedUrl2 = new URL( + "https://www.example.com/api/buy/" + + productId2); + URL createdUrl2 = demoPurchaser.createApiUrl(productId2); + Assertions.assertEquals(expectedUrl2, createdUrl2); + } + + @Test + void getDataTarget_ReturnsExpectedDataOrigin() { + String dataTarget = demoPurchaser.getDataTarget(); + assertEquals(demoDataTarget, dataTarget); + } + + @Test + void getApiKey_ReturnsExpectedApiKey() { + String apiKey = demoPurchaser.getApiKey(); + assertEquals(demoApiKey, apiKey); + } +} diff --git a/src/test/java/de/rwu/easydrop/api/client/EbaySellerTest.java b/src/test/java/de/rwu/easydrop/api/client/EbaySellerTest.java new file mode 100644 index 0000000..978aa63 --- /dev/null +++ b/src/test/java/de/rwu/easydrop/api/client/EbaySellerTest.java @@ -0,0 +1,77 @@ +package de.rwu.easydrop.api.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; + +class EbaySellerTest { + private EbaySeller demoSeller; + + private static String demoApiKey = "my-api-key"; + private static String demoApiUrl = "https://www.example.com/api"; + private static String demoDataTarget = "eBay"; + + @BeforeEach + void setup() { + demoSeller = new EbaySeller( + demoApiUrl, + demoApiKey); + MockitoAnnotations.openMocks(this); + } + + @Test + void testConstructor() { + // Assert + try { + Field baseUrlField = EbaySeller.class.getDeclaredField("baseUrl"); + baseUrlField.setAccessible(true); + Assertions.assertEquals(demoApiUrl, baseUrlField.get(demoSeller)); + + Field apiKeyField = EbaySeller.class.getDeclaredField("apiKey"); + apiKeyField.setAccessible(true); + Assertions.assertEquals(demoApiKey, apiKeyField.get(demoSeller)); + } catch (NoSuchFieldException e) { + Assertions.fail(); + } catch (IllegalAccessException e) { + Assertions.fail(); + } + } + + @Test + void testCreateApiUrl() throws MalformedURLException { + // Test case 1 + String productId1 = "12345"; + URL expectedUrl1 = new URL( + "https://www.example.com/api/sell/" + + productId1); + URL createdUrl1 = demoSeller.createApiUrl(productId1); + Assertions.assertEquals(expectedUrl1, createdUrl1); + + // Test case 2 + String productId2 = "67890"; + URL expectedUrl2 = new URL( + "https://www.example.com/api/sell/" + + productId2); + URL createdUrl2 = demoSeller.createApiUrl(productId2); + Assertions.assertEquals(expectedUrl2, createdUrl2); + } + + @Test + void getDataTarget_ReturnsExpectedDataOrigin() { + String dataTarget = demoSeller.getDataTarget(); + assertEquals(demoDataTarget, dataTarget); + } + + @Test + void getApiKey_ReturnsExpectedApiKey() { + String apiKey = demoSeller.getApiKey(); + assertEquals(demoApiKey, apiKey); + } +} diff --git a/src/test/java/de/rwu/easydrop/exception/DataWriterExceptionTest.java b/src/test/java/de/rwu/easydrop/exception/DataWriterExceptionTest.java new file mode 100644 index 0000000..fd00b3e --- /dev/null +++ b/src/test/java/de/rwu/easydrop/exception/DataWriterExceptionTest.java @@ -0,0 +1,61 @@ +package de.rwu.easydrop.exception; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class DataWriterExceptionTest { + + @Test + void constructor_WithMessage_SetsMessage() { + // Arrange + String message = "Data source error"; + + // Act + DataWriterException exception = new DataWriterException(message); + + // Assert + assertEquals(message, exception.getMessage()); + } + + @Test + void constructor_WithMessageAndCause_SetsMessageAndCause() { + // Arrange + String message = "Data source error"; + Throwable cause = new IllegalArgumentException("Invalid argument"); + + // Act + DataWriterException exception = new DataWriterException(message, cause); + + // Assert + assertEquals(message, exception.getMessage()); + assertEquals(cause, exception.getCause()); + } + + @Test + void constructor_WithNullMessage_SetsNullMessage() { + // Act + DataWriterException exception = new DataWriterException(null); + + // Assert + assertEquals(null, exception.getMessage()); + } + + @Test + void constructor_WithNullCause_SetsNullCause() { + // Act + DataWriterException exception = new DataWriterException("Data source error", null); + + // Assert + assertEquals(null, exception.getCause()); + } + + @Test + void throw_DataWriterException() { + // Act and Assert + assertThrows(DataWriterException.class, () -> { + throw new DataWriterException("Data source error"); + }); + } +}