-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
373 additions
and
83 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
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
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,242 @@ | ||
using System.Net; | ||
using System.IO.Compression; | ||
|
||
using Newtonsoft.Json; | ||
|
||
using Bundler.QA.Common; | ||
using Bundler.Server.Models; | ||
|
||
namespace Bundler.QA.Backend | ||
{ | ||
[NonParallelizable] | ||
internal class BundlerAPITest : BaseTest | ||
{ | ||
private HttpClient _client; | ||
|
||
[OneTimeSetUp] | ||
public void Setup() | ||
=> this._client = new() { BaseAddress = new Uri("http://localhost:5001") }; | ||
|
||
[OneTimeTearDown] | ||
public void Teardown() | ||
=> this._client.Dispose(); | ||
|
||
private static string ChangeExtension(string filename) | ||
{ | ||
return Path.GetExtension(filename) switch | ||
{ | ||
".png" or ".jpg" or ".jpeg" => Path.ChangeExtension(filename, ".t3x"), | ||
".otf" or ".ttf" => Path.ChangeExtension(filename, ".bcfnt"), | ||
_ => filename | ||
}; | ||
} | ||
|
||
private static void ValidateZipArchive(string console, string base64, string[] filenames) | ||
{ | ||
Console.WriteLine($"Validating {console} archive..."); | ||
|
||
if (console == "ctr") // change extensions based on file extension (png, jpg, ttf) | ||
filenames = Array.ConvertAll(filenames, f => ChangeExtension(f)); | ||
|
||
var bytes = Convert.FromBase64String(base64); | ||
using var stream = new MemoryStream(bytes); | ||
|
||
using var zip = new ZipArchive(stream); | ||
|
||
Assert.That(zip.Entries, Has.Count.EqualTo(filenames.Length)); | ||
|
||
foreach (var filename in filenames) | ||
Assert.That(zip.Entries, Has.One.Matches<ZipArchiveEntry>(e => e.Name == filename)); | ||
} | ||
|
||
#region Textures | ||
|
||
[TestCase("dio.jpg")] | ||
[TestCase("lenny.png")] | ||
[Description("Test valid texture files (jpg, png) can upload (within size limits).")] | ||
public async Task TestTextureConversion(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
|
||
content.Add(fileBytes, filename, filename); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
var json = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); | ||
var expected = Path.ChangeExtension(filename, "t3x"); | ||
|
||
Assert.Multiple(() => { | ||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); | ||
Assert.That(json, Contains.Key("log")); | ||
Assert.That(json, Contains.Key(expected)); | ||
}); | ||
} | ||
|
||
[TestCase("cat_big_width.png")] | ||
[TestCase("cat_big_height.png")] | ||
[TestCase("cat_big_both.png")] | ||
[TestCase("cat_big_width.jpg")] | ||
[TestCase("cat_big_height.jpg")] | ||
[TestCase("cat_big_both.jpg")] | ||
[Description("Test large texture files cannot upload (> 1024 pixels).")] | ||
public async Task TestUploadBigTextureDimensions(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
|
||
content.Add(fileBytes, filename, filename); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.UnprocessableEntity)); | ||
} | ||
|
||
[TestCase("small_both.png")] | ||
[TestCase("small_height.png")] | ||
[TestCase("small_width.png")] | ||
[TestCase("small_both.jpg")] | ||
[TestCase("small_height.jpg")] | ||
[TestCase("small_width.jpg")] | ||
[Description("Test small texture files cannot upload (< 3 pixels).")] | ||
public async Task TestUploadSmallFileDimensions(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
|
||
content.Add(fileBytes, filename, filename); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.UnprocessableEntity)); | ||
} | ||
|
||
[TestCase] | ||
[Description("Test 'corrupt' texture files cannot upload.")] | ||
public async Task TestUploadCorruptTexture() | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData("corrupt.png")); | ||
|
||
content.Add(fileBytes, "corrupt.png", "corrupt.png"); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.UnprocessableEntity)); | ||
} | ||
|
||
[TestCase("chika.gif")] | ||
[TestCase("rectangle.bmp")] | ||
[TestCase("rectangle.tga")] | ||
[Description("Test invalid file types cannot upload.")] | ||
public async Task TestUploadInvalidTexture(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
|
||
content.Add(fileBytes, filename, filename); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.UnsupportedMediaType)); | ||
} | ||
|
||
#endregion | ||
|
||
#region Fonts | ||
|
||
[TestCase("Oneday.otf")] | ||
[TestCase("Perfect DOS VGA 437.ttf")] | ||
public async Task TestFontConversion(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
|
||
content.Add(fileBytes, filename, filename); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
var json = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); | ||
var expected = Path.ChangeExtension(filename, "bcfnt"); | ||
|
||
Assert.Multiple(() => { | ||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); | ||
Assert.That(json, Contains.Key("log")); | ||
Assert.That(json, Contains.Key(expected)); | ||
}); | ||
} | ||
|
||
[TestCase] | ||
[Description("Test 'corrupt' font files cannot upload.")] | ||
public async Task TestUploadCorruptFont() | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData("corrupt.ttf")); | ||
|
||
content.Add(fileBytes, "corrupt.ttf", "corrupt.ttf"); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.UnprocessableEntity)); | ||
} | ||
|
||
[TestCase] | ||
[Description("Test invalid font files cannot upload.")] | ||
public async Task TestUploadInvalidFont() | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
var fileBytes = new ByteArrayContent(Assets.GetData("arial.fnt")); | ||
|
||
content.Add(fileBytes, "arial.fnt", "arial.fnt"); | ||
var response = await this._client.PostAsync("convert", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); | ||
} | ||
|
||
#endregion | ||
|
||
#region Bundles | ||
|
||
[TestCase("bundle-macOS.zip")] | ||
[Description("Test uploading a bundle *directly* to /compile works")] | ||
public async Task TestUploadBundle(string filename) | ||
{ | ||
var content = new MultipartFormDataContent(); | ||
|
||
var fileBytes = new ByteArrayContent(Assets.GetData(filename)); | ||
content.Add(fileBytes, filename, filename); | ||
|
||
BundlerQuery query = new() | ||
{ | ||
Title = "Test Bundle", | ||
Description = "Test Bundle Description", | ||
Author = "Test Author", | ||
Version = "1.0.0", | ||
Targets = "ctr,hac,cafe" | ||
}; | ||
|
||
var response = await this._client.PostAsync($"compile?{query}", content); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); | ||
} | ||
|
||
/* super basic test, there's what, 120 possible combinations? */ | ||
[TestCase("Hello", "World", "MEMES", "0.1.0", "")] | ||
[TestCase("Hello", "World", "MEMES", "", "ctr,cafe,hac")] | ||
[TestCase("Hello", "World", "", "0.1.0", "ctr,cafe,hac")] | ||
[TestCase("Hello", "", "MEMES", "0.1.0", "ctr,cafe,hac")] | ||
[TestCase("", "World", "MEMES", "0.1.0", "ctr,cafe,hac")] | ||
[TestCase("", "", "", "", "")] | ||
[Description("Doing a POST request to /compile without a completed query should return a 400")] | ||
public async Task TestUploadBundleNoCompleteQuery(string title, string description, string author, string version, string targets) | ||
{ | ||
BundlerQuery query = new() | ||
{ | ||
Title = title, | ||
Description = description, | ||
Author = author, | ||
Version = version, | ||
Targets = targets | ||
}; | ||
|
||
var response = await this._client.PostAsync($"compile?{query}", new MultipartFormDataContent()); | ||
|
||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
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
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 |
---|---|---|
@@ -1,36 +1,32 @@ | ||
using System.Linq; | ||
using System.IO.Compression; | ||
|
||
namespace Bundler.QA.Common | ||
{ | ||
public class Assets | ||
{ | ||
private const string ResourcesPath = "Resources"; | ||
private static Assets? _instance = null; | ||
|
||
private readonly Dictionary<string, byte[]> AssetData = []; | ||
private readonly Dictionary<string, Dictionary<string, byte[]>> AssetCollections = []; | ||
|
||
private Assets() | ||
private static readonly Dictionary<string, byte[]> Data = []; | ||
|
||
static Assets() | ||
{ | ||
foreach (var file in Directory.GetFiles(ResourcesPath, "*", SearchOption.AllDirectories)) | ||
{ | ||
var (name, data) = (Path.GetFullPath(file), File.ReadAllBytes(file)); | ||
this.AssetData.Add(name, data); | ||
Data.Add(name, data); | ||
} | ||
} | ||
|
||
public static Assets Instance() | ||
=> _instance ??= new(); | ||
|
||
public string GetFilepath(string name) | ||
public static string GetFilepath(string name) | ||
{ | ||
var filepath = this.AssetData.Keys.FirstOrDefault(k => k.Contains(name)); | ||
var filepath = Data.Keys.FirstOrDefault(k => k.Contains(name)); | ||
return filepath is null ? throw new FileNotFoundException($"File not found: {name}") : filepath; | ||
} | ||
|
||
public byte[] GetData(string name) | ||
public static byte[] GetData(string name) | ||
{ | ||
return this.AssetData[name]; | ||
var bytes = Data.FirstOrDefault(k => k.Key.Contains(name)).Value; | ||
return bytes is null ? throw new FileNotFoundException($"File not found: {name}") : bytes; | ||
} | ||
} | ||
} |
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,13 @@ | ||
using System.IO.Compression; | ||
|
||
namespace Bundler.QA.Common | ||
{ | ||
public class BaseTest | ||
{ | ||
public static void CreateBundle(string name, Span<(string name, string path)> files) | ||
{ | ||
using var bundle = ZipFile.Open(name, ZipArchiveMode.Create); | ||
foreach (var file in files) bundle.CreateEntryFromFile(Assets.GetFilepath(file.name), file.path); | ||
} | ||
} | ||
} |
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.