// Path: src/main/java/com/apresa/restflow/fsm/Event.java
// public class Event {
// 
// 	private String name;
// 	private Map<String, Object> params = new HashMap<>();
// 
// 	public Event(Object name) {
// 		this.name = name.toString();
// 	}
// 
// 	public static Event build(Object name) {
// 		return new Event(name);
// 	}
// 
// 	public Event param(String name, Object value) {
// 		this.params.put(name, value);
// 		return this;
// 	}
// 
// 	@SuppressWarnings("unchecked")
// 	public <T> T getParameter(String name) {
// 		return (T) params.get(name);
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferEvents.java
// public class TransferEvents {
// 	public static final String FILL = "FILL";
// 	public static final String PROCEED = "PROCEED";
// 	public static final String SIGN = "SIGN";
// 	public static final String EXECUTE = "EXECUTE";
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferFlow.java
// @Flow(TransferStatus.class)
// @Transitions({
// 	@Transition(event=TransferEvents.FILL, from=TransferStatusConst.INITIAL, to=TransferStatusConst.INITIAL),
// 	@Transition(event=TransferEvents.PROCEED, from=TransferStatusConst.INITIAL, to=TransferStatusConst.PENDING_SIGNATURE),
// 	@Transition(event=TransferEvents.SIGN, from=TransferStatusConst.PENDING_SIGNATURE, to=TransferStatusConst.PENDING_OTP),
// 	@Transition(event=TransferEvents.EXECUTE, from=TransferStatusConst.PENDING_OTP, to=TransferStatusConst.EXECUTED)
// })
// public class TransferFlow extends AbstractBeanFlow<Transfer>{
// 
// 	@Guard(TransferEvents.SIGN)
// 	private boolean checkValidSignature(Transfer transfer, @EventParam("signature") String signature) {
// 		return Utils.checkValidSignature(transfer, signature);
// 	}
// 
// 	@Guard(TransferEvents.EXECUTE)
// 	private boolean checkValidOTP(Transfer transfer, @EventParam("otp") String otp) {
// 		return Utils.hashOTP(otp).equals(transfer.otpHash);
// 	}
// 
// 	@OnState(TransferStatusConst.PENDING_OTP)
// 	private void generateOTP(Transfer transfer) {
// 		Utils.addOTP(transfer);
// 	}
// 
// 	@On(TransferEvents.FILL)
// 	private void fillData(Transfer transfer, @EventParam("amount") Float amount, @EventParam("src") String src, @EventParam("target") String target) {
// 		transfer.amount = amount != null ? amount : transfer.amount;
// 		transfer.src = src != null ? src : transfer.src;
// 		transfer.target = target != null ? target : transfer.target;
// 	}
// 
// 	@Guards({
// 		@Guard(TransferEvents.PROCEED),
// 		@Guard(TransferEvents.SIGN),
// 		@Guard(TransferEvents.EXECUTE)
// 	})
// 
// 	private boolean validateData(Transfer transfer) {
// 		return Utils.checkValidData(transfer);
// 	}
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferStatus.java
// public enum TransferStatus {
// 	INITIAL,
// 	PENDING_SIGNATURE,
// 	PENDING_OTP,
// 	EXECUTED,
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/model/Transfer.java
// public class Transfer {
// 	@StateReference
// 	public TransferStatus status = TransferStatus.INITIAL;
// 
// 	public Float amount;
// 	public String src;
// 	public String target;
// 	public String otpHash;
// }


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.apresa.restflow.fsm.Event;
import com.apresa.restflow.samples.transfers.flow.TransferEvents;
import com.apresa.restflow.samples.transfers.flow.TransferFlow;
import com.apresa.restflow.samples.transfers.flow.TransferStatus;
import com.apresa.restflow.samples.transfers.model.Transfer;
	@Test
	public void itShouldReturnFalseIfTransitionIsUnknown() throws Exception {
		Transfer t = initTransfer();
		assertFalse(flow.raise(Event.build("NON_EXISTING"), t));
	}

	@Test
	public void itShouldReturnFalseIfGuardsAreNotOk() throws Exception {
		Transfer t = initTransfer();

		fillTransfer(t);

		assertTrue(
			flow.raise(
				Event.build(TransferEvents.FILL)
					.param("amount", -1.0f)
			, t)
		);

		assertEquals(t.target, "DST_ACCOUNT");
		assertFalse(flow.raise(new Event(TransferEvents.PROCEED), t));
	}

	@Test
	public void itShouldReturnFalseIfTransitionIsNotPossibleInTheState() throws Exception {
		Transfer t = initTransfer();

		fillTransfer(t);
		proceedTransfer(t);

// Path: src/main/java/com/apresa/restflow/fsm/Event.java
// public class Event {
// 
// 	private String name;
// 	private Map<String, Object> params = new HashMap<>();
// 
// 	public Event(Object name) {
// 		this.name = name.toString();
// 	}
// 
// 	public static Event build(Object name) {
// 		return new Event(name);
// 	}
// 
// 	public Event param(String name, Object value) {
// 		this.params.put(name, value);
// 		return this;
// 	}
// 
// 	@SuppressWarnings("unchecked")
// 	public <T> T getParameter(String name) {
// 		return (T) params.get(name);
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferEvents.java
// public class TransferEvents {
// 	public static final String FILL = "FILL";
// 	public static final String PROCEED = "PROCEED";
// 	public static final String SIGN = "SIGN";
// 	public static final String EXECUTE = "EXECUTE";
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferFlow.java
// @Flow(TransferStatus.class)
// @Transitions({
// 	@Transition(event=TransferEvents.FILL, from=TransferStatusConst.INITIAL, to=TransferStatusConst.INITIAL),
// 	@Transition(event=TransferEvents.PROCEED, from=TransferStatusConst.INITIAL, to=TransferStatusConst.PENDING_SIGNATURE),
// 	@Transition(event=TransferEvents.SIGN, from=TransferStatusConst.PENDING_SIGNATURE, to=TransferStatusConst.PENDING_OTP),
// 	@Transition(event=TransferEvents.EXECUTE, from=TransferStatusConst.PENDING_OTP, to=TransferStatusConst.EXECUTED)
// })
// public class TransferFlow extends AbstractBeanFlow<Transfer>{
// 
// 	@Guard(TransferEvents.SIGN)
// 	private boolean checkValidSignature(Transfer transfer, @EventParam("signature") String signature) {
// 		return Utils.checkValidSignature(transfer, signature);
// 	}
// 
// 	@Guard(TransferEvents.EXECUTE)
// 	private boolean checkValidOTP(Transfer transfer, @EventParam("otp") String otp) {
// 		return Utils.hashOTP(otp).equals(transfer.otpHash);
// 	}
// 
// 	@OnState(TransferStatusConst.PENDING_OTP)
// 	private void generateOTP(Transfer transfer) {
// 		Utils.addOTP(transfer);
// 	}
// 
// 	@On(TransferEvents.FILL)
// 	private void fillData(Transfer transfer, @EventParam("amount") Float amount, @EventParam("src") String src, @EventParam("target") String target) {
// 		transfer.amount = amount != null ? amount : transfer.amount;
// 		transfer.src = src != null ? src : transfer.src;
// 		transfer.target = target != null ? target : transfer.target;
// 	}
// 
// 	@Guards({
// 		@Guard(TransferEvents.PROCEED),
// 		@Guard(TransferEvents.SIGN),
// 		@Guard(TransferEvents.EXECUTE)
// 	})
// 
// 	private boolean validateData(Transfer transfer) {
// 		return Utils.checkValidData(transfer);
// 	}
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferStatus.java
// public enum TransferStatus {
// 	INITIAL,
// 	PENDING_SIGNATURE,
// 	PENDING_OTP,
// 	EXECUTED,
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/model/Transfer.java
// public class Transfer {
// 	@StateReference
// 	public TransferStatus status = TransferStatus.INITIAL;
// 
// 	public Float amount;
// 	public String src;
// 	public String target;
// 	public String otpHash;
// }


// Path: src/test/java/com/apresa/restflow/samples/transfers/TransferFlowTests.java
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.apresa.restflow.fsm.Event;
import com.apresa.restflow.samples.transfers.flow.TransferEvents;
import com.apresa.restflow.samples.transfers.flow.TransferFlow;
import com.apresa.restflow.samples.transfers.flow.TransferStatus;
import com.apresa.restflow.samples.transfers.model.Transfer;

	@Test
	public void itShouldReturnFalseIfTransitionIsUnknown() throws Exception {
		Transfer t = initTransfer();
		assertFalse(flow.raise(Event.build("NON_EXISTING"), t));
	}

	@Test
	public void itShouldReturnFalseIfGuardsAreNotOk() throws Exception {
		Transfer t = initTransfer();

		fillTransfer(t);

		assertTrue(
			flow.raise(
				Event.build(TransferEvents.FILL)
					.param("amount", -1.0f)
			, t)
		);

		assertEquals(t.target, "DST_ACCOUNT");
		assertFalse(flow.raise(new Event(TransferEvents.PROCEED), t));
	}

	@Test
	public void itShouldReturnFalseIfTransitionIsNotPossibleInTheState() throws Exception {
		Transfer t = initTransfer();

		fillTransfer(t);
		proceedTransfer(t);

		assertFalse(flow.raise(Event.build(TransferEvents.FILL), t));