Migrate to SQLite EF provider for testing (#966)

* Migrate to Sqlite EF provider for testing

* Fix failing unit test
This commit is contained in:
Josh 2024-01-17 19:03:07 -06:00 committed by GitHub
parent 25eaae1542
commit c529dada35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 115 additions and 142 deletions

View file

@ -94,7 +94,7 @@ public class CommentControllerTests
Type = SlotType.User, Type = SlotType.User,
}, },
}; };
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[]{slots,}); await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(slots);
CommentController commentController = new(dbMock); CommentController commentController = new(dbMock);
commentController.SetupTestController("<comment><message>test</message></comment>"); commentController.SetupTestController("<comment><message>test</message></comment>");
@ -122,7 +122,7 @@ public class CommentControllerTests
Type = SlotType.Developer, Type = SlotType.Developer,
}, },
}; };
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[] { slots, }); await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(slots);
CommentController commentController = new(dbMock); CommentController commentController = new(dbMock);
commentController.SetupTestController("<comment><message>test</message></comment>"); commentController.SetupTestController("<comment><message>test</message></comment>");

View file

@ -205,7 +205,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>." + "\nuni
{ {
List<UserEntity> users = new() List<UserEntity> users = new()
{ {
MockHelper.GetUnitTestUser(),
new UserEntity new UserEntity
{ {
UserId = 2, UserId = 2,
@ -259,10 +258,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>." + "\nuni
{ {
UserEntity unitTestUser = MockHelper.GetUnitTestUser(); UserEntity unitTestUser = MockHelper.GetUnitTestUser();
unitTestUser.EmailAddressVerified = true; unitTestUser.EmailAddressVerified = true;
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new List<UserEntity> await using DatabaseContext dbMock = await MockHelper.GetTestDatabase();
{
unitTestUser,
});
Mock<IMailService> mailMock = getMailServiceMock(); Mock<IMailService> mailMock = getMailServiceMock();

View file

@ -1,5 +1,5 @@
using System.Collections; using System.Collections.Generic;
using System.Collections.Generic; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
@ -57,26 +57,29 @@ public class SlotControllerTests
}; };
List<UserEntity> users = new() List<UserEntity> users = new()
{ {
MockHelper.GetUnitTestUser(),
new UserEntity new UserEntity
{ {
Username = "bytest", Username = "bytest",
UserId = 2, UserId = 2,
}, },
new UserEntity
{
Username = "user3",
UserId = 3,
},
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new IList[] DatabaseContext db = await MockHelper.GetTestDatabase(slots, users);
{
slots, users,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
IActionResult result = await slotsController.SlotsBy("bytest"); IActionResult result = await slotsController.SlotsBy("bytest");
const int expectedElements = 2; const int expectedElements = 2;
HashSet<int> expectedSlotIds = new(){1, 2,};
GenericSlotResponse slotResponse = result.CastTo<OkObjectResult, GenericSlotResponse>(); GenericSlotResponse slotResponse = result.CastTo<OkObjectResult, GenericSlotResponse>();
Assert.Equal(expectedElements, slotResponse.Slots.Count); Assert.Equal(expectedElements, slotResponse.Slots.Count);
Assert.Equal(expectedSlotIds, slotResponse.Slots.OfType<GameUserSlot>().Select(s => s.SlotId).ToHashSet());
} }
[Fact] [Fact]
@ -105,17 +108,13 @@ public class SlotControllerTests
}; };
List<UserEntity> users = new() List<UserEntity> users = new()
{ {
MockHelper.GetUnitTestUser(),
new UserEntity new UserEntity
{ {
Username = "bytest", Username = "bytest",
UserId = 2, UserId = 2,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new IList[] DatabaseContext db = await MockHelper.GetTestDatabase(slots, users);
{
slots, users,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -143,13 +142,11 @@ public class SlotControllerTests
{ {
new SlotEntity new SlotEntity
{ {
CreatorId = 1,
SlotId = 2, SlotId = 2,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -165,14 +162,12 @@ public class SlotControllerTests
{ {
new SlotEntity new SlotEntity
{ {
CreatorId = 1,
SlotId = 2, SlotId = 2,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -195,13 +190,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanetVita, GameVersion = GameVersion.LittleBigPlanetVita,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new IList[] DatabaseContext db = await MockHelper.GetTestDatabase(slots, tokens);
{
slots, tokens,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(token); slotsController.SetupTestController(token);
@ -224,13 +217,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet1, GameVersion = GameVersion.LittleBigPlanet1,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new IList[] DatabaseContext db = await MockHelper.GetTestDatabase(slots, tokens);
{
slots, tokens,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(token); slotsController.SetupTestController(token);
@ -259,14 +250,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 27, SlotId = 27,
CreatorId = 4, CreatorId = 1,
SubLevel = false, SubLevel = false,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -283,14 +271,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 27, SlotId = 27,
CreatorId = 4, CreatorId = 1,
Hidden = true, Hidden = true,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -307,13 +292,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 27, SlotId = 27,
CreatorId = 1,
Type = SlotType.Developer, Type = SlotType.Developer,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -330,11 +313,11 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 27, SlotId = 27,
CreatorId = 4, CreatorId = 1,
SubLevel = true, SubLevel = true,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new []{slots,}); DatabaseContext db = await MockHelper.GetTestDatabase(slots);
SlotsController slotsController = new(db); SlotsController slotsController = new(db);
slotsController.SetupTestController(); slotsController.SetupTestController();
@ -353,14 +336,12 @@ public class SlotControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 1, SlotId = 1,
CreatorId = 1,
InternalSlotId = 25, InternalSlotId = 25,
Type = SlotType.Developer, Type = SlotType.Developer,
}, },
}; };
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(slots);
{
slots,
});
SlotsController controller = new(db); SlotsController controller = new(db);
controller.SetupTestController(); controller.SetupTestController();
@ -405,31 +386,32 @@ public class SlotControllerTests
roomMutex.WaitOne(); roomMutex.WaitOne();
try try
{ {
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(new List<SlotEntity>
{ {
new List<SlotEntity> new()
{ {
new() SlotId = 1,
{ CreatorId = 1,
SlotId = 1, Type = SlotType.User,
Type = SlotType.User, },
}, new()
new() {
{ SlotId = 2,
SlotId = 2, CreatorId = 1,
Type = SlotType.User, Type = SlotType.User,
}, },
new() new()
{ {
SlotId = 3, SlotId = 3,
Type = SlotType.User, CreatorId = 1,
}, Type = SlotType.User,
new() },
{ new()
SlotId = 4, {
Type = SlotType.Developer, SlotId = 4,
InternalSlotId = 10, CreatorId = 1,
}, Type = SlotType.Developer,
InternalSlotId = 10,
}, },
}); });
SlotsController controller = new(db); SlotsController controller = new(db);
@ -466,16 +448,14 @@ public class SlotControllerTests
roomMutex.WaitOne(); roomMutex.WaitOne();
try try
{ {
DatabaseContext db = await MockHelper.GetTestDatabase(new[] DatabaseContext db = await MockHelper.GetTestDatabase(new List<SlotEntity>
{ {
new List<SlotEntity> new()
{ {
new() SlotId = 4,
{ CreatorId = 1,
SlotId = 4, Type = SlotType.Developer,
Type = SlotType.Developer, InternalSlotId = 10,
InternalSlotId = 10,
},
}, },
}); });
SlotsController controller = new(db); SlotsController controller = new(db);
@ -515,4 +495,4 @@ public class SlotControllerTests
} }
} }
#endregion #endregion
} }

View file

@ -40,18 +40,21 @@ public class StatisticsControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 1, SlotId = 1,
CreatorId = 1,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 3, SlotId = 3,
CreatorId = 1,
TeamPick = true, TeamPick = true,
}, },
}; };
await using DatabaseContext db = await MockHelper.GetTestDatabase(new []{slots,}); await using DatabaseContext db = await MockHelper.GetTestDatabase(slots);
StatisticsController statsController = new(db); StatisticsController statsController = new(db);
statsController.SetupTestController(); statsController.SetupTestController();
@ -74,21 +77,24 @@ public class StatisticsControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 1, SlotId = 1,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 3, SlotId = 3,
CreatorId = 1,
TeamPick = true, TeamPick = true,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
}; };
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[]{slots,}); await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(slots);
StatisticsController statsController = new(dbMock); StatisticsController statsController = new(dbMock);
statsController.SetupTestController(); statsController.SetupTestController();
@ -111,21 +117,24 @@ public class StatisticsControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 1, SlotId = 1,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet1, GameVersion = GameVersion.LittleBigPlanet1,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet1, GameVersion = GameVersion.LittleBigPlanet1,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 3, SlotId = 3,
CreatorId = 1,
TeamPick = true, TeamPick = true,
GameVersion = GameVersion.LittleBigPlanet1, GameVersion = GameVersion.LittleBigPlanet1,
}, },
}; };
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[] {slots,}); await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(slots);
StatisticsController statsController = new(dbMock); StatisticsController statsController = new(dbMock);
statsController.SetupTestController(); statsController.SetupTestController();
@ -146,21 +155,24 @@ public class StatisticsControllerTests
new SlotEntity new SlotEntity
{ {
SlotId = 1, SlotId = 1,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 2, SlotId = 2,
CreatorId = 1,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
new SlotEntity new SlotEntity
{ {
SlotId = 3, SlotId = 3,
CreatorId = 1,
TeamPick = true, TeamPick = true,
GameVersion = GameVersion.LittleBigPlanet2, GameVersion = GameVersion.LittleBigPlanet2,
}, },
}; };
await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[] {slots,}); await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(slots);
StatisticsController statsController = new(dbMock); StatisticsController statsController = new(dbMock);
statsController.SetupTestController(); statsController.SetupTestController();

