Ejemplo n.º 1
0
        public async Task GetSingleQuoteData_ShouldReturnNoDataAndQueueQuery_WhenFirstTime()
        {
            SymbolSearchResultDTO searchResult = await SearchSymbol("TSLA", ExchangeType.NASDAQ);

            List <StockSingleQuoteDataDTO> dataDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            Assert.Single(dataDtos);

            var dataDto = dataDtos[0];

            Assert.Equal(searchResult.SymbolId, dataDto.SymbolId);
            Assert.Null(dataDto.Data);

            var startTime = DateTime.UtcNow;

            while (dataDto.Data == null)
            {
                await CheckTimeOut(startTime);

                List <StockSingleQuoteDataDTO> newData = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

                dataDto = newData[0];
            }

            AssertSingleQuote(dataDto, searchResult.SymbolId);
        }
Ejemplo n.º 2
0
        public async Task Should_DeletePortfolioWithSymbols()
        {
            // Create Portfolio
            var createPortfolioResponse = await _client.PostAsync(ApiPath.Portfolio(), new { name = string.Empty }.ToJsonPayload());

            createPortfolioResponse.EnsureSuccessStatusCode();

            var portfolio = await createPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.True(portfolio.Id > 0);

            // Search for symbols by keyword
            SymbolSearchResultDTO jpmSymbol = await FetchSymbol("JPM", ExchangeType.NYSE);

            // Add symbols to Portfolio
            var addJPMResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = jpmSymbol.SymbolId }.ToJsonPayload());

            addJPMResponse.EnsureSuccessStatusCode();

            // Verify Portfolio exists
            var getPortfolioResponse = await _client.GetAsync(ApiPath.Portfolio(portfolio.Id));

            getPortfolioResponse.EnsureSuccessStatusCode();

            // Delete and check it no longer exists
            var deletePortfolioResponse = await _client.DeleteAsync(ApiPath.Portfolio(portfolio.Id));

            deletePortfolioResponse.EnsureSuccessStatusCode();

            var getPortfolioAfterDeleteResponse = await _client.GetAsync(ApiPath.Portfolio(portfolio.Id));

            Assert.Equal(HttpStatusCode.NotFound, getPortfolioAfterDeleteResponse.StatusCode);
        }
Ejemplo n.º 3
0
        public async Task GetSingleQuoteData_ShouldUpdateQueryResults_WhenResultsFromDBStale()
        {
            // Trigger the query so it is saved into the database.
            SymbolSearchResultDTO searchResult = await SearchSymbol("TSLA", ExchangeType.NASDAQ);

            List <StockSingleQuoteDataDTO> dataDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            Assert.Single(dataDtos);

            var dataDto = dataDtos[0];

            Assert.Equal(searchResult.SymbolId, dataDto.SymbolId);
            Assert.Null(dataDto.Data);

            var startTime = DateTime.UtcNow;

            // Wait for query to execute and until there is data
            while (dataDto.Data == null)
            {
                await CheckTimeOut(startTime);

                List <StockSingleQuoteDataDTO> newData = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

                dataDto = newData[0];
            }

            AssertSingleQuote(dataDto, searchResult.SymbolId);

            // Make the data stale
            var modifiedDate = new DateTime(2000, 1, 1);;
            await _dbFixture.Connection.ExecuteAsync($"UPDATE SingleQuoteData SET LastUpdated = '{modifiedDate}'");

            //reset the server so it will update the cache with the stale value.
            // System should detect the stale data and trigger an update.
            await RestartServer();

            var dbDataDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            var dbDataDto = dbDataDtos[0];

            // Wait for query to execute and until there is data
            while (dbDataDto.LastUpdated <= modifiedDate)
            {
                await CheckTimeOut(startTime);

                List <StockSingleQuoteDataDTO> newData = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

                dbDataDto = newData[0];
            }

            Assert.Equal(searchResult.SymbolId, dbDataDto.SymbolId);
            Assert.True(dbDataDto.LastUpdated > DateTime.UtcNow.AddMinutes(-5));
        }
