Skip to content

Commit bc485c0

Browse files
committed
initital commit
0 parents  commit bc485c0

26 files changed

+2750
-0
lines changed

.config/dotnet-tools.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"cake.tool": {
6+
"version": "1.1.0",
7+
"commands": [
8+
"dotnet-cake"
9+
]
10+
}
11+
}
12+
}

.github/workflows/deploy.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Deploy
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
deploy:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@v2
12+
with:
13+
fetch-depth: 0
14+
15+
- name: Deploy to NuGet
16+
env:
17+
FLOAT_NUGET_TOKEN: ${{ secrets.FLOAT_NUGET_TOKEN }}
18+
run: ./build.sh --task=Deploy --configuration=Release --nugetUrl="https://api.nuget.org/v3/index.json" --nugetToken="${FLOAT_NUGET_TOKEN}"

.github/workflows/test.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Setup .NET
17+
uses: actions/setup-dotnet@v1
18+
with:
19+
dotnet-version: 5.0.x
20+
- name: Restore dependencies
21+
run: dotnet restore
22+
- name: Build
23+
run: dotnet build --no-restore
24+
- name: Test
25+
run: dotnet test --no-build --verbosity normal

.gitignore

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Autosave files
2+
*~
3+
4+
# build
5+
[Oo]bj/
6+
[Bb]in/
7+
packages/
8+
TestResults/
9+
10+
# globs
11+
Makefile.in
12+
*.DS_Store
13+
*.sln.cache
14+
*.suo
15+
*.cache
16+
*.pidb
17+
*.userprefs
18+
*.usertasks
19+
config.log
20+
config.make
21+
config.status
22+
aclocal.m4
23+
install-sh
24+
autom4te.cache/
25+
*.user
26+
*.tar.gz
27+
tarballs/
28+
test-results/
29+
Thumbs.db
30+
31+
# Mac bundle stuff
32+
*.dmg
33+
*.app
34+
35+
# resharper
36+
*_Resharper.*
37+
*.Resharper
38+
39+
# dotCover
40+
*.dotCover
41+
TestResult.xml
42+
Resource.designer.cs
43+
.vs
44+
45+
.vscode
46+
*/coverage.*.xml
47+
48+
#Cake
49+
tools/*
50+
!tools/packages.config
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net5.0</TargetFramework>
4+
<IsPackable>false</IsPackable>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
9+
<PackageReference Include="NunitXml.TestLogger" Version="3.0.117" />
10+
<PackageReference Include="xunit" Version="2.4.1" />
11+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
<PrivateAssets>all</PrivateAssets>
13+
</PackageReference>
14+
<PackageReference Include="coverlet.msbuild" Version="3.1.0">
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
<PrivateAssets>all</PrivateAssets>
17+
</PackageReference>
18+
<PackageReference Include="Float.TinCan.ActivityLibrary" Version="0.7.1" />
19+
</ItemGroup>
20+
<ItemGroup>
21+
<ProjectReference Include="..\Float.HttpServer\Float.HttpServer.csproj" />
22+
</ItemGroup>
23+
</Project>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
using Float.TinCan.ActivityLibrary;
7+
using Xunit;
8+
9+
namespace Float.HttpServer.Tests
10+
{
11+
public class HttpRouterTests
12+
{
13+
readonly HttpClient client = new HttpClient();
14+
15+
[Fact]
16+
public async Task TestAddResponseMiddleware()
17+
{
18+
var port = PortSelector.SelectForAddress("127.0.0.1", 55555);
19+
var server = new LocalHttpServer("127.0.0.1", port);
20+
server.Get("/1234", new TestResponder());
21+
server.Start();
22+
var response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
23+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
24+
25+
server.Use(
26+
new List<HttpRouter.HttpMethod> { HttpRouter.HttpMethod.GET },
27+
(HttpListenerRequest request, ref HttpListenerResponse response) =>
28+
{
29+
response.StatusCode = (int)HttpStatusCode.NotFound;
30+
return true;
31+
});
32+
response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
33+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
34+
35+
server.Use(
36+
new List<HttpRouter.HttpMethod> { HttpRouter.HttpMethod.GET },
37+
(HttpListenerRequest request, ref HttpListenerResponse response) =>
38+
{
39+
response.StatusCode = (int)HttpStatusCode.NotFound;
40+
return false;
41+
});
42+
43+
response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
44+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
45+
server.Dispose();
46+
}
47+
48+
[Fact]
49+
public async Task TestAddResponser()
50+
{
51+
var port = PortSelector.SelectForAddress("127.0.0.1", 55555);
52+
var server = new LocalHttpServer("127.0.0.1", port);
53+
server.Get("/1234", new TestResponder());
54+
server.Start();
55+
56+
var response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
57+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
58+
59+
response = await GetResponse($"http://{server.Host}:{server.Port}/1234/5678");
60+
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
61+
62+
server.Get("/1234/:id", new TestResponder());
63+
response = await GetResponse($"http://{server.Host}:{server.Port}/1234/5678");
64+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
65+
server.Dispose();
66+
}
67+
68+
[Fact]
69+
public async Task TestSetDefaultResponder()
70+
{
71+
var port = PortSelector.SelectForAddress("127.0.0.1", 55555);
72+
var server = new LocalHttpServer("127.0.0.1", port);
73+
server.SetDefaultResponder(new TestResponder());
74+
server.Start();
75+
76+
var response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
77+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
78+
79+
response = await GetResponse($"http://{server.Host}:{server.Port}/12345678");
80+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
81+
server.Dispose();
82+
}
83+
84+
[Fact]
85+
public async Task TestSetErrorResponder()
86+
{
87+
var port = PortSelector.SelectForAddress("127.0.0.1", 56000);
88+
var server = new LocalHttpServer("127.0.0.1", port);
89+
// Check error responder.
90+
server.SetErrorResponder(new ErrorResponder404());
91+
server.Start();
92+
var response = await GetResponse($"http://{server.Host}:{server.Port}/1234");
93+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
94+
server.Dispose();
95+
}
96+
97+
private async Task<HttpResponseMessage> GetResponse(string url)
98+
{
99+
var request = new HttpRequestMessage
100+
{
101+
RequestUri = new Uri(url)
102+
};
103+
104+
return await client.SendAsync(request);
105+
}
106+
107+
class TestResponder : IHttpResponder
108+
{
109+
public void GenerateResponse(in HttpListenerRequest httpRequest, ref HttpListenerResponse httpResponse, IDictionary<string, string> parameters)
110+
{
111+
httpResponse.StatusCode = (int)HttpStatusCode.OK;
112+
}
113+
}
114+
}
115+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
using Float.TinCan.ActivityLibrary;
7+
using Xunit;
8+
9+
namespace Float.HttpServer.Tests
10+
{
11+
public class LocalHttpServerTests
12+
{
13+
[Fact]
14+
public void TestLifecycle()
15+
{
16+
var port = PortSelector.SelectForAddress("127.0.0.1");
17+
var server = new LocalHttpServer("127.0.0.1", port);
18+
Assert.False(server.IsServerAvailable());
19+
server.Start();
20+
Assert.True(server.IsServerAvailable());
21+
server.Restart(PortSelector.SelectForAddress("127.0.0.1"));
22+
Assert.True(server.IsServerAvailable());
23+
server.Stop();
24+
Assert.False(server.IsServerAvailable());
25+
}
26+
27+
[Fact]
28+
public async Task TestRequest()
29+
{
30+
var port = PortSelector.SelectForAddress("127.0.0.1");
31+
var server = new LocalHttpServer("127.0.0.1", port);
32+
server.Get("/1234", new TestResponder());
33+
server.Start();
34+
35+
using (var client = new HttpClient())
36+
{
37+
var request = new HttpRequestMessage
38+
{
39+
RequestUri = new Uri($"http://{server.Host}:{server.Port}/1234")
40+
};
41+
42+
var response = await client.SendAsync(request);
43+
Assert.Equal(418, (int)response.StatusCode);
44+
45+
var request2 = new HttpRequestMessage
46+
{
47+
RequestUri = new Uri($"http://{server.Host}:{server.Port}/12345")
48+
};
49+
50+
var response2 = await client.SendAsync(request2);
51+
Assert.Equal(HttpStatusCode.InternalServerError, response2.StatusCode);
52+
}
53+
54+
server.Stop();
55+
}
56+
57+
[Fact]
58+
public void TestBrokenLifecycle()
59+
{
60+
var port = PortSelector.SelectForAddress("127.0.0.1");
61+
var server = new LocalHttpServer("127.0.0.1", port);
62+
server.Start();
63+
Assert.True(server.IsServerAvailable());
64+
server.Restart(port);
65+
Assert.True(server.IsServerAvailable());
66+
server.Restart(port);
67+
Assert.True(server.IsServerAvailable());
68+
server.Dispose();
69+
70+
// FIXME: I should throw a disposed exception.
71+
Assert.False(server.IsServerAvailable());
72+
}
73+
74+
[Fact]
75+
public void TestStartifecycle()
76+
{
77+
var port = PortSelector.SelectForAddress("127.0.0.1");
78+
var server = new LocalHttpServer("127.0.0.1", port);
79+
server.Start();
80+
server.Start();
81+
Assert.True(server.IsServerAvailable());
82+
server.Restart(port);
83+
Assert.True(server.IsServerAvailable());
84+
server.Restart(port);
85+
Assert.True(server.IsServerAvailable());
86+
}
87+
88+
[Fact]
89+
public void TestStopLifecycle()
90+
{
91+
var port = PortSelector.SelectForAddress("127.0.0.1");
92+
var server = new LocalHttpServer("127.0.0.1", port);
93+
server.Stop();
94+
Assert.False(server.IsServerAvailable());
95+
server.Stop();
96+
Assert.False(server.IsServerAvailable());
97+
server.Start();
98+
Assert.True(server.IsServerAvailable());
99+
server.Stop();
100+
server.Restart(port);
101+
Assert.True(server.IsServerAvailable());
102+
}
103+
}
104+
105+
class TestResponder : IHttpResponder
106+
{
107+
public void GenerateResponse(in HttpListenerRequest httpRequest, ref HttpListenerResponse httpResponse, IDictionary<string, string> parameters)
108+
{
109+
// I'm a little curious why they don't have this in the library...
110+
httpResponse.StatusCode = 418;
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)