public async Task GetSingleQuoteData_ShouldReturnSingleQuoteQueryResultWithoutError_WhenSuccessful() { var singleQuoteData = new SingleQuoteData( symbolId: 1, ticker: "MSFT", high: 1, low: 2, open: 3, previousClose: 4, volume: 5, change: 6, price: 7, changePercent: 0.9m, lastUpdated: DateTime.UtcNow, lastTradingDay: DateTime.UtcNow ); var client = new AlphaVantageClient(_mockHttpFactory.Object, _mockAlphaVantageOptionsAccessor.Object, _mockParserFactory.Object, _mockLogger.Object); SetupMockHttpClient("mockData", HttpStatusCode.OK); _singleQuoteDataCsvParser.Setup(x => x.ParseJson(-1, It.IsAny <string>())).Returns(singleQuoteData); var query = new SingleQuoteQuery(-1); var queryResult = await client.GetSingleQuoteData(query, "MSFT", "NASDAQ"); Assert.False(queryResult.HasError); Assert.Equal("MSFT", queryResult.Data.Ticker); Assert.Equal(singleQuoteData.LastUpdated, queryResult.Data.LastUpdated); }
public async Task UpsertSingleQuoteData_ShouldThrowException_WhenSavingFailed() { _stockDataRepository.Setup(s => s.UpsertSingleQuoteData(It.IsAny <UpsertSingleQuoteData>())).Returns(Task.FromResult(false)); var query = new SingleQuoteQuery(1); var queryResult = new SingleQuoteQueryResult("MSFT", _singleQuoteData); await Assert.ThrowsAsync <ArgumentException>(async() => await _service.UpsertSingleQuoteData(query, queryResult)); }
public async Task GetSingleQuoteData_ShouldReturnQueryResultWithError_WhenErrorSendingRequestWithHttpClient() { var client = new AlphaVantageClient(_mockHttpFactory.Object, _mockAlphaVantageOptionsAccessor.Object, _mockParserFactory.Object, _mockLogger.Object); _mockHttpFactory = new Mock <IHttpClientFactory>(); var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>() ) .Throws <Exception>(); var httpClient = new HttpClient(handlerMock.Object); _mockHttpFactory.Setup(x => x.CreateClient(It.IsAny <string>())).Returns(httpClient); var query = new SingleQuoteQuery(-1); var queryResult = await client.GetSingleQuoteData(query, "MSFT", "NASDAQ"); Assert.True(queryResult.HasError); Assert.NotNull(queryResult.ErrorMessage); }
public void GetSubscriptionInfos_ReturnsSubscriberCountEqualsTimesAdded_WhenMultipleQueries() { var querySubscription = new QuerySubscriptions(); var queryCount = 2; var query = new SingleQuoteQuery(1); var queryCount2 = 3; var query2 = new SingleQuoteQuery(2); for (var i = 0; i < queryCount; i++) { querySubscription.AddSubscriber(query); } for (var i = 0; i < queryCount2; i++) { querySubscription.AddSubscriber(query2); } var querySubscriptionInfos = querySubscription.GetSubscriptionInfos(); Assert.Equal(2, querySubscriptionInfos.Count()); var subcribedQuery = querySubscriptionInfos.First(x => x.Query == query); var subcribedQuery2 = querySubscriptionInfos.First(x => x.Query == query2); Assert.Equal(queryCount, subcribedQuery.SubscriberCount); Assert.Equal(queryCount2, subcribedQuery2.SubscriberCount); }
/// <summary> /// Saves the single quote query result or updates it if it already exists. /// </summary> /// <param name="query"><see cref="SingleQuoteQuery"/> to upsert data for.</param> /// <param name="queryResult"><see cref="SingleQuoteQueryResult"/> stock data results to save.</param> /// <remarks> /// Will update the database and then <see cref="SingleQuoteCache"/> if it was successful. /// Error results will be ignored. /// </remarks> public async Task UpsertSingleQuoteData(SingleQuoteQuery query, SingleQuoteQueryResult queryResult) { if (queryResult.HasError) { return; } _logger.LogTrace("Query SymbolId {id} added to cache", query.SymbolId); const int primaryKeyViolationCode = 2627; try { bool successfulSave = await _stockDataRepository.UpsertSingleQuoteData(new UpsertSingleQuoteData(query.SymbolId, queryResult.Data)); _logger.LogTrace("Query SymbolId {id} saved to database", query.SymbolId); if (!successfulSave) { throw new ArgumentException($"query for symbolId {query.SymbolId} was not able to be updated"); } } catch (SqlException ex) when(ex.ErrorCode == primaryKeyViolationCode) { _logger.LogError("Query SymbolId {id} was duplicate insert in database", query.SymbolId); // Ignore the error since it means a race condition where we tried insert twice. // But that's fine since the stock data is unlikely to be different if it's that close in time. // This is more performant than adding locks as this case should be very exceptional. } // Only insert into cache if it successfully saved into database. _singleQuoteCache.Upsert(query.SymbolId, queryResult); }
public void GetSubscriberCount_ShouldReturnZero_WhenQueryNotFound() { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); long subscriberCount = querySubscription.GetSubscriberCount(query); Assert.Equal(0, subscriberCount); }
public async Task UpsertSingleQuoteData_ShouldNotUpsertSingleQuoteData_WhenQueryResultHasError() { _stockDataRepository.Setup(s => s.UpsertSingleQuoteData(It.IsAny <UpsertSingleQuoteData>())).Returns(Task.FromResult(true)); var query = new SingleQuoteQuery(1); var queryResult = new SingleQuoteQueryResult("error"); await _service.UpsertSingleQuoteData(query, queryResult); _stockDataRepository.Verify(s => s.UpsertSingleQuoteData(It.IsAny <UpsertSingleQuoteData>()), Times.Never); Assert.False(_cache.TryGet(query.SymbolId, out SingleQuoteQueryResult cachedResult)); }
public async Task GetSingleQuoteData_ShouldReturnQueryResultWithError_WhenHttpRequestNotOK() { var client = new AlphaVantageClient(_mockHttpFactory.Object, _mockAlphaVantageOptionsAccessor.Object, _mockParserFactory.Object, _mockLogger.Object); SetupMockHttpClient("", HttpStatusCode.Unauthorized); var query = new SingleQuoteQuery(-1); var queryResult = await client.GetSingleQuoteData(query, "MSFT", "NASDAQ"); Assert.True(queryResult.HasError); }
public async Task GetSingleQuote_ShouldReturnErrorWhenUnknownSymbol() { var query = new SingleQuoteQuery(-1); var ticker = "AB1234567890"; var alphaVantageClient = new AlphaVantageClient(_mockHttpFactory, _mockAlphaVantageOptionsAccessor.Object, _parserFactory, _mockLogger.Object); SingleQuoteQueryResult singleQuoteResult = await alphaVantageClient.GetSingleQuoteData(query, ticker, "NYSE"); Assert.True(singleQuoteResult.HasError); Assert.False(string.IsNullOrEmpty(singleQuoteResult.ErrorMessage)); }
public async Task GetSingleQuoteData_ShouldGetValueFromCache() { var query = new SingleQuoteQuery(1); var queryResult = new SingleQuoteQueryResult("MSFT", _singleQuoteData); _cache.Upsert(query.SymbolId, queryResult); StockSingleQuoteDataDTO data = await _service.GetSingleQuoteData(query.SymbolId); Assert.Equal(queryResult.Data, data.Data); _stockDataRepository.Verify(s => s.GetSingleQuoteData(It.IsAny <int>()), Times.Never); }
public void GetSubscriptionInfos_ReturnsZeroSubscriberCount_WhenQueryCleared() { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); querySubscription.AddSubscriber(query); querySubscription.ClearQuery(query); var querySubscriptionInfos = querySubscription.GetSubscriptionInfos(); Assert.Empty(querySubscriptionInfos); }
public async Task UpsertSingleQuoteData_ShouldUpsertSingleQuoteDataAndSaveIntoCache() { _stockDataRepository.Setup(s => s.UpsertSingleQuoteData(It.IsAny <UpsertSingleQuoteData>())).Returns(Task.FromResult(true)); var query = new SingleQuoteQuery(1); var queryResult = new SingleQuoteQueryResult("MSFT", _singleQuoteData); await _service.UpsertSingleQuoteData(query, queryResult); _stockDataRepository.Verify(s => s.UpsertSingleQuoteData(It.Is <UpsertSingleQuoteData>(u => u.SymbolId == query.SymbolId))); _cache.TryGet(query.SymbolId, out SingleQuoteQueryResult cachedResult); Assert.Equal(queryResult, cachedResult); }
public void GetSubscriberCount_ShouldReturnSubcriberCount_ForQuery() { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); querySubscription.AddSubscriber(query); querySubscription.AddSubscriber(query); long subscriberCount = querySubscription.GetSubscriberCount(query); Assert.Equal(2, subscriberCount); }
public async Task GetSingleQuoteData_ShouldReturnQueryResultWithError_WhenParsingError() { var query = new SingleQuoteQuery(-1); var client = new AlphaVantageClient(_mockHttpFactory.Object, _mockAlphaVantageOptionsAccessor.Object, _mockParserFactory.Object, _mockLogger.Object); SetupMockHttpClient("", HttpStatusCode.OK); _singleQuoteDataCsvParser.Setup(x => x.ParseJson(It.IsAny <int>(), It.IsAny <string>())).Throws(new Exception()); var queryResult = await client.GetSingleQuoteData(query, "MSFT", "NASDAQ"); Assert.True(queryResult.HasError); Assert.NotNull(queryResult.ErrorMessage); }
public async Task GetSingleQuoteData_ShouldGetValueFromDBAndSaveToCache_WhenNotInCache() { var query = new SingleQuoteQuery(1); var queryResult = new SingleQuoteQueryResult("MSFT", _singleQuoteData); _stockDataRepository.Setup(s => s.GetSingleQuoteData(It.IsAny <int>())).Returns(Task.FromResult(_singleQuoteData)); StockSingleQuoteDataDTO data = await _service.GetSingleQuoteData(query.SymbolId); Assert.Equal(queryResult.Data, data.Data); _stockDataRepository.Verify(s => s.GetSingleQuoteData(It.IsAny <int>()), Times.Once); _cache.TryGet(query.SymbolId, out SingleQuoteQueryResult cachedResult); Assert.Equal(queryResult.Data, cachedResult.Data); }
public void GetSubscriptionInfos_ReturnsSubscriberCountEqualTimesAdded(int timesAdded) { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); for (var i = 0; i < timesAdded; i++) { querySubscription.AddSubscriber(query); } var querySubscriptionInfos = querySubscription.GetSubscriptionInfos(); Assert.Single(querySubscriptionInfos); Assert.Equal(timesAdded, querySubscriptionInfos.Single().SubscriberCount); Assert.Equal(query, querySubscriptionInfos.Single().Query); }
public SingleQuoteContext( IStockClient stockClient, SingleQuoteCache queryResultCache, ISymbolRepository symbolRepository, IStockDataService stockDataService, IStockNotificationCenter notificationCenter, SingleQuoteQuery query, ILogger <SingleQuoteContext> logger) { _stockClient = stockClient; _queryResultCache = queryResultCache; _symbolRepository = symbolRepository; _stockDataService = stockDataService; _notificationCenter = notificationCenter; _query = query; _logger = logger; }
public void GetSubscriptionInfos_SubscriberCountNeverLessThanZero_WhenSubscribersRemoved() { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); querySubscription.AddSubscriber(query); querySubscription.RemoveSubscriber(query); querySubscription.RemoveSubscriber(query); querySubscription.RemoveSubscriber(query); var querySubscriptionInfos = querySubscription.GetSubscriptionInfos(); Assert.Single(querySubscriptionInfos); Assert.Equal(0, querySubscriptionInfos.Single().SubscriberCount); Assert.Equal(query, querySubscriptionInfos.Single().Query); }
public async Task GetSingleQuote_ShouldReturnSingleQuoteStockData() { var query = new SingleQuoteQuery(-1); var ticker = "MSFT"; var alphaVantageClient = new AlphaVantageClient(_mockHttpFactory, _mockAlphaVantageOptionsAccessor.Object, _parserFactory, _mockLogger.Object); SingleQuoteQueryResult singleQuoteResult = await alphaVantageClient.GetSingleQuoteData(query, ticker, "NASDAQ"); Assert.False(singleQuoteResult.HasError); Assert.True(singleQuoteResult.Data.Low >= 0); Assert.True(singleQuoteResult.Data.High >= 0); Assert.True(singleQuoteResult.Data.Open >= 0); Assert.True(singleQuoteResult.Data.Volume >= 0); Assert.True(singleQuoteResult.Data.Price >= 0); Assert.True(singleQuoteResult.Data.PreviousClose >= 0); Assert.True(singleQuoteResult.Data.LastUpdated > new DateTime()); Assert.True(singleQuoteResult.Data.LastTradingDay > new DateTime()); Assert.Equal(ticker, singleQuoteResult.Data.Ticker); }
public void GetSubscriptionInfos_ReturnsSubscriberCountEqualTimesAddedAndSubtracted_WhenSingleQuery(int timesAdded, int timesRemoved) { var querySubscription = new QuerySubscriptions(); var query = new SingleQuoteQuery(1); for (var i = 0; i < timesAdded; i++) { querySubscription.AddSubscriber(query); } for (var i = 0; i < timesRemoved; i++) { querySubscription.RemoveSubscriber(query); } var querySubscriptionInfos = querySubscription.GetSubscriptionInfos(); var expectedCount = Math.Abs(timesAdded - timesRemoved); Assert.Single(querySubscriptionInfos); Assert.Equal(expectedCount, querySubscriptionInfos.Single().SubscriberCount); Assert.Equal(query, querySubscriptionInfos.Single().Query); }
public void AddSubscriberToSingleQuote(int symbolId) { var query = new SingleQuoteQuery(symbolId); _querySubscriptions.AddSubscriber(query); }
public SingleQuoteContext GenerateSingleQuoteContext(SingleQuoteQuery query) { return(_singleQuoteFactory(query)); }