View file

@ -71,7 +71,8 @@ public class DigestMiddlewareTests
const int expectedCode = 403; const int expectedCode = 403;
Assert.Equal(expectedCode, context.Response.StatusCode); Assert.True(expectedCode == context.Response.StatusCode,
"The digest middleware accepted the request when it shouldn't have (are you running this test in Debug mode?)");
Assert.False(context.Response.Headers.TryGetValue("X-Digest-A", out _)); Assert.False(context.Response.Headers.TryGetValue("X-Digest-A", out _));
Assert.False(context.Response.Headers.TryGetValue("X-Digest-B", out _)); Assert.False(context.Response.Headers.TryGetValue("X-Digest-B", out _));
} }

View file

@ -87,7 +87,7 @@ public class SetLastContactMiddlewareTests
}, },
}; };
DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[]{lastContacts,}); DatabaseContext dbMock = await MockHelper.GetTestDatabase(lastContacts);
await middleware.InvokeAsync(context, dbMock); await middleware.InvokeAsync(context, dbMock);
@ -132,10 +132,7 @@ public class SetLastContactMiddlewareTests
}; };
tokens[0].GameVersion = GameVersion.LittleBigPlanet2; tokens[0].GameVersion = GameVersion.LittleBigPlanet2;
DatabaseContext dbMock = await MockHelper.GetTestDatabase(new[] DatabaseContext dbMock = await MockHelper.GetTestDatabase(tokens);
{
tokens,
});
await middleware.InvokeAsync(context, dbMock); await middleware.InvokeAsync(context, dbMock);

