Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 9d1fea0

Browse files
method not allowed
1 parent 9e1725e commit 9d1fea0

12 files changed

Lines changed: 201 additions & 36 deletions

src/SqlStreamStore.HAL.Tests/AllStreamMessageTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ public class AllStreamMessageTests : IDisposable
1010
{
1111
public AllStreamMessageTests()
1212
{
13-
_fixture = new MiddlewareFixture();
13+
_fixture = new SqlStreamStoreHalMiddlewareFixture();
1414
}
1515

1616
public void Dispose() => _fixture.Dispose();
17-
private readonly MiddlewareFixture _fixture;
17+
private readonly SqlStreamStoreHalMiddlewareFixture _fixture;
1818
private const string HeadOfAll = "stream?d=b&m=20&p=-1";
1919

2020
[Fact]
Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,50 @@
11
namespace SqlStreamStore.HAL.Tests
22
{
33
using System;
4-
using System.Linq;
54
using System.Net.Http;
65
using System.Net.Http.Headers;
7-
using System.Threading.Tasks;
8-
using SqlStreamStore.Streams;
6+
using AppFunc = System.Func<
7+
System.Collections.Generic.IDictionary<string, object>,
8+
System.Threading.Tasks.Task>;
9+
10+
using MidFunc = System.Func<
11+
System.Func<
12+
System.Collections.Generic.IDictionary<string, object>,
13+
System.Threading.Tasks.Task>,
14+
System.Func<
15+
System.Collections.Generic.IDictionary<string, object>,
16+
System.Threading.Tasks.Task>>;
917

1018
public class MiddlewareFixture : IDisposable
1119
{
12-
public MiddlewareFixture()
20+
private readonly OwinHttpMessageHandler _messageHandler;
21+
22+
public MiddlewareFixture(AppFunc appFunc)
23+
: this(new OwinHttpMessageHandler(appFunc))
24+
{
25+
}
26+
27+
public MiddlewareFixture(MidFunc midFunc)
28+
: this(new OwinHttpMessageHandler(midFunc))
29+
{
30+
}
31+
32+
private MiddlewareFixture(OwinHttpMessageHandler messageHandler)
1333
{
14-
StreamStore = new InMemoryStreamStore();
15-
HttpClient = new HttpClient(
16-
new OwinHttpMessageHandler(SqlStreamStoreHalMiddleware.UseSqlStreamStoreHal(StreamStore)))
34+
_messageHandler = messageHandler;
35+
36+
HttpClient = new HttpClient(_messageHandler)
1737
{
1838
BaseAddress = new UriBuilder().Uri,
1939
DefaultRequestHeaders = { Accept = { new MediaTypeWithQualityHeaderValue("application/hal+json") } }
2040
};
2141
}
22-
23-
public IStreamStore StreamStore { get; }
24-
2542
public HttpClient HttpClient { get; }
2643

2744
public void Dispose()
2845
{
46+
_messageHandler.Dispose();
2947
HttpClient.Dispose();
30-
StreamStore.Dispose();
3148
}
32-
33-
public Task<AppendResult> WriteNMessages(string streamId, int n)
34-
=> StreamStore.AppendToStream(
35-
streamId,
36-
ExpectedVersion.Any,
37-
Enumerable.Range(0, n)
38-
.Select(_ => new NewStreamMessage(Guid.NewGuid(), "type", "{}", "{}"))
39-
.ToArray());
4049
}
4150
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
namespace SqlStreamStore.HAL.Tests
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Net;
7+
using System.Net.Http;
8+
using System.Threading.Tasks;
9+
using Microsoft.Owin;
10+
using Xunit;
11+
using AppFunc = System.Func<
12+
System.Collections.Generic.IDictionary<string, object>,
13+
System.Threading.Tasks.Task>;
14+
using MidFunc = System.Func<
15+
System.Func<
16+
System.Collections.Generic.IDictionary<string, object>,
17+
System.Threading.Tasks.Task>,
18+
System.Func<
19+
System.Collections.Generic.IDictionary<string, object>,
20+
System.Threading.Tasks.Task>>;
21+
22+
public class OnlyReadsAreHandledTests : IDisposable
23+
{
24+
private static readonly HttpMethod[] s_methods =
25+
{
26+
HttpMethod.Delete,
27+
HttpMethod.Options,
28+
HttpMethod.Post,
29+
HttpMethod.Put,
30+
HttpMethod.Trace,
31+
new HttpMethod("PATCH")
32+
};
33+
34+
private readonly IStreamStore _streamStore;
35+
private readonly AppFunc _methodNotAllowed;
36+
37+
public OnlyReadsAreHandledTests()
38+
{
39+
_streamStore = new InMemoryStreamStore();
40+
_methodNotAllowed = env =>
41+
{
42+
var context = new OwinContext(env);
43+
context.Response.StatusCode = 405;
44+
45+
return Task.CompletedTask;
46+
};
47+
}
48+
49+
public static IEnumerable<object[]> StreamCases()
50+
=> from method in s_methods
51+
from path in new[] { "", "/1", "/1/1" }
52+
select new object[] { method, path };
53+
54+
[Theory, MemberData(nameof(StreamCases))]
55+
public async Task non_supported_method_on_stream(HttpMethod method, string path)
56+
{
57+
using(var fixture = new MiddlewareFixture(
58+
ReadStreamMiddleware.UseStreamStore(_streamStore)(_methodNotAllowed)))
59+
{
60+
var response = await fixture.HttpClient.SendAsync(new HttpRequestMessage(method, path));
61+
62+
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
63+
}
64+
}
65+
66+
public static IEnumerable<object[]> AllStreamCases()
67+
=> from method in s_methods
68+
from path in new[] { "", "/1" }
69+
select new object[] { method, path };
70+
71+
72+
[Theory, MemberData(nameof(AllStreamCases))]
73+
public async Task non_supported_method_on_all_stream(HttpMethod method, string path)
74+
{
75+
using(var fixture = new MiddlewareFixture(
76+
ReadAllStreamMiddleware.UseStreamStore(_streamStore)(_methodNotAllowed)))
77+
{
78+
var response = await fixture.HttpClient.SendAsync(new HttpRequestMessage(method, path));
79+
80+
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
81+
}
82+
}
83+
84+
85+
public void Dispose() => _streamStore.Dispose();
86+
}
87+
}

src/SqlStreamStore.HAL.Tests/SqlStreamStore.HAL.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
2525
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
2626
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta1-build3642" />
27+
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.1" />
2728
</ItemGroup>
2829
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
2930
<PackageReference Include="System.Net.Http" Version="4.3.2" />
@@ -33,5 +34,4 @@
3334
<Reference Include="System.Net.Http" />
3435
<Reference Include="Microsoft.CSharp" />
3536
</ItemGroup>
36-
3737
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace SqlStreamStore.HAL.Tests
2+
{
3+
using System;
4+
using System.Linq;
5+
using System.Net.Http;
6+
using System.Threading.Tasks;
7+
using SqlStreamStore.Streams;
8+
using MidFunc = System.Func<
9+
System.Func<
10+
System.Collections.Generic.IDictionary<string, object>,
11+
System.Threading.Tasks.Task>,
12+
System.Func<
13+
System.Collections.Generic.IDictionary<string, object>,
14+
System.Threading.Tasks.Task>>;
15+
16+
public class SqlStreamStoreHalMiddlewareFixture : IDisposable
17+
{
18+
private readonly MiddlewareFixture _inner;
19+
public IStreamStore StreamStore { get; }
20+
public HttpClient HttpClient => _inner.HttpClient;
21+
22+
public SqlStreamStoreHalMiddlewareFixture()
23+
{
24+
StreamStore = new InMemoryStreamStore();
25+
_inner = new MiddlewareFixture(SqlStreamStoreHalMiddleware.UseSqlStreamStoreHal(StreamStore));
26+
}
27+
28+
public void Dispose()
29+
{
30+
StreamStore.Dispose();
31+
}
32+
33+
public Task<AppendResult> WriteNMessages(string streamId, int n)
34+
=> StreamStore.AppendToStream(
35+
streamId,
36+
ExpectedVersion.Any,
37+
Enumerable.Range(0, n)
38+
.Select(_ => new NewStreamMessage(Guid.NewGuid(), "type", "{}", "{}"))
39+
.ToArray());
40+
}
41+
}

src/SqlStreamStore.HAL.Tests/StreamMessageTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ public class StreamMessageTests
99
{
1010
public StreamMessageTests()
1111
{
12-
_fixture = new MiddlewareFixture();
12+
_fixture = new SqlStreamStoreHalMiddlewareFixture();
1313
}
1414

1515
public void Dispose() => _fixture.Dispose();
16-
private readonly MiddlewareFixture _fixture;
16+
private readonly SqlStreamStoreHalMiddlewareFixture _fixture;
1717
private const string HeadOfStream = "a-stream?d=b&m=20&p=-1";
1818

1919
[Fact]

src/SqlStreamStore.HAL.Tests/StreamNavigationTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ public class StreamNavigationTests : IDisposable
1212
private const string FirstLinkQuery = "d=f&m=20&p=0";
1313
private const string LastLinkQuery = "d=b&m=20&p=-1";
1414

15-
private readonly MiddlewareFixture _fixture;
15+
private readonly SqlStreamStoreHalMiddlewareFixture _fixture;
1616

1717
public StreamNavigationTests()
1818
{
19-
_fixture = new MiddlewareFixture();
19+
_fixture = new SqlStreamStoreHalMiddlewareFixture();
2020
}
2121

2222

src/SqlStreamStore.HAL/OwinContextExtensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace SqlStreamStore.HAL
99

1010
internal static class OwinContextExtensions
1111
{
12-
public static readonly RecyclableMemoryStreamManager s_StreamManager
12+
private static readonly RecyclableMemoryStreamManager s_StreamManager
1313
= new RecyclableMemoryStreamManager();
1414

1515
public static async Task WriteHalResponse(this IOwinContext context, Response response)
@@ -38,5 +38,8 @@ public static async Task WriteHalResponse(this IOwinContext context, Response re
3838
await stream.CopyToAsync(context.Response.Body, 8192, context.Request.CallCancelled);
3939
}
4040
}
41+
42+
public static bool IsGetOrHead(this IOwinContext context)
43+
=> context.Request.Method == "GET" || context.Request.Method == "HEAD";
4144
}
4245
}

