Skip to content

Commit

Permalink
Merge branch 'master' into scoreinfo-suuuuuuuuuuuuuuuuuuuuuuuuuucks
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy committed May 7, 2024
2 parents 9617252 + ec158c6 commit ce9cef9
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 16 deletions.
98 changes: 98 additions & 0 deletions osu.Server.Spectator.Tests/ChatFiltersTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Threading.Tasks;
using Moq;
using osu.Game.Online.Multiplayer;
using osu.Server.Spectator.Database;
using osu.Server.Spectator.Database.Models;
using Xunit;

namespace osu.Server.Spectator.Tests
{
public class ChatFiltersTest
{
private readonly Mock<IDatabaseFactory> factoryMock;
private readonly Mock<IDatabaseAccess> databaseMock;

public ChatFiltersTest()
{
factoryMock = new Mock<IDatabaseFactory>();
databaseMock = new Mock<IDatabaseAccess>();

factoryMock.Setup(factory => factory.GetInstance()).Returns(databaseMock.Object);
}

[Theory]
[InlineData("bad phrase", "good phrase")]
[InlineData("WHAT HAPPENS IF I SAY BAD THING IN CAPS", "WHAT HAPPENS IF I SAY good THING IN CAPS")]
[InlineData("thing is bad", "thing is good")]
[InlineData("look at this badness", "look at this goodness")]
public async Task TestPlainFilterReplacement(string input, string expectedOutput)
{
databaseMock.Setup(db => db.GetAllChatFiltersAsync()).ReturnsAsync([
new chat_filter { match = "bad", replacement = "good" },
new chat_filter { match = "fullword", replacement = "okay", whitespace_delimited = true },
new chat_filter { match = "absolutely forbidden", replacement = "", block = true }
]);

var filters = new ChatFilters(factoryMock.Object);

Assert.Equal(expectedOutput, await filters.FilterAsync(input));
}

[Theory]
[InlineData("fullword at the start", "okay at the start")]
[InlineData("FULLWORD IN CAPS!!", "okay IN CAPS!!")]
[InlineData("at the end is fullword", "at the end is okay")]
[InlineData("middle is where the fullword is", "middle is where the okay is")]
[InlineData("anotherfullword is not replaced", "anotherfullword is not replaced")]
[InlineData("fullword fullword2", "okay great")]
[InlineData("fullwordfullword2", "fullwordfullword2")]
[InlineData("i do a delimiter/inside", "i do a nice try")]
public async Task TestWhitespaceDelimitedFilterReplacement(string input, string expectedOutput)
{
databaseMock.Setup(db => db.GetAllChatFiltersAsync()).ReturnsAsync([
new chat_filter { match = "bad", replacement = "good" },
new chat_filter { match = "fullword", replacement = "okay", whitespace_delimited = true },
new chat_filter { match = "fullword2", replacement = "great", whitespace_delimited = true },
new chat_filter { match = "delimiter/inside", replacement = "nice try", whitespace_delimited = true },
new chat_filter { match = "absolutely forbidden", replacement = "", block = true }
]);

var filters = new ChatFilters(factoryMock.Object);

Assert.Equal(expectedOutput, await filters.FilterAsync(input));
}

[Theory]
[InlineData("absolutely forbidden")]
[InlineData("sPoNGeBoB SaYS aBSolUtElY FoRbIdDeN")]
[InlineData("this is absolutely forbidden full stop!!!")]
public async Task TestBlockingFilter(string input)
{
databaseMock.Setup(db => db.GetAllChatFiltersAsync()).ReturnsAsync([
new chat_filter { match = "bad", replacement = "good" },
new chat_filter { match = "fullword", replacement = "okay", whitespace_delimited = true },
new chat_filter { match = "absolutely forbidden", replacement = "", block = true }
]);

var filters = new ChatFilters(factoryMock.Object);

await Assert.ThrowsAsync<InvalidStateException>(() => filters.FilterAsync(input));
}

[Fact]
public async Task TestLackOfBlockingFilters()
{
databaseMock.Setup(db => db.GetAllChatFiltersAsync()).ReturnsAsync([
new chat_filter { match = "bad", replacement = "good" },
new chat_filter { match = "fullword", replacement = "okay", whitespace_delimited = true },
]);

var filters = new ChatFilters(factoryMock.Object);

await filters.FilterAsync("this should be completely fine"); // should not throw
}
}
}
55 changes: 55 additions & 0 deletions osu.Server.Spectator.Tests/SpectatorHubTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Distributed;
Expand Down Expand Up @@ -525,5 +526,59 @@ await hub.EndPlaySession(new SpectatorState
mockScoreStorage.Verify(s => s.WriteAsync(It.Is<Score>(score => score.ScoreInfo.OnlineID == 456)), Times.Never);
mockReceiver.Verify(clients => clients.UserFinishedPlaying(streamer_id, It.Is<SpectatorState>(m => m.State == SpectatedUserState.Failed)), Times.Once());
}

[Fact]
public async Task ScoreRankPopulatedCorrectly()
{
AppSettings.SaveReplays = true;

Mock<IHubCallerClients<ISpectatorClient>> mockClients = new Mock<IHubCallerClients<ISpectatorClient>>();
Mock<ISpectatorClient> mockReceiver = new Mock<ISpectatorClient>();
mockClients.Setup(clients => clients.All).Returns(mockReceiver.Object);
mockClients.Setup(clients => clients.Group(SpectatorHub.GetGroupId(streamer_id))).Returns(mockReceiver.Object);

Mock<HubCallerContext> mockContext = new Mock<HubCallerContext>();

mockContext.Setup(context => context.UserIdentifier).Returns(streamer_id.ToString());
hub.Context = mockContext.Object;
hub.Clients = mockClients.Object;

mockDatabase.Setup(db => db.GetScoreFromToken(1234)).Returns(Task.FromResult<SoloScore?>(new SoloScore
{
id = 456,
passed = true
}));

await hub.BeginPlaySession(1234, new SpectatorState
{
BeatmapID = beatmap_id,
RulesetID = 0,
State = SpectatedUserState.Playing,
});

await hub.SendFrameData(new FrameDataBundle(
new FrameHeader(new ScoreInfo
{
Accuracy = 0.95,
Statistics = new Dictionary<HitResult, int>
{
[HitResult.Great] = 19,
[HitResult.Miss] = 1,
}
}, new ScoreProcessorStatistics()),
new[] { new LegacyReplayFrame(1234, 0, 0, ReplayButtonState.None) }));

await hub.EndPlaySession(new SpectatorState
{
BeatmapID = beatmap_id,
RulesetID = 0,
State = SpectatedUserState.Passed,
});

await scoreUploader.Flush();

mockScoreStorage.Verify(s => s.WriteAsync(It.Is<Score>(score => score.ScoreInfo.Rank == ScoreRank.A)), Times.Once);
mockReceiver.Verify(clients => clients.UserFinishedPlaying(streamer_id, It.Is<SpectatorState>(m => m.State == SpectatedUserState.Passed)), Times.Once());
}
}
}
Loading

0 comments on commit ce9cef9

Please sign in to comment.