-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from NashTech-Labs/feature/Added-shipment_test…
…_cases Added test cases and ReadMe file for shipment service
- Loading branch information
Showing
9 changed files
with
502 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
## Shipment Service | ||
|
||
#### Application Overview | ||
This application is designed to manage the shipment process in a system using the Axon Framework for CQRS (Command Query Responsibility Segregation) and Event Sourcing. It includes components for handling the creation of shipments, persisting shipment details in a database, and publishing events to a Google Cloud Pub/Sub topic. | ||
|
||
## Workflow | ||
|
||
### Shipment Creation: | ||
* The process begins with a CreateShipmentCommand, which is handled by the ShipmentAggregate class. | ||
* The aggregate processes the command, applies the ShipmentCreatedEvent, and triggers the OrderShippedEvent. | ||
|
||
### Event Handling: | ||
* The ShipmentCreatedEvent is handled by the ShipmentEventHandler. | ||
* The event handler extracts user information and shipment details from the event. | ||
* It saves the shipment details to a database using the ShipmentRepository. | ||
* Additionally, it uses the PubSubPublisherService to publish the shipment details to a Google Cloud Pub/Sub topic. | ||
|
||
### Google Cloud Pub/Sub Integration: | ||
* The PubSubPublisherService initializes the Pub/Sub publisher during application startup (@PostConstruct). | ||
* The publisher is responsible for converting shipment data into a Pub/Sub message and publishing it to the configured topic. | ||
* During application shutdown (@PreDestroy), the publisher is gracefully shut down. | ||
|
||
### Data Storage: | ||
* Shipment details, including user information, are persisted to a database for future reference. | ||
* The ShipmentRepository handles the database interactions. | ||
|
||
## Key Components | ||
|
||
### ShipmentAggregate: | ||
|
||
Manages the state and behavior related to the creation of shipments. | ||
Applies events to update its internal state. | ||
|
||
### ShipmentEventHandler: | ||
Listens for the ShipmentCreatedEvent. | ||
Extracts shipment and user details from the event. | ||
Saves shipment details to a database using the ShipmentRepository. | ||
Publishes shipment details to Google Cloud Pub/Sub using the PubSubPublisherService. | ||
|
||
### PubSubPublisherService: | ||
Initializes a Google Cloud Pub/Sub publisher during application startup. | ||
Publishes shipment data to a Pub/Sub topic. | ||
Gracefully shuts down the publisher during application shutdown. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
209 changes: 209 additions & 0 deletions
209
shipment-service/src/test/java/com/nashtech/shipment/aggregate/ShipmentAggregateTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
package com.nashtech.shipment.aggregate; | ||
|
||
import com.nashtech.common.command.CreateShipmentCommand; | ||
import com.nashtech.common.event.OrderShippedEvent; | ||
import com.nashtech.common.event.ShipmentCreatedEvent; | ||
import com.nashtech.shipment.util.ObjectCreator; | ||
import com.nashtech.shipment.util.TestTag; | ||
import org.axonframework.test.aggregate.AggregateTestFixture; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
@Tag(TestTag.SMALL_TESTS) | ||
class ShipmentAggregateTest { | ||
private AggregateTestFixture<ShipmentAggregate> fixture; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
fixture = new AggregateTestFixture<>(ShipmentAggregate.class); | ||
} | ||
|
||
@Test | ||
void testShipmentAggregateCreation() { | ||
|
||
CreateShipmentCommand createShipmentCommand = ObjectCreator.getShipmentCommand(); | ||
|
||
ShipmentCreatedEvent shipmentCreatedEvent = ObjectCreator.getShipmentCreatedEvent(); | ||
|
||
OrderShippedEvent shippedEvent = ObjectCreator.getOrderShippedEvent(); | ||
|
||
fixture.givenNoPriorActivity() | ||
.when(createShipmentCommand) | ||
.expectEvents(shipmentCreatedEvent, shippedEvent); | ||
} | ||
|
||
|
||
@Test | ||
void test_shipment_created_event_handling_with_null_values() { | ||
ShipmentAggregate shipmentAggregate = new ShipmentAggregate(); | ||
ShipmentCreatedEvent shipmentCreatedEvent = ShipmentCreatedEvent.builder().build(); | ||
|
||
shipmentAggregate.on(shipmentCreatedEvent); | ||
|
||
assertNull(shipmentAggregate.getShipmentId()); | ||
assertNull(shipmentAggregate.getOrderId()); | ||
assertNull(shipmentAggregate.getPaymentId()); | ||
assertNull(shipmentAggregate.getProductId()); | ||
assertNull(shipmentAggregate.getBrand()); | ||
assertNull(shipmentAggregate.getQuantity()); | ||
assertNull(shipmentAggregate.getBasePrice()); | ||
assertNull(shipmentAggregate.getSubTotal()); | ||
assertNull(shipmentAggregate.getTotal()); | ||
assertNull(shipmentAggregate.getTax()); | ||
assertNull(shipmentAggregate.getTotalTax()); | ||
assertNull(shipmentAggregate.getUser()); | ||
} | ||
|
||
@Test | ||
void test_shipment_aggregate_state_update() { | ||
|
||
ShipmentCreatedEvent shipmentCreatedEvent = ShipmentCreatedEvent.builder() | ||
.shipmentId("shipmentId") | ||
.orderId("orderId") | ||
.paymentId("paymentId") | ||
.productId("productId") | ||
.quantity(10) | ||
.brand("brand") | ||
.basePrice(100.0) | ||
.tax(0.1f) | ||
.totalTax(10.0f) | ||
.subTotal(1000.0) | ||
.total(1100.0) | ||
.user(ObjectCreator.getUser()) | ||
.build(); | ||
ShipmentAggregate shipmentAggregate = new ShipmentAggregate(); | ||
shipmentAggregate.on(shipmentCreatedEvent); | ||
assertEquals(shipmentCreatedEvent.getShipmentId(), shipmentAggregate.getShipmentId()); | ||
assertEquals(shipmentCreatedEvent.getOrderId(), shipmentAggregate.getOrderId()); | ||
assertEquals(shipmentCreatedEvent.getPaymentId(), shipmentAggregate.getPaymentId()); | ||
assertEquals(shipmentCreatedEvent.getProductId(), shipmentAggregate.getProductId()); | ||
assertEquals(shipmentCreatedEvent.getQuantity(), shipmentAggregate.getQuantity()); | ||
assertEquals(shipmentCreatedEvent.getBrand(), shipmentAggregate.getBrand()); | ||
assertEquals(shipmentCreatedEvent.getBasePrice(), shipmentAggregate.getBasePrice()); | ||
assertEquals(shipmentCreatedEvent.getTax(), shipmentAggregate.getTax()); | ||
assertEquals(shipmentCreatedEvent.getTotalTax(), shipmentAggregate.getTotalTax()); | ||
assertEquals(shipmentCreatedEvent.getSubTotal(), shipmentAggregate.getSubTotal()); | ||
assertEquals(shipmentCreatedEvent.getTotal(), shipmentAggregate.getTotal()); | ||
assertEquals(shipmentCreatedEvent.getUser(), shipmentAggregate.getUser()); | ||
} | ||
|
||
@Test | ||
void testShipmentCreatedEventHandling() { | ||
|
||
ShipmentAggregate shipmentAggregate = new ShipmentAggregate(); | ||
ShipmentCreatedEvent shipmentCreatedEvent = ObjectCreator.getShipmentCreatedEvent(); | ||
shipmentAggregate.on(shipmentCreatedEvent); | ||
assertEquals(shipmentCreatedEvent.getShipmentId(), shipmentAggregate.getShipmentId()); | ||
assertEquals(shipmentCreatedEvent.getOrderId(), shipmentAggregate.getOrderId()); | ||
assertEquals(shipmentCreatedEvent.getPaymentId(), shipmentAggregate.getPaymentId()); | ||
assertEquals(shipmentCreatedEvent.getProductId(), shipmentAggregate.getProductId()); | ||
assertEquals(shipmentCreatedEvent.getBrand(), shipmentAggregate.getBrand()); | ||
assertEquals(shipmentCreatedEvent.getQuantity(), shipmentAggregate.getQuantity()); | ||
assertEquals(shipmentCreatedEvent.getBasePrice(), shipmentAggregate.getBasePrice()); | ||
assertEquals(shipmentCreatedEvent.getSubTotal(), shipmentAggregate.getSubTotal()); | ||
assertEquals(shipmentCreatedEvent.getTotal(), shipmentAggregate.getTotal()); | ||
assertEquals(shipmentCreatedEvent.getTax(), shipmentAggregate.getTax()); | ||
assertEquals(shipmentCreatedEvent.getTotalTax(), shipmentAggregate.getTotalTax()); | ||
assertEquals(shipmentCreatedEvent.getUser(), shipmentAggregate.getUser()); | ||
} | ||
|
||
@Test | ||
void test_negative_totalTax_throws_exception() { | ||
CreateShipmentCommand createShipmentCommand = CreateShipmentCommand.builder() | ||
.shipmentId("shipmentId") | ||
.orderId("orderId") | ||
.paymentId("paymentId") | ||
.productId("productId") | ||
.quantity(10) | ||
.brand("brand") | ||
.basePrice(100.0) | ||
.tax(0.1f) | ||
.totalTax(-10.0f) | ||
.subTotal(1000.0) | ||
.total(1100.0) | ||
.user(ObjectCreator.getUser()) | ||
.build(); | ||
|
||
assertThrows(IllegalStateException.class, () -> { | ||
new ShipmentAggregate(createShipmentCommand); | ||
}); | ||
} | ||
|
||
|
||
@Test | ||
void testShipmentCreatedEventHandlingWithNullValues() { | ||
|
||
ShipmentAggregate shipmentAggregate = new ShipmentAggregate(); | ||
ShipmentCreatedEvent shipmentCreatedEvent = ShipmentCreatedEvent.builder().build(); | ||
|
||
shipmentAggregate.on(shipmentCreatedEvent); | ||
|
||
assertNull(shipmentAggregate.getShipmentId()); | ||
assertNull(shipmentAggregate.getOrderId()); | ||
assertNull(shipmentAggregate.getPaymentId()); | ||
assertNull(shipmentAggregate.getProductId()); | ||
assertNull(shipmentAggregate.getBrand()); | ||
assertNull(shipmentAggregate.getQuantity()); | ||
assertNull(shipmentAggregate.getBasePrice()); | ||
assertNull(shipmentAggregate.getSubTotal()); | ||
assertNull(shipmentAggregate.getTotal()); | ||
assertNull(shipmentAggregate.getTax()); | ||
assertNull(shipmentAggregate.getTotalTax()); | ||
assertNull(shipmentAggregate.getUser()); | ||
} | ||
|
||
@Test | ||
void test_instantiation_success() { | ||
ShipmentAggregate shipmentAggregate = new ShipmentAggregate(); | ||
assertNotNull(shipmentAggregate); | ||
} | ||
|
||
|
||
@Test | ||
void testShipmentAggregateConstructorWithNullShipmentId() { | ||
CreateShipmentCommand createShipmentCommand = CreateShipmentCommand.builder() | ||
.shipmentId(null) | ||
.orderId("orderId") | ||
.paymentId("paymentId") | ||
.productId("productId") | ||
.quantity(10) | ||
.brand("brand") | ||
.basePrice(100.0) | ||
.tax(0.1f) | ||
.totalTax(10.0f) | ||
.subTotal(1000.0) | ||
.total(1100.0) | ||
.user(ObjectCreator.getUser()) | ||
.build(); | ||
|
||
assertThrows(IllegalStateException.class, () -> { | ||
new ShipmentAggregate(createShipmentCommand); | ||
}); | ||
} | ||
|
||
@Test | ||
void testShipmentAggregateConstructorWithInvalidTotalCalculation() { | ||
CreateShipmentCommand createShipmentCommand = CreateShipmentCommand.builder() | ||
.shipmentId("shipmentId") | ||
.orderId("orderId") | ||
.paymentId("paymentId") | ||
.productId("productId") | ||
.quantity(-1) // Invalid quantity | ||
.brand("brand") | ||
.basePrice(100.0) | ||
.tax(0.1f) | ||
.totalTax(10.0f) | ||
.subTotal(1000.0) | ||
.total(1100.0) | ||
.user(ObjectCreator.getUser()) | ||
.build(); | ||
|
||
assertThrows(IllegalStateException.class, () -> { | ||
new ShipmentAggregate(createShipmentCommand); | ||
}); | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
shipment-service/src/test/java/com/nashtech/shipment/handler/ShipmentEventHandlerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.nashtech.shipment.handler; | ||
|
||
import com.nashtech.common.event.ShipmentCreatedEvent; | ||
import com.nashtech.shipment.entity.ShipmentEntity; | ||
import com.nashtech.shipment.repository.ShipmentRepository; | ||
import com.nashtech.shipment.service.PubSubPublisherService; | ||
import com.nashtech.shipment.util.ObjectCreator; | ||
import com.nashtech.shipment.util.TestTag; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
|
||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.times; | ||
|
||
@Tag(TestTag.SMALL_TESTS) | ||
class ShipmentEventHandlerTest { | ||
|
||
@Test | ||
void testShipmentEventHandler() { | ||
|
||
ShipmentRepository mockShipmentRepository = Mockito.mock(ShipmentRepository.class); | ||
PubSubPublisherService mockPubSubPublisherService = Mockito.mock(PubSubPublisherService.class); | ||
|
||
ShipmentEventHandler shipmentEventHandler = new ShipmentEventHandler(mockShipmentRepository, mockPubSubPublisherService); | ||
|
||
ShipmentCreatedEvent shipmentCreatedEvent = ObjectCreator.getShipmentCreatedEvent(); | ||
|
||
|
||
shipmentEventHandler.on(shipmentCreatedEvent); | ||
|
||
|
||
Mockito.verify(mockShipmentRepository, times(1)).save(any(ShipmentEntity.class)); | ||
Mockito.verify(mockPubSubPublisherService, times(1)).messagePublisher(any(ShipmentEntity.class)); | ||
} | ||
|
||
} |
Oops, something went wrong.