-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
split dev server out from main Nessie project
- Loading branch information
Showing
18 changed files
with
807 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Abstractions.TestingHelpers; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace DevServer.Tests | ||
{ | ||
public class AutoRefreshTests | ||
{ | ||
private readonly AutoRefresh autorefresh; | ||
|
||
public AutoRefreshTests() | ||
{ | ||
this.autorefresh = new AutoRefresh(); | ||
} | ||
|
||
[Fact] | ||
public async Task KeepAliveLoop_CancelRequested_IsCanceled() | ||
{ | ||
var tokenSource = new CancellationTokenSource(); | ||
|
||
// system under test | ||
var task = autorefresh.KeepAliveLoop(tokenSource.Token); | ||
tokenSource.Cancel(); | ||
|
||
await Assert.ThrowsAsync<TaskCanceledException>(() => task); | ||
} | ||
|
||
[Fact] | ||
public void SendPollResponse_WithTwoRefreshes_ContainsTwoRefreshes() | ||
{ | ||
autorefresh.SendClientRefresh(); | ||
autorefresh.SendClientRefresh(); | ||
|
||
var response = autorefresh.SendPollResponse(); | ||
|
||
Assert.Equal( | ||
"data: refresh\r\n\r\ndata: refresh\r\n\r\n", | ||
new StreamReader(response.Body).ReadToEnd() | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task AppendAutoRefreshJavaScript_HtmlFile_AppendsAutoRefreshJavaScript() | ||
{ | ||
var response = CreateMemoryStreamResponse("howdy", "text/html"); | ||
|
||
// system under test | ||
await autorefresh.AppendAutoRefreshJavaScript(response, response.Body, CancellationToken.None); | ||
|
||
response.Body.Position = 0; | ||
var content = new StreamReader(response.Body).ReadToEnd(); | ||
|
||
Assert.Contains("howdy", content); | ||
Assert.Contains("window.location.reload", content); | ||
|
||
response.Body.Dispose(); | ||
} | ||
|
||
[Fact] | ||
public async Task AppendAutoRefreshJavaScript_NotHtmlFile_DoesNotAppendAutoRefreshJavaScript() | ||
{ | ||
var response = CreateMemoryStreamResponse("{}", "application/json"); | ||
|
||
// system under test | ||
await autorefresh.AppendAutoRefreshJavaScript(response, response.Body, CancellationToken.None); | ||
|
||
response.Body.Position = 0; | ||
var content = new StreamReader(response.Body).ReadToEnd(); | ||
|
||
Assert.Equal("{}", content.Trim()); | ||
|
||
response.Body.Dispose(); | ||
} | ||
|
||
private static HttpServerResponse CreateMemoryStreamResponse(string content, string contentType) | ||
{ | ||
var stream = new MemoryStream(); | ||
var writer = new StreamWriter(stream); | ||
writer.WriteLine(content); | ||
writer.Flush(); | ||
var response = new HttpServerResponse(HttpStatusCode.OK, new WebHeaderCollection(), stream, contentType); | ||
return response; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<None Remove="IntegrationTests\WebRoot\fruits\apple.html" /> | ||
<None Remove="IntegrationTests\WebRoot\fruits\pineapple.html" /> | ||
<None Remove="IntegrationTests\WebRoot\fruits\tomato.html" /> | ||
<None Remove="IntegrationTests\WebRoot\index.html" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="IntegrationTests\WebRoot\fruits\apple.html"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="IntegrationTests\WebRoot\fruits\pineapple.html"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="IntegrationTests\WebRoot\fruits\tomato.html"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="IntegrationTests\WebRoot\index.html"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</Content> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" /> | ||
<PackageReference Include="System.IO.Abstractions" Version="2.1.0.256" /> | ||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="2.1.0.256" /> | ||
<PackageReference Include="xunit" Version="2.3.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DevServer\DevServer.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Abstractions.TestingHelpers; | ||
using System.Net; | ||
using System.Text; | ||
using Xunit; | ||
|
||
namespace DevServer.Tests | ||
{ | ||
public class HttpServerResponseTests | ||
{ | ||
[Fact] | ||
public void HtmlResponse_DefaultParams_IsSuccessfulHtmlResponse() | ||
{ | ||
var response = HttpServerResponse.HtmlResponse("Hello"); | ||
|
||
Assert.Equal("Hello", new StreamReader(response.Body).ReadToEnd()); | ||
Assert.Equal("text/html", response.ContentType); | ||
Assert.Equal(200, (int)response.StatusCode); | ||
|
||
response.Body.Dispose(); | ||
} | ||
|
||
[Fact] | ||
public void StringResponse_WithSpecifiedParameters_UsesArguments() | ||
{ | ||
var response = HttpServerResponse.StringResponse("{}", "application/json", HttpStatusCode.OK); | ||
|
||
Assert.Equal("{}", new StreamReader(response.Body).ReadToEnd()); | ||
Assert.Equal("application/json", response.ContentType); | ||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
|
||
response.Body.Dispose(); | ||
} | ||
|
||
[Fact] | ||
public void FileResponse_WithModifiedFileTime_SetsAsLastModifiedTimeHeader() | ||
{ | ||
var fs = new MockFileSystem(new Dictionary<string, MockFileData> | ||
{ | ||
[@"C:\myserver\hello.json"] = new MockFileData("{}") | ||
}); | ||
// set file modification time | ||
var written = DateTime.Now.AddDays(-1); | ||
fs.File.SetLastWriteTime(@"C:\myserver\hello.json", written); | ||
|
||
// system under test | ||
var response = HttpServerResponse.FileResponse(fs, @"C:\myserver\hello.json"); | ||
|
||
Assert.Equal("{}", new StreamReader(response.Body).ReadToEnd()); | ||
Assert.Equal(written.ToString("r"), response.Headers[HttpRequestHeader.LastModified]); | ||
|
||
response.Body.Dispose(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Net.Http; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace DevServer.Tests | ||
{ | ||
/// <summary> | ||
/// Integration tests. These tests create and assert against a running webserver! | ||
/// </summary> | ||
public class IntegrationTests | ||
{ | ||
[Fact] | ||
[Trait("Category", "Integration")] | ||
public async Task ServeWebsite() | ||
{ | ||
var http = new HttpClient(); | ||
var cwd = Path.Combine( | ||
Directory.GetCurrentDirectory(), | ||
@"IntegrationTests\WebRoot\" | ||
); | ||
using(var server = new HttpServer(cwd, "localhost", 8080, enableAutorefresh: false)) | ||
{ | ||
server.Start(CancellationToken.None); | ||
|
||
await Get_NoPath_ShouldReturnIndexHtml(http); | ||
await Get_IndexPath_ShouldReturnIndexHtml(http); | ||
await Get_DirectoryPath_ShouldReturnDirectoryListing(http); | ||
} // server should end when it is disposed | ||
} | ||
|
||
private static async Task Get_NoPath_ShouldReturnIndexHtml(HttpClient http) | ||
{ | ||
var response = await http.GetAsync("http://localhost:8080/"); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
Assert.Equal("Hello World", content); | ||
} | ||
|
||
private static async Task Get_IndexPath_ShouldReturnIndexHtml(HttpClient http) | ||
{ | ||
var response = await http.GetAsync("http://localhost:8080/index.html"); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
Assert.Equal("Hello World", content); | ||
} | ||
|
||
private static async Task Get_DirectoryPath_ShouldReturnDirectoryListing(HttpClient http) | ||
{ | ||
var response = await http.GetAsync("http://localhost:8080/fruits/"); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
Assert.Contains("Directory Listing", content); | ||
Assert.Contains("apple", content); | ||
Assert.Contains("pineapple", content); | ||
Assert.Contains("tomato", content); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
apples are crunchy and delicious |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pineapples are sweet and delicious |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
tomatoes are of questionable fruit status |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello World |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Abstractions.TestingHelpers; | ||
using System.Net; | ||
using Xunit; | ||
|
||
namespace DevServer.Tests | ||
{ | ||
public class RequestHandlerTests | ||
{ | ||
private RequestHandler requestHandler; | ||
|
||
public RequestHandlerTests() | ||
{ | ||
var fs = new MockFileSystem(new Dictionary<string, MockFileData> | ||
{ | ||
[@"C:\myserver\index.html"] = new MockFileData("Welcome to my blog"), | ||
[@"C:\myserver\puppies.html"] = new MockFileData("this a page about my puppies"), | ||
[@"C:\myserver\puppies\fido.jpg"] = new MockFileData(Array.Empty<byte>()), | ||
[@"C:\myserver\puppies\boxer.jpg"] = new MockFileData(Array.Empty<byte>()), | ||
[@"C:\myserver\puppies\pogo.jpg"] = new MockFileData(Array.Empty<byte>()), | ||
[@"C:\private.txt"] = new MockFileData("the password is passw0rd"), | ||
}); | ||
this.requestHandler = new RequestHandler(@"C:\myserver\", fs); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithAbsolutePath_ReturnsContent() | ||
{ | ||
var response = requestHandler.GenerateResponse("/index.html"); | ||
Assert.Equal("Welcome to my blog", new StreamReader(response.Body).ReadToEnd()); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithRelativePath_ReturnsContent() | ||
{ | ||
var response = requestHandler.GenerateResponse("index.html"); | ||
Assert.Equal("Welcome to my blog", new StreamReader(response.Body).ReadToEnd()); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithBoundedDirectoryTraversal_EvaluatesTraversal() | ||
{ | ||
// this traversal is ok, because it's still under the web root | ||
var response = requestHandler.GenerateResponse("/puppies/../index.html"); | ||
Assert.Equal("Welcome to my blog", new StreamReader(response.Body).ReadToEnd()); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithEscapingDirectoryTraversal_DoesNotEvaluatesTraversal() | ||
{ | ||
// this traversal is NOT ok, because it's trying to escape the web root. | ||
var response = requestHandler.GenerateResponse("/../private.txt"); | ||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithHtmlFile_ReturnsHtmlContentType() | ||
{ | ||
var response = requestHandler.GenerateResponse("/index.html"); | ||
Assert.Equal("text/html", response.ContentType); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_WithJpegFile_ReturnsJpegContentType() | ||
{ | ||
var response = requestHandler.GenerateResponse("/puppies/fido.jpg"); | ||
Assert.Equal("image/jpeg", response.ContentType); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_NoFileName_ReturnsIndexHtml() | ||
{ | ||
var response = requestHandler.GenerateResponse("/"); | ||
Assert.Equal("Welcome to my blog", new StreamReader(response.Body).ReadToEnd()); | ||
} | ||
|
||
[Fact] | ||
public void GenerateResponse_Directory_ReturnsDirectoryListing() | ||
{ | ||
var response = requestHandler.GenerateResponse("/puppies/"); | ||
string content = new StreamReader(response.Body).ReadToEnd(); | ||
|
||
Assert.Contains("Directory Listing", content); | ||
// we should assert that the listing has the three jpg files here, but this bug prevents it: | ||
// https://github.com/System-IO-Abstractions/System.IO.Abstractions/issues/405 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.