示例#1
0
            public void Return_Valid_CacheKey()
            {
                string account  = "51671327713";
                string expected = $"account_{account}";

                string actual = CacheKeyHelper.GetAccountCacheKey(account);

                Assert.Equal(expected, actual);
            }
示例#2
0
 public void ThrowArgumentNullException()
 {
     Assert.Throws <ArgumentNullException>(() => CacheKeyHelper.GetAccountCacheKey(null));
 }
示例#3
0
 public void ThrowArgumentException_If_EmptyOrWhiteSpace(string account)
 {
     Assert.Throws <ArgumentException>(() => CacheKeyHelper.GetAccountCacheKey(account));
 }
        public async Task <ElronAccountModel> Handle(ElronAccountQuery request, CancellationToken cancellationToken)
        {
            var accountData = await _memoryCache.GetOrCreateAsync(CacheKeyHelper.GetAccountCacheKey(request.Id), async entry =>
            {
                // cache the account object for 15minutes
                entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15);

                var message = new HttpRequestMessage(HttpMethod.Get, $"/Account/Login?cardNumber={request.Id}&ReturnUrl=%2fAccount%2fStatement%3fallTransactions%3dTrue");
                var result  = await _httpClient.SendAsync(message, cancellationToken);

                result.EnsureSuccessStatusCode();

                var parser  = new HtmlParser();
                var content = parser.Parse(await result.Content.ReadAsStringAsync()).QuerySelector(".content");

                var balanceNode = content.QuerySelector("fieldset input.currency");
                if (balanceNode == null)
                {
                    throw new ScrapeException("Failed to find balance node.");
                }

                if (!decimal.TryParse(balanceNode.Attributes["value"].Value.Replace(",", "."), NumberStyles.Number, CultureInfo.InvariantCulture, out decimal balance))
                {
                    throw new ScrapeException("Failed to parse balance.");
                }

                var account = new ElronAccountModel {
                    Id = request.Id, Balance = balance, LastCheck = DateTime.Now
                };

                var transactionsTableNode = content.QuerySelector("table > tbody");
                if (transactionsTableNode == null)
                {
                    return(account);
                }

                var tableRows = transactionsTableNode.QuerySelectorAll("tr");

                foreach (var tableRow in tableRows)
                {
                    var transaction = new ElronAccountModel.Transaction();

                    var columns = tableRow.QuerySelectorAll("td");

                    var dateNode = columns[0];
                    var nameNode = columns[2];
                    var sumNode  = columns[3].QuerySelector("span");

                    transaction.Date = DateTime.ParseExact(dateNode.TextContent.Trim(), "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
                    transaction.Sum  = decimal.Parse(sumNode.TextContent.Replace(",", ".").Trim(), NumberStyles.Number, CultureInfo.InvariantCulture);

                    // This needs a better solution
                    transaction.Name = nameNode.TextContent.Trim().Split('\t')[0].Trim();

                    var ticketNode = columns[1].QuerySelector("a");
                    if (ticketNode == null)
                    {
                        goto AddTransaction;
                    }

                    string tickerNodeHref = ticketNode.Attributes["href"].Value;

                    var ticketGuid = Guid.Parse(tickerNodeHref.Substring(tickerNodeHref.Length - 36));

                    var ticket = new ElronAccountModel.Ticket()
                    {
                        Id     = ticketGuid,
                        Number = ticketNode.TextContent.Trim(),
                        Url    = new Uri(_httpClient.BaseAddress, tickerNodeHref).AbsoluteUri
                    };

                    transaction.Ticket = ticket;

                    var validityNode = nameNode.QuerySelector("div.validity");
                    if (validityNode == null)
                    {
                        goto AddTransaction;
                    }

                    string validityString = validityNode.TextContent.Trim().Substring(10);
                    var dateStrings       = validityString.Split('-').Select(d => d.Trim()).ToArray();

                    var validFrom = DateTime.ParseExact(dateStrings[0], "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
                    var validTo   = DateTime.ParseExact(dateStrings[1], "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);

                    var periodTicket = new ElronAccountModel.PeriodTicket()
                    {
                        ValidFrom = validFrom,
                        ValidTo   = validTo
                    };

                    transaction.PeriodTicket = periodTicket;

AddTransaction:
                    account.Transactions.Add(transaction);
                }

                return(account);
            });

            return(SortAccountTransactions(accountData));
        }