Skip to content

Commit 19141e4

Browse files
committed
Move specific migration tests into own classes, test photo subject migration
1 parent 2504ec1 commit 19141e4

3 files changed

Lines changed: 255 additions & 64 deletions

File tree

RefreshTests.GameServer/Tests/Workers/MigrationTests.cs

Lines changed: 9 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using Refresh.Database.Models.Authentication;
22
using Refresh.Database.Models.Levels;
3-
using Refresh.Database.Models.Pins;
43
using Refresh.Database.Models.Users;
54
using Refresh.Database.Models.Workers;
6-
using Refresh.Interfaces.Workers.Migrations;
75
using Refresh.Workers.State;
86

97
namespace RefreshTests.GameServer.Tests.Workers;
@@ -32,68 +30,6 @@ public void MigrationJobWorks()
3230
Assert.That(allLevels.All(l => l.Title == "Level test"), Is.True);
3331
}
3432

35-
[Test]
36-
public void WebsitePinMigrationDoesNotBreakPagination()
37-
{
38-
using TestContext context = this.GetServer();
39-
40-
for (int i = 0; i < 50; i++)
41-
{
42-
GameUser user = context.CreateUser();
43-
context.Database.AddPinProgress(new()
44-
{
45-
PinId = (long)ServerPins.SignIntoWebsite,
46-
Progress = i + 1,
47-
Publisher = user,
48-
FirstPublished = new(),
49-
LastUpdated = new(),
50-
IsBeta = false,
51-
Platform = TokenPlatform.RPCS3,
52-
}, false);
53-
54-
context.Database.AddPinProgress(new()
55-
{
56-
PinId = (long)ServerPins.SignIntoWebsite,
57-
Progress = i + 1,
58-
Publisher = user,
59-
FirstPublished = new(),
60-
LastUpdated = new(),
61-
IsBeta = true,
62-
Platform = TokenPlatform.RPCS3,
63-
}, false);
64-
}
65-
context.Database.SaveChanges();
66-
Assert.That(context.Database.GetTotalPinProgresses(), Is.EqualTo(100));
67-
68-
// Prepare migration
69-
CorrectWebsitePinProgressPlatformMigration job = new();
70-
context.Database.UpdateOrCreateJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, new MigrationJobState()
71-
{
72-
Total = 100 // Since we already have to manually create the state
73-
}, WorkerClass.Refresh);
74-
context.Database.Refresh();
75-
76-
object? stateObject = context.Database.GetJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
77-
Assert.That(stateObject, Is.Not.Null);
78-
job.JobState = stateObject!;
79-
80-
// Migrate
81-
job.ExecuteJob(context.GetWorkContext());
82-
context.Database.Refresh();
83-
84-
stateObject = context.Database.GetJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
85-
Assert.That(stateObject, Is.Not.Null);
86-
87-
// While we're not actually testing pagination here (batch count can't be edited + don't want to create over 1000 users here, would take too long),
88-
// it should be enough to simply ensure that both the total and processed counts are adjusted to be less than 100 (as 50 pins were deleted)
89-
MigrationJobState jobState = (MigrationJobState)stateObject!;
90-
Assert.That(jobState.Processed, Is.EqualTo(50));
91-
Assert.That(jobState.Total, Is.EqualTo(50));
92-
Assert.That(jobState.Complete, Is.True);
93-
94-
Assert.That(context.Database.GetTotalPinProgresses(), Is.EqualTo(50));
95-
}
96-
9733
[Test]
9834
public void DeletingEntitiesDuringMigrationJobDoesNotBreakPagination()
9935
{
@@ -128,6 +64,9 @@ public void DeletingEntitiesDuringMigrationJobDoesNotBreakPagination()
12864
Assert.That(context.Database.GetTotalLevelCount(), Is.EqualTo(15));
12965
Assert.That(context.Database.GetNewestLevels(20, 0, null, new(TokenGame.Website)).Items.Count(l => l.Title.EndsWith(" test")), Is.EqualTo(3));
13066

67+
stateObject = context.Database.GetJobState(typeof(TestMigrationJobDeletingLevels).Name, typeof(MigrationJobState), WorkerClass.Refresh);
68+
Assert.That(stateObject, Is.Not.Null);
69+
13170
MigrationJobState jobState = (MigrationJobState)stateObject!;
13271
Assert.That(jobState.Processed, Is.EqualTo(3));
13372
Assert.That(jobState.Total, Is.EqualTo(15));
@@ -141,6 +80,9 @@ public void DeletingEntitiesDuringMigrationJobDoesNotBreakPagination()
14180
Assert.That(context.Database.GetTotalLevelCount(), Is.EqualTo(12));
14281
Assert.That(context.Database.GetNewestLevels(20, 0, null, new(TokenGame.Website)).Items.Count(l => l.Title.EndsWith(" test")), Is.EqualTo(6));
14382

83+
stateObject = context.Database.GetJobState(typeof(TestMigrationJobDeletingLevels).Name, typeof(MigrationJobState), WorkerClass.Refresh);
84+
Assert.That(stateObject, Is.Not.Null);
85+
14486
jobState = (MigrationJobState)stateObject!;
14587
Assert.That(jobState.Processed, Is.EqualTo(6));
14688
Assert.That(jobState.Total, Is.EqualTo(12));
@@ -154,6 +96,9 @@ public void DeletingEntitiesDuringMigrationJobDoesNotBreakPagination()
15496
Assert.That(context.Database.GetTotalLevelCount(), Is.EqualTo(9));
15597
Assert.That(context.Database.GetNewestLevels(20, 0, null, new(TokenGame.Website)).Items.Count(l => l.Title.EndsWith(" test")), Is.EqualTo(9));
15698

99+
stateObject = context.Database.GetJobState(typeof(TestMigrationJobDeletingLevels).Name, typeof(MigrationJobState), WorkerClass.Refresh);
100+
Assert.That(stateObject, Is.Not.Null);
101+
157102
jobState = (MigrationJobState)stateObject!;
158103
Assert.That(jobState.Processed, Is.EqualTo(9));
159104
Assert.That(jobState.Total, Is.EqualTo(9));
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
using Refresh.Database.Models.Assets;
2+
using Refresh.Database.Models.Photos;
3+
using Refresh.Database.Models.Users;
4+
using Refresh.Database.Models.Workers;
5+
using Refresh.Interfaces.Workers.Migrations;
6+
using Refresh.Workers.State;
7+
8+
namespace RefreshTests.GameServer.Tests.Workers;
9+
10+
public class PhotoMigrationTests : GameServerTest
11+
{
12+
private const string TEST_ASSET_HASH = "0ec63b140374ba704a58fa0c743cb357683313dd";
13+
14+
[Test]
15+
public void MigratesPhotoSubjectsButNotMultipleTimes()
16+
{
17+
using TestContext context = this.GetServer();
18+
GameUser user = context.CreateUser();
19+
context.Database.AddAssetToDatabase(new()
20+
{
21+
AssetHash = TEST_ASSET_HASH,
22+
AssetType = GameAssetType.Png,
23+
AssetFormat = GameAssetFormat.Unknown,
24+
OriginalUploader = user,
25+
UploadDate = new(new DateTime(2026, 3, 11), TimeSpan.Zero),
26+
});
27+
28+
for (int i = 0; i < 10; i++)
29+
{
30+
context.Database.Add(new GamePhoto()
31+
{
32+
TakenAt = new(new DateTime(2026, 3, 18), TimeSpan.Zero),
33+
PublishedAt = new(new DateTime(2026, 3, 18), TimeSpan.Zero),
34+
PublisherId = user.UserId,
35+
SmallAssetHash = TEST_ASSET_HASH,
36+
MediumAssetHash = TEST_ASSET_HASH,
37+
LargeAssetHash = TEST_ASSET_HASH,
38+
PlanHash = "plan",
39+
LevelType = "pod",
40+
OriginalLevelId = 0,
41+
OriginalLevelName = "",
42+
43+
#pragma warning disable CS0618 // obsoletion
44+
Subject1DisplayName = "p",
45+
Subject1Bounds = [3,1,4,1],
46+
Subject2DisplayName = "i",
47+
Subject2Bounds = [5,9,2,7],
48+
#pragma warning restore CS0618
49+
});
50+
}
51+
52+
context.Database.SaveChanges();
53+
Assert.That(context.Database.GetTotalPhotoCount(), Is.EqualTo(10));
54+
55+
MoveSubjectsOutOfGamePhotosMigration job = new();
56+
context.Database.UpdateOrCreateJobState(typeof(MoveSubjectsOutOfGamePhotosMigration).Name, new MigrationJobState()
57+
{
58+
Total = 10
59+
}, WorkerClass.Refresh);
60+
context.Database.Refresh();
61+
62+
object? stateObject = context.Database.GetJobState(typeof(MoveSubjectsOutOfGamePhotosMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
63+
Assert.That(stateObject, Is.Not.Null);
64+
job.JobState = stateObject!;
65+
66+
// Migrate - First cycle
67+
job.ExecuteJob(context.GetWorkContext());
68+
context.Database.Refresh();
69+
70+
Assert.That(context.Database.GetTotalPhotoCount(), Is.EqualTo(10));
71+
foreach(GamePhoto photo in context.Database.GetRecentPhotos(10, 0).Items.ToArray())
72+
{
73+
Assert.That(photo.Subjects.Count, Is.EqualTo(2));
74+
Assert.That(context.Database.GetTotalSubjectsInPhoto(photo), Is.EqualTo(2));
75+
76+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "p"), Is.EqualTo(1));
77+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "i"), Is.EqualTo(1));
78+
79+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 1), Is.EqualTo(1));
80+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 2), Is.EqualTo(1));
81+
}
82+
83+
stateObject = context.Database.GetJobState(typeof(MoveSubjectsOutOfGamePhotosMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
84+
Assert.That(stateObject, Is.Not.Null);
85+
86+
MigrationJobState jobState = (MigrationJobState)stateObject!;
87+
Assert.That(jobState.Processed, Is.EqualTo(10));
88+
Assert.That(jobState.Total, Is.EqualTo(10));
89+
Assert.That(jobState.Complete, Is.True);
90+
91+
// Add new, unmigrated photos
92+
for (int i = 0; i < 5; i++)
93+
{
94+
context.Database.Add(new GamePhoto()
95+
{
96+
TakenAt = new(new DateTime(2026, 3, 27), TimeSpan.Zero),
97+
PublishedAt = new(new DateTime(2026, 3, 27), TimeSpan.Zero),
98+
PublisherId = user.UserId,
99+
SmallAssetHash = TEST_ASSET_HASH,
100+
MediumAssetHash = TEST_ASSET_HASH,
101+
LargeAssetHash = TEST_ASSET_HASH,
102+
PlanHash = "plan",
103+
LevelType = "pod",
104+
OriginalLevelId = 0,
105+
OriginalLevelName = "",
106+
107+
#pragma warning disable CS0618 // obsoletion
108+
Subject1DisplayName = "d",
109+
Subject1Bounds = [1,2,3,4],
110+
Subject2DisplayName = "a",
111+
Subject2Bounds = [1,2,3,4],
112+
Subject3DisplayName = "n",
113+
Subject3Bounds = [1,2,3,4],
114+
Subject4DisplayName = "k",
115+
Subject4Bounds = [1,2,3,4],
116+
#pragma warning restore CS0618
117+
});
118+
}
119+
context.Database.SaveChanges();
120+
Assert.That(context.Database.GetTotalPhotoCount(), Is.EqualTo(15));
121+
context.Database.Refresh();
122+
123+
// Reset state, to test both the migrated photos not having their subjects re-migrated (should be skipped entirely due to SortAndFilter()),
124+
// and to also test the new photos being migrated
125+
jobState.Total = 5;
126+
jobState.Processed = 0;
127+
job.JobState = jobState;
128+
context.Database.UpdateOrCreateJobState(typeof(MoveSubjectsOutOfGamePhotosMigration).Name, jobState, WorkerClass.Refresh);
129+
context.Database.Refresh();
130+
131+
// Migrate - Second cycle
132+
job.ExecuteJob(context.GetWorkContext());
133+
context.Database.Refresh();
134+
135+
Assert.That(context.Database.GetTotalPhotoCount(), Is.EqualTo(15));
136+
foreach(GamePhoto photo in context.Database.GetRecentPhotos(10, 5).Items.ToArray())
137+
{
138+
// The photos from the first cycle still only have 2 subjects each
139+
Assert.That(photo.Subjects.Count, Is.EqualTo(2));
140+
Assert.That(context.Database.GetTotalSubjectsInPhoto(photo), Is.EqualTo(2));
141+
142+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "p"), Is.EqualTo(1));
143+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "i"), Is.EqualTo(1));
144+
145+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 1), Is.EqualTo(1));
146+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 2), Is.EqualTo(1));
147+
}
148+
149+
foreach(GamePhoto photo in context.Database.GetRecentPhotos(5, 0).Items.ToArray())
150+
{
151+
Assert.That(photo.Subjects.Count, Is.EqualTo(4));
152+
Assert.That(context.Database.GetTotalSubjectsInPhoto(photo), Is.EqualTo(4));
153+
154+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "d"), Is.EqualTo(1));
155+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "a"), Is.EqualTo(1));
156+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "n"), Is.EqualTo(1));
157+
Assert.That(photo.Subjects.Count(s => s.DisplayName == "k"), Is.EqualTo(1));
158+
159+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 1), Is.EqualTo(1));
160+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 2), Is.EqualTo(1));
161+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 3), Is.EqualTo(1));
162+
Assert.That(photo.Subjects.Count(s => s.PlayerId == 4), Is.EqualTo(1));
163+
}
164+
165+
stateObject = context.Database.GetJobState(typeof(MoveSubjectsOutOfGamePhotosMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
166+
Assert.That(stateObject, Is.Not.Null);
167+
168+
jobState = (MigrationJobState)stateObject!;
169+
Assert.That(jobState.Processed, Is.EqualTo(5));
170+
Assert.That(jobState.Total, Is.EqualTo(5));
171+
Assert.That(jobState.Complete, Is.True);
172+
}
173+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using Refresh.Database.Models.Authentication;
2+
using Refresh.Database.Models.Pins;
3+
using Refresh.Database.Models.Users;
4+
using Refresh.Database.Models.Workers;
5+
using Refresh.Interfaces.Workers.Migrations;
6+
using Refresh.Workers.State;
7+
8+
namespace RefreshTests.GameServer.Tests.Workers;
9+
10+
public class PinMigrationTests : GameServerTest
11+
{
12+
[Test]
13+
public void WebsitePinMigrationDoesNotBreakPagination()
14+
{
15+
using TestContext context = this.GetServer();
16+
17+
for (int i = 0; i < 50; i++)
18+
{
19+
GameUser user = context.CreateUser();
20+
context.Database.AddPinProgress(new()
21+
{
22+
PinId = (long)ServerPins.SignIntoWebsite,
23+
Progress = i + 1,
24+
Publisher = user,
25+
FirstPublished = new(),
26+
LastUpdated = new(),
27+
IsBeta = false,
28+
Platform = TokenPlatform.RPCS3,
29+
}, false);
30+
31+
context.Database.AddPinProgress(new()
32+
{
33+
PinId = (long)ServerPins.SignIntoWebsite,
34+
Progress = i + 1,
35+
Publisher = user,
36+
FirstPublished = new(),
37+
LastUpdated = new(),
38+
IsBeta = true,
39+
Platform = TokenPlatform.RPCS3,
40+
}, false);
41+
}
42+
context.Database.SaveChanges();
43+
Assert.That(context.Database.GetTotalPinProgresses(), Is.EqualTo(100));
44+
45+
// Prepare migration
46+
CorrectWebsitePinProgressPlatformMigration job = new();
47+
context.Database.UpdateOrCreateJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, new MigrationJobState()
48+
{
49+
Total = 100 // Since we already have to manually create the state
50+
}, WorkerClass.Refresh);
51+
context.Database.Refresh();
52+
53+
object? stateObject = context.Database.GetJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
54+
Assert.That(stateObject, Is.Not.Null);
55+
job.JobState = stateObject!;
56+
57+
// Migrate
58+
job.ExecuteJob(context.GetWorkContext());
59+
context.Database.Refresh();
60+
61+
stateObject = context.Database.GetJobState(typeof(CorrectWebsitePinProgressPlatformMigration).Name, typeof(MigrationJobState), WorkerClass.Refresh);
62+
Assert.That(stateObject, Is.Not.Null);
63+
64+
// While we're not actually testing pagination here (batch count can't be edited + don't want to create over 1000 users here, would take too long),
65+
// it should be enough to simply ensure that both the total and processed counts are adjusted to be less than 100 (as 50 pins were deleted)
66+
MigrationJobState jobState = (MigrationJobState)stateObject!;
67+
Assert.That(jobState.Processed, Is.EqualTo(50));
68+
Assert.That(jobState.Total, Is.EqualTo(50));
69+
Assert.That(jobState.Complete, Is.True);
70+
71+
Assert.That(context.Database.GetTotalPinProgresses(), Is.EqualTo(50));
72+
}
73+
}

0 commit comments

Comments
 (0)