src/SqlStreamStore.HAL/Properties/AssemblyInfo.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Reflection;
2+
using System.Runtime.CompilerServices;
23
using System.Runtime.InteropServices;
34

45
// General Information about an assembly is controlled through the following
@@ -34,4 +35,6 @@
3435
// [assembly: AssemblyVersion("1.0.*")]
3536

3637
[assembly: AssemblyVersion("1.0.0.0")]
37-
[assembly: AssemblyFileVersion("1.0.0.0")]
38+
[assembly: AssemblyFileVersion("1.0.0.0")]
39+
40+
[assembly: InternalsVisibleTo("SqlStreamStore.HAL.Tests")]

src/SqlStreamStore.HAL/AllStreamMiddleware.cs renamed to src/SqlStreamStore.HAL/ReadAllStreamMiddleware.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace SqlStreamStore.HAL
99
System.Threading.Tasks.Task>
1010
>;
1111

12-
internal static class AllStreamMiddleware
12+
internal static class ReadAllStreamMiddleware
1313
{
1414
public static MidFunc UseStreamStore(IReadonlyStreamStore streamStore)
1515
{
@@ -28,10 +28,10 @@ public static MidFunc UseStreamStore(IReadonlyStreamStore streamStore)
2828
}
2929

3030
private static bool IsStream(IOwinContext context)
31-
=> !context.Request.Path.HasValue;
31+
=> context.IsGetOrHead() && !context.Request.Path.HasValue;
3232

3333
private static bool IsStreamMessage(IOwinContext context)
34-
=> long.TryParse(context.Request.Path.Value?.Remove(0, 1), out var _);
34+
=> context.IsGetOrHead() && long.TryParse(context.Request.Path.Value?.Remove(0, 1), out var _);
3535

3636
private static MidFunc GetStream(AllStreamResource allStream) => next => async env =>
3737
{

0 commit comments

Comments
 (0)