mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-08-09 21:38:43 +00:00
Merge branch 'main' into account-banning
This commit is contained in:
commit
2eef5392a1
19 changed files with 581 additions and 25 deletions
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
|
@ -13,9 +13,9 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- { prettyName: Windows, fullName: windows-latest, database: true }
|
||||
- { prettyName: macOS, fullName: macos-latest, database: true }
|
||||
- { prettyName: Linux, fullName: ubuntu-latest, database: true }
|
||||
- { prettyName: Windows, fullName: windows-latest, database: true, webTest: false }
|
||||
- { prettyName: macOS, fullName: macos-latest, database: true, webTest: false }
|
||||
- { prettyName: Linux, fullName: ubuntu-latest, database: true, webTest: true }
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
DB_DATABASE: lighthouse
|
||||
|
@ -44,11 +44,19 @@ jobs:
|
|||
- name: Compile
|
||||
run: dotnet build -c Debug
|
||||
|
||||
- name: Test
|
||||
- name: Run tests on ProjectLighthouse.Tests
|
||||
continue-on-error: true
|
||||
run: dotnet test --logger "trx;LogFileName=${{github.workspace}}/TestResults-${{matrix.os.prettyName}}.trx"
|
||||
run: dotnet test --logger "trx;LogFileName=${{github.workspace}}/TestResults-${{matrix.os.prettyName}}-Tests.trx" ProjectLighthouse.Tests
|
||||
|
||||
- name: Run tests on ProjectLighthouse.Tests.GameApiTests
|
||||
continue-on-error: true
|
||||
run: dotnet test --logger "trx;LogFileName=${{github.workspace}}/TestResults-${{matrix.os.prettyName}}-GameApiTests.trx" ProjectLighthouse.Tests.GameApiTests
|
||||
|
||||
- name: Run tests on ProjectLighthouse.Tests.WebsiteTests
|
||||
if: ${{ matrix.os.webTest }}
|
||||
continue-on-error: true
|
||||
run: dotnet test --logger "trx;LogFileName=${{github.workspace}}/TestResults-${{matrix.os.prettyName}}-WebsiteTests.trx" ProjectLighthouse.Tests.WebsiteTests
|
||||
|
||||
# Attempt to upload results even if test fails.
|
||||
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
|
||||
- name: Upload Test Results
|
||||
|
@ -56,7 +64,7 @@ jobs:
|
|||
if: ${{ always() }}
|
||||
with:
|
||||
name: lighthouse-test-results-${{matrix.os.prettyName}}
|
||||
path: ${{github.workspace}}/TestResults-${{matrix.os.prettyName}}.trx
|
||||
path: ${{github.workspace}}/TestResults-${{matrix.os.prettyName}}-*.trx
|
||||
|
||||
- name: Process Test Results
|
||||
id: process-trx
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using LBPUnion.ProjectLighthouse.Types.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
namespace ProjectLighthouse.Tests.GameApiTests
|
||||
{
|
||||
public class AuthenticationTests : LighthouseTest
|
||||
public class AuthenticationTests : LighthouseServerTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ShouldReturnErrorOnNoPostData()
|
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
namespace ProjectLighthouse.Tests.GameApiTests
|
||||
{
|
||||
public class DatabaseTests : LighthouseTest
|
||||
public class DatabaseTests : LighthouseServerTest
|
||||
{
|
||||
[DatabaseFact]
|
||||
public async Task CanCreateUserTwice()
|
||||
|
@ -21,8 +23,6 @@ namespace LBPUnion.ProjectLighthouse.Tests
|
|||
Assert.NotNull(userB);
|
||||
|
||||
await database.RemoveUser(userA); // Only remove userA since userA and userB are the same user
|
||||
|
||||
await database.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,12 +4,13 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
namespace ProjectLighthouse.Tests.GameApiTests
|
||||
{
|
||||
public class MatchTests : LighthouseTest
|
||||
public class MatchTests : LighthouseServerTest
|
||||
{
|
||||
private static readonly SemaphoreSlim semaphore = new(1, 1);
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
|
||||
<PackageReference Include="xunit" Version="2.4.1"/>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ProjectLighthouse.Tests\ProjectLighthouse.Tests.csproj"/>
|
||||
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\ProjectLighthouse.Tests\ExampleFiles\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,15 +1,17 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
||||
using Xunit;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
namespace ProjectLighthouse.Tests.GameApiTests
|
||||
{
|
||||
public class SlotTests : LighthouseTest
|
||||
public class SlotTests : LighthouseServerTest
|
||||
{
|
||||
[DatabaseFact]
|
||||
public async Task ShouldOnlyShowUsersLevels()
|
|
@ -3,11 +3,12 @@ using System.IO;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
namespace ProjectLighthouse.Tests.GameApiTests
|
||||
{
|
||||
public class UploadTests : LighthouseTest
|
||||
public class UploadTests : LighthouseServerTest
|
||||
{
|
||||
public UploadTests()
|
||||
{
|
64
ProjectLighthouse.Tests.WebsiteTests/AdminTests.cs
Normal file
64
ProjectLighthouse.Tests.WebsiteTests/AdminTests.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using OpenQA.Selenium;
|
||||
using Xunit;
|
||||
|
||||
namespace ProjectLighthouse.Tests.WebsiteTests
|
||||
{
|
||||
public class AdminTests : LighthouseWebTest
|
||||
{
|
||||
public const string AdminPanelButtonXPath = "/html/body/div/header/div/div/div/a[2]";
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldShowAdminPanelButtonWhenAdmin()
|
||||
{
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||
|
||||
WebToken webToken = new()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = HashHelper.GenerateAuthToken(),
|
||||
};
|
||||
|
||||
database.WebTokens.Add(webToken);
|
||||
user.IsAdmin = true;
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/");
|
||||
this.Driver.Manage().Cookies.AddCookie(new Cookie("LighthouseToken", webToken.UserToken));
|
||||
this.Driver.Navigate().Refresh();
|
||||
|
||||
Assert.Contains("Admin Panel", this.Driver.FindElement(By.XPath(AdminPanelButtonXPath)).Text);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldNotShowAdminPanelButtonWhenNotAdmin()
|
||||
{
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||
|
||||
WebToken webToken = new()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = HashHelper.GenerateAuthToken(),
|
||||
};
|
||||
|
||||
database.WebTokens.Add(webToken);
|
||||
user.IsAdmin = false;
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/");
|
||||
this.Driver.Manage().Cookies.AddCookie(new Cookie("LighthouseToken", webToken.UserToken));
|
||||
this.Driver.Navigate().Refresh();
|
||||
|
||||
Assert.DoesNotContain("Admin Panel", this.Driver.FindElement(By.XPath(AdminPanelButtonXPath)).Text);
|
||||
}
|
||||
}
|
||||
}
|
106
ProjectLighthouse.Tests.WebsiteTests/AuthenticationTests.cs
Normal file
106
ProjectLighthouse.Tests.WebsiteTests/AuthenticationTests.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenQA.Selenium;
|
||||
using Xunit;
|
||||
|
||||
namespace ProjectLighthouse.Tests.WebsiteTests
|
||||
{
|
||||
public class AuthenticationTests : LighthouseWebTest
|
||||
{
|
||||
[DatabaseFact]
|
||||
public async Task ShouldLoginWithPassword()
|
||||
{
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
|
||||
string password = HashHelper.Sha256Hash(HashHelper.GenerateRandomBytes(64).ToArray());
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash(HashHelper.Sha256Hash(password)));
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||
this.Driver.FindElement(By.Id("password")).SendKeys(password);
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||
Assert.NotNull(webToken);
|
||||
|
||||
await database.RemoveUser(user);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldNotLoginWithNoPassword()
|
||||
{
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("just like the hindenberg,"));
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||
Assert.Null(webToken);
|
||||
|
||||
await database.RemoveUser(user);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldNotLoginWithWrongPassword()
|
||||
{
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||
this.Driver.FindElement(By.Id("password")).SendKeys("nah man");
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||
Assert.Null(webToken);
|
||||
|
||||
await database.RemoveUser(user);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldLoginWithInjectedCookie()
|
||||
{
|
||||
const string loggedInAsUsernameTextXPath = "/html/body/div/div/div/p[1]/b";
|
||||
|
||||
await using Database database = new();
|
||||
Random random = new();
|
||||
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||
|
||||
WebToken webToken = new()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = HashHelper.GenerateAuthToken(),
|
||||
};
|
||||
|
||||
database.WebTokens.Add(webToken);
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
INavigation navigation = this.Driver.Navigate();
|
||||
|
||||
navigation.GoToUrl(this.BaseAddress + "/");
|
||||
this.Driver.Manage().Cookies.AddCookie(new Cookie("LighthouseToken", webToken.UserToken));
|
||||
Assert.Throws<NoSuchElementException>(() => this.Driver.FindElement(By.XPath(loggedInAsUsernameTextXPath)));
|
||||
navigation.Refresh();
|
||||
Assert.True(this.Driver.FindElement(By.XPath(loggedInAsUsernameTextXPath)).Text == user.Username);
|
||||
|
||||
await database.RemoveUser(user);
|
||||
}
|
||||
}
|
||||
}
|
50
ProjectLighthouse.Tests.WebsiteTests/LighthouseWebTest.cs
Normal file
50
ProjectLighthouse.Tests.WebsiteTests/LighthouseWebTest.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using Xunit;
|
||||
|
||||
namespace ProjectLighthouse.Tests.WebsiteTests
|
||||
{
|
||||
[Collection(nameof(LighthouseWebTest))]
|
||||
public class LighthouseWebTest : IDisposable
|
||||
{
|
||||
public readonly IWebHost WebHost = new WebHostBuilder().UseKestrel().UseStartup<TestStartup>().UseWebRoot("StaticFiles").Build();
|
||||
public readonly string BaseAddress;
|
||||
|
||||
public readonly IWebDriver Driver;
|
||||
|
||||
public LighthouseWebTest()
|
||||
{
|
||||
this.WebHost.Start();
|
||||
|
||||
IServerAddressesFeature? serverAddressesFeature = WebHost.ServerFeatures.Get<IServerAddressesFeature>();
|
||||
if (serverAddressesFeature == null) throw new ArgumentNullException();
|
||||
|
||||
this.BaseAddress = serverAddressesFeature.Addresses.First();
|
||||
|
||||
ChromeOptions chromeOptions = new();
|
||||
if (Convert.ToBoolean(Environment.GetEnvironmentVariable("CI") ?? "false"))
|
||||
{
|
||||
chromeOptions.AddArgument("headless");
|
||||
chromeOptions.AddArgument("no-sandbox");
|
||||
chromeOptions.AddArgument("disable-dev-shm-usage");
|
||||
Console.WriteLine("We are in a CI environment, so chrome headless mode has been enabled.");
|
||||
}
|
||||
|
||||
this.Driver = new ChromeDriver(chromeOptions);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Driver.Close();
|
||||
this.Driver.Dispose();
|
||||
this.WebHost.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
|
||||
<PackageReference Include="Selenium.WebDriver" Version="4.1.0"/>
|
||||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="96.0.4664.4500"/>
|
||||
<PackageReference Include="xunit" Version="2.4.1"/>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ProjectLighthouse.Tests\ProjectLighthouse.Tests.csproj"/>
|
||||
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
84
ProjectLighthouse.Tests.WebsiteTests/RegisterTests.cs
Normal file
84
ProjectLighthouse.Tests.WebsiteTests/RegisterTests.cs
Normal file
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Tests;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenQA.Selenium;
|
||||
using Xunit;
|
||||
|
||||
namespace ProjectLighthouse.Tests.WebsiteTests
|
||||
{
|
||||
public class RegisterTests : LighthouseWebTest
|
||||
{
|
||||
[DatabaseFact]
|
||||
public async Task ShouldRegister()
|
||||
{
|
||||
await using Database database = new();
|
||||
|
||||
string username = "unitTestUser" + new Random().Next();
|
||||
string password = HashHelper.Sha256Hash(HashHelper.GenerateRandomBytes(64).ToArray());
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/register");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(username);
|
||||
|
||||
this.Driver.FindElement(By.Id("password")).SendKeys(password);
|
||||
this.Driver.FindElement(By.Id("confirmPassword")).SendKeys(password);
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
User? user = await database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
Assert.NotNull(user);
|
||||
|
||||
await database.RemoveUser(user);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldNotRegisterWithMismatchingPasswords()
|
||||
{
|
||||
await using Database database = new();
|
||||
|
||||
string username = "unitTestUser" + new Random().Next();
|
||||
string password = HashHelper.Sha256Hash(HashHelper.GenerateRandomBytes(64).ToArray());
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/register");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(username);
|
||||
|
||||
this.Driver.FindElement(By.Id("password")).SendKeys(password);
|
||||
this.Driver.FindElement(By.Id("confirmPassword")).SendKeys(password + "a");
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
User? user = await database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
Assert.Null(user);
|
||||
}
|
||||
|
||||
[DatabaseFact]
|
||||
public async Task ShouldNotRegisterWithTakenUsername()
|
||||
{
|
||||
await using Database database = new();
|
||||
|
||||
string username = "unitTestUser" + new Random().Next();
|
||||
string password = HashHelper.Sha256Hash(HashHelper.GenerateRandomBytes(64).ToArray());
|
||||
|
||||
await database.CreateUser(username, HashHelper.BCryptHash(password));
|
||||
User? user = await database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
Assert.NotNull(user);
|
||||
|
||||
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/register");
|
||||
|
||||
this.Driver.FindElement(By.Id("text")).SendKeys(username);
|
||||
|
||||
this.Driver.FindElement(By.Id("password")).SendKeys(password);
|
||||
this.Driver.FindElement(By.Id("confirmPassword")).SendKeys(password);
|
||||
|
||||
this.Driver.FindElement(By.Id("submit")).Click();
|
||||
|
||||
Assert.Contains("The username you've chosen is already taken.", this.Driver.PageSource);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,15 +14,14 @@ using Microsoft.EntityFrameworkCore;
|
|||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
{
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
public class LighthouseTest
|
||||
public class LighthouseServerTest
|
||||
{
|
||||
public readonly HttpClient Client;
|
||||
public readonly TestServer Server;
|
||||
|
||||
public LighthouseTest()
|
||||
public LighthouseServerTest()
|
||||
{
|
||||
this.Server = new TestServer(new WebHostBuilder().UseStartup<TestStartup>());
|
||||
|
||||
this.Client = this.Server.CreateClient();
|
||||
}
|
||||
public async Task<HttpResponseMessage> AuthenticateResponse(int number = -1, bool createUser = true)
|
|
@ -32,9 +32,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||
<Content Include="ExampleFiles\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -4,7 +4,7 @@ using Xunit;
|
|||
|
||||
namespace LBPUnion.ProjectLighthouse.Tests
|
||||
{
|
||||
public class SerializerTests : LighthouseTest
|
||||
public class SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void BlankElementWorks()
|
|
@ -4,6 +4,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse", "Projec
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests", "ProjectLighthouse.Tests\ProjectLighthouse.Tests.csproj", "{AFC74569-B289-4ACC-B21C-313A3A62C017}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D360C08E-EA47-43AC-A566-FDF413442980}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests.GameApiTests", "ProjectLighthouse.Tests.GameApiTests\ProjectLighthouse.Tests.GameApiTests.csproj", "{200EED99-FE3E-45C6-A51E-76ED9819CA2B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests.WebsiteTests", "ProjectLighthouse.Tests.WebsiteTests\ProjectLighthouse.Tests.WebsiteTests.csproj", "{CF65EB5B-5364-4D2A-8639-F147A67F08E7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -17,6 +23,16 @@ Global
|
|||
{AFC74569-B289-4ACC-B21C-313A3A62C017}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AFC74569-B289-4ACC-B21C-313A3A62C017}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AFC74569-B289-4ACC-B21C-313A3A62C017}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AFC74569-B289-4ACC-B21C-313A3A62C017}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{AFC74569-B289-4ACC-B21C-313A3A62C017} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||
{CF65EB5B-5364-4D2A-8639-F147A67F08E7} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Affero/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=asdf/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCAS/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCES/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCET/@EntryIndexedValue">True</s:Boolean>
|
||||
|
|
|
@ -91,7 +91,21 @@ namespace LBPUnion.ProjectLighthouse.Controllers
|
|||
|
||||
[HttpGet("slots/lbp2cool")]
|
||||
[HttpGet("slots/cool")]
|
||||
public async Task<IActionResult> CoolSlots([FromQuery] int page) => await this.LuckyDipSlots(30 * page, 30, 69);
|
||||
public async Task<IActionResult> CoolSlots
|
||||
(
|
||||
[FromQuery] int pageStart,
|
||||
[FromQuery] int pageSize,
|
||||
[FromQuery] string gameFilterType,
|
||||
[FromQuery] int players,
|
||||
[FromQuery] Boolean move,
|
||||
[FromQuery] int? page = null
|
||||
)
|
||||
{
|
||||
int _pageStart = pageStart;
|
||||
if (page != null) _pageStart = (int)page * 30;
|
||||
// bit of a better placeholder until we can track average user interaction with /stream endpoint
|
||||
return await ThumbsSlots(_pageStart, Math.Min(pageSize, 30), gameFilterType, players, move, "thisWeek");
|
||||
}
|
||||
|
||||
[HttpGet("slots")]
|
||||
public async Task<IActionResult> NewestSlots([FromQuery] int pageStart, [FromQuery] int pageSize)
|
||||
|
@ -198,5 +212,137 @@ namespace LBPUnion.ProjectLighthouse.Controllers
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
[HttpGet("slots/thumbs")]
|
||||
public async Task<IActionResult> ThumbsSlots
|
||||
(
|
||||
[FromQuery] int pageStart,
|
||||
[FromQuery] int pageSize,
|
||||
[FromQuery] string gameFilterType,
|
||||
[FromQuery] int players,
|
||||
[FromQuery] Boolean move,
|
||||
[FromQuery] string? dateFilterType = null
|
||||
)
|
||||
{
|
||||
Random rand = new();
|
||||
|
||||
IEnumerable<Slot> slots = FilterByRequest(gameFilterType, dateFilterType)
|
||||
.AsEnumerable()
|
||||
.OrderByDescending(s => s.Thumbsup)
|
||||
.ThenBy(_ => rand.Next())
|
||||
.Skip(pageStart - 1)
|
||||
.Take(Math.Min(pageSize, 30));
|
||||
|
||||
string response = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize());
|
||||
|
||||
return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30)));
|
||||
}
|
||||
|
||||
[HttpGet("slots/mostUniquePlays")]
|
||||
public async Task<IActionResult> MostUniquePlaysSlots
|
||||
(
|
||||
[FromQuery] int pageStart,
|
||||
[FromQuery] int pageSize,
|
||||
[FromQuery] string gameFilterType,
|
||||
[FromQuery] int players,
|
||||
[FromQuery] Boolean move,
|
||||
[FromQuery] string? dateFilterType = null
|
||||
)
|
||||
{
|
||||
Random rand = new();
|
||||
|
||||
IEnumerable<Slot> slots = FilterByRequest(gameFilterType, dateFilterType)
|
||||
.AsEnumerable()
|
||||
.OrderByDescending
|
||||
(
|
||||
s =>
|
||||
{
|
||||
// probably not the best way to do this?
|
||||
return GetGameFilter(gameFilterType) switch
|
||||
{
|
||||
GameVersion.LittleBigPlanet1 => s.PlaysLBP1Unique,
|
||||
GameVersion.LittleBigPlanet2 => s.PlaysLBP2Unique,
|
||||
GameVersion.LittleBigPlanet3 => s.PlaysLBP3Unique,
|
||||
GameVersion.LittleBigPlanetVita => s.PlaysLBPVitaUnique,
|
||||
_ => s.PlaysUnique,
|
||||
};
|
||||
}
|
||||
)
|
||||
.ThenBy(_ => rand.Next())
|
||||
.Skip(pageStart - 1)
|
||||
.Take(Math.Min(pageSize, 30));
|
||||
|
||||
string response = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize());
|
||||
|
||||
return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30)));
|
||||
}
|
||||
|
||||
[HttpGet("slots/mostHearted")]
|
||||
public async Task<IActionResult> MostHeartedSlots
|
||||
(
|
||||
[FromQuery] int pageStart,
|
||||
[FromQuery] int pageSize,
|
||||
[FromQuery] string gameFilterType,
|
||||
[FromQuery] int players,
|
||||
[FromQuery] Boolean move,
|
||||
[FromQuery] string? dateFilterType = null
|
||||
)
|
||||
{
|
||||
Random rand = new();
|
||||
|
||||
IEnumerable<Slot> slots = FilterByRequest(gameFilterType, dateFilterType)
|
||||
.AsEnumerable()
|
||||
.OrderByDescending(s => s.Hearts)
|
||||
.ThenBy(_ => rand.Next())
|
||||
.Skip(pageStart - 1)
|
||||
.Take(Math.Min(pageSize, 30));
|
||||
|
||||
string response = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize());
|
||||
|
||||
return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30)));
|
||||
}
|
||||
|
||||
public GameVersion GetGameFilter(string gameFilterType)
|
||||
{
|
||||
return gameFilterType switch
|
||||
{
|
||||
"lbp1" => GameVersion.LittleBigPlanet1,
|
||||
"lbp2" => GameVersion.LittleBigPlanet2,
|
||||
"lbp3" => GameVersion.LittleBigPlanet3,
|
||||
"both" => GameVersion.LittleBigPlanet2, // LBP2 default option
|
||||
_ => GameVersion.Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
public IQueryable<Slot> FilterByRequest(string gameFilterType, string? dateFilterType)
|
||||
{
|
||||
string _dateFilterType = dateFilterType ?? "";
|
||||
|
||||
long oldestTime = _dateFilterType switch
|
||||
{
|
||||
"thisWeek" => DateTimeOffset.Now.AddDays(-7).ToUnixTimeMilliseconds(),
|
||||
"thisMonth" => DateTimeOffset.Now.AddDays(-31).ToUnixTimeMilliseconds(),
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
GameVersion gameVersion = GetGameFilter(gameFilterType);
|
||||
|
||||
IQueryable<Slot> whereSlots;
|
||||
|
||||
// ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
|
||||
if (gameFilterType == "both")
|
||||
{
|
||||
// Get game versions less than the current version
|
||||
// Needs support for LBP3 ("both" = LBP1+2)
|
||||
whereSlots = this.database.Slots.Where(s => s.GameVersion <= gameVersion && s.FirstUploaded >= oldestTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get game versions exactly equal to gamefiltertype
|
||||
whereSlots = this.database.Slots.Where(s => s.GameVersion == gameVersion && s.FirstUploaded >= oldestTime);
|
||||
}
|
||||
|
||||
return whereSlots.Include(s => s.Creator).Include(s => s.Location);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue