package org.knowm.xchange.btcmarkets.service; import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.fail; import static org.powermock.api.mockito.PowerMockito.mock; import java.io.IOException; import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.knowm.xchange.ExchangeFactory; import org.knowm.xchange.btcmarkets.BTCMarketsAuthenticated; import org.knowm.xchange.btcmarkets.BTCMarketsExchange; import org.knowm.xchange.btcmarkets.BtcMarketsAssert; import org.knowm.xchange.btcmarkets.dto.BTCMarketsException; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsCancelOrderRequest; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsCancelOrderResponse; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsMyTradingRequest; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsOrder; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsOrders; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsPlaceOrderResponse; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsTradeHistory; import org.knowm.xchange.btcmarkets.dto.trade.BTCMarketsUserTrade; import org.knowm.xchange.currency.CurrencyPair; import org.knowm.xchange.dto.Order; import org.knowm.xchange.dto.trade.LimitOrder; import org.knowm.xchange.dto.trade.MarketOrder; import org.knowm.xchange.dto.trade.OpenOrders; import org.knowm.xchange.dto.trade.UserTrade; import org.knowm.xchange.dto.trade.UserTrades; import org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamCurrencyPair; import org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamPaging; import org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamsTimeSpan; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import si.mazi.rescu.SynchronizedValueFactory; @RunWith(PowerMockRunner.class) @PrepareForTest({ BTCMarketsAuthenticated.class, BTCMarketsMyTradingRequest.class, BTCMarketsCancelOrderRequest.class, BTCMarketsOrder.class }) @PowerMockIgnore("javax.crypto.*") public class BTCMarketsTradeServiceTest extends BTCMarketsTestSupport { private BTCMarketsExchange exchange; private BTCMarketsTradeService marketsTradeService; @Before public void setUp() { exchange = (BTCMarketsExchange) ExchangeFactory.INSTANCE.createExchange(BTCMarketsExchange.class.getCanonicalName()); exchange.getExchangeSpecification().getExchangeSpecificParameters().put(BTCMarketsExchange.CURRENCY_PAIR, CurrencyPair.BTC_AUD); exchange.getExchangeSpecification().setUserName(SPECIFICATION_USERNAME); exchange.getExchangeSpecification().setApiKey(SPECIFICATION_API_KEY); exchange.getExchangeSpecification().setSecretKey(SPECIFICATION_SECRET_KEY); marketsTradeService = new BTCMarketsTradeService(exchange); } @Test public void shouldConstructObject() { assertThat(Whitebox.getInternalState(marketsTradeService, "currencyPair")).isEqualTo(CurrencyPair.BTC_AUD); } @Test(expected = IllegalArgumentException.class) public void shouldFailToConstructObjectOnCorruptedContext() { // given exchange.getExchangeSpecification().getExchangeSpecificParameters().put(BTCMarketsExchange.CURRENCY_PAIR, "BTC/AUD"); // when marketsTradeService = new BTCMarketsTradeService(exchange); // then fail("BTCMarketsTradeService should throw IllegalArgumentException when exchange context contains CurrencyPair parameter of wrong type"); } @Test public void shouldPlaceMarketOrder() throws IOException { // given MarketOrder marketOrder = new MarketOrder(Order.OrderType.BID, new BigDecimal("10.00000000"), CurrencyPair.BTC_AUD); BTCMarketsOrder btcMarketsOrder = new BTCMarketsOrder(new BigDecimal("10.00000000"), BigDecimal.ZERO, "AUD", "BTC", BTCMarketsOrder.Side.Bid, BTCMarketsOrder.Type.Market, "generatedReqId"); BTCMarketsPlaceOrderResponse orderResponse = new BTCMarketsPlaceOrderResponse(true, null, 0, "11111", 12345); BTCMarketsAuthenticated btcm = mock(BTCMarketsAuthenticated.class); PowerMockito.when(btcm.placeOrder(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(btcMarketsOrder, "clientRequestId"))).thenReturn(orderResponse); Whitebox.setInternalState(marketsTradeService, "btcm", btcm); // when String placed = marketsTradeService.placeMarketOrder(marketOrder); // then assertThat(placed).isEqualTo("12345"); } @Test public void shouldPlaceLimitOrder() throws IOException { // given LimitOrder limitOrder = new LimitOrder(Order.OrderType.ASK, new BigDecimal("10.00000000"), CurrencyPair.BTC_AUD, "11111", new Date(1234567890L), new BigDecimal("20.00000000")); BTCMarketsOrder btcMarketsOrder = new BTCMarketsOrder(new BigDecimal("10.00000000"), new BigDecimal("20.00000000"), "AUD", "BTC", BTCMarketsOrder.Side.Ask, BTCMarketsOrder.Type.Limit, "generatedReqId"); BTCMarketsPlaceOrderResponse orderResponse = new BTCMarketsPlaceOrderResponse(true, null, 0, "11111", 12345); BTCMarketsAuthenticated btcm = mock(BTCMarketsAuthenticated.class); PowerMockito.when(btcm.placeOrder(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(btcMarketsOrder, "clientRequestId"))).thenReturn(orderResponse); Whitebox.setInternalState(marketsTradeService, "btcm", btcm); // when String placed = marketsTradeService.placeLimitOrder(limitOrder); // then assertThat(placed).isEqualTo("12345"); } @Test public void shouldCancelOrder() throws IOException { // given BTCMarketsCancelOrderRequest cancelOrderRequest = new BTCMarketsCancelOrderRequest(111L); BTCMarketsCancelOrderResponse orderResponse = new BTCMarketsCancelOrderResponse(true, null, 0, Arrays.asList(new BTCMarketsException(true, null, 0, "12345", 111L, null))); BTCMarketsAuthenticated btcm = mock(BTCMarketsAuthenticated.class); PowerMockito.when(btcm.cancelOrder(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(cancelOrderRequest))).thenReturn(orderResponse); Whitebox.setInternalState(marketsTradeService, "btcm", btcm); // when boolean cancelled = marketsTradeService.cancelOrder("111"); // then assertThat(cancelled).isTrue(); } @Test public void shouldGetTradeHistory() throws Exception { // given final List<BTCMarketsUserTrade> expectedBtcMarketsUserTrades = expectedBtcMarketsUserTrades(); final UserTrade[] expectedUserTrades = expectedUserTrades(); BTCMarketsMyTradingRequest defaultRequest = new BTCMarketsMyTradingRequest("AUD", "BTC", null, null); BTCMarketsMyTradingRequest pagingRequest = new BTCMarketsMyTradingRequest("AUD", "BTC", 120, null); BTCMarketsMyTradingRequest timeSpanRequest = new BTCMarketsMyTradingRequest("AUD", "BTC", null, new Date(1234567890L)); BTCMarketsTradeHistory defaultResponse = Whitebox.invokeConstructor(BTCMarketsTradeHistory.class, new Class[] { Boolean.class, String.class, Integer.class, List.class }, new Object[] { true, "", 0, Collections.singletonList(expectedBtcMarketsUserTrades.get(0)) }); BTCMarketsTradeHistory pagingResponse = Whitebox.invokeConstructor(BTCMarketsTradeHistory.class, new Class[] { Boolean.class, String.class, Integer.class, List.class }, new Object[] { true, "", 0, expectedBtcMarketsUserTrades.subList(1, 3) }); BTCMarketsTradeHistory timeSpanResponse = Whitebox.invokeConstructor(BTCMarketsTradeHistory.class, new Class[] { Boolean.class, String.class, Integer.class, List.class }, new Object[] { true, "", 0, expectedBtcMarketsUserTrades.subList(2, 4) }); BTCMarketsAuthenticated btcm = mock(BTCMarketsAuthenticated.class); PowerMockito.when(btcm.getTradeHistory(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(defaultRequest))).thenReturn(defaultResponse); PowerMockito.when(btcm.getTradeHistory(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(pagingRequest))).thenReturn(pagingResponse); PowerMockito.when(btcm.getTradeHistory(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(timeSpanRequest))).thenReturn(timeSpanResponse); Whitebox.setInternalState(marketsTradeService, "btcm", btcm); // when UserTrades defaultTrades = marketsTradeService.getTradeHistory(new DefaultTradeHistoryParamCurrencyPair()); UserTrades pagingTrades = marketsTradeService.getTradeHistory(new DefaultTradeHistoryParamPaging(120)); UserTrades timeSpanTrades = marketsTradeService.getTradeHistory(new DefaultTradeHistoryParamsTimeSpan(new Date(1234567890L))); List<UserTrade> defaultUserTrades = defaultTrades.getUserTrades(); List<UserTrade> pagingUserTrades = pagingTrades.getUserTrades(); List<UserTrade> timeSpanUserTrades = timeSpanTrades.getUserTrades(); // then assertThat(defaultUserTrades).hasSize(1); BtcMarketsAssert.assertEquals(defaultUserTrades.get(0), expectedUserTrades[0]); assertThat(pagingUserTrades).hasSize(2); for (int i = 0; i < pagingUserTrades.size(); i++) { BtcMarketsAssert.assertEquals(pagingUserTrades.get(i), expectedUserTrades[i + 1]); } assertThat(timeSpanUserTrades).hasSize(2); for (int i = 0; i < timeSpanUserTrades.size(); i++) { BtcMarketsAssert.assertEquals(timeSpanUserTrades.get(i), expectedUserTrades[i + 2]); } } @Test public void shouldGetOpenOrders() throws Exception { // given final BTCMarketsOrder[] expectedBtcMarketsOrders = expectedBtcMarketsOrders(); final LimitOrder[] expectedOrders = expectedOrders(); BTCMarketsMyTradingRequest request = new BTCMarketsMyTradingRequest("AUD", "BTC", 50, null); BTCMarketsOrders response = Whitebox.invokeConstructor(BTCMarketsOrders.class, new Class[] { Boolean.class, String.class, Integer.class, List.class }, new Object[] { true, "", 0, Arrays.asList(expectedBtcMarketsOrders[0], expectedBtcMarketsOrders[1]) }); BTCMarketsAuthenticated btcm = mock(BTCMarketsAuthenticated.class); PowerMockito.when(btcm.getOpenOrders(Mockito.eq(SPECIFICATION_API_KEY), Mockito.any(SynchronizedValueFactory.class), Mockito.any(BTCMarketsDigest.class), Mockito.refEq(request))).thenReturn(response); Whitebox.setInternalState(marketsTradeService, "btcm", btcm); // when OpenOrders openOrders = marketsTradeService.getOpenOrders(); List<LimitOrder> ordersList = openOrders.getOpenOrders(); // then assertThat(ordersList).hasSize(2); for (int i = 0; i < ordersList.size(); i++) { BtcMarketsAssert.assertEquals(ordersList.get(i), expectedOrders[i]); } } @Test public void shouldCreateHistoryParams() { // when BTCMarketsTradeService.HistoryParams historyParams = marketsTradeService.createTradeHistoryParams(); // then assertThat(historyParams.getPageLength()).isEqualTo(100); assertThat(historyParams.getStartTime()).isNull(); } }