Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

100 lines
3.7KB

  1. using CartWise.Application.Services;
  2. using CartWise.Domain.Enums;
  3. using CartWise.Infrastructure.Data;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace CartWise.Application.Tests;
  6. public class PriceServiceTests : IDisposable
  7. {
  8. private static readonly DateTime Now = new(2026, 8, 10, 12, 0, 0, DateTimeKind.Utc);
  9. private readonly CartWiseDbContext _db;
  10. private readonly PriceService _sut;
  11. public PriceServiceTests()
  12. {
  13. var options = new DbContextOptionsBuilder<CartWiseDbContext>()
  14. .UseInMemoryDatabase(Guid.NewGuid().ToString())
  15. .Options;
  16. _db = new CartWiseDbContext(options);
  17. _sut = new PriceService(_db, TimeProvider.System);
  18. }
  19. public void Dispose()
  20. {
  21. _db.Dispose();
  22. GC.SuppressFinalize(this);
  23. }
  24. [Fact]
  25. public async Task GetHouseholdPriceInsightAsync_ReturnsNullWhenNoObservationsExist()
  26. {
  27. var insight = await _sut.GetHouseholdPriceInsightAsync(Guid.NewGuid(), Guid.NewGuid());
  28. Assert.Null(insight);
  29. }
  30. [Fact]
  31. public async Task RecordObservationAsync_ThenGetInsight_ReturnsLatestAverageMedianAndLowest()
  32. {
  33. var householdId = Guid.NewGuid();
  34. var productId = Guid.NewGuid();
  35. await _sut.RecordObservationAsync(productId, 3.00m, Now.AddDays(-2), PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  36. await _sut.RecordObservationAsync(productId, 5.00m, Now.AddDays(-1), PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  37. await _sut.RecordObservationAsync(productId, 4.00m, Now, PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  38. var insight = await _sut.GetHouseholdPriceInsightAsync(householdId, productId);
  39. Assert.NotNull(insight);
  40. Assert.Equal(3, insight!.ObservationCount);
  41. Assert.Equal(4.00m, insight.LatestPrice);
  42. Assert.Equal(Now, insight.LatestObservedUtc);
  43. Assert.Equal(4.00m, insight.AveragePrice);
  44. Assert.Equal(4.00m, insight.MedianPrice);
  45. Assert.Equal(3.00m, insight.LowestPrice);
  46. }
  47. [Fact]
  48. public async Task GetHouseholdPriceInsightAsync_ComputesMedianForEvenCount()
  49. {
  50. var householdId = Guid.NewGuid();
  51. var productId = Guid.NewGuid();
  52. await _sut.RecordObservationAsync(productId, 2.00m, Now.AddDays(-1), PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  53. await _sut.RecordObservationAsync(productId, 4.00m, Now, PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  54. var insight = await _sut.GetHouseholdPriceInsightAsync(householdId, productId);
  55. Assert.Equal(3.00m, insight!.MedianPrice);
  56. }
  57. [Fact]
  58. public async Task GetHouseholdPriceInsightAsync_DoesNotMixDifferentHouseholds()
  59. {
  60. var productId = Guid.NewGuid();
  61. await _sut.RecordObservationAsync(productId, 3.00m, Now, PriceObservationSourceType.UserEntered, 1m, householdId: Guid.NewGuid());
  62. var insight = await _sut.GetHouseholdPriceInsightAsync(Guid.NewGuid(), productId);
  63. Assert.Null(insight);
  64. }
  65. [Fact]
  66. public async Task GetHouseholdPriceHistoryAsync_ReturnsNewestFirst()
  67. {
  68. var householdId = Guid.NewGuid();
  69. var productId = Guid.NewGuid();
  70. await _sut.RecordObservationAsync(productId, 3.00m, Now.AddDays(-1), PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  71. await _sut.RecordObservationAsync(productId, 4.00m, Now, PriceObservationSourceType.UserEntered, 1m, householdId: householdId);
  72. var history = await _sut.GetHouseholdPriceHistoryAsync(householdId, productId);
  73. Assert.Equal(2, history.Count);
  74. Assert.Equal(4.00m, history[0].Price);
  75. Assert.Equal(3.00m, history[1].Price);
  76. }
  77. }

Powered by TurnKey Linux.