Skip to content

Commit 07d933e

Browse files
authored
Merge d3df6f7 into ac48c18
2 parents ac48c18 + d3df6f7 commit 07d933e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+801
-65
lines changed

.github/workflows/build.yml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- uses: actions/cache@v2
3535
id: cache
3636
with:
37-
path: ~/.nuget/packages
37+
path: C:\Users\runneradmin\.nuget\packages
3838
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
3939
restore-keys: |
4040
${{ runner.os }}-nuget-
@@ -43,18 +43,43 @@ jobs:
4343
#if: steps.cache.outputs.cache-hit != 'true'
4444
run: |
4545
nuget restore Snittlistan.sln
46-
Get-ChildItem -Recurse C:\Users\runneradmin\.nuget
4746
4847
- name: Build
4948
run: msbuild build.build -t:All -p:Version=$env:BUILD_VERSION -p:WIX_PATH=$env:wix -p:NUnitConsoleRunnerPath=C:\Users\runneradmin\.nuget\packages\nunit.consolerunner\3.12.0\
5049

50+
- name: Upload a Build Artifact
51+
uses: actions/upload-artifact@v2
52+
with:
53+
name: 'Test Result'
54+
path: Build\_build\TestResult.html
55+
5156
- name: Push tag
5257
id: tag
5358
uses: laputansoft/[email protected]
5459
with:
5560
github_token: ${{ secrets.GITHUB_TOKEN }}
5661
tag: ${{ env.BUILD_VERSION }}
5762