Ejemplo n.º 4
0
        public async Task GetSingleQuoteData_ShouldQueueQuery_ForEachStock_WhenTwoIntervals()
        {
            // First call should return no data since it does not exist.
            SymbolSearchResultDTO tslaSearchResult = await SearchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO jpmSearchResult = await SearchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO shopSearchResult = await SearchSymbol("SHOP", ExchangeType.NASDAQ);

            SymbolSearchResultDTO faceBookSearchResult = await SearchSymbol("FB", ExchangeType.NASDAQ);



            var symbolIdsToGet = new int[]
            {
                tslaSearchResult.SymbolId,
                jpmSearchResult.SymbolId,
                shopSearchResult.SymbolId,
                faceBookSearchResult.SymbolId
            };

            if (AppTestSettings.Instance.EventBusOptions.MaxQueriesPerInterval >= symbolIdsToGet.Length)
            {
                throw new InvalidOperationException("Number of symbols to fetch should be greater than the max per interval.");
            }

            List <StockSingleQuoteDataDTO> dataDtos = await GetSingleQuoteData(symbolIdsToGet);

            Assert.Equal(4, dataDtos.Count());

            Assert.All(dataDtos, d => Assert.Null(d.Data));

            var startTime = DateTime.UtcNow;

            // Wait for query to execute until all populated
            while (dataDtos.Count(d => d.Data == null) != 0)
            {
                await CheckTimeOut(startTime);

                dataDtos = await GetSingleQuoteData(symbolIdsToGet);
            }

            AssertSingleQuote(dataDtos[0], tslaSearchResult.SymbolId);
            AssertSingleQuote(dataDtos[1], jpmSearchResult.SymbolId);
            AssertSingleQuote(dataDtos[2], shopSearchResult.SymbolId);
            AssertSingleQuote(dataDtos[3], faceBookSearchResult.SymbolId);
        }
Ejemplo n.º 5
0
        public async Task Should_OnlyShowedTheTopMembers()
        {
            TestUser testUser1 = await CreateTestUserWithPortfolio();

            TestUser testUser2 = await CreateTestUserWithPortfolio();

            TestUser testUser3 = await CreateTestUserWithPortfolio();

            SymbolSearchResultDTO jpmStock = await FetchSymbol("JPM", ExchangeType.NYSE);

            // Add singlequote stocks
            var jpmData = new SingleQuoteData(jpmStock.SymbolId, jpmStock.Ticker, 200, 200, 200, 200, 200, 200, 0, 0, DateTime.UtcNow, DateTime.UtcNow);

            await SetSingleQuoteData(new UpsertSingleQuoteData(jpmStock.SymbolId, jpmData));

            // Add symbols User 1
            await AddSymbolToPortfolioWithAvgPrice(testUser1, jpmStock.SymbolId, 100);

            // Add symbols User 2
            await AddSymbolToPortfolioWithAvgPrice(testUser2, jpmStock.SymbolId, 200);

            // Add symbols User 3
            await AddSymbolToPortfolioWithAvgPrice(testUser3, jpmStock.SymbolId, 300);

            var leaderBoardResponse = await _client.GetAsync(ApiPath.LeaderBoard(2));

            LeaderBoardViewModel leaderBoardViewModel = await leaderBoardResponse.Content.ReadAsAsync <LeaderBoardViewModel>();

            // Verify calculations
            BoardValue bestPerformerRank1 = leaderBoardViewModel.BestPerformers.Values.ElementAt(0);
            BoardValue bestPerformerRank2 = leaderBoardViewModel.BestPerformers.Values.ElementAt(1);

            BoardValue worstPerformerRank1 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(0);
            BoardValue worstPerformerRank2 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(1);

            Assert.Equal(2, leaderBoardViewModel.BestPerformers.Values.Count());
            Assert.Equal(2, leaderBoardViewModel.WorstPerformers.Values.Count());

            Assert.Equal(testUser1.UserId, Guid.Parse(bestPerformerRank1.Id));
            Assert.Equal(testUser2.UserId, Guid.Parse(bestPerformerRank2.Id));

            Assert.Equal(testUser3.UserId, Guid.Parse(worstPerformerRank1.Id));
            Assert.Equal(testUser2.UserId, Guid.Parse(worstPerformerRank2.Id));
        }