View file

@ -1,9 +1,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
@ -14,6 +14,7 @@ using LBPUnion.ProjectLighthouse.Types.Users;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Xunit; using Xunit;
@ -42,17 +43,22 @@ public static class MockHelper
public static T2 CastTo<T1, T2>(this IActionResult result) where T1 : ObjectResult public static T2 CastTo<T1, T2>(this IActionResult result) where T1 : ObjectResult
{ {
Assert.IsType<T1>(result); T1 typedResult = Assert.IsType<T1>(result);
T1? typedResult = result as T1;
Assert.NotNull(typedResult); Assert.NotNull(typedResult);
Assert.NotNull(typedResult.Value); Assert.NotNull(typedResult.Value);
Assert.IsType<T2?>(typedResult.Value); T2 finalResult = Assert.IsType<T2>(typedResult.Value);
T2? finalResult = (T2?)typedResult.Value;
Assert.NotNull(finalResult); Assert.NotNull(finalResult);
return finalResult; return finalResult;
} }
public static async Task<DatabaseContext> GetTestDatabase(IEnumerable<IList> sets, [CallerMemberName] string caller = "", [CallerLineNumber] int lineNum = 0) private static async Task<DbContextOptionsBuilder<DatabaseContext>> GetInMemoryDbOptions()
{
DbConnection connection = new SqliteConnection("DataSource=:memory:");
await connection.OpenAsync();
return new DbContextOptionsBuilder<DatabaseContext>().UseSqlite(connection);
}
public static async Task<DatabaseContext> GetTestDatabase(params object[] sets)
{ {
await RoomHelper.Rooms.RemoveAllAsync(); await RoomHelper.Rooms.RemoveAllAsync();
@ -64,27 +70,32 @@ public static class MockHelper
setDict[type] = list; setDict[type] = list;
} }
if (!setDict.TryGetValue(typeof(GameTokenEntity), out _)) setDict.TryAdd(typeof(GameTokenEntity), new List<GameTokenEntity>());
setDict.TryAdd(typeof(UserEntity), new List<UserEntity>());
// add the default user token if another token with id 1 isn't specified
if (setDict.TryGetValue(typeof(GameTokenEntity), out IList? tokens))
{ {
setDict[typeof(GameTokenEntity)] = new List<GameTokenEntity> if (tokens.Cast<GameTokenEntity>().FirstOrDefault(t => t.TokenId == 1) == null)
{ {
GetUnitTestToken(), setDict[typeof(GameTokenEntity)].Add(GetUnitTestToken());
}; }
} }
if (!setDict.TryGetValue(typeof(UserEntity), out _)) // add the default user if another user with id 1 isn't specified
if (setDict.TryGetValue(typeof(UserEntity), out IList? users))
{ {
setDict[typeof(UserEntity)] = new List<UserEntity> if (users.Cast<UserEntity>().FirstOrDefault(u => u.UserId == 1) == null)
{ {
GetUnitTestUser(), setDict[typeof(UserEntity)].Add(GetUnitTestUser());
}; }
} }
DbContextOptions<DatabaseContext> options = new DbContextOptionsBuilder<DatabaseContext>() DbContextOptions<DatabaseContext> options = (await GetInMemoryDbOptions()).Options;
.UseInMemoryDatabase($"{caller}_{lineNum}")
.Options;
await using DatabaseContext context = new(options); await using DatabaseContext context = new(options);
await context.Database.EnsureCreatedAsync();
foreach (IList list in setDict.Select(p => p.Value)) foreach (IList list in setDict.Select(p => p.Value))
{ {
foreach (object item in list) foreach (object item in list)
@ -93,35 +104,8 @@ public static class MockHelper
} }
} }
await context.SaveChangesAsync(); await context.SaveChangesAsync();
await context.DisposeAsync();
return new DatabaseContext(options);
}
public static async Task<DatabaseContext> GetTestDatabase(List<UserEntity>? users = null, List<GameTokenEntity>? tokens = null,
[CallerMemberName] string caller = "", [CallerLineNumber] int lineNum = 0
)
{
await RoomHelper.Rooms.RemoveAllAsync();
users ??= new List<UserEntity>
{
GetUnitTestUser(),
};
tokens ??= new List<GameTokenEntity>
{
GetUnitTestToken(),
};
DbContextOptions<DatabaseContext> options = new DbContextOptionsBuilder<DatabaseContext>()
.UseInMemoryDatabase($"{caller}_{lineNum}")
.Options;
await using DatabaseContext context = new(options);
context.Users.AddRange(users);
context.GameTokens.AddRange(tokens);
await context.SaveChangesAsync();
await context.DisposeAsync();
return new DatabaseContext(options); return new DatabaseContext(options);
} }

