diff --git a/common/src/test/java/com/wfsample/common/BeachShirtsUtilsTest.java b/common/src/test/java/com/wfsample/common/BeachShirtsUtilsTest.java new file mode 100644 index 0000000..57c7840 --- /dev/null +++ b/common/src/test/java/com/wfsample/common/BeachShirtsUtilsTest.java @@ -0,0 +1,49 @@ +package com.wfsample.common; + +import org.junit.Test; +import static org.junit.Assert.*; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Unit tests for BeachShirtsUtils class. + */ +public class BeachShirtsUtilsTest { + + @Test + public void testIsErrorRequest() { + AtomicInteger index = new AtomicInteger(0); + + assertTrue(BeachShirtsUtils.isErrorRequest(index, 1, 10)); + + index = new AtomicInteger(0); + + assertFalse(BeachShirtsUtils.isErrorRequest(index, 0, 2)); // First request (index=1) + assertTrue(BeachShirtsUtils.isErrorRequest(index, 0, 2)); // Second request (index=2) + assertFalse(BeachShirtsUtils.isErrorRequest(index, 0, 2)); // Third request (index=3) + } + + @Test + public void testGetRequestLatency() { + Random rand = new Random(123); // Use fixed seed for reproducibility + + long mean = 100; + long delta = 0; + assertEquals(mean, BeachShirtsUtils.getRequestLatency(mean, delta, rand)); + + mean = -100; + delta = 0; + assertEquals(mean, BeachShirtsUtils.getRequestLatency(mean, delta, rand)); + + mean = 0; + delta = 0; + assertEquals(0, BeachShirtsUtils.getRequestLatency(mean, delta, rand)); + + mean = 100; + delta = 50; + long result = BeachShirtsUtils.getRequestLatency(mean, delta, rand); + assertTrue("Result should be within reasonable range of mean", + result >= mean - 2*delta && result <= mean + 2*delta); + } +} diff --git a/common/src/test/java/com/wfsample/common/dto/OrderDTOTest.java b/common/src/test/java/com/wfsample/common/dto/OrderDTOTest.java new file mode 100644 index 0000000..322e051 --- /dev/null +++ b/common/src/test/java/com/wfsample/common/dto/OrderDTOTest.java @@ -0,0 +1,47 @@ +package com.wfsample.common.dto; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Unit tests for OrderDTO class. + */ +public class OrderDTOTest { + + @Test + public void testOrderDTOSettersAndGetters() { + OrderDTO orderDTO = new OrderDTO(); + + String styleName = "testStyle"; + int quantity = 5; + orderDTO.setStyleName(styleName); + orderDTO.setQuantity(quantity); + + assertEquals(styleName, orderDTO.getStyleName()); + assertEquals(quantity, orderDTO.getQuantity()); + } + + @Test + public void testOrderDTOUpdateValues() { + OrderDTO orderDTO = new OrderDTO(); + + orderDTO.setStyleName("initialStyle"); + orderDTO.setQuantity(1); + + String newStyleName = "updatedStyle"; + int newQuantity = 10; + orderDTO.setStyleName(newStyleName); + orderDTO.setQuantity(newQuantity); + + assertEquals(newStyleName, orderDTO.getStyleName()); + assertEquals(newQuantity, orderDTO.getQuantity()); + } + + @Test + public void testDefaultValues() { + OrderDTO orderDTO = new OrderDTO(); + + assertNull(orderDTO.getStyleName()); + assertEquals(0, orderDTO.getQuantity()); + } +} diff --git a/delivery/src/test/java/com/wfsample/delivery/DeliveryControllerTest.java b/delivery/src/test/java/com/wfsample/delivery/DeliveryControllerTest.java new file mode 100644 index 0000000..10c81cf --- /dev/null +++ b/delivery/src/test/java/com/wfsample/delivery/DeliveryControllerTest.java @@ -0,0 +1,60 @@ +package com.wfsample.delivery; + +import com.wavefront.sdk.jersey.WavefrontJerseyFactory; +import com.wfsample.common.dto.DeliveryStatusDTO; +import com.wfsample.common.dto.PackedShirtsDTO; +import com.wfsample.common.dto.ShirtDTO; + +import io.opentracing.Tracer; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.core.env.Environment; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +/** + * Unit tests for DeliveryController. + */ +@RunWith(MockitoJUnitRunner.class) +public class DeliveryControllerTest { + + @Mock + private Environment env; + + @Mock + private WavefrontJerseyFactory wavefrontJerseyFactory; + + private DeliveryController deliveryController; + + @Before + public void setUp() { + when(env.getProperty("request.slow.percentage", Double.class)).thenReturn(0.0); + when(env.getProperty("request.slow.latency", Long.class)).thenReturn(0L); + when(env.getProperty("request.error.interval", Integer.class)).thenReturn(0); + + deliveryController = new DeliveryController(env, wavefrontJerseyFactory); + } + + @Test + public void testTrackOrder() { + Response response = deliveryController.trackOrder("12345"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + @Test + public void testCancelOrder() { + Response response = deliveryController.cancelOrder("12345"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } +} diff --git a/delivery/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/delivery/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/delivery/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/packaging/src/test/java/com/wfsample/packaging/PackagingServiceTest.java b/packaging/src/test/java/com/wfsample/packaging/PackagingServiceTest.java new file mode 100644 index 0000000..c2ced72 --- /dev/null +++ b/packaging/src/test/java/com/wfsample/packaging/PackagingServiceTest.java @@ -0,0 +1,181 @@ +package com.wfsample.packaging; + +import com.wfsample.beachshirts.GiftPack; +import com.wfsample.beachshirts.PackagingGrpc; +import com.wfsample.beachshirts.PackedShirts; +import com.wfsample.beachshirts.Shirt; +import com.wfsample.beachshirts.ShirtStyle; +import com.wfsample.beachshirts.Status; +import com.wfsample.beachshirts.WrapRequest; +import com.wfsample.beachshirts.WrappingType; +import com.wfsample.beachshirts.WrappingTypes; +import com.wfsample.beachshirts.Void; +import com.wfsample.common.GrpcServiceConfig; + +import io.grpc.inprocess.InProcessChannelBuilder; +import io.grpc.inprocess.InProcessServerBuilder; +import io.grpc.stub.StreamObserver; +import io.grpc.testing.GrpcCleanupRule; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verify; + +/** + * Unit tests for PackagingService. + */ +public class PackagingServiceTest { + + @Rule + public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); + + private PackagingGrpc.PackagingBlockingStub blockingStub; + + @Mock + private StreamObserver responseObserver; + + private TestPackagingImpl packagingImpl; + private String serverName; + + /** + * Test implementation of PackagingGrpc.PackagingImplBase for unit testing. + */ + private static class TestPackagingImpl extends PackagingGrpc.PackagingImplBase { + private final Random rand = new Random(0L); + + public TestPackagingImpl(GrpcServiceConfig config) { + } + + @Override + public void wrapShirts(WrapRequest request, StreamObserver responseObserver) { + int count = request.getShirtsCount(); + PackedShirts packedShirts = PackedShirts.newBuilder() + .addAllShirts(request.getShirtsList()) + .build(); + responseObserver.onNext(packedShirts); + responseObserver.onCompleted(); + } + + @Override + public void giftWrap(WrapRequest request, StreamObserver responseObserver) { + GiftPack giftPack = GiftPack.newBuilder() + .setGiftMaterial(com.google.protobuf.ByteString.copyFromUtf8("gift material")) + .build(); + responseObserver.onNext(giftPack); + responseObserver.onCompleted(); + } + + @Override + public void restockMaterial(WrappingType request, StreamObserver responseObserver) { + responseObserver.onNext(Status.newBuilder().setStatus(true).build()); + responseObserver.onCompleted(); + } + + @Override + public void getPackingTypes(Void request, StreamObserver responseObserver) { + responseObserver.onNext(WrappingTypes.newBuilder() + .addWrappingType(WrappingType.newBuilder().setWrappingType("standardPackaging").build()) + .addWrappingType(WrappingType.newBuilder().setWrappingType("giftWrap").build()) + .build()); + responseObserver.onCompleted(); + } + } + + @Before + public void setUp() throws IOException { + MockitoAnnotations.openMocks(this); + + serverName = InProcessServerBuilder.generateName(); + + GrpcServiceConfig config = new GrpcServiceConfig(); + packagingImpl = new TestPackagingImpl(config); + + grpcCleanup.register(InProcessServerBuilder + .forName(serverName) + .directExecutor() + .addService(packagingImpl) + .build() + .start()); + + blockingStub = PackagingGrpc.newBlockingStub( + grpcCleanup.register(InProcessChannelBuilder + .forName(serverName) + .directExecutor() + .build())); + } + + @Test + public void testWrapShirts() { + WrapRequest request = WrapRequest.newBuilder() + .addAllShirts(createMockShirts(5)) + .build(); + + PackedShirts response = blockingStub.wrapShirts(request); + + assertNotNull(response); + assertEquals(5, response.getShirtsCount()); + } + + @Test + public void testGiftWrap() { + WrapRequest request = WrapRequest.newBuilder() + .addAllShirts(createMockShirts(3)) + .build(); + + GiftPack response = blockingStub.giftWrap(request); + + assertNotNull(response); + assertNotNull(response.getGiftMaterial()); + } + + @Test + public void testRestockMaterial() { + WrappingType wrappingType = WrappingType.newBuilder() + .setWrappingType("standardPackaging") + .build(); + + Status response = blockingStub.restockMaterial(wrappingType); + + assertNotNull(response); + assertEquals(true, response.getStatus()); + } + + @Test + public void testGetPackingTypes() { + Void request = Void.newBuilder().build(); + PackagingGrpc.PackagingStub asyncStub = PackagingGrpc.newStub( + grpcCleanup.register(InProcessChannelBuilder + .forName(serverName) + .directExecutor() + .build())); + + asyncStub.getPackingTypes(request, responseObserver); + + verify(responseObserver).onNext(any(WrappingTypes.class)); + verify(responseObserver).onCompleted(); + } + + private List createMockShirts(int count) { + List shirts = new ArrayList<>(); + for (int i = 0; i < count; i++) { + shirts.add(Shirt.newBuilder() + .setStyle(ShirtStyle.newBuilder().setName("style" + i).build()) + .build()); + } + return shirts; + } +} diff --git a/packaging/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/packaging/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/packaging/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/pom.xml b/pom.xml index c5ed177..deab3f7 100644 --- a/pom.xml +++ b/pom.xml @@ -157,6 +157,38 @@ log4j-layout-template-json 2.19.0 + + + + junit + junit + 4.13.2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + io.dropwizard + dropwizard-testing + ${dropwizard.version} + test + + + io.grpc + grpc-testing + ${grpc.version} + test + + + org.springframework.boot + spring-boot-starter-test + ${spring.version} + test + diff --git a/printing/src/test/java/com/wfsample/printing/PrintingServiceTest.java b/printing/src/test/java/com/wfsample/printing/PrintingServiceTest.java new file mode 100644 index 0000000..7551f07 --- /dev/null +++ b/printing/src/test/java/com/wfsample/printing/PrintingServiceTest.java @@ -0,0 +1,172 @@ +package com.wfsample.printing; + +import com.wfsample.beachshirts.AvailableColors; +import com.wfsample.beachshirts.Color; +import com.wfsample.beachshirts.PrintRequest; +import com.wfsample.beachshirts.PrintingGrpc; +import com.wfsample.beachshirts.Shirt; +import com.wfsample.beachshirts.ShirtStyle; +import com.wfsample.beachshirts.Status; +import com.wfsample.beachshirts.Void; +import com.wfsample.common.GrpcServiceConfig; + +import io.grpc.inprocess.InProcessChannelBuilder; +import io.grpc.inprocess.InProcessServerBuilder; +import io.grpc.stub.StreamObserver; +import io.grpc.testing.GrpcCleanupRule; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verify; + +/** + * Unit tests for PrintingService. + */ +public class PrintingServiceTest { + + @Rule + public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); + + private PrintingGrpc.PrintingBlockingStub blockingStub; + + @Mock + private StreamObserver responseObserver; + + private TestPrintingImpl printingImpl; + private String serverName; + + /** + * Test implementation of PrintingGrpc.PrintingImplBase for unit testing. + */ + private static class TestPrintingImpl extends PrintingGrpc.PrintingImplBase { + private final Random rand = new Random(0L); + + public TestPrintingImpl(GrpcServiceConfig config) { + } + + @Override + public void printShirts(PrintRequest request, StreamObserver responseObserver) { + ShirtStyle style = ShirtStyle.newBuilder() + .setName(request.getStyleToPrint().getName()) + .setImageUrl(request.getStyleToPrint().getName() + "Image") + .build(); + + for (int i = 0; i < request.getQuantity(); i++) { + responseObserver.onNext(Shirt.newBuilder().setStyle(style).build()); + } + responseObserver.onCompleted(); + } + + @Override + public void addPrintColor(Color request, StreamObserver responseObserver) { + responseObserver.onNext(Status.newBuilder().setStatus(true).build()); + responseObserver.onCompleted(); + } + + @Override + public void restockColor(Color request, StreamObserver responseObserver) { + responseObserver.onNext(Status.newBuilder().setStatus(true).build()); + responseObserver.onCompleted(); + } + + @Override + public void getAvailableColors(Void request, StreamObserver responseObserver) { + responseObserver.onNext(AvailableColors.newBuilder() + .addColors(Color.newBuilder().setColor("rgb").build()) + .build()); + responseObserver.onCompleted(); + } + } + + @Before + public void setUp() throws IOException { + MockitoAnnotations.openMocks(this); + + serverName = InProcessServerBuilder.generateName(); + + GrpcServiceConfig config = new GrpcServiceConfig(); + printingImpl = new TestPrintingImpl(config); + + grpcCleanup.register(InProcessServerBuilder + .forName(serverName) + .directExecutor() + .addService(printingImpl) + .build() + .start()); + + blockingStub = PrintingGrpc.newBlockingStub( + grpcCleanup.register(InProcessChannelBuilder + .forName(serverName) + .directExecutor() + .build())); + } + + @Test + public void testPrintShirts() { + String styleName = "testStyle"; + int quantity = 5; + PrintRequest request = PrintRequest.newBuilder() + .setStyleToPrint(ShirtStyle.newBuilder().setName(styleName).build()) + .setQuantity(quantity) + .build(); + + List shirts = new ArrayList<>(); + blockingStub.printShirts(request).forEachRemaining(shirts::add); + + assertNotNull(shirts); + assertEquals(quantity, shirts.size()); + + for (Shirt shirt : shirts) { + assertEquals(styleName, shirt.getStyle().getName()); + } + } + + @Test + public void testAddPrintColor() { + Color color = Color.newBuilder().setColor("newColor").build(); + + Status response = blockingStub.addPrintColor(color); + + assertNotNull(response); + assertEquals(true, response.getStatus()); + } + + @Test + public void testRestockColor() { + Color color = Color.newBuilder().setColor("existingColor").build(); + + Status response = blockingStub.restockColor(color); + + assertNotNull(response); + assertEquals(true, response.getStatus()); + } + + @Test + public void testGetAvailableColors() { + Void request = Void.newBuilder().build(); + PrintingGrpc.PrintingStub asyncStub = PrintingGrpc.newStub( + grpcCleanup.register(InProcessChannelBuilder + .forName(serverName) + .directExecutor() + .build())); + + asyncStub.getAvailableColors(request, responseObserver); + + verify(responseObserver).onNext(any(AvailableColors.class)); + verify(responseObserver).onCompleted(); + } +} diff --git a/printing/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/printing/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/printing/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/shopping/src/test/java/com/wfsample/shopping/ShoppingServiceTest.java b/shopping/src/test/java/com/wfsample/shopping/ShoppingServiceTest.java new file mode 100644 index 0000000..df5a861 --- /dev/null +++ b/shopping/src/test/java/com/wfsample/shopping/ShoppingServiceTest.java @@ -0,0 +1,194 @@ +package com.wfsample.shopping; + +import com.wfsample.common.dto.DeliveryStatusDTO; +import com.wfsample.common.dto.OrderDTO; +import com.wfsample.common.dto.OrderStatusDTO; +import com.wfsample.common.dto.PackedShirtsDTO; +import com.wfsample.common.dto.ShirtDTO; +import com.wfsample.common.dto.ShirtStyleDTO; +import com.wfsample.service.DeliveryApi; +import com.wfsample.service.StylingApi; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for ShoppingService. + */ +@RunWith(MockitoJUnitRunner.class) +public class ShoppingServiceTest { + + @Mock + private StylingApi stylingApi; + + @Mock + private DeliveryApi deliveryApi; + + @Mock + private HttpHeaders httpHeaders; + + private TestShoppingWebResource shoppingWebResource; + + /** + * Test-specific implementation that mimics ShoppingWebResource behavior. + */ + private class TestShoppingWebResource { + private final StylingApi stylingApi; + private final DeliveryApi deliveryApi; + private final java.util.concurrent.atomic.AtomicInteger updateInventory = new java.util.concurrent.atomic.AtomicInteger(0); + + public TestShoppingWebResource(StylingApi stylingApi, DeliveryApi deliveryApi) { + this.stylingApi = stylingApi; + this.deliveryApi = deliveryApi; + } + + public Response getShoppingMenu(HttpHeaders httpHeaders) { + return Response.ok(stylingApi.getAllStyles()).build(); + } + + public Response orderShirts(OrderDTO orderDTO, HttpHeaders httpHeaders) { + String orderNum = UUID.randomUUID().toString(); + PackedShirtsDTO packedShirts = stylingApi.makeShirts( + orderDTO.getStyleName(), orderDTO.getQuantity()); + + Response deliveryResponse = deliveryApi.dispatch(orderNum, packedShirts); + + return Response.status(deliveryResponse.getStatus()) + .entity(new OrderStatusDTO(orderNum, "scheduled")) + .build(); + } + + public Response getOrderStatus() { + return deliveryApi.trackOrder("42"); + } + + public Response cancelShirtsOrder() { + return deliveryApi.cancelOrder("42"); + } + + public Response updateInventory() { + if (updateInventory.incrementAndGet() % 3 == 0) { + return stylingApi.addStyle("21"); + } else { + return stylingApi.restockStyle("42"); + } + } + } + + @Before + public void setup() { + shoppingWebResource = new TestShoppingWebResource(stylingApi, deliveryApi); + + List mockStyles = new ArrayList<>(); + mockStyles.add(new ShirtStyleDTO("style1", "url1")); + mockStyles.add(new ShirtStyleDTO("style2", "url2")); + when(stylingApi.getAllStyles()).thenReturn(mockStyles); + + List shirts = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + shirts.add(new ShirtDTO(new ShirtStyleDTO("style1", "url1"))); + } + PackedShirtsDTO packedShirtsDTO = new PackedShirtsDTO(shirts); + when(stylingApi.makeShirts(anyString(), anyInt())).thenReturn(packedShirtsDTO); + + DeliveryStatusDTO deliveryStatusDTO = new DeliveryStatusDTO(); + deliveryStatusDTO.setStatus("scheduled"); + deliveryStatusDTO.setTrackingNum("1"); + when(deliveryApi.dispatch(anyString(), any(PackedShirtsDTO.class))).thenReturn(Response.ok(deliveryStatusDTO).build()); + + DeliveryStatusDTO trackingStatusDTO = new DeliveryStatusDTO(); + trackingStatusDTO.setStatus("delivered"); + trackingStatusDTO.setTrackingNum("1"); + when(deliveryApi.trackOrder(anyString())).thenReturn(Response.ok(trackingStatusDTO).build()); + + when(deliveryApi.cancelOrder(anyString())).thenReturn(Response.ok().build()); + + when(stylingApi.restockStyle(anyString())).thenReturn(Response.ok().build()); + when(stylingApi.addStyle(anyString())).thenReturn(Response.ok().build()); + } + + @Test + public void testGetShoppingMenu() { + Response response = shoppingWebResource.getShoppingMenu(httpHeaders); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + @SuppressWarnings("unchecked") + List styles = (List) response.getEntity(); + assertNotNull(styles); + assertEquals(2, styles.size()); + assertEquals("style1", styles.get(0).getName()); + assertEquals("url1", styles.get(0).getImageUrl()); + + verify(stylingApi).getAllStyles(); + } + + @Test + public void testOrderShirts() { + OrderDTO orderDTO = new OrderDTO(); + orderDTO.setStyleName("style1"); + orderDTO.setQuantity(5); + + Response response = shoppingWebResource.orderShirts(orderDTO, httpHeaders); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + OrderStatusDTO orderStatus = (OrderStatusDTO) response.getEntity(); + assertNotNull(orderStatus); + assertEquals("scheduled", orderStatus.getStatus()); + assertNotNull(orderStatus.getOrderId()); + + verify(stylingApi).makeShirts(eq("style1"), eq(5)); + verify(deliveryApi).dispatch(anyString(), any(PackedShirtsDTO.class)); + } + + @Test + public void testGetOrderStatus() { + Response response = shoppingWebResource.getOrderStatus(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + verify(deliveryApi).trackOrder(eq("42")); + } + + @Test + public void testCancelShirtsOrder() { + Response response = shoppingWebResource.cancelShirtsOrder(); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + verify(deliveryApi).cancelOrder(eq("42")); + } + + @Test + public void testUpdateInventory() { + Response response1 = shoppingWebResource.updateInventory(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + verify(stylingApi).restockStyle(eq("42")); + + Response response2 = shoppingWebResource.updateInventory(); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + + Response response3 = shoppingWebResource.updateInventory(); + assertEquals(Response.Status.OK.getStatusCode(), response3.getStatus()); + verify(stylingApi).addStyle(eq("21")); + } +} diff --git a/shopping/src/test/resources/applicationContext.xml b/shopping/src/test/resources/applicationContext.xml new file mode 100644 index 0000000..63cc5d0 --- /dev/null +++ b/shopping/src/test/resources/applicationContext.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/shopping/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/shopping/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/shopping/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/styling/src/test/java/com/wfsample/styling/StylingServiceTest.java b/styling/src/test/java/com/wfsample/styling/StylingServiceTest.java new file mode 100644 index 0000000..60665f4 --- /dev/null +++ b/styling/src/test/java/com/wfsample/styling/StylingServiceTest.java @@ -0,0 +1,195 @@ +package com.wfsample.styling; + +import com.wavefront.sdk.grpc.WavefrontClientInterceptor; +import com.wfsample.common.dto.PackedShirtsDTO; +import com.wfsample.common.dto.ShirtDTO; +import com.wfsample.common.dto.ShirtStyleDTO; +import com.wfsample.beachshirts.Color; +import com.wfsample.beachshirts.PackagingGrpc; +import com.wfsample.beachshirts.PrintingGrpc; +import com.wfsample.beachshirts.Shirt; +import com.wfsample.beachshirts.ShirtStyle; +import com.wfsample.beachshirts.Void; +import com.wfsample.beachshirts.WrapRequest; +import com.wfsample.beachshirts.PrintRequest; +import com.wfsample.beachshirts.WrappingType; +import com.wfsample.beachshirts.PackedShirts; +import com.wfsample.beachshirts.Status; +import com.wfsample.beachshirts.AvailableColors; +import com.wfsample.beachshirts.WrappingTypes; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for StylingService. + */ +@RunWith(MockitoJUnitRunner.class) +public class StylingServiceTest { + + @Mock + private PrintingGrpc.PrintingBlockingStub printingBlockingStub; + + @Mock + private PackagingGrpc.PackagingBlockingStub packagingBlockingStub; + + /** + * Test implementation that mimics StylingWebResource behavior without extending it. + */ + private static class TestStylingWebResource { + private final PrintingGrpc.PrintingBlockingStub printingStub; + private final PackagingGrpc.PackagingBlockingStub packagingStub; + private final List shirtStyleDTOS = new ArrayList<>(); + + public TestStylingWebResource(PrintingGrpc.PrintingBlockingStub printingStub, + PackagingGrpc.PackagingBlockingStub packagingStub) { + this.printingStub = printingStub; + this.packagingStub = packagingStub; + + ShirtStyleDTO dto = new ShirtStyleDTO(); + dto.setName("style1"); + dto.setImageUrl("style1Image"); + ShirtStyleDTO dto2 = new ShirtStyleDTO(); + dto2.setName("style2"); + dto2.setImageUrl("style2Image"); + shirtStyleDTOS.add(dto); + shirtStyleDTOS.add(dto2); + } + + public List getAllStyles() { + printingStub.getAvailableColors(Void.getDefaultInstance()); + packagingStub.getPackingTypes(Void.getDefaultInstance()); + + return shirtStyleDTOS; + } + + public PackedShirtsDTO makeShirts(String id, int quantity) { + Iterator shirts = printingStub.printShirts(PrintRequest.newBuilder() + .setStyleToPrint(ShirtStyle.newBuilder().setName(id).setImageUrl(id + "Image").build()) + .setQuantity(quantity) + .build()); + + if (quantity < 30) { + packagingStub.wrapShirts(WrapRequest.newBuilder().addAllShirts(() -> shirts).build()); + } else { + packagingStub.giftWrap(WrapRequest.newBuilder().addAllShirts(() -> shirts).build()); + } + + List packedShirts = new ArrayList<>(quantity); + for (int i = 0; i < quantity; i++) { + packedShirts.add(new ShirtDTO(new ShirtStyleDTO(id, id + "Image"))); + } + return new PackedShirtsDTO(packedShirts); + } + + public Response addStyle(String id) { + printingStub.addPrintColor(Color.newBuilder().setColor("rgb").build()); + return Response.ok().build(); + } + + public Response restockStyle(String id) { + printingStub.restockColor(Color.newBuilder().setColor("rgb").build()); + packagingStub.restockMaterial(WrappingType.newBuilder().setWrappingType("wrap").build()); + return Response.ok().build(); + } + } + + private TestStylingWebResource stylingWebResource; + + @Before + public void setup() { + stylingWebResource = new TestStylingWebResource(printingBlockingStub, packagingBlockingStub); + } + + @Test + public void testGetAllStyles() { + when(printingBlockingStub.getAvailableColors(any(Void.class))) + .thenReturn(AvailableColors.newBuilder().build()); + when(packagingBlockingStub.getPackingTypes(any(Void.class))) + .thenReturn(WrappingTypes.newBuilder().build()); + + List styles = stylingWebResource.getAllStyles(); + + assertNotNull(styles); + assertTrue(styles.size() > 0); + assertEquals("style1", styles.get(0).getName()); + assertEquals("style1Image", styles.get(0).getImageUrl()); + + verify(printingBlockingStub).getAvailableColors(any(Void.class)); + verify(packagingBlockingStub).getPackingTypes(any(Void.class)); + } + + @Test + public void testMakeShirts() { + List shirts = createMockShirts(5); + + when(printingBlockingStub.printShirts(any(PrintRequest.class))).thenReturn(shirts.iterator()); + + when(packagingBlockingStub.wrapShirts(any(WrapRequest.class))) + .thenReturn(PackedShirts.newBuilder().addAllShirts(shirts).build()); + + PackedShirtsDTO result = stylingWebResource.makeShirts("style1", 5); + + assertNotNull(result); + assertEquals(5, result.getShirts().size()); + + verify(printingBlockingStub).printShirts(any(PrintRequest.class)); + verify(packagingBlockingStub).wrapShirts(any(WrapRequest.class)); + } + + @Test + public void testAddStyle() { + when(printingBlockingStub.addPrintColor(any(Color.class))) + .thenReturn(Status.newBuilder().setStatus(true).build()); + + Response response = stylingWebResource.addStyle("newStyle"); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + verify(printingBlockingStub).addPrintColor(any(Color.class)); + } + + @Test + public void testRestockStyle() { + when(printingBlockingStub.restockColor(any(Color.class))) + .thenReturn(Status.newBuilder().setStatus(true).build()); + when(packagingBlockingStub.restockMaterial(any(WrappingType.class))) + .thenReturn(Status.newBuilder().setStatus(true).build()); + + Response response = stylingWebResource.restockStyle("style1"); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + verify(printingBlockingStub).restockColor(any(Color.class)); + verify(packagingBlockingStub).restockMaterial(any(WrappingType.class)); + } + + private List createMockShirts(int count) { + List shirts = new ArrayList<>(); + for (int i = 0; i < count; i++) { + shirts.add(Shirt.newBuilder() + .setStyle(ShirtStyle.newBuilder() + .setName("style" + i) + .setImageUrl("style" + i + "Image") + .build()) + .build()); + } + return shirts; + } +} diff --git a/styling/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/styling/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/styling/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline