package com.sigmaflare.binancej; import com.codepoetics.ambivalence.Either; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.sigmaflare.binancej.entities.Candlestick; import com.sigmaflare.binancej.entities.ServiceError; import com.sigmaflare.binancej.entities.Interval; import com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException; import com.sigmaflare.binancej.matchers.GetMatcher; import org.apache.commons.io.FileUtils; import org.apache.http.ProtocolVersion; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicStatusLine; import org.junit.Before; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.List; import static com.sigmaflare.binancej.Constant.BASE_ENDPOINT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class CandlestickMethodTests { private static ObjectMapper mapper = Helpers.objectMapperBuilder(); private final String url = String.format("%s%s", BASE_ENDPOINT, "/api/v1/klines?symbol=TEST&interval=8h"); private final String urlWithLimit = String.format("%s%s", url, "&limit=1000"); private final String urlWithStartTime = String.format("%s%s", url, "&startTime=1234"); private final String urlWithEndTime = String.format("%s%s", url, "&endTime=1234"); private final String urlWithLimitAndStartTime = String.format("%s%s", urlWithLimit, "&startTime=1234"); private final String urlWithLimitAndEndTime = String.format("%s%s", urlWithLimit, "&endTime=1234"); private List candlesticks; // This will just make mocking easier on us... private String data; @Before public void setUp() throws IOException { ClassLoader classLoader = ExchangeInfoMethodTests.class.getClassLoader(); File file = new File(classLoader.getResource("candlestick_response_sample.json").getFile()); JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, Candlestick.class); data = FileUtils.readFileToString(file, "UTF-8"); candlesticks = mapper.readValue(data, type); } /** * testFieldsAreCorrect is a test method to insure field alignment. Since a custom deserializer * is used to convert an array into a Candlestick object, it's important that field alignment * is checked so numbers are guaranteed. */ @Test public void testFieldsAreCorrect() { Candlestick c = candlesticks.get(0); assertEquals(1499040000000L, c.getOpenTime()); assertEquals(new BigDecimal("0.01634790"), c.getOpen()); assertEquals(new BigDecimal("0.80000000"), c.getHigh()); assertEquals(new BigDecimal("0.01575800"), c.getLow()); assertEquals(new BigDecimal("0.01577100"), c.getClose()); assertEquals(new BigDecimal("148976.11427815"), c.getVolume()); assertEquals(1499644799999L, c.getCloseTime()); assertEquals(new BigDecimal("2434.19055334"), c.getQuoteAssetVolume()); assertEquals(308L, c.getNumberOfTrades()); assertEquals(new BigDecimal("1756.87402397"), c.getTakerBuyBaseAssetVolume()); assertEquals(new BigDecimal("28.46694368"), c.getTakerBuyQuoteAssetVolume()); // There's a field marked ignore after TakerBuyQuoteAssetVolume... } @Test public void testCandlestickServiceReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(url, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test public void testCandlestickServiceWithLimitReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(urlWithLimit, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS, 1000); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test public void testCandlestickServiceWithLimitAndStartTimeReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(urlWithLimitAndStartTime, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS, 1000, 1234L,true); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test public void testCandlestickServiceWithLimitAndEndTimeReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(urlWithLimitAndEndTime, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS, 1000, 1234L,false); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test public void testCandlestickServiceWithStartTimeReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(urlWithStartTime, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS, 1234L,true); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test public void testCandlestickServiceWithEndTimeReturnsSuccessfully() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(urlWithEndTime, "1234")))) .thenReturn(mockedCloseableHttpResponse); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS, 1234L,false); assertTrue(res.isRight()); assertEquals(Helpers.extractEitherValueSafely(res.right()), candlesticks); } @Test(expected = BinanceServiceUnreachableException.class) public void testCandlestickServiceWithoutHttpEntityThrows() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 200, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(url, "1234")))) .thenReturn(mockedCloseableHttpResponse); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS); } @Test public void TestCandlestickServiceBadApiKeyReturns400() throws IOException, BinanceServiceUnreachableException { CloseableHttpClient mockedCloseableHttpClient = mock(CloseableHttpClient.class); CloseableHttpResponse mockedCloseableHttpResponse = mock(CloseableHttpResponse.class); when(mockedCloseableHttpResponse.getStatusLine()) .thenReturn(new BasicStatusLine(new ProtocolVersion("TEST", 1, 0), 400, "test")); when(mockedCloseableHttpClient.execute(argThat(new GetMatcher(url, "1234")))) .thenReturn(mockedCloseableHttpResponse); ServiceError serviceError = ServiceError.builder().code(400).message("Bad API Key").build(); BasicHttpEntity httpEntity = new BasicHttpEntity(); httpEntity.setContent( new ByteArrayInputStream(mapper.writeValueAsString(serviceError).getBytes(StandardCharsets.UTF_8))); when(mockedCloseableHttpResponse.getEntity()).thenReturn(httpEntity); MarketData marketData = new MarketData("1234", "abcd", mockedCloseableHttpClient); Either> res = marketData.getCandleStickData("TEST", Interval.EIGHT_HOURS); assertTrue(res.isLeft()); assertEquals(Helpers.extractEitherValueSafely(res.left()), serviceError); } }