Skip to content

Commit

Permalink
test: fix unit tests (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
rbeauchamp authored Aug 22, 2024
1 parent 42078a9 commit 5af5ce7
Show file tree
Hide file tree
Showing 27 changed files with 785 additions and 412 deletions.
14 changes: 7 additions & 7 deletions RxDBDotNet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BB53E83A-96E
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1B5323DD-D124-4F5D-AFED-27F0F20DD545}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RxDBDotNet.LiveDocsTestModelGenerator", "tests\RxDBDotNet.LiveDocsTestModelGenerator\RxDBDotNet.LiveDocsTestModelGenerator.csproj", "{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RxDBDotNet.Tests.Setup", "tests\RxDBDotNet.Tests.Setup\RxDBDotNet.Tests.Setup.csproj", "{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "worflows", "worflows", "{5DB93DDB-67AD-4567-9447-DB02A6898BEE}"
Expand All @@ -52,6 +50,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "worflows", "worflows", "{5D
.github\workflows\release.yml = .github\workflows\release.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RxDBDotNet.TestModelGenerator", "tests\RxDBDotNet.TestModelGenerator\RxDBDotNet.TestModelGenerator.csproj", "{8A87D363-2E01-41B4-8535-AC8F1448FEE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -78,14 +78,14 @@ Global
{3ACC4CC0-E7A3-4738-94BE-AE1B6E0DA0EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3ACC4CC0-E7A3-4738-94BE-AE1B6E0DA0EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3ACC4CC0-E7A3-4738-94BE-AE1B6E0DA0EC}.Release|Any CPU.Build.0 = Release|Any CPU
{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD}.Release|Any CPU.Build.0 = Release|Any CPU
{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9}.Release|Any CPU.Build.0 = Release|Any CPU
{8A87D363-2E01-41B4-8535-AC8F1448FEE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A87D363-2E01-41B4-8535-AC8F1448FEE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A87D363-2E01-41B4-8535-AC8F1448FEE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A87D363-2E01-41B4-8535-AC8F1448FEE3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -98,9 +98,9 @@ Global
{4096CC6C-F920-409A-8F1C-39FAA9919F1E} = {A12DF744-A396-4895-8E1F-3C44349EE0A9}
{831469C1-446D-4CAC-8EC2-DC9E153716D9} = {A12DF744-A396-4895-8E1F-3C44349EE0A9}
{3ACC4CC0-E7A3-4738-94BE-AE1B6E0DA0EC} = {A12DF744-A396-4895-8E1F-3C44349EE0A9}
{8CB00FE2-5DA2-4785-A5A8-157A97AFBCDD} = {1B5323DD-D124-4F5D-AFED-27F0F20DD545}
{9E5A3A3E-D100-48B3-ABC9-3A5C80CF98E9} = {1B5323DD-D124-4F5D-AFED-27F0F20DD545}
{5DB93DDB-67AD-4567-9447-DB02A6898BEE} = {41216137-D61B-414F-BE61-FABEA436ABA8}
{8A87D363-2E01-41B4-8535-AC8F1448FEE3} = {1B5323DD-D124-4F5D-AFED-27F0F20DD545}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {33885AAE-E818-451C-9604-9002D28B4F7B}
Expand Down
33 changes: 31 additions & 2 deletions example/LiveDocs.GraphQLApi/Data/LiveDocsDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
using LiveDocs.GraphQLApi.Models.Entities;
using LiveDocs.GraphQLApi.Infrastructure;
using LiveDocs.GraphQLApi.Models.Entities;
using LiveDocs.GraphQLApi.Models.Shared;
using Microsoft.EntityFrameworkCore;

namespace LiveDocs.GraphQLApi.Data;

public class LiveDocsDbContext(DbContextOptions options) : DbContext(options)
public class LiveDocsDbContext : DbContext
{
public LiveDocsDbContext()
{
}

public LiveDocsDbContext(DbContextOptions options) : base(options)
{
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
ArgumentNullException.ThrowIfNull(optionsBuilder);

if (optionsBuilder.IsConfigured)
{
return;
}

var sqlServerUrl = Environment.GetEnvironmentVariable(ConfigKeys.DbConnectionString);

optionsBuilder
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.UseSqlServer(
sqlServerUrl,
sqlServerDbContextOptionsBuilder => sqlServerDbContextOptionsBuilder
.EnableRetryOnFailure());
}

public DbSet<User> Users => Set<User>();
public DbSet<Workspace> Workspaces => Set<Workspace>();
public DbSet<LiveDoc> LiveDocs => Set<LiveDoc>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ public static class LiveDocsDbInitializer
{
public static async Task InitializeAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken)
{
using var scope = serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<LiveDocsDbContext>();
var dbContext = serviceProvider.GetRequiredService<LiveDocsDbContext>();

await dbContext.Database.EnsureCreatedAsync(cancellationToken);

Expand Down
11 changes: 8 additions & 3 deletions example/LiveDocs.GraphQLApi/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using HotChocolate.AspNetCore;
using HotChocolate.Subscriptions;
using LiveDocs.GraphQLApi.Data;
using LiveDocs.GraphQLApi.Infrastructure;
using LiveDocs.GraphQLApi.Models.Replication;
Expand Down Expand Up @@ -66,10 +67,10 @@ protected virtual void ConfigureGraphQLServer(IServiceCollection services,
ConfigureDefaultGraphQLServer(services);
}

public static void ConfigureDefaultGraphQLServer(IServiceCollection services)
public static void ConfigureDefaultGraphQLServer(IServiceCollection services, string? topicPrefix = null)
{
// Configure the GraphQL server
services.AddGraphQLServer()
var graphQLBuilder = services.AddGraphQLServer()
.ModifyRequestOptions(o => o.IncludeExceptionDetails = true)
// Simulate scenario where the library user
// has already added their own root query type.
Expand All @@ -79,8 +80,12 @@ public static void ConfigureDefaultGraphQLServer(IServiceCollection services)
.AddReplicatedDocument<ReplicatedWorkspace>()
.AddReplicatedDocument<ReplicatedLiveDoc>()
.AddReplicatedDocument<Hero>()
.AddRedisSubscriptions(provider => provider.GetRequiredService<IConnectionMultiplexer>())
.AddSubscriptionDiagnostics();

graphQLBuilder.AddRedisSubscriptions(provider => provider.GetRequiredService<IConnectionMultiplexer>(), new SubscriptionOptions
{
TopicPrefix = topicPrefix,
});
}

protected static void ConfigureDbContext(
Expand Down
9 changes: 4 additions & 5 deletions src/RxDBDotNet/Security/AccessRequirementHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,17 @@ protected override Task HandleRequirementAsync(
ArgumentNullException.ThrowIfNull(requirement);

var user = context.User;

var policies = requirement.SecurityOptions.Policies
.Where(p => p.Type.HasFlag(requirement.Type));

foreach (var policy in policies)
if (policies.Any(policy => !policy.Requirement(user)))
{
if (!policy.Requirement(user))
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}

context.Succeed(requirement);

return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using GraphQlClientGenerator;
using Newtonsoft.Json;

namespace RxDBDotNet.LiveDocsTestModelGenerator;
namespace RxDBDotNet.TestModelGenerator;

public static class GraphQlClientFactory
{
Expand Down Expand Up @@ -52,7 +52,7 @@ public static async Task GenerateLiveDocsGraphQLClientAsync(this HttpClient http

Console.WriteLine($"The current directory is '{currentDirectory}'");

await File.WriteAllTextAsync("./Model/LiveDocsGraphQLClient.cs", modifiedCsharpCode);
await File.WriteAllTextAsync("./Model/GraphQLTestModel.cs", modifiedCsharpCode);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Globalization;
using System.Text.RegularExpressions;

namespace RxDBDotNet.LiveDocsTestModelGenerator;
namespace RxDBDotNet.TestModelGenerator;

internal static class NamingHelper
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using RxDBDotNet.Tests.Setup;

namespace RxDBDotNet.LiveDocsTestModelGenerator;
namespace RxDBDotNet.TestModelGenerator;

public sealed class Program
{
public static async Task Main()
{
Console.WriteLine("Generating LiveDocsGraphQLClient...");
Console.WriteLine("Generating GraphQLTestModel...");

var factory = WebApplicationFactorySetupUtil.Setup();

Expand All @@ -16,11 +16,11 @@ public static async Task Main()
{
await client.GenerateLiveDocsGraphQLClientAsync();

Console.WriteLine("LiveDocsGraphQLClient generated successfully.");
Console.WriteLine("GraphQLTestModel generated successfully.");
}
catch (Exception ex)
{
Console.WriteLine($"Error generating LiveDocsGraphQLClient: {ex.Message}");
Console.WriteLine($"Error generating GraphQLTestModel: {ex.Message}");

Environment.Exit(1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using GraphQlClientGenerator;
using LiveDocs.GraphQLApi.Models.Shared;

namespace RxDBDotNet.LiveDocsTestModelGenerator;
namespace RxDBDotNet.TestModelGenerator;

internal sealed class ScalarFieldTypeMappingProvider : IScalarFieldTypeMappingProvider
{
Expand Down
126 changes: 98 additions & 28 deletions tests/RxDBDotNet.Tests.Setup/DbSetupUtil.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
using LiveDocs.GraphQLApi.Infrastructure;
using Docker.DotNet.Models;
using Docker.DotNet;
using LiveDocs.GraphQLApi.Infrastructure;
using Testcontainers.MsSql;
using Xunit.Abstractions;
using LiveDocs.GraphQLApi.Data;
using LiveDocs.GraphQLApi.Models.Entities;
using LiveDocs.GraphQLApi.Models.Replication;
using LiveDocs.GraphQLApi.Models.Shared;
using Microsoft.EntityFrameworkCore;

namespace RxDBDotNet.Tests.Setup;

public static class DbSetupUtil
{
private const string DbConnectionString = "Server=127.0.0.1,1445;Database=LiveDocsTestDb;User Id=sa;Password=Password123!;TrustServerCertificate=True";

private static readonly SemaphoreSlim Semaphore = new(1, 1);

private static volatile bool _isInitialized;

public static async Task SetupAsync(
IServiceProvider serviceProvider,
ITestOutputHelper output,
CancellationToken cancellationToken)
public static async Task SetupAsync()
{
ArgumentNullException.ThrowIfNull(output);

await Semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

await Semaphore.WaitAsync();
try
{
if (!_isInitialized)
{
output.WriteLine("Initializing the unit test db");
const string containerName = "rxdbdotnet_test_db";
const string saPassword = "Password123!";

// Specify a host port that will be consistent across runs
// const int hostPort = 58000;
var sqlServerDockerContainer = new MsSqlBuilder()
.WithName("livedocs_test_db")
.WithPassword("Password123!")
// Bind the container's SQL Server port to the host port
// .WithPortBinding(hostPort, containerPort: 1433)
.Build();
// Check if the container already exists
using var dockerClientConfiguration = new DockerClientConfiguration();
using var client = dockerClientConfiguration.CreateClient();
var existingContainers = await client.Containers.ListContainersAsync(new ContainersListParameters
{
All = true,
});
var existingContainer =
existingContainers.FirstOrDefault(c => c.Names.Contains($"/{containerName}", StringComparer.OrdinalIgnoreCase));

await sqlServerDockerContainer.StartAsync(cancellationToken).ConfigureAwait(false);
if (existingContainer != null)
{
if (!string.Equals(existingContainer.State, "running", StringComparison.OrdinalIgnoreCase))
{
// Start the existing container
await client.Containers.StartContainerAsync(existingContainer.ID, new ContainerStartParameters());
}
}
else
{
var sqlServerDockerContainer = new MsSqlBuilder().WithName(containerName)
.WithPassword(saPassword)
.WithPortBinding(1445, 1433)
.WithCleanUp(false)
.Build();
await sqlServerDockerContainer.StartAsync();
}

var connectionStringToMaster = sqlServerDockerContainer.GetConnectionString();
Environment.SetEnvironmentVariable(ConfigKeys.DbConnectionString, DbConnectionString);

// Modify the connection string to use the consistent port
var connectionStringToTestDb = connectionStringToMaster
.Replace("master", "LiveDocsTestDb", StringComparison.OrdinalIgnoreCase);
await using var dbContext = new LiveDocsDbContext();

Environment.SetEnvironmentVariable(
ConfigKeys.DbConnectionString,
connectionStringToTestDb);
await dbContext.Database.EnsureCreatedAsync();

await LiveDocsDbInitializer.InitializeAsync(serviceProvider, cancellationToken).ConfigureAwait(false);
await SeedDataAsync(dbContext);

_isInitialized = true;
}
Expand All @@ -55,5 +71,59 @@ public static async Task SetupAsync(
{
Semaphore.Release();
}

Environment.SetEnvironmentVariable(ConfigKeys.DbConnectionString, DbConnectionString);
}

private static async Task SeedDataAsync(LiveDocsDbContext dbContext)
{
if (await dbContext.Workspaces.AnyAsync())
{
return; // Data has already been seeded
}

var workspacePk = RT.Comb.Provider.Sql.Create();
var liveDocsWorkspace = new Workspace
{
Id = workspacePk,
Name = "LiveDocs Org Workspace",
UpdatedAt = DateTimeOffset.UtcNow,
IsDeleted = false,
ReplicatedDocumentId = workspacePk,
};

await dbContext.Workspaces.AddAsync(liveDocsWorkspace);

var userPk = RT.Comb.Provider.Sql.Create();
var systemAdminReplicatedUser = new ReplicatedUser
{
Id = userPk,
FirstName = "System",
LastName = "Admin",
Email = "[email protected]",
JwtAccessToken = null,
WorkspaceId = liveDocsWorkspace.Id,
UpdatedAt = DateTimeOffset.UtcNow,
IsDeleted = false,
};

var jwtAccessToken = JwtUtil.GenerateJwtToken(systemAdminReplicatedUser, UserRole.SystemAdmin);

var superAdminUser = new User
{
Id = userPk,
FirstName = "System",
LastName = "Admin",
Email = "[email protected]",
JwtAccessToken = jwtAccessToken,
WorkspaceId = liveDocsWorkspace.Id,
UpdatedAt = DateTimeOffset.UtcNow,
IsDeleted = false,
ReplicatedDocumentId = userPk,
};

await dbContext.Users.AddAsync(superAdminUser);

await dbContext.SaveChangesAsync();
}
}
Loading

0 comments on commit 5af5ce7

Please sign in to comment.