63+
#- name: Comment pull request
64+
# uses: machine-learning-apps/pr-comment@master
65+
# if: ${{ github.event_name == 'pull_request' }}
66+
# env:
67+
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68+
# with:
69+
# path: Build\_build\TestResult.html
70+
71+
- name: Comment pull request
72+
uses: actions/[email protected]
73+
if: github.event_name == 'pull_request'
74+
with:
75+
github-token: ${{ secrets.GITHUB_TOKEN }}
76+
script: |
77+
const fs = require('fs');
78+
const filename = "Build/_build/TestResult.html";
79+
const contents = fs.readFileSync(filename, "utf8");
80+
const { issue: { number: issue_number }, repo: { owner, repo } } = context;
81+
github.issues.createComment({ issue_number, owner, repo, body: contents });
82+
5883
- name: Create release
5984
id: create_release
6085
uses: actions/create-release@v1

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ obj/
2727
_ReSharper*/
2828
[Tt]est[Rr]esult*
2929
packages
30-
Snittlistan.Web/Web.Release.config
3130
Snittlistan.Web/Snittlistan.Publish.xml
3231
Snittlistan.Web/App_Data/Database
3332
Tools/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#nullable enable
2+
3+
namespace Snittlistan.Test.ApiControllers.Infrastructure
4+
{
5+
public class IdGenerator
6+
{
7+
private int _currentId;
8+
9+
public int GetNext()
10+
{
11+
return ++_currentId;
12+
}
13+
}
14+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#nullable enable
2+
3+
namespace Snittlistan.Test.ApiControllers.Infrastructure
4+
{
5+
using System;
6+
using System.Collections;
7+
using System.Collections.Generic;
8+
using System.Collections.ObjectModel;
9+
using System.Data.Entity;
10+
using System.Data.Entity.Infrastructure;
11+
using System.Linq;
12+
using System.Linq.Expressions;
13+
using System.Reflection;
14+
using System.Threading.Tasks;
15+
using Snittlistan.Web.Infrastructure.Database;
16+
17+
public sealed class InMemoryDbSet<T> : IDbSet<T>, IDbAsyncEnumerable<T> where T : class
18+
{
19+
private readonly IdGenerator _generator;
20+
private readonly HashSet<T> _data;
21+
private readonly IQueryable<T> _query;
22+
23+
public InMemoryDbSet(IdGenerator generator)
24+
{
25+
_generator = generator;
26+
_data = new HashSet<T>();
27+
_query = _data.AsQueryable();
28+
}
29+
30+
public ObservableCollection<T> Local => new(_data);
31+
32+
public Type ElementType => _query.ElementType;
33+
34+
public Expression Expression => _query.Expression;
35+
36+
public IQueryProvider Provider => new InMemoryDbAsyncQueryProvider<T>(_query.Provider);
37+
38+
public IQueryable<T> AsQueryable()
39+
{
40+
return _query;
41+
}
42+
43+
public T Add(T entity)
44+
{
45+
_ = _data.Add(entity);
46+
Type type = typeof(T);
47+
string idPropertyName = $"{type.Name}Id";
48+
PropertyInfo propertyInfo = type.GetProperty(idPropertyName);
49+
if (propertyInfo == null)
50+
{
51+
throw new Exception($"No {idPropertyName} property found on {type.Name} class");
52+
}
53+
54+
propertyInfo.SetValue(entity, _generator.GetNext());
55+
56+
return entity;
57+
}
58+
59+
public T Attach(T entity)
60+
{
61+
_ = _data.Add(entity);
62+
return entity;
63+
}
64+
65+
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
66+
{
67+
throw new NotImplementedException();
68+
}
69+
70+
public T Create()
71+
{
72+
return Activator.CreateInstance<T>();
73+
}
74+
75+
public T Find(params object[] keyValues)
76+
{
77+
throw new NotImplementedException("Derive from FakeDbSet and override Find");
78+
}
79+
80+
public T Remove(T entity)
81+
{
82+
_ = _data.Remove(entity);
83+
return entity;
84+
}
85+
86+
public IEnumerator<T> GetEnumerator()
87+
{
88+
return _data.GetEnumerator();
89+
}
90+
91+
IEnumerator IEnumerable.GetEnumerator()
92+
{
93+
return _data.GetEnumerator();
94+
}
95+
96+
public IDbAsyncEnumerator<T> GetAsyncEnumerator()
97+
{
98+
return new InMemoryDbAsyncEnumerator<T>(GetEnumerator());
99+
}
100+
101+
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
102+
{
103+
return GetAsyncEnumerator();
104+
}
105+
}
106+
107+
public class InMemoryContext : ISnittlistanContext, IBitsContext
108+
{
109+
public InMemoryContext()
110+
{
111+
IdGenerator generator = new();
112+
DelayedTasks = new InMemoryDbSet<DelayedTask>(generator);
113+
PublishedTasks = new InMemoryDbSet<PublishedTask>(generator);
114+
Tenants = new InMemoryDbSet<Tenant>(generator);
115+
Teams = new InMemoryDbSet<Bits_Team>(generator);
116+
Hallar = new InMemoryDbSet<Bits_Hall>(generator);
117+
}
118+
119+
public IDbSet<DelayedTask> DelayedTasks { get; }
120+
121+
public IDbSet<PublishedTask> PublishedTasks { get; }
122+
123+
public IDbSet<Bits_Team> Teams { get; }
124+
125+
public IDbSet<Bits_Hall> Hallar { get; }
126+
127+
public IDbSet<Tenant> Tenants { get; }
128+
129+
public DbChangeTracker ChangeTracker => throw new NotImplementedException();
130+
131+
public int SaveChanges()
132+
{
133+
throw new NotImplementedException();
134+
}
135+
136+
public Task<int> SaveChangesAsync()
137+
{
138+
throw new NotImplementedException();
139+
}
140+
}
141+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#nullable enable
2+
3+
namespace Snittlistan.Test.ApiControllers.Infrastructure
4+
{
5+
using System.Collections.Generic;
6+
using System.Data.Entity.Infrastructure;
7+
using System.Linq;
8+
using System.Linq.Expressions;
9+
10+
public class InMemoryDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T>
11+
{
12+
public InMemoryDbAsyncEnumerable(IEnumerable<T> enumerable)
13+
: base(enumerable)
14+
{ }
15+
16+
public InMemoryDbAsyncEnumerable(Expression expression)
17+
: base(expression)
18+
{ }
19+
20+
public IQueryProvider Provider => new InMemoryDbAsyncQueryProvider<T>(this);
21+
22+
public IDbAsyncEnumerator<T> GetAsyncEnumerator()
23+
{
24+
return new InMemoryDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
25+
}
26+
27+
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
28+
{
29+
return GetAsyncEnumerator();
30+
}
31+
}
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#nullable enable
2+
3+
namespace Snittlistan.Test.ApiControllers.Infrastructure
4+
{
5+
using System.Collections.Generic;
6+
using System.Data.Entity.Infrastructure;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
public class InMemoryDbAsyncEnumerator<T> : IDbAsyncEnumerator<T>
11+
{
12+
private readonly IEnumerator<T> _inner;
13+
14+
public InMemoryDbAsyncEnumerator(IEnumerator<T> inner)
15+
{
16+
_inner = inner;
17+
}
18+
19+
public T Current => _inner.Current;
20+
21+
object? IDbAsyncEnumerator.Current => Current;
22+
23+
public void Dispose()
24+
{
25+
_inner.Dispose();
26+
}
27+
28+
public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
29+
{
30+
return Task.FromResult(_inner.MoveNext());
31+
}
32+
}
33+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#nullable enable
2+
3+
namespace Snittlistan.Test.ApiControllers.Infrastructure
4+
{
5+
using System.Data.Entity.Infrastructure;
6+
using System.Linq;
7+
using System.Linq.Expressions;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
11+
public class InMemoryDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
12+
{
13+
private readonly IQueryProvider _inner;
14+
15+
public InMemoryDbAsyncQueryProvider(IQueryProvider inner)
16+
{
17+
_inner = inner;
18+
}
19+
20+
public IQueryable CreateQuery(Expression expression)
21+
{
22+
return new InMemoryDbAsyncEnumerable<TEntity>(expression);
23+
}
24+
25+
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
26+
{
27+
return new InMemoryDbAsyncEnumerable<TElement>(expression);
28+
}
29+
30+
public object Execute(Expression expression)
31+
{
32+
return _inner.Execute(expression);
33+
}
34+
35+
public TResult Execute<TResult>(Expression expression)
36+
{
37+
return _inner.Execute<TResult>(expression);
38+
}
39+
40+
public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
41+
{
42+
return Task.FromResult(Execute(expression));
43+
}
44+
45+
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
46+
{
47+
return Task.FromResult(Execute<TResult>(expression));
48+
}
49+
}
50+
}

Snittlistan.Test/ApiControllers/WebApiIntegrationTest.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,40 @@ namespace Snittlistan.Test.ApiControllers
1515
using NUnit.Framework;
1616
using Raven.Client;
1717
using Snittlistan.Queue;
18+
using Snittlistan.Test.ApiControllers.Infrastructure;
1819
using Snittlistan.Web;
1920
using Snittlistan.Web.Infrastructure.Attributes;
21+
using Snittlistan.Web.Infrastructure.Database;
2022
using Snittlistan.Web.Infrastructure.Installers;
2123
using Snittlistan.Web.Infrastructure.IoC;
2224

2325
public abstract class WebApiIntegrationTest
2426
{
2527
protected HttpClient Client { get; private set; } = null!;
2628

29+
protected Databases Databases { get; private set; } = null!;
30+
2731
private IWindsorContainer Container { get; set; } = null!;
2832

2933
[SetUp]
30-
public void SetUp()
34+
public async Task SetUp()
3135
{
3236
HttpConfiguration configuration = new();
3337
Container = new WindsorContainer();
38+
InMemoryContext inMemoryContext = new();
3439
_ = Container.Install(
3540
new ControllerInstaller(),
3641
new ApiControllerInstaller(),
3742
new ControllerFactoryInstaller(),
3843
new RavenInstaller(DocumentStoreMode.InMemory),
44+
new TaskHandlerInstaller(),
45+
new DatabaseContextInstaller(() => new(inMemoryContext, inMemoryContext)),
3946
EventStoreInstaller.FromAssembly(typeof(MvcApplication).Assembly, DocumentStoreMode.InMemory),
4047
new EventStoreSessionInstaller(LifestyleType.Scoped));
4148
_ = Container.Register(Component.For<IMsmqTransaction>().Instance(Mock.Of<IMsmqTransaction>()));
42-
Task.Run(async () => await OnSetUp(Container)).Wait();
49+
await OnSetUp(Container);
4350

44-
MvcApplication.Bootstrap(Container, configuration);
51+
MvcApplication.Bootstrap(Container, configuration, () => new(inMemoryContext, inMemoryContext));
4552
Client = new HttpClient(new HttpServer(configuration));
4653
OnlyLocalAllowedAttribute.SkipValidation = true;
4754

Snittlistan.Test/Snittlistan.Test.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@
4747
<Reference Include="System.Xml" />
4848
</ItemGroup>
4949
<ItemGroup>
50+
<Compile Include="ApiControllers\Infrastructure\IdGenerator.cs" />
51+
<Compile Include="ApiControllers\Infrastructure\InMemoryContext.cs" />
5052
<Compile Include="ApiControllers\Task_Post_RegisterMatch.cs" />
53+
<Compile Include="ApiControllers\Infrastructure\InMemoryDbAsyncEnumerable.cs" />
54+
<Compile Include="ApiControllers\Infrastructure\InMemoryDbAsyncEnumerator.cs" />
55+
<Compile Include="ApiControllers\Infrastructure\InMemoryDbAsyncQueryProvider.cs" />
5156
<Compile Include="ApiControllers\WebApiIntegrationTest.cs" />
5257
<Compile Include="BitsClientTest.cs" />
5358
<Compile Include="BitsGateway.cs" />

0 commit comments

Comments
 (0)