Skip to content
20 changes: 14 additions & 6 deletions src/main/java/edu/iis/mto/time/Order.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package edu.iis.mto.time;

import java.time.Clock;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Order {

private static final long VALID_PERIOD_HOURS = 24;
private State orderState;
private List<OrderItem> items = new ArrayList<>();
private LocalDateTime subbmitionDate;
private LocalDateTime submissionDate;
private Clock clock;

public Order() {
public Order(Clock clock) {
orderState = State.CREATED;
this.clock = clock;
}

public Order() {
this(Clock.systemDefaultZone());
}

public void addItem(OrderItem item) {
Expand All @@ -28,14 +36,14 @@ public void submit() {
requireState(State.CREATED);

orderState = State.SUBMITTED;
subbmitionDate = LocalDateTime.now();
submissionDate = LocalDateTime.now(clock);

}

public void confirm() {
requireState(State.SUBMITTED);
long hoursElapsedAfterSubmittion = subbmitionDate.until(LocalDateTime.now(), ChronoUnit.HOURS);
if (hoursElapsedAfterSubmittion > VALID_PERIOD_HOURS) {
long hoursElapsedAfterSubmission = submissionDate.until(LocalDateTime.now(clock), ChronoUnit.HOURS);
if (hoursElapsedAfterSubmission > VALID_PERIOD_HOURS) {
orderState = State.CANCELLED;
throw new OrderExpiredException();
}
Expand All @@ -59,7 +67,7 @@ private void requireState(State... allowedStates) {
}

throw new OrderStateException("order should be in state "
+ allowedStates
+ Arrays.toString(allowedStates)
+ " to perform required operation, but is in "
+ orderState);

Expand Down
178 changes: 174 additions & 4 deletions src/test/java/edu/iis/mto/time/OrderTest.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,189 @@
package edu.iis.mto.time;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.time.*;


class OrderTest {

@Mock
Clock clock;

@BeforeEach
void setUp() throws Exception {}
void setUp(){
clock = Mockito.mock(Clock.class);
}

@Test
void noOffsetEmptyOrderItemStateTest() {
Order order = new Order();
assertEquals(order.getOrderState(), Order.State.CREATED);
}

@Test
void noOffsetOneItemOrderItemStateTest() {
Order order = new Order();
order.addItem(new OrderItem());
assertEquals(order.getOrderState(), Order.State.CREATED);
}

@Test
void noOffsetFiveItemsOrderItemStateTest() {
Order order = new Order();
for(int i = 0; i < 5; i++){
order.addItem(new OrderItem());
}
assertEquals(order.getOrderState(), Order.State.CREATED);
}

@Test
void noOffsetFiveItemsOrderItemSubmittedStateTest() {
Order order = new Order();
for(int i = 0; i < 5; i++){
order.addItem(new OrderItem());
}
order.submit();
assertEquals(order.getOrderState(), Order.State.SUBMITTED);
}

@Test
void noOffsetFiveItemsOrderItemConfirmedStateTest() {
Order order = new Order();
for (int i = 0; i < 5; i++) {
order.addItem(new OrderItem());
}
order.submit();
order.confirm();
assertEquals(order.getOrderState(), Order.State.CONFIRMED);
}

@Test
void noOffsetFiveItemsOrderItemRealizedStateTest() {
Order order = new Order();
for (int i = 0; i < 5; i++) {
order.addItem(new OrderItem());
}
order.submit();
order.confirm();
order.realize();
assertEquals(order.getOrderState(), Order.State.REALIZED);
}

@Test
void aFewOursItemsOrderItemRealizedStateTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withHour(5).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withHour(7).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
for (int i = 0; i < 5; i++) {
order.addItem(new OrderItem());
}
order.submit();
order.confirm();
order.realize();
assertEquals(order.getOrderState(), Order.State.REALIZED);
}

@Test
void oneYearEmptyOrderItemStateTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withYear(1999).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withYear(2000).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
order.submit();
assertThrows(OrderExpiredException.class, order::confirm);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
}

@Test
void aFewMonthsEmptyOrderItemStateTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(100).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(200).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
order.submit();
assertThrows(OrderExpiredException.class, order::confirm);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
}

@Test
void oneWeekEmptyOrderItemStateTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(7).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(14).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
order.submit();
assertThrows(OrderExpiredException.class, order::confirm);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
}

@Test
void oneDayAndABitMoreEmptyOrderItemStateTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(7).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(8).withHour(1).withSecond(1).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
order.submit();
assertThrows(OrderExpiredException.class, order::confirm);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
}

@Test
void oneDayAndABitMoreFiveItemsOrderItemStatesTest() {
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(7).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(8).withHour(1).withSecond(1).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
for(int i = 0 ; i < 5; i++){
order.addItem(new OrderItem());
}
order.submit();
assertThrows(OrderExpiredException.class, order::confirm);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
assertThrows(OrderStateException.class, order::realize);
assertEquals(order.getOrderState(), Order.State.CANCELLED);
}

@Test
void test() {
fail("Not yet implemented");
void oneDayEmptyOrderItemStateTest() { //one day passed... and, still alright?
Instant instant1 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(7).toInstant();
Instant instant2 = (Instant.EPOCH).atZone(ZoneOffset.UTC).withDayOfYear(8).toInstant();
Mockito.when(clock.instant())
.thenReturn(instant1)
.thenReturn(instant2);
Mockito.when(clock.getZone())
.thenReturn(ZoneOffset.UTC);
Order order = new Order(clock);
order.submit();
assertEquals(order.getOrderState(), Order.State.SUBMITTED);
}

}