Ejemplo n.º 6
0
        public async Task Should_IgnorePortfolioSymbolsWithNoAveragePrice()
        {
            TestUser testUser1 = await CreateTestUserWithPortfolio();

            TestUser testUser2 = await CreateTestUserWithPortfolio();

            SymbolSearchResultDTO jpmStock = await FetchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO fbStock = await FetchSymbol("FB", ExchangeType.NASDAQ);

            // Add singlequote stocks
            var jpmData = new SingleQuoteData(jpmStock.SymbolId, jpmStock.Ticker, 200, 200, 200, 200, 200, 200, 0, 0, DateTime.UtcNow, DateTime.UtcNow);
            var fbData  = new SingleQuoteData(fbStock.SymbolId, fbStock.Ticker, 333.33m, 333.33m, 333.33m, 333.33m, 333.33m, 300, 0, 0, DateTime.UtcNow, DateTime.UtcNow);

            await SetSingleQuoteData(new UpsertSingleQuoteData(jpmStock.SymbolId, jpmData));
            await SetSingleQuoteData(new UpsertSingleQuoteData(fbData.SymbolId, fbData));

            // Add symbols User 1
            await AddSymbolToPortfolioWithAvgPrice(testUser1, jpmStock.SymbolId, 100);
            await AddSymbolToPortfolio(testUser1, fbStock.SymbolId);

            // Add symbols User 2
            await AddSymbolToPortfolio(testUser2, jpmStock.SymbolId);
            await AddSymbolToPortfolio(testUser2, fbStock.SymbolId);

            var leaderBoardResponse = await _client.GetAsync(ApiPath.LeaderBoard(2));

            LeaderBoardViewModel leaderBoardViewModel = await leaderBoardResponse.Content.ReadAsAsync <LeaderBoardViewModel>();

            // Verify calculations
            BoardValue bestPerformerRank1  = leaderBoardViewModel.BestPerformers.Values.ElementAt(0);
            BoardValue worstPerformerRank1 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(0);

            Assert.Single(leaderBoardViewModel.BestPerformers.Values);
            Assert.Single(leaderBoardViewModel.WorstPerformers.Values);

            Assert.Equal(testUser1.UserId, Guid.Parse(bestPerformerRank1.Id));
            Assert.Equal("100.00", bestPerformerRank1.Value);

            Assert.Equal(testUser1.UserId, Guid.Parse(worstPerformerRank1.Id));
            Assert.Equal("100.00", worstPerformerRank1.Value);
        }
Ejemplo n.º 7
0
        public async Task Should_DeleteSymbolFromPortfolio()
        {
            // Create Portfolio
            var createPortfolioResponse = await _client.PostAsync(ApiPath.Portfolio(), new { name = string.Empty }.ToJsonPayload());

            createPortfolioResponse.EnsureSuccessStatusCode();

            var portfolio = await createPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.True(portfolio.Id > 0);

            // Search for symbols by keyword
            SymbolSearchResultDTO tslaSymbol = await FetchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO jpmSymbol = await FetchSymbol("JPM", ExchangeType.NYSE);

            // Add symbols to Portfolio
            var addTSLAResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = tslaSymbol.SymbolId }.ToJsonPayload());

            addTSLAResponse.EnsureSuccessStatusCode();

            var addJPMResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = jpmSymbol.SymbolId }.ToJsonPayload());

            addJPMResponse.EnsureSuccessStatusCode();

            // Delete JPM
            var jpmPortfolioSymbol = await addJPMResponse.Content.ReadAsAsync <PortfolioSymbol>();

            var deleteJPMResponse = await _client.DeleteAsync(ApiPath.PortfolioSymbols(portfolio.Id, jpmPortfolioSymbol.Id));

            deleteJPMResponse.EnsureSuccessStatusCode();

            // Check only one symbol left on Portfolio
            var getPortfolioResponse = await _client.GetAsync(ApiPath.Portfolio(portfolio.Id));

            getPortfolioResponse.EnsureSuccessStatusCode();
            var fetchedPortfolio = await getPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.Single(fetchedPortfolio.PortfolioSymbols);
            Assert.Equal("TSLA", fetchedPortfolio.PortfolioSymbols.First().Ticker);
        }
Ejemplo n.º 8
0
        public async Task Should_UpdateAveragePricePortfolioSymbol()
        {
            // Create Portfolio
            var createPortfolioResponse = await _client.PostAsync(ApiPath.Portfolio(), new { name = string.Empty }.ToJsonPayload());

            createPortfolioResponse.EnsureSuccessStatusCode();

            var portfolio = await createPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.True(portfolio.Id > 0);

            // Search for symbols by keyword
            SymbolSearchResultDTO jpmSymbol = await FetchSymbol("JPM", ExchangeType.NYSE);

            // Add symbols to Portfolio
            var addJPMResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = jpmSymbol.SymbolId }.ToJsonPayload());

            addJPMResponse.EnsureSuccessStatusCode();
            var jpmPortfolioSymbol = await addJPMResponse.Content.ReadAsAsync <PortfolioSymbol>();

            var newAvgPricePayload = new
            {
                AveragePrice = 1.24m
            }.ToJsonPayload();

            var updateAveragePriceResponse = await _client.PatchAsync(ApiPath.PortfolioSymbolsAveragePrice(portfolio.Id, jpmPortfolioSymbol.Id), newAvgPricePayload);

            updateAveragePriceResponse.EnsureSuccessStatusCode();

            var getPortfolioResponse = await _client.GetAsync(ApiPath.Portfolio(portfolio.Id));

            var fetchedPortfolio = await getPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.Equal(portfolio.Id, fetchedPortfolio.Id);

            var jpm = fetchedPortfolio.PortfolioSymbols.Single(s => s.Ticker == "JPM");

            Assert.Equal(1.24m, jpm.AveragePrice);
        }
Ejemplo n.º 9
0
        public async Task Should_ReturnBadRequestWhenSymbolAlreadyExistsInPortfolio()
        {
            // Create Portfolio
            var createPortfolioResponse = await _client.PostAsync(ApiPath.Portfolio(), new { name = string.Empty }.ToJsonPayload());

            createPortfolioResponse.EnsureSuccessStatusCode();

            var portfolio = await createPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.True(portfolio.Id > 0);

            // Search for symbols by keyword
            SymbolSearchResultDTO tslaSymbol = await FetchSymbol("TSLA", ExchangeType.NASDAQ);

            // Add symbols to Portfolio
            var addTSLAResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = tslaSymbol.SymbolId }.ToJsonPayload());

            addTSLAResponse.EnsureSuccessStatusCode();

            var addTSLAResponse2 = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = tslaSymbol.SymbolId }.ToJsonPayload());

            Assert.Equal(HttpStatusCode.BadRequest, addTSLAResponse2.StatusCode);
        }
Ejemplo n.º 10
0
        public async Task GetSingleQuoteData_ShouldQueueQuery_ForEachStock()
        {
            // First call should return no data since it does not exist.
            SymbolSearchResultDTO tslaSearchResult = await SearchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO jpmSearchResult = await SearchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO shopSearchResult = await SearchSymbol("SHOP", ExchangeType.NASDAQ);

            var symbolIdsToGet = new int[]
            {
                tslaSearchResult.SymbolId,
                jpmSearchResult.SymbolId,
                shopSearchResult.SymbolId,
            };

            List <StockSingleQuoteDataDTO> dataDtos = await GetSingleQuoteData(symbolIdsToGet);

            Assert.Equal(3, dataDtos.Count());

            Assert.All(dataDtos, d => Assert.Null(d.Data));

            var startTime = DateTime.UtcNow;

            // Wait for query to execute until all populated
            while (dataDtos.Count(d => d.Data == null) != 0)
            {
                await CheckTimeOut(startTime);

                dataDtos = await GetSingleQuoteData(symbolIdsToGet);
            }

            AssertSingleQuote(dataDtos[0], tslaSearchResult.SymbolId);
            AssertSingleQuote(dataDtos[1], jpmSearchResult.SymbolId);
            AssertSingleQuote(dataDtos[2], shopSearchResult.SymbolId);
        }
Ejemplo n.º 11
0
        public async Task Should_ReturnMostBearishAndMostBullishStocksByVotes()
        {
            TestUser testUser1 = await CreateTestUserWithPortfolio();

            TestUser testUser2 = await CreateTestUserWithPortfolio();

            TestUser testUser3 = await CreateTestUserWithPortfolio();

            SymbolSearchResultDTO jpmStock = await FetchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO fbStock = await FetchSymbol("FB", ExchangeType.NASDAQ);

            SymbolSearchResultDTO tslaStock = await FetchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO msftStock = await FetchSymbol("MSFT", ExchangeType.NASDAQ);

            // User 1 votes
            await SubmitVoteForUser(new VoteCommand { SymbolId = jpmStock.SymbolId, Direction = VoteDirection.UpVote }, testUser1.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = fbStock.SymbolId, Direction = VoteDirection.UpVote }, testUser1.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = tslaStock.SymbolId, Direction = VoteDirection.DownVote }, testUser1.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = msftStock.SymbolId, Direction = VoteDirection.DownVote }, testUser1.UserId);

            // User 2 votes
            await SubmitVoteForUser(new VoteCommand { SymbolId = jpmStock.SymbolId, Direction = VoteDirection.UpVote }, testUser2.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = fbStock.SymbolId, Direction = VoteDirection.DownVote }, testUser2.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = tslaStock.SymbolId, Direction = VoteDirection.DownVote }, testUser2.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = msftStock.SymbolId, Direction = VoteDirection.DownVote }, testUser2.UserId);

            // User 2 votes
            await SubmitVoteForUser(new VoteCommand { SymbolId = jpmStock.SymbolId, Direction = VoteDirection.UpVote }, testUser3.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = fbStock.SymbolId, Direction = VoteDirection.None }, testUser3.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = tslaStock.SymbolId, Direction = VoteDirection.DownVote }, testUser3.UserId);
            await SubmitVoteForUser(new VoteCommand { SymbolId = msftStock.SymbolId, Direction = VoteDirection.UpVote }, testUser3.UserId);

            var leaderBoardResponse = await _client.GetAsync(ApiPath.LeaderBoard(4));

            LeaderBoardViewModel leaderBoardViewModel = await leaderBoardResponse.Content.ReadAsAsync <LeaderBoardViewModel>();

            // Verify most bullish order
            BoardValue mostBullishRank1 = leaderBoardViewModel.MostBullish.Values.ElementAt(0);
            BoardValue mostBullishRank2 = leaderBoardViewModel.MostBullish.Values.ElementAt(1);
            BoardValue mostBullishRank3 = leaderBoardViewModel.MostBullish.Values.ElementAt(2);
            BoardValue mostBullishRank4 = leaderBoardViewModel.MostBullish.Values.ElementAt(3);

            Assert.Equal(jpmStock.SymbolId.ToString(), mostBullishRank1.Id);
            Assert.Equal("JPM", mostBullishRank1.Name);
            Assert.Equal("3", mostBullishRank1.Value);

            Assert.Equal(fbStock.SymbolId.ToString(), mostBullishRank2.Id);
            Assert.Equal("FB", mostBullishRank2.Name);
            Assert.Equal("0", mostBullishRank2.Value);

            Assert.Equal(msftStock.SymbolId.ToString(), mostBullishRank3.Id);
            Assert.Equal("MSFT", mostBullishRank3.Name);
            Assert.Equal("-1", mostBullishRank3.Value);

            Assert.Equal(tslaStock.SymbolId.ToString(), mostBullishRank4.Id);
            Assert.Equal("TSLA", mostBullishRank4.Name);
            Assert.Equal("-3", mostBullishRank4.Value);

            // Verify most bearish order
            BoardValue mostBearishRank1 = leaderBoardViewModel.MostBearish.Values.ElementAt(0);
            BoardValue mostBearishRank2 = leaderBoardViewModel.MostBearish.Values.ElementAt(1);
            BoardValue mostBearishRank3 = leaderBoardViewModel.MostBearish.Values.ElementAt(2);
            BoardValue mostBearishRank4 = leaderBoardViewModel.MostBearish.Values.ElementAt(3);

            Assert.Equal(tslaStock.SymbolId.ToString(), mostBearishRank1.Id);
            Assert.Equal("TSLA", mostBearishRank1.Name);
            Assert.Equal("-3", mostBearishRank1.Value);

            Assert.Equal(msftStock.SymbolId.ToString(), mostBearishRank2.Id);
            Assert.Equal("MSFT", mostBearishRank2.Name);
            Assert.Equal("-1", mostBearishRank2.Value);

            Assert.Equal(fbStock.SymbolId.ToString(), mostBearishRank3.Id);
            Assert.Equal("FB", mostBearishRank3.Name);
            Assert.Equal("0", mostBearishRank3.Value);

            Assert.Equal(jpmStock.SymbolId.ToString(), mostBearishRank4.Id);
            Assert.Equal("JPM", mostBearishRank4.Name);
            Assert.Equal("3", mostBearishRank4.Value);
        }
