forked from aneshas/tactical-ddd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgresEventStoreTests.cs
148 lines (123 loc) · 4.76 KB
/
PostgresEventStoreTests.cs
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Dapper;
using FluentAssertions;
using Npgsql;
using Tactical.DDD.EventSourcing.Postgres;
using Xunit;
namespace Tactical.DDD.EventSourcing.Integration.Tests
{
public class PostgresEventStoreTests : IntegrationTest
{
[Fact]
public async Task ShouldLoadSavedEventsPerAggregate()
{
var aggregateAId = new FooId();
var aggregateAEvents = new List<DomainEvent>
{
new FooEvent(1, DateTime.Now),
new FooEvent(2, DateTime.Now),
new FooEvent(3, DateTime.Now)
};
var aggregateBId = new FooId();
var aggregateBEvents = new List<DomainEvent>
{
new FooEvent(4, DateTime.Now),
new FooEvent(5, DateTime.Now),
new FooEvent(6, DateTime.Now)
};
var meta = new Dictionary<string, string>
{
{"foo", "bar"},
{"client-ip", "127.0.0.1"}
};
await EventStore.SaveEventsAsync(
nameof(FooAggregate), aggregateAId, 0, aggregateAEvents, meta);
await EventStore.SaveEventsAsync(
nameof(FooAggregate), aggregateBId, 0, aggregateBEvents, meta);
var events = await EventStore.LoadEventsAsync(aggregateAId);
Action<Event> AssertEvent(int version, int value) =>
@event =>
{
@event.Id.Should().Be((uint) value);
@event.StreamId.Should().Be(aggregateAId);
@event.StreamVersion.Should().Be(version);
@event.StreamName.Should().Be(nameof(FooAggregate));
@event.Meta.Should().BeEquivalentTo(meta);
var domainEvent = @event.DomainEvent as FooEvent;
Assert.NotNull(domainEvent);
domainEvent.Value.Should().Be(value);
};
events
.Should()
.SatisfyRespectively(
AssertEvent(1, 1),
AssertEvent(2, 2),
AssertEvent(3, 3)
);
}
[Fact]
public async Task ShouldThrowNotFoundException() =>
await Assert.ThrowsAsync<AggregateNotFoundException>(() =>
EventStore.LoadEventsAsync(new FooId()));
[Fact]
public async Task ShouldThrowConcurrencyCheckException()
{
var fooId = new FooId();
var events = new List<DomainEvent>
{
new FooEvent(1, DateTime.Now),
new FooEvent(2, DateTime.Now),
new FooEvent(3, DateTime.Now)
};
await EventStore.SaveEventsAsync(
nameof(FooAggregate), fooId, 0, events, new Dictionary<string, string>());
await Assert.ThrowsAsync<EventStoreConcurrencyCheckException>(() =>
EventStore.SaveEventsAsync(
nameof(FooAggregate), fooId, 0, events, new Dictionary<string, string>()));
}
[Fact]
public async Task ShouldLoadEventsFromOffset()
{
var fooId = new FooId();
var events = new List<DomainEvent>
{
new FooEvent(1, DateTime.Now),
new FooEvent(2, DateTime.Now),
new FooEvent(3, DateTime.Now),
new FooEvent(4, DateTime.Now),
new FooEvent(5, DateTime.Now)
};
await EventStore.SaveEventsAsync(
nameof(FooAggregate), fooId, 0, events, new Dictionary<string, string>());
var loadedEvents = await EventStore.LoadEventsAsync(typeof(FooAggregate), 2, 2);
loadedEvents
.Should()
.SatisfyRespectively(
@event =>
{
@event.Offset.Should().Be(3);
var e = @event.Event as FooEvent;
e.Value.Should().Be(3);
e.CreatedAt.Should().BeSameDateAs(DateTime.Today);
},
@event =>
{
@event.Offset.Should().Be(4);
var e = @event.Event as FooEvent;
e.Value.Should().Be(4);
e.CreatedAt.Should().BeSameDateAs(DateTime.Today);
}
);
}
[Fact]
public async Task NoResultsShouldYieldAnEmptyEnumerable()
{
var events = await EventStore.LoadEventsAsync(typeof(FooAggregate), 0, 100);
events
.Should()
.BeEmpty();
}
}
}