-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDataModelReferenceTests.cs
More file actions
153 lines (131 loc) · 5.48 KB
/
DataModelReferenceTests.cs
File metadata and controls
153 lines (131 loc) · 5.48 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using Microsoft.EntityFrameworkCore;
using SIL.Harmony.Changes;
using SIL.Harmony.Sample.Changes;
using SIL.Harmony.Sample.Models;
using SIL.Harmony.Tests;
namespace Tests;
public class DataModelReferenceTests : DataModelTestBase
{
private readonly Guid _word1Id = Guid.NewGuid();
private readonly Guid _word2Id = Guid.NewGuid();
public override async Task InitializeAsync()
{
await base.InitializeAsync();
await WriteNextChange(SetWord(_word1Id, "entity1"));
await WriteNextChange(SetWord(_word2Id, "entity2"));
}
[Fact]
public async Task DeleteAfterTheFactRewritesReferences()
{
var addRef = await WriteNextChange(new AddAntonymReferenceChange(_word1Id, _word2Id));
var entryWithRef = await DataModel.GetLatest<Word>(_word1Id);
entryWithRef!.AntonymId.Should().Be(_word2Id);
await WriteChangeBefore(addRef, new DeleteChange<Word>(_word2Id));
var entryWithoutRef = await DataModel.GetLatest<Word>(_word1Id);
entryWithoutRef!.AntonymId.Should().BeNull();
}
[Fact]
public async Task DeleteRemovesAllReferences()
{
await WriteNextChange(new AddAntonymReferenceChange(_word1Id, _word2Id));
var entryWithRef = await DataModel.GetLatest<Word>(_word1Id);
entryWithRef!.AntonymId.Should().Be(_word2Id);
await WriteNextChange(new DeleteChange<Word>(_word2Id));
var entryWithoutRef = await DataModel.GetLatest<Word>(_word1Id);
entryWithoutRef!.AntonymId.Should().BeNull();
}
[Fact]
public async Task SnapshotsDontGetMutatedByADelete()
{
var refAdd = await WriteNextChange(new AddAntonymReferenceChange(_word1Id, _word2Id));
await WriteNextChange(new DeleteChange<Word>(_word2Id));
var word = await DataModel.GetAtCommit<Word>(refAdd.Id, _word1Id);
word.Should().NotBeNull();
word.AntonymId.Should().Be(_word2Id);
}
[Fact]
public async Task DeleteRetroactivelyRemovesRefs()
{
var entityId3 = Guid.NewGuid();
await WriteNextChange(SetWord(entityId3, "entity3"));
await WriteNextChange(new AddAntonymReferenceChange(_word1Id, _word2Id));
var delete = await WriteNextChange(new DeleteChange<Word>(_word2Id));
//a ref was synced in the past, it happened before the delete, the reference should be retroactively removed
await WriteChangeBefore(delete, new AddAntonymReferenceChange(entityId3, _word2Id));
var entry = await DataModel.GetLatest<Word>(entityId3);
entry!.AntonymId.Should().BeNull();
}
[Fact]
public async Task DeleteDoesNotEffectARootSnapshotCreatedBeforeTheDelete()
{
var wordId = Guid.NewGuid();
var initialWordCommit = await WriteNextChange(new NewWordChange(wordId, "entity1", antonymId: _word1Id), add: false);
var deleteWordCommit = await WriteNextChange(DeleteWord(_word1Id), add: false);
await AddCommitsViaSync([
initialWordCommit,
deleteWordCommit
]);
var snapshot = await DbContext.Snapshots.SingleAsync(s => s.CommitId == initialWordCommit.Id);
var initialWord = (Word) snapshot.Entity;
initialWord.AntonymId.Should().Be(_word1Id);
snapshot = await DbContext.Snapshots.SingleAsync(s => s.CommitId == deleteWordCommit.Id && s.EntityId == wordId);
var wordWithoutRef = (Word) snapshot.Entity;
wordWithoutRef.AntonymId.Should().BeNull();
}
[Fact]
public async Task AddAndDeleteInSameCommitDeletesRefs()
{
var wordId = Guid.NewGuid();
var definitionId = Guid.NewGuid();
await WriteNextChange(
[
SetWord(wordId, "original"),
NewDefinition(wordId, "the shiny one everything started with", "adj", 0, definitionId),
new DeleteChange<Word>(wordId),
]);
var def = await DataModel.GetLatest<Definition>(definitionId);
def.Should().NotBeNull();
def.DeletedAt.Should().NotBeNull();
}
[Fact]
public async Task UpdateAndDeleteParentInSameCommitWorks()
{
var wordId = Guid.NewGuid();
var definitionId = Guid.NewGuid();
await WriteNextChange(
[
SetWord(wordId, "original"),
NewDefinition(wordId, "the shiny one everything started with", "adj", 0, definitionId),
]);
await WriteNextChange(
[
new SetDefinitionPartOfSpeechChange(definitionId, "pos2"),
new DeleteChange<Word>(wordId),
]);
var def = await DataModel.GetLatest<Definition>(definitionId);
def.Should().NotBeNull();
def.PartOfSpeech.Should().Be("pos2");
def.DeletedAt.Should().NotBeNull();
}
[Fact]
public async Task AddAndDeleteInSameSyncDeletesRefs()
{
var wordId = Guid.NewGuid();
var definitionId = Guid.NewGuid();
var initialCommit = await WriteNextChange(
[
SetWord(wordId, "original"),
NewDefinition(wordId, "the shiny one everything started with", "adj", 0, definitionId),
], add: false);
var deleteCommit = await WriteNextChange(
new DeleteChange<Word>(wordId),
add: false);
await AddCommitsViaSync([
initialCommit,
deleteCommit
]);
var def = await DataModel.GetLatest<Definition>(definitionId);
def.Should().NotBeNull();
def.DeletedAt.Should().NotBeNull();
}
}