Ejemplo n.º 12
0
        public async Task Should_ReturnBestAndWorstPerformers()
        {
            TestUser testUser1 = await CreateTestUserWithPortfolio();

            TestUser testUser2 = await CreateTestUserWithPortfolio();

            TestUser testUser3 = await CreateTestUserWithPortfolio();

            SymbolSearchResultDTO jpmStock = await FetchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO fbStock = await FetchSymbol("FB", ExchangeType.NASDAQ);

            SymbolSearchResultDTO tslaStock = await FetchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO msftStock = await FetchSymbol("MSFT", ExchangeType.NASDAQ);

            // Add singlequote stocks
            var jpmData  = new SingleQuoteData(jpmStock.SymbolId, jpmStock.Ticker, 200, 200, 200, 200, 200, 200, 0, 0, DateTime.UtcNow, DateTime.UtcNow);
            var fbData   = new SingleQuoteData(fbStock.SymbolId, fbStock.Ticker, 333.33m, 333.33m, 333.33m, 333.33m, 333.33m, 300, 0, 0, DateTime.UtcNow, DateTime.UtcNow);
            var tslaData = new SingleQuoteData(tslaStock.SymbolId, tslaStock.Ticker, 888.88m, 888.88m, 888.88m, 888.88m, 888.88m, 800, 0, 0, DateTime.UtcNow, DateTime.UtcNow);
            var msftData = new SingleQuoteData(msftStock.SymbolId, msftStock.Ticker, 225, 225, 225, 225, 225, 200, 0, 0, DateTime.UtcNow, DateTime.UtcNow);

            await SetSingleQuoteData(new UpsertSingleQuoteData(jpmStock.SymbolId, jpmData));
            await SetSingleQuoteData(new UpsertSingleQuoteData(fbData.SymbolId, fbData));
            await SetSingleQuoteData(new UpsertSingleQuoteData(tslaData.SymbolId, tslaData));
            await SetSingleQuoteData(new UpsertSingleQuoteData(msftData.SymbolId, msftData));

            // Add symbols User 1
            await AddSymbolToPortfolioWithAvgPrice(testUser1, jpmStock.SymbolId, 100.25m);
            await AddSymbolToPortfolioWithAvgPrice(testUser1, fbStock.SymbolId, 260.35m);
            await AddSymbolToPortfolioWithAvgPrice(testUser1, msftStock.SymbolId, 175.50m);

            // Add symbols User 2
            await AddSymbolToPortfolioWithAvgPrice(testUser2, jpmStock.SymbolId, 5.00m);
            await AddSymbolToPortfolioWithAvgPrice(testUser2, fbStock.SymbolId, 10.00m);

            // Add Symbols Users 3
            await AddSymbolToPortfolioWithAvgPrice(testUser3, jpmStock.SymbolId, 180.88m);
            await AddSymbolToPortfolioWithAvgPrice(testUser3, fbStock.SymbolId, 400.00m);
            await AddSymbolToPortfolioWithAvgPrice(testUser3, tslaStock.SymbolId, 1000m);
            await AddSymbolToPortfolioWithAvgPrice(testUser3, msftStock.SymbolId, 300.90m);

            var leaderBoardResponse = await _client.GetAsync(ApiPath.LeaderBoard(3));

            LeaderBoardViewModel leaderBoardViewModel = await leaderBoardResponse.Content.ReadAsAsync <LeaderBoardViewModel>();

            // Verify calculations
            BoardValue bestPerformerRank1 = leaderBoardViewModel.BestPerformers.Values.ElementAt(0);
            BoardValue bestPerformerRank2 = leaderBoardViewModel.BestPerformers.Values.ElementAt(1);
            BoardValue bestPerformerRank3 = leaderBoardViewModel.BestPerformers.Values.ElementAt(2);

            Assert.Equal(3, leaderBoardViewModel.BestPerformers.Values.Count());

            Assert.Equal(testUser2.UserId, Guid.Parse(bestPerformerRank1.Id));
            Assert.Equal(testUser1.UserId, Guid.Parse(bestPerformerRank2.Id));
            Assert.Equal(testUser3.UserId, Guid.Parse(bestPerformerRank3.Id));

            Assert.Equal(testUser2.UserId, Guid.Parse(bestPerformerRank1.Name));
            Assert.Equal(testUser1.UserId, Guid.Parse(bestPerformerRank2.Name));
            Assert.Equal(testUser3.UserId, Guid.Parse(bestPerformerRank3.Name));

            Assert.Equal("3,566.65", bestPerformerRank1.Value);
            Assert.Equal("51.91", bestPerformerRank2.Value);
            Assert.Equal("-10.61", bestPerformerRank3.Value);

            BoardValue worstPerformerRank1 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(0);
            BoardValue worstPerformerRank2 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(1);
            BoardValue worstPerformerRank3 = leaderBoardViewModel.WorstPerformers.Values.ElementAt(2);

            Assert.Equal(3, leaderBoardViewModel.WorstPerformers.Values.Count());

            Assert.Equal(testUser3.UserId, Guid.Parse(worstPerformerRank1.Id));
            Assert.Equal(testUser1.UserId, Guid.Parse(worstPerformerRank2.Id));
            Assert.Equal(testUser2.UserId, Guid.Parse(worstPerformerRank3.Id));

            Assert.Equal("-10.61", worstPerformerRank1.Value);
            Assert.Equal("51.91", worstPerformerRank2.Value);
            Assert.Equal("3,566.65", worstPerformerRank3.Value);
        }
