Skip to content

Feature/mttl 503 get notes by target #8

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

Merged
merged 6 commits into from
Apr 13, 2021
Merged
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: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ tmp/
/notes-api.Tests/Properties/launchSettings.json

.fake
.ionide
.ionide

testresults/
16 changes: 0 additions & 16 deletions NotesApi.Tests/ConnectionString.cs

This file was deleted.

32 changes: 0 additions & 32 deletions NotesApi.Tests/DatabaseTests.cs

This file was deleted.

91 changes: 57 additions & 34 deletions NotesApi.Tests/DynamoDbIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,73 @@
using System.Net.Http;
using NotesApi.V1.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Npgsql;
using NUnit.Framework;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using System.Net.Http;
using Xunit;

namespace NotesApi.Tests
{
public class DynamoDbIntegrationTests<TStartup> where TStartup : class
public class DynamoDbIntegrationTests<TStartup> : IDisposable where TStartup : class
{
protected HttpClient Client { get; private set; }
private DynamoDbMockWebApplicationFactory<TStartup> _factory;
protected IDynamoDBContext DynamoDbContext => _factory?.DynamoDbContext;
protected List<Action> CleanupActions { get; set; }
public HttpClient Client { get; private set; }
public IDynamoDBContext DynamoDbContext => _factory?.DynamoDbContext;

private readonly DynamoDbMockWebApplicationFactory<TStartup> _factory;
private readonly List<TableDef> _tables = new List<TableDef>
{
// TODO: Populate the list of table(s) and their key property details here, for example:
//new TableDef { Name = "example_table", KeyName = "id", KeyType = ScalarAttributeType.N }
new TableDef
{
Name = "Notes",
KeyName = "targetId",
KeyType = ScalarAttributeType.S,
RangeKeyName = "id",
RangeKeyType = ScalarAttributeType.S,
LocalSecondaryIndexes = new List<LocalSecondaryIndex>(new[]
{
new LocalSecondaryIndex
{
IndexName = "NotesByDate",
KeySchema = new List<KeySchemaElement>(new[]
{
new KeySchemaElement("targetId", KeyType.HASH),
new KeySchemaElement("dateTime", KeyType.RANGE)
}),
Projection = new Projection { ProjectionType = ProjectionType.ALL }
}
})
}
};

private static void EnsureEnvVarConfigured(string name, string defaultValue)
{
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(name)))
Environment.SetEnvironmentVariable(name, defaultValue);
}

[OneTimeSetUp]
public void OneTimeSetUp()
public DynamoDbIntegrationTests()
{
EnsureEnvVarConfigured("DynamoDb_LocalMode", "true");
EnsureEnvVarConfigured("DynamoDb_LocalServiceUrl", "http://localhost:8000");
_factory = new DynamoDbMockWebApplicationFactory<TStartup>(_tables);
Client = _factory.CreateClient();
}

[OneTimeTearDown]
public void OneTimeTearDown()
public void Dispose()
{
_factory.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

[SetUp]
public void BaseSetup()
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
Client = _factory.CreateClient();
CleanupActions = new List<Action>();
if (disposing && !_disposed)
{
if (null != _factory)
_factory.Dispose();
_disposed = true;
}
}

[TearDown]
public void BaseTearDown()
private static void EnsureEnvVarConfigured(string name, string defaultValue)
{
foreach (var act in CleanupActions)
act();
Client.Dispose();
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(name)))
Environment.SetEnvironmentVariable(name, defaultValue);
}
}

Expand All @@ -65,6 +76,18 @@ public class TableDef
public string Name { get; set; }
public string KeyName { get; set; }
public ScalarAttributeType KeyType { get; set; }
public string RangeKeyName { get; set; }
public ScalarAttributeType RangeKeyType { get; set; }
public List<LocalSecondaryIndex> LocalSecondaryIndexes { get; set; } = new List<LocalSecondaryIndex>();
}


[CollectionDefinition("DynamoDb collection", DisableParallelization = true)]
public class DynamoDbCollection : ICollectionFixture<DynamoDbIntegrationTests<Startup>>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
}

33 changes: 23 additions & 10 deletions NotesApi.Tests/DynamoDbMockWebApplicationFactory.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using System.Data.Common;
using NotesApi;
using NotesApi.V1.Infrastructure;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NotesApi.V1.Infrastructure;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.Model;
using System.Linq;

