-
-
Notifications
You must be signed in to change notification settings - Fork 545
Expand file tree
/
Copy pathProjectionsTests.cs
More file actions
131 lines (109 loc) · 4.55 KB
/
ProjectionsTests.cs
File metadata and controls
131 lines (109 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using FluentAssertions;
using IntroductionToEventSourcing.Projections.MultiStream.Tools;
using Xunit;
namespace IntroductionToEventSourcing.Projections.MultiStream;
// EVENTS
public record PaymentRecorded(
Guid PaymentId,
Guid OrderId,
decimal Amount
);
public record MerchantLimitsChecked(
Guid PaymentId,
Guid MerchantId,
bool IsWithinLimits
);
public record FraudScoreCalculated(
Guid PaymentId,
decimal Score,
bool IsAcceptable
);
public record PaymentVerificationCompleted(
Guid PaymentId,
bool IsApproved
);
// ENUMS
public enum VerificationStatus
{
Pending,
Passed,
Failed
}
public enum PaymentStatus
{
Pending,
Approved,
Rejected
}
// READ MODEL
public class PaymentVerification
{
public Guid Id { get; set; }
public PaymentStatus Status { get; set; }
}
public class ProjectionsTests
{
[Fact]
[Trait("Category", "SkipCI")]
public void MultiStreamProjection_ForPaymentVerification_ShouldSucceed()
{
var payment1Id = Guid.CreateVersion7();
var payment2Id = Guid.CreateVersion7();
var payment3Id = Guid.CreateVersion7();
var payment4Id = Guid.CreateVersion7();
var order1Id = Guid.CreateVersion7();
var order2Id = Guid.CreateVersion7();
var order3Id = Guid.CreateVersion7();
var order4Id = Guid.CreateVersion7();
var merchant1Id = Guid.CreateVersion7();
var merchant2Id = Guid.CreateVersion7();
var fraudCheck1Id = Guid.CreateVersion7();
var fraudCheck2Id = Guid.CreateVersion7();
var fraudCheck3Id = Guid.CreateVersion7();
var eventStore = new EventStore();
var database = new Database();
// TODO:
// 1. Create a PaymentVerificationProjection class that handles each event type.
// Events arrive on different streams (payment, merchant, fraud check),
// but they share PaymentId — use PaymentId as the read model key.
// 2. Register your event handlers using `eventStore.Register`.
// Payment 1: Approved — all checks pass
eventStore.Append(payment1Id, new PaymentRecorded(payment1Id, order1Id, 100m));
eventStore.Append(merchant1Id, new MerchantLimitsChecked(payment1Id, merchant1Id, true));
eventStore.Append(fraudCheck1Id, new FraudScoreCalculated(payment1Id, 0.1m, true));
eventStore.Append(payment1Id, new PaymentVerificationCompleted(payment1Id, true));
// Payment 2: Merchant rejected — exceeds merchant limits
eventStore.Append(payment2Id, new PaymentRecorded(payment2Id, order2Id, 5000m));
eventStore.Append(merchant2Id, new MerchantLimitsChecked(payment2Id, merchant2Id, false));
eventStore.Append(fraudCheck2Id, new FraudScoreCalculated(payment2Id, 0.2m, true));
eventStore.Append(payment2Id, new PaymentVerificationCompleted(payment2Id, false));
// Payment 3: Fraud rejected — high fraud score
eventStore.Append(payment3Id, new PaymentRecorded(payment3Id, order3Id, 200m));
eventStore.Append(merchant1Id, new MerchantLimitsChecked(payment3Id, merchant1Id, true));
eventStore.Append(fraudCheck3Id, new FraudScoreCalculated(payment3Id, 0.95m, false));
eventStore.Append(payment3Id, new PaymentVerificationCompleted(payment3Id, false));
// Payment 4: Pending — still awaiting fraud check and final decision
eventStore.Append(payment4Id, new PaymentRecorded(payment4Id, order4Id, 50m));
eventStore.Append(merchant1Id, new MerchantLimitsChecked(payment4Id, merchant1Id, true));
// Assert Payment 1: Approved
var payment1 = database.Get<PaymentVerification>(payment1Id)!;
payment1.Should().NotBeNull();
payment1.Id.Should().Be(payment1Id);
payment1.Status.Should().Be(PaymentStatus.Approved);
// Assert Payment 2: Merchant rejected
var payment2 = database.Get<PaymentVerification>(payment2Id)!;
payment2.Should().NotBeNull();
payment2.Id.Should().Be(payment2Id);
payment2.Status.Should().Be(PaymentStatus.Rejected);
// Assert Payment 3: Fraud rejected
var payment3 = database.Get<PaymentVerification>(payment3Id)!;
payment3.Should().NotBeNull();
payment3.Id.Should().Be(payment3Id);
payment3.Status.Should().Be(PaymentStatus.Rejected);
// Assert Payment 4: Pending
var payment4 = database.Get<PaymentVerification>(payment4Id)!;
payment4.Should().NotBeNull();
payment4.Id.Should().Be(payment4Id);
payment4.Status.Should().Be(PaymentStatus.Pending);
}
}