Ejemplo n.º 13
0
        public async Task GetSingleQuoteData_ShouldReturnDataFromCacheAndDB_WhenItExists()
        {
            // First call should return no data since it does not exist.
            SymbolSearchResultDTO searchResult = await SearchSymbol("TSLA", ExchangeType.NASDAQ);

            List <StockSingleQuoteDataDTO> dataDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            Assert.Single(dataDtos);

            var dataDto = dataDtos[0];

            Assert.Equal(searchResult.SymbolId, dataDto.SymbolId);
            Assert.Null(dataDto.Data);

            var startTime = DateTime.UtcNow;

            // Wait for query to execute and until there is data
            while (dataDto.Data == null)
            {
                await CheckTimeOut(startTime);

                List <StockSingleQuoteDataDTO> newData = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

                dataDto = newData[0];
            }

            AssertSingleQuote(dataDto, searchResult.SymbolId);

            // Next update the LastUpdated date of the single quote data entry in the database.
            // however when this single quote data is fetched it the date should not match since
            // the database is updated but not cache, which is where it will be fetched from.
            var modifiedDate = new DateTime(2000, 1, 1);;
            await _dbFixture.Connection.ExecuteAsync($"UPDATE SingleQuoteData SET LastUpdated = '{modifiedDate}'");

            var cacheDataDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            Assert.Single(cacheDataDtos);

            var cacheDataDto = cacheDataDtos[0];

            AssertSingleQuote(cacheDataDto, searchResult.SymbolId);
            Assert.NotEqual(cacheDataDto.LastUpdated.Value.ToString("yyyy-mm-dd"), modifiedDate.ToString("yyyy-mm-dd"));

            // Restarting server will clear cache so we should get the updated DB value.
            await RestartServer();

            var dbDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            Assert.Single(dataDtos);

            var dbDto = dbDtos[0];

            AssertSingleQuote(dbDto, searchResult.SymbolId);

            Assert.Equal(dbDto.LastUpdated.Value.ToString("yyyy-mm-dd"), modifiedDate.ToString("yyyy-mm-dd"));

            // Update the DB entry again. Getting the data should get the cache version so it will be unaffected.
            await _dbFixture.Connection.ExecuteAsync($"UPDATE SingleQuoteData SET LastUpdated = '2001-01-01'");

            var secondCachedDtos = await GetSingleQuoteData(new int[] { searchResult.SymbolId });

            var secondCachedDto = secondCachedDtos[0];

            Assert.Equal(dbDto.LastUpdated, secondCachedDto.LastUpdated);
        }