namespace NotesApi.Tests
{
Expand Down Expand Up @@ -48,10 +46,25 @@ private static void EnsureTablesExist(IAmazonDynamoDB dynamoDb, List<TableDef> t
{
try
{
var keySchema = new List<KeySchemaElement> { new KeySchemaElement(table.KeyName, KeyType.HASH) };
var attributes = new List<AttributeDefinition> { new AttributeDefinition(table.KeyName, table.KeyType) };
if (!string.IsNullOrEmpty(table.RangeKeyName))
{
keySchema.Add(new KeySchemaElement(table.RangeKeyName, KeyType.RANGE));
attributes.Add(new AttributeDefinition(table.RangeKeyName, table.RangeKeyType));
}

var indexRangeKey = table.LocalSecondaryIndexes.SelectMany(x => x.KeySchema).FirstOrDefault(y => y.KeyType == KeyType.RANGE);
if (null != indexRangeKey)
attributes.Add(new AttributeDefinition(indexRangeKey.AttributeName, ScalarAttributeType.S)); // Assume a string for now.

var request = new CreateTableRequest(table.Name,
new List<KeySchemaElement> { new KeySchemaElement(table.KeyName, KeyType.HASH) },
new List<AttributeDefinition> { new AttributeDefinition(table.KeyName, table.KeyType) },
new ProvisionedThroughput(3, 3));
keySchema,
attributes,
new ProvisionedThroughput(3, 3))
{
LocalSecondaryIndexes = table.LocalSecondaryIndexes
};
_ = dynamoDb.CreateTableAsync(request).GetAwaiter().GetResult();
}
catch (ResourceInUseException)
Expand Down
31 changes: 31 additions & 0 deletions NotesApi.Tests/InMemoryTraceListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace NotesApi.Tests
{
public class InMemoryTraceListener : TraceListener
{
private readonly List<string> _traces = new List<string>();

public void Reset()
{
_traces.Clear();
}

public bool ContainsTrace(string msg)
{
return _traces.Any(x => x.Contains(msg));
}

public override void Write(string message)
{
_traces.Add(message);
}

public override void WriteLine(string message)
{
_traces.Add(message);
}
}
}
39 changes: 26 additions & 13 deletions NotesApi.Tests/NotesApi.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.11.0" />
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
<PackageReference Include="Bogus" Version="25.0.4" />
<PackageReference Include="Moq" Version="4.10.1" />
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.3" />
</ItemGroup>
<ItemGroup>
<Compile Remove="TestResults\**" />
<Content Remove="TestResults\**" />
<EmbeddedResource Remove="TestResults\**" />
<None Remove="TestResults\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.16.0" />
<PackageReference Include="coverlet.msbuild" Version="3.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.13" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Bogus" Version="33.0.2" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NotesApi\NotesApi.csproj" />
Expand Down
7 changes: 7 additions & 0 deletions NotesApi.Tests/RunCoverage.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
md .\TestResults

dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=TestResults\coverage.cobertura.xml
reportgenerator "-reports:TestResults/coverage.cobertura.xml" "-targetdir:TestResults/CoverageReport" -reporttypes:Html
call .\TestResults\CoverageReport\index.html

rem pause
48 changes: 26 additions & 22 deletions NotesApi.Tests/V1/Controllers/BaseControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,46 @@
using Microsoft.AspNetCore.Routing;
using NotesApi.V1;
using NotesApi.V1.Controllers;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace NotesApi.Tests.V1.Controllers
{
[TestFixture]
public class BaseControllerTests
public class BaseControllerFacts
{
private BaseController _classUnderTest;
private ControllerContext _controllerContext;
private HttpContext _httpContext;
private readonly BaseController _sut;
private readonly ControllerContext _controllerContext;
private readonly HttpContext _stubHttpContext;

[SetUp]
public void Setup()
public BaseControllerFacts()
{
_httpContext = new DefaultHttpContext();
_classUnderTest = new BaseController();
_controllerContext = new ControllerContext(new ActionContext(_httpContext, new RouteData(), new ControllerActionDescriptor()));
_classUnderTest.ControllerContext = _controllerContext;
_stubHttpContext = new DefaultHttpContext();
_controllerContext = new ControllerContext(new ActionContext(_stubHttpContext, new RouteData(), new ControllerActionDescriptor()));
_sut = new BaseController();

_sut.ControllerContext = _controllerContext;
}

[Test]
public void ShouldThrowExceptionIfNoCorrelationHeader()
[Fact]
public void GetCorrelationShouldThrowExceptionIfCorrelationHeaderUnavailable()
{
_classUnderTest.Invoking(x => x.GetCorrelationId()).Should().Throw<KeyNotFoundException>().WithMessage("Request is missing a correlationId");
// Arrange + Act + Assert
_sut.Invoking(x => x.GetCorrelationId())
.Should().Throw<KeyNotFoundException>()
.WithMessage("Request is missing a correlationId");
}

[Test]
[Fact]
public void GetCorrelationShouldReturnCorrelationIdWhenExists()
{
_httpContext.Request.Headers.Add(CorrelationConstants.CorrelationId, "123");
var response = _classUnderTest.GetCorrelationId();
response.Should().BeEquivalentTo("123");
// Arrange
_stubHttpContext.Request.Headers.Add(CorrelationConstants.CorrelationId, "123");

// Act
var result = _sut.GetCorrelationId();

// Assert
result.Should().BeEquivalentTo("123");
}


Expand Down
Loading