Skip to content

Commit

Permalink
Move integration tests into own test project #255
Browse files Browse the repository at this point in the history
  • Loading branch information
Spacelord-XaN committed Feb 20, 2024
1 parent 61f96c8 commit 74045a0
Show file tree
Hide file tree
Showing 36 changed files with 1,072 additions and 1,215 deletions.
8 changes: 7 additions & 1 deletion VeloBasar.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BraunauMobil.VeloBasar.Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BraunauMobil.VeloBasar.DataGenerator", "test\BraunauMobil.VeloBasar.DataGenerator\BraunauMobil.VeloBasar.DataGenerator.csproj", "{4F4A648F-A253-48B4-8E7E-9CD51EEB39FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BraunauMobil.VeloBasar.StatusPushTestServer", "test\BraunauMobil.VeloBasar.StatusPushTestServer\BraunauMobil.VeloBasar.StatusPushTestServer.csproj", "{4D4402FE-60B7-43ED-9277-337D0433E867}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BraunauMobil.VeloBasar.StatusPushTestServer", "test\BraunauMobil.VeloBasar.StatusPushTestServer\BraunauMobil.VeloBasar.StatusPushTestServer.csproj", "{4D4402FE-60B7-43ED-9277-337D0433E867}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BraunauMobil.VeloBasar.IntegrationTests", "test\BraunauMobil.VeloBasar.IntegrationTests\BraunauMobil.VeloBasar.IntegrationTests.csproj", "{B0860A22-2C22-4FA3-B272-658AC624F871}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -33,6 +35,10 @@ Global
{4D4402FE-60B7-43ED-9277-337D0433E867}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D4402FE-60B7-43ED-9277-337D0433E867}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D4402FE-60B7-43ED-9277-337D0433E867}.Release|Any CPU.Build.0 = Release|Any CPU
{B0860A22-2C22-4FA3-B272-658AC624F871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0860A22-2C22-4FA3-B272-658AC624F871}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0860A22-2C22-4FA3-B272-658AC624F871}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0860A22-2C22-4FA3-B272-658AC624F871}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
4 changes: 3 additions & 1 deletion src/BraunauMobil.VeloBasar/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@

namespace BraunauMobil.VeloBasar;