Ejemplo n.º 14
0
        public async Task Should_ReorderPortfolioSymbols()
        {
            var payload = new { name = "" }.ToJsonPayload();

            // Create Portfolio
            var createPortfolioResponse = await _client.PostAsync(ApiPath.Portfolio(), payload);

            createPortfolioResponse.EnsureSuccessStatusCode();

            var portfolio = await createPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.True(portfolio.Id > 0);

            // Search for symbols by keyword
            SymbolSearchResultDTO tslaSymbol = await FetchSymbol("TSLA", ExchangeType.NASDAQ);

            SymbolSearchResultDTO jpmSymbol = await FetchSymbol("JPM", ExchangeType.NYSE);

            SymbolSearchResultDTO fbSymbol = await FetchSymbol("FB", ExchangeType.NASDAQ);

            SymbolSearchResultDTO msftSymbol = await FetchSymbol("MSFT", ExchangeType.NASDAQ);

            // Add symbols to Portfolio
            var addTSLAResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = tslaSymbol.SymbolId }.ToJsonPayload());

            addTSLAResponse.EnsureSuccessStatusCode();
            var tslaPortfolioSymbol = await addTSLAResponse.Content.ReadAsAsync <PortfolioSymbol>();

            var addJPMResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = jpmSymbol.SymbolId }.ToJsonPayload());

            addJPMResponse.EnsureSuccessStatusCode();
            var jpmPortfolioSymbol = await addJPMResponse.Content.ReadAsAsync <PortfolioSymbol>();

            var addFBResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = fbSymbol.SymbolId }.ToJsonPayload());

            addFBResponse.EnsureSuccessStatusCode();
            var fbPortfolioSymbol = await addFBResponse.Content.ReadAsAsync <PortfolioSymbol>();

            var addMSFTResponse = await _client.PostAsync(ApiPath.PortfolioSymbols(portfolio.Id), new { SymbolId = msftSymbol.SymbolId }.ToJsonPayload());

            addMSFTResponse.EnsureSuccessStatusCode();
            var msftPortfolioSymbol = await addMSFTResponse.Content.ReadAsAsync <PortfolioSymbol>();

            // Check starting order is as expected

            Assert.Equal(1, tslaPortfolioSymbol.SortOrder);
            Assert.Equal(2, jpmPortfolioSymbol.SortOrder);
            Assert.Equal(3, fbPortfolioSymbol.SortOrder);
            Assert.Equal(4, msftPortfolioSymbol.SortOrder);

            var newOrder = new
            {
                PortfolioSymbolIdToSortOrder = new Dictionary <int, int>
                {
                    { fbPortfolioSymbol.Id, 1 },
                    { tslaPortfolioSymbol.Id, 2 },
                    { msftPortfolioSymbol.Id, 3 },
                    { jpmPortfolioSymbol.Id, 4 },
                }
            }.ToJsonPayload();

            var reorderTSLAResponse = await _client.PatchAsync(ApiPath.PortfolioSymbolsReorder(portfolio.Id), newOrder);

            reorderTSLAResponse.EnsureSuccessStatusCode();

            var getPortfolioResponse = await _client.GetAsync(ApiPath.Portfolio(portfolio.Id));

            var fetchedPortfolio = await getPortfolioResponse.Content.ReadAsAsync <Portfolio>();

            Assert.Equal(portfolio.Id, fetchedPortfolio.Id);

            var tsla = fetchedPortfolio.PortfolioSymbols.Single(s => s.Ticker == "TSLA");
            var jpm  = fetchedPortfolio.PortfolioSymbols.Single(s => s.Ticker == "JPM");
            var fb   = fetchedPortfolio.PortfolioSymbols.Single(s => s.Ticker == "FB");
            var msft = fetchedPortfolio.PortfolioSymbols.Single(s => s.Ticker == "MSFT");

            Assert.Equal(1, fb.SortOrder);
            Assert.Equal(2, tsla.SortOrder);
            Assert.Equal(3, msft.SortOrder);
            Assert.Equal(4, jpm.SortOrder);
        }