View file

@ -30,7 +30,7 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Moq" Version="4.20.69" /> <PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.13" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.13" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -19,6 +19,7 @@ public class ModerationTests
ModerationCaseEntity @case = new() ModerationCaseEntity @case = new()
{ {
CaseId = 1, CaseId = 1,
CreatorId = 1,
ExpiresAt = DateTime.UnixEpoch, ExpiresAt = DateTime.UnixEpoch,
CreatorUsername = "unitTestUser", CreatorUsername = "unitTestUser",
}; };
@ -41,6 +42,7 @@ public class ModerationTests
ModerationCaseEntity @case = new() ModerationCaseEntity @case = new()
{ {
CaseId = 2, CaseId = 2,
CreatorId = 1,
ExpiresAt = DateTime.UtcNow.AddHours(1), ExpiresAt = DateTime.UtcNow.AddHours(1),
CreatorUsername = "unitTestUser", CreatorUsername = "unitTestUser",
}; };
@ -63,6 +65,7 @@ public class ModerationTests
ModerationCaseEntity @case = new() ModerationCaseEntity @case = new()
{ {
CaseId = 3, CaseId = 3,
CreatorId = 1,
ExpiresAt = DateTime.UnixEpoch, ExpiresAt = DateTime.UnixEpoch,
DismissedAt = DateTime.UnixEpoch, DismissedAt = DateTime.UnixEpoch,
CreatorUsername = "unitTestUser", CreatorUsername = "unitTestUser",