public static class Program
#pragma warning disable CA1052 // Static holder types should be Static or NotInheritable
public class Program
#pragma warning restore CA1052 // Static holder types should be Static or NotInheritable
{
public static async Task Main(string[] args)
{
Expand Down
57 changes: 57 additions & 0 deletions src/BraunauMobil.VeloBasar/appsettings.IntegrationTests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"ApplicationSettings": {
"Culture": "en-US"
},
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WordPressStatusPushSettings": {
"Enabled": false,
"EndpointUrl": null,
"ApiKey": null
},
"PrintSettings": {
"Acceptance": {
"SignatureText": "For XYZ:",
"SubTitle": "We accepted these products:",
"TokenTitle": "Online-Query-Code:",
"TransactionType": 0,
"TitleFormat": "XYZ - {0} : Acceptance receipt #{1}",
"StatusLinkFormat": "statusLink={0}"
},
"Sale": {
"FooterText": "Thanks!",
"HintText": "Please be aware of.",
"SellerInfoText": "*Seller contact",
"SubTitle": "We sold theses products:",
"TransactionType": 2,
"TitleFormat": "XYZ - {0} : Sale receipt #{1}"
},
"Settlement": {
"ConfirmationText": "I confirm.",
"SignatureText": "Signature",
"SoldTitle": "We sold these products:",
"NotSoldTitle": "We could not sell these products:",
"TransactionType": 3,
"TitleFormat": "XYZ - {0} : Settlement #{1}",
"BankTransactionTextFormat": "XYZ - Revenue {0}"
},
"Label": {
"MaxDescriptionLength": 150,
"TitleFormat": "XYZ - {0}"
},
"PageMargins": {
"Left": 20,
"Top": 20,
"Right": 20,
"Bottom": 20
},
"BannerFilePath": "",
"BannerSubtitle": "XYZ Address",
"Website": "XYZ website",
"QrCodeLengthMillimeters": 50
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using AngleSharp.Dom;

namespace BraunauMobil.VeloBasar.IntegrationTests;

public static class AngleSharpExtensions
{
public static IHtmlAnchorElement QueryAnchorByText(this IParentNode node, string text)
{
ArgumentNullException.ThrowIfNull(node);
ArgumentNullException.ThrowIfNull(text);

return node.QueryElement<IHtmlAnchorElement>("a", button => button.InnerHtml == text);
}

public static IHtmlButtonElement QueryButtonByText(this IParentNode node, string text)

{
ArgumentNullException.ThrowIfNull(node);
ArgumentNullException.ThrowIfNull(text);

return node.QueryElement<IHtmlButtonElement>("button", button => button.InnerHtml == text);
}

public static IHtmlAnchorElement QueryTableDetailsLink(this IParentNode node, int rowId)
{
ArgumentNullException.ThrowIfNull(node);

IHtmlTableElement? table = node.QuerySelector<IHtmlTableElement>("table");
table.Should().NotBeNull();
IHtmlTableRowElement headerRow = table!.Rows[0];
INode idHeaderCell = headerRow.Cells.Should().ContainSingle(cell => cell.TextContent == "Id").Subject;
int idColumnIndex = headerRow.Cells.Index(idHeaderCell);

IHtmlTableRowElement row = table.Rows.Should().ContainSingle(row => row.Cells[idColumnIndex].TextContent == rowId.ToString()).Subject;
return row.QueryAnchorByText("Details");
}

public static IHtmlFormElement QueryForm(this IParentNode node, string selector = "form")
{
ArgumentNullException.ThrowIfNull(node);
ArgumentNullException.ThrowIfNull(selector);

return node.QuerySelector(selector)
.Should().BeAssignableTo<IHtmlFormElement>().Subject;
}

public static TElement QueryElement<TElement>(this IParentNode node, string selector)
{
ArgumentNullException.ThrowIfNull(node);
ArgumentNullException.ThrowIfNull(selector);

return node.QuerySelector(selector)
.Should().BeAssignableTo<TElement>().Subject;
}

public static TElement QueryElement<TElement>(this IParentNode node, string selector, Func<TElement, bool> predicate)
{
ArgumentNullException.ThrowIfNull(node);
ArgumentNullException.ThrowIfNull(selector);

TElement? element = node.QuerySelectorAll(selector)
.OfType<TElement>()
.FirstOrDefault(predicate);
element.Should().NotBeNull();
return element!;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

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

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<Compile Remove="IntegrationTests_TOMIGRATE_TOHTTTP\**" />
<Content Remove="IntegrationTests_TOMIGRATE_TOHTTTP\**" />
<EmbeddedResource Remove="IntegrationTests_TOMIGRATE_TOHTTTP\**" />
<None Remove="IntegrationTests_TOMIGRATE_TOHTTTP\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AngleSharp" Version="1.1.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\BraunauMobil.VeloBasar\BraunauMobil.VeloBasar.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using BraunauMobil.VeloBasar.BusinessLogic;
using BraunauMobil.VeloBasar.Data;
using BraunauMobil.VeloBasar.IntegrationTests.Mockups;
using BraunauMobil.VeloBasar.Pdf;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System.Data.Common;
using Xan.Extensions;

namespace BraunauMobil.VeloBasar.IntegrationTests;

public class CustomWebApplicationFactory
: WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
ServiceDescriptor dbContextDescriptor = services.Single(d => d.ServiceType == typeof(DbContextOptions<VeloDbContext>));
services.Remove(dbContextDescriptor);

ServiceDescriptor? dbConnectionDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbConnection));
if (dbConnectionDescriptor is not null)
{
services.Remove(dbConnectionDescriptor);
}

// Create open SqliteConnection so EF won't automatically close it.
services.AddSingleton<DbConnection>(container =>
{
SqliteConnection connection = new ("DataSource=:memory:");
connection.Open();

return connection;
});

services.AddDbContext<VeloDbContext>((container, options) =>
{
DbConnection connection = container.GetRequiredService<DbConnection>();
options.UseSqlite(connection);
});

ServiceDescriptor clockDescriptor = services.Single(d => d.ServiceType == typeof(IClock));
services.Remove(clockDescriptor);
services.AddSingleton<IClock>(X.Clock);

ServiceDescriptor appContextDescriptor = services.Single(d => d.ServiceType == typeof(IAppContext));
services.Remove(appContextDescriptor);
services.AddScoped<IAppContext, AppContextWrapper>();

ServiceDescriptor setupServiceDescriptor = services.Single(d => d.ServiceType == typeof(ISetupService));
services.Remove(setupServiceDescriptor);
services.AddScoped<ISetupService, SetupServiceWrapper>();

ServiceDescriptor transactionDocumentGeneratorDescriptor = services.Single(d => d.ServiceType == typeof(ITransactionDocumentGenerator));
services.Remove(transactionDocumentGeneratorDescriptor);
services.AddScoped<ITransactionDocumentGenerator, JsonTransactionDocumentGenerator>();

ServiceDescriptor productLabelGeneratorDescriptor = services.Single(d => d.ServiceType == typeof(IProductLabelGenerator));
services.Remove(productLabelGeneratorDescriptor);
services.AddScoped<IProductLabelGenerator, JsonProductLabelGenerator>();
});

builder.UseEnvironment("IntegrationTests");
}
}
4 changes: 4 additions & 0 deletions test/BraunauMobil.VeloBasar.IntegrationTests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global using AngleSharp.Html.Dom;
global using BraunauMobil.VeloBasar.Models.Documents;
global using FluentAssertions;
global using Xunit;
Loading

0 comments on commit 74045a0

Please sign in to comment.