Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests for Seeder #25

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ steps:
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\*tests.dll
!**\*seeder.unittests.dll
53 changes: 53 additions & 0 deletions src/Sway.Database.Seeder.UnitTests/ExecutorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace Sway.Database.Seeder.UnitTests;

using Moq;
using Sway.Database.Seeder.Options;
using Sway.Database.Seeder.Sinks;

public sealed class ExecutorTests
{
private Mock<ISink> mockSink;
private Mock<ISinkFactory> mockSinkFactory;
private IExecutor executor;
private SeedingOption seedingOption;

[Before(Test)]
public void Setup()
{
this.mockSink = new Mock<ISink>();
this.mockSinkFactory = new Mock<ISinkFactory>();

this.mockSinkFactory
.Setup(x => x.CreateSink(It.IsAny<SwayEntity>(), It.IsAny<SinkType>()))
.Returns(this.mockSink.Object);

this.seedingOption = new SeedingOption
{
Count = 1,
Entity = SwayEntity.User,
Destination = SinkType.Database,
};

this.executor = new Executor(
this.mockSinkFactory.Object,
this.seedingOption);
}

[Test]
[Retry(3)]
public async Task ExecuteAsync_InvokedProvisionAsync()
{
await this.executor.ExecuteAsync(default);

this.mockSink.Verify(
x => x.ProvisionAsync(1, default),
Times.Once());
}

[Test]
[DependsOn(nameof(ExecuteAsync_InvokedProvisionAsync))]
public async Task AfterExecution_ObjectNotNull()
{
await Assert.That(this.executor).IsNotNull();
}
}
8 changes: 8 additions & 0 deletions src/Sway.Database.Seeder.UnitTests/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "<Pending>", Scope = "type", Target = "~T:Sway.Database.Seeder.UnitTests.ExecutorTests")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="TUnit" Version="0.1.783" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sway.Database.Seeder\Sway.Database.Seeder.csproj" />
</ItemGroup>

</Project>
20 changes: 20 additions & 0 deletions src/Sway.Database.Seeder/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// In SDK-style projects such as this one, several assembly attributes that were historically
// defined in this file are now automatically added during build and populated with
// values defined in project properties. For details of which attributes are included
// and how to customise this process see: https://aka.ms/assembly-info-properties


// Setting ComVisible to false makes the types in this assembly not visible to COM
// components. If you need to access a type in this assembly from COM, set the ComVisible
// attribute to true on that type.

[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM.

[assembly: Guid("90f0fb08-0432-46c1-b99a-d12110b71fe3")]
[assembly: InternalsVisibleTo("Sway.Database.Seeder.UnitTests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
14 changes: 11 additions & 3 deletions src/Sway.Database.Seeder/Generator/IGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
namespace Sway.Database.Seeder.Generator;
using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// The interface for entity generator.
/// </summary>
/// <typeparam name="T">The entity to be generated.</typeparam>
internal interface IGenerator<T>
{
/// <summary>
/// Generate a list of <typeparamref name="T"/>.
/// </summary>
/// <param name="count">Amount of entities to be generated.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The list of generated entities.</returns>
Task<IEnumerable<T>> GenerateAsync(int count, CancellationToken cancellationToken);
}
20 changes: 14 additions & 6 deletions src/Sway.Database.Seeder/Generator/PaymentMethodGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// The generator class for <see cref="PaymentMethod"/>.
/// </summary>
internal sealed class PaymentMethodGenerator : IGenerator<PaymentMethod>
{
private readonly Guid existingUserId;
private readonly IEnumerable<PaymentType> paymentTypes;

private Faker<PaymentMethod> cryptoFaker;
private Faker<PaymentMethod> cardFaker;
private Faker<PaymentMethod> onlineBankingFaker;
private Faker<PaymentMethod> ewalletFaker;

private readonly Dictionary<string, string> crytoProviders = new()
{
{ "Bitcoin", "BTC" },
Expand All @@ -33,6 +30,16 @@ internal sealed class PaymentMethodGenerator : IGenerator<PaymentMethod>
private readonly List<string> cardIssuingBanks = ["Public Bank", "OCBC Bank", "Hong Leong Bank", "Maybank", "CIMB Bank"];
private readonly List<string> ewalletProviders = ["Touch N Go", "Boost", "Grab Pay", "Alipay", "Sway", "Razer Pay"];

private Faker<PaymentMethod> cryptoFaker;
private Faker<PaymentMethod> cardFaker;
private Faker<PaymentMethod> onlineBankingFaker;
private Faker<PaymentMethod> ewalletFaker;

/// <summary>
/// Initializes a new instance of the <see cref="PaymentMethodGenerator"/> class.
/// </summary>
/// <param name="existingUserId">The existing user to be binded with the new payment methods.</param>
/// <param name="paymentTypes">The payment type variants.</param>
public PaymentMethodGenerator(Guid existingUserId, IEnumerable<PaymentType> paymentTypes)
{
this.existingUserId = Guard.ThrowIfDefault(existingUserId);
Expand All @@ -44,6 +51,7 @@ public PaymentMethodGenerator(Guid existingUserId, IEnumerable<PaymentType> paym
this.ConfigureEWalletPaymentMethodFaker();
}

/// <inheritdoc/>
public Task<IEnumerable<PaymentMethod>> GenerateAsync(int count, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand Down
10 changes: 9 additions & 1 deletion src/Sway.Database.Seeder/Generator/ProductRatingGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// The generator class for <see cref="ProductRating"/>.
/// </summary>
internal sealed class ProductRatingGenerator : IGenerator<ProductRating>
{
private readonly Guid existingProductId;
private readonly Guid existingUserId;
private Faker<ProductRating> faker;

/// <summary>
/// Initializes a new instance of the <see cref="ProductRatingGenerator"/> class.
/// </summary>
/// <param name="existingProductId">The existing product to be binded.</param>
/// <param name="existingUserId">The existing user who make the rating.</param>
public ProductRatingGenerator(Guid existingProductId, Guid existingUserId)
{
this.existingProductId = Guard.ThrowIfDefault(existingProductId);
Expand All @@ -24,6 +31,7 @@ public ProductRatingGenerator(Guid existingProductId, Guid existingUserId)
this.ConfigureProductRatingFaker();
}

/// <inheritdoc/>
public Task<IEnumerable<ProductRating>> GenerateAsync(int count, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand Down
7 changes: 7 additions & 0 deletions src/Sway.Database.Seeder/Generator/UserGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@
using System.Linq;
using System.Threading.Tasks;

/// <summary>
/// The generator class for <see cref="User"/>.
/// </summary>
internal sealed class UserGenerator : IGenerator<User>
{
private Faker<User> faker;

/// <summary>
/// Initializes a new instance of the <see cref="UserGenerator"/> class.
/// </summary>
public UserGenerator()
{
this.ConfigureUserFaker();
}

/// <inheritdoc/>
public Task<IEnumerable<User>> GenerateAsync(int count, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand Down
12 changes: 12 additions & 0 deletions src/Sway.Database.Seeder/NamingStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
namespace Sway.Database.Seeder;

/// <summary>
/// The naming strategy for naming a file.
/// </summary>
internal enum NamingStrategy
{
/// <summary>
/// The default value.
/// </summary>
None,

/// <summary>
/// Name by random <see cref="Guid"/>.
/// </summary>
Guid,

/// <summary>
/// Name by current timestamp.
/// </summary>
Timestamp,
}
8 changes: 7 additions & 1 deletion src/Sway.Database.Seeder/Options/DatabaseOption.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
namespace Sway.Database.Seeder.Options;

/// <summary>
/// The configurations for database.
/// </summary>
internal sealed class DatabaseOption
{
public string ConnectionString { get; set; }
/// <summary>
/// Gets or sets the connection string of the database.
/// </summary>
public string ConnectionString { get; set; } = null!;
}
28 changes: 28 additions & 0 deletions src/Sway.Database.Seeder/Options/SeedingOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,47 @@

using Sway.Core.Models;

/// <summary>
/// The configurations for generating <see cref="ProductRating"/>.
/// </summary>
/// <param name="ExistingProductId">The existing product Id.</param>
/// <param name="ExistingUserId">The existing user Id.</param>
internal record ProductRatingOption(Guid ExistingProductId, Guid ExistingUserId);

/// <summary>
/// The configurations for generating <see cref="PaymentMethod"/>.
/// </summary>
/// <param name="ExistingUserId">The existing user Id.</param>
/// <param name="PaymentTypes">The payment types to be generated.</param>
internal record PaymentMethodOption(Guid ExistingUserId, IEnumerable<PaymentType> PaymentTypes);

/// <summary>
/// The configurations pertaining to seeding.
/// </summary>
internal sealed class SeedingOption
{
/// <summary>
/// Gets or sets the destination which the generated entities should go to.
/// </summary>
public SinkType Destination { get; set; }

/// <summary>
/// Gets or sets the number of entites should be generated.
/// </summary>
public int Count { get; set; }

/// <summary>
/// Gets or sets the entity to be generated.
/// </summary>
public SwayEntity Entity { get; set; }

/// <summary>
/// Gets or sets the configurations for product rating.
/// </summary>
public ProductRatingOption ProductRatingOption { get; set; }

/// <summary>
/// Gets or sets the configurations for payment method.
/// </summary>
public PaymentMethodOption PaymentMethodOption { get; set; }
}
11 changes: 10 additions & 1 deletion src/Sway.Database.Seeder/Options/SqlSinkOption.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
namespace Sway.Database.Seeder.Options;

/// <summary>
/// The configurations for SQL script sink.
/// </summary>
internal sealed class SqlSinkOption
{
public string OutputPath { get; set; }
/// <summary>
/// Gets or sets the output path for the SQL files generated.
/// </summary>
public string OutputPath { get; set; } = null!;

/// <summary>
/// Gets or sets the naming strategy of the files generated.
/// </summary>
public NamingStrategy NamingStrategy { get; set; }
}
7 changes: 7 additions & 0 deletions src/Sway.sln
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sway.Web.Mvc", "Sway.Web.Mv
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sway.Database.Seeder", "Sway.Database.Seeder\Sway.Database.Seeder.csproj", "{1F473C6B-DE7B-4F91-A72E-E7E0F5732C01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sway.Database.Seeder.UnitTests", "Sway.Database.Seeder.UnitTests\Sway.Database.Seeder.UnitTests.csproj", "{AA117586-82B8-4DB7-94BC-5E2272AC59AF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -73,12 +75,17 @@ Global
{1F473C6B-DE7B-4F91-A72E-E7E0F5732C01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F473C6B-DE7B-4F91-A72E-E7E0F5732C01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F473C6B-DE7B-4F91-A72E-E7E0F5732C01}.Release|Any CPU.Build.0 = Release|Any CPU
{AA117586-82B8-4DB7-94BC-5E2272AC59AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA117586-82B8-4DB7-94BC-5E2272AC59AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA117586-82B8-4DB7-94BC-5E2272AC59AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA117586-82B8-4DB7-94BC-5E2272AC59AF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5BAA2566-3B21-402B-8219-972AC0E2DEB6} = {988783AC-9ED0-4AEF-AFD6-FD4F3E7CA70F}
{AA117586-82B8-4DB7-94BC-5E2272AC59AF} = {988783AC-9ED0-4AEF-AFD6-FD4F3E7CA70F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D4C1AEF2-0F1A-423E-870D-870F0483410A}
Expand Down
Loading