Skip to content

Commit ec4a6b4

Browse files
Merge pull request #45 from nullinside-development-group/feature/Poc2Prod
Initial skeleton for unit testing
2 parents ff00e7e + ddf9e95 commit ec4a6b4

20 files changed

+279
-42
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using Moq;
2+
using Nullinside.Api.Common.Twitch;
3+
using Nullinside.Api.Model.Ddl;
4+
using Nullinside.Api.TwitchBot.ChatRules;
5+
6+
namespace Nullinside.Api.TwitchBot.Tests.ChatRules;
7+
8+
/// <summary>
9+
/// A generic set of sets that all chat rules should be put through.
10+
/// </summary>
11+
/// <typeparam name="T"></typeparam>
12+
public abstract class AChatRuleUnitTestBase<T> : UnitTestBase where T : AChatRule, new()
13+
{
14+
/// <summary>
15+
/// Tests that the message filter is capable of passing at all.
16+
/// </summary>
17+
/// <param name="goodString">A friendly string with no issues.</param>
18+
[Test]
19+
[TestCase("Hello I love candy and sprinkles")]
20+
public async Task TestItDoesntAlwaysFail(string goodString)
21+
{
22+
var rule = new T();
23+
var botProxy = new Mock<ITwitchApiProxy>();
24+
25+
// Process the message and assert that we pass the message.
26+
var chat = new TwitchChatMessage(true, goodString, "123", "456");
27+
var result = await rule.Handle("123", botProxy.Object, chat, _db);
28+
Assert.That(result, Is.True);
29+
30+
// Process the message and assert that we pass the message.
31+
chat = new TwitchChatMessage(false, goodString, "123", "456");
32+
result = await rule.Handle("123", botProxy.Object, chat, _db);
33+
Assert.That(result, Is.True);
34+
}
35+
36+
/// <summary>
37+
/// Tests that the rules are only running when they should be.
38+
/// </summary>
39+
[Test]
40+
public void TestShouldRun()
41+
{
42+
var rule = new T();
43+
44+
// Rule is turned on and so is scanning.
45+
var shouldRun = rule.ShouldRun(new TwitchUserConfig { Enabled = true, BanKnownBots = true });
46+
Assert.That(shouldRun, Is.True);
47+
48+
// Scanning is turned off
49+
shouldRun = rule.ShouldRun(new TwitchUserConfig { Enabled = false, BanKnownBots = true });
50+
Assert.That(shouldRun, Is.False);
51+
52+
// Rule is turned off.
53+
shouldRun = rule.ShouldRun(new TwitchUserConfig { Enabled = true, BanKnownBots = false });
54+
Assert.That(shouldRun, Is.False);
55+
56+
// Everything is off.
57+
shouldRun = rule.ShouldRun(new TwitchUserConfig { Enabled = false, BanKnownBots = false });
58+
Assert.That(shouldRun, Is.False);
59+
}
60+
}

src/Nullinside.Api.TwitchBot.Tests/ChatRules/BestCheapViewersTests.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
using Moq;
2+
using Nullinside.Api.Common.Twitch;
3+
using Nullinside.Api.TwitchBot.ChatRules;
4+
15
namespace Nullinside.Api.TwitchBot.Tests.ChatRules;
26

3-
public class BestCheapViewersTests
7+
/// <summary>
8+
/// Tests the <see cref="BestCheapViewers" /> class.
9+
/// </summary>
10+
public class BestCheapViewersTests : AChatRuleUnitTestBase<BestCheapViewers>
411
{
12+
/// <summary>
13+
/// Tests strings that have been typed in chats.
14+
/// </summary>
15+
/// <param name="badString">The string that should fail.</param>
516
[Test]
617
[TestCase("Best viewers on ***")]
718
[TestCase("Best viewers on ***")]
@@ -18,9 +29,14 @@ public class BestCheapViewersTests
1829
[TestCase("C̀heap Viewers on ***")]
1930
[TestCase("Cheaͧp v̫iewers on ***")]
2031
[TestCase("Cheaͧp v̫iewers on *** ")]
21-
public void TestKnownStrings(string badString)
32+
public async Task TestKnownStrings(string badString)
2233
{
23-
// Need to put interfaces in front of the classes before we can do this.
24-
Assert.Pass();
34+
var rule = new BestCheapViewers();
35+
var botProxy = new Mock<ITwitchApiProxy>();
36+
var chat = new TwitchChatMessage(true, badString, "123", "456");
37+
38+
// Process the message and assert that we fail the message.
39+
var result = await rule.Handle("123", botProxy.Object, chat, _db);
40+
Assert.That(result, Is.False);
2541
}
2642
}
Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,55 @@
1-
namespace Nullinside.Api.TwitchBot.Tests.ChatRules;
1+
using Moq;
2+
using Nullinside.Api.Common.Twitch;
3+
using Nullinside.Api.TwitchBot.ChatRules;
24

3-
public class DiscordTests
5+
namespace Nullinside.Api.TwitchBot.Tests.ChatRules;
6+
7+
/// <summary>
8+
/// Tests the <see cref="Discord" /> class.
9+
/// </summary>
10+
public class DiscordTests : AChatRuleUnitTestBase<Discord>
411
{
12+
/// <summary>
13+
/// Tests the strings typed in chats.
14+
/// </summary>
15+
/// <param name="badString">The string that should fail.</param>
516
[Test]
6-
[TestCase("Hello mate you stream pretty cool that's why I follow I would love to be a fan of yours if you don't mind kindly add me on Discord: 👉👉lacaster5")]
7-
[TestCase("Hello, I just recently found your channel and can already tell that your content is great, and I would love to stick with you long term. If you're open to it, I'd be willing to connect with you on Discord. My username is teecash1000")]
8-
[TestCase("Hey there 👋 You stream pretty cool that’s why I followed you. I will like to make you a friend and be a fan, if you don’t mind Kindly chat me on Discord, my Discord username is tuckzay")]
9-
[TestCase("Hi! Just wanted to say that I absolutely love your gameplay and content.l'd love to connect better with you on Discord if that's possible. Looking forward to more awesome streams from you! My username is 👉👉👉 edisonpires")]
10-
[TestCase("What's up Friend, great stream! I'm having a blast watching you stream. Let's move the conversation to Discord, where we can discuss more about streaming in more detail and get to know each other better. See you there! My discord username is 👉john_6029")]
11-
public void TestKnownStrings(string badString)
17+
[TestCase(
18+
"Hello mate you stream pretty cool that's why I follow I would love to be a fan of yours if you don't mind kindly add me on Discord: 👉👉lacaster5")]
19+
[TestCase(
20+
"Hello, I just recently found your channel and can already tell that your content is great, and I would love to stick with you long term. If you're open to it, I'd be willing to connect with you on Discord. My username is teecash1000")]
21+
[TestCase(
22+
"Hey there 👋 You stream pretty cool that’s why I followed you. I will like to make you a friend and be a fan, if you don’t mind Kindly chat me on Discord, my Discord username is tuckzay")]
23+
[TestCase(
24+
"Hi! Just wanted to say that I absolutely love your gameplay and content.l'd love to connect better with you on Discord if that's possible. Looking forward to more awesome streams from you! My username is 👉👉👉 edisonpires")]
25+
[TestCase(
26+
"What's up Friend, great stream! I'm having a blast watching you stream. Let's move the conversation to Discord, where we can discuss more about streaming in more detail and get to know each other better. See you there! My discord username is 👉john_6029")]
27+
public async Task TestKnownStrings(string badString)
1228
{
13-
// Need to put interfaces in front of the classes before we can do this.
14-
Assert.Pass();
29+
var rule = new Discord();
30+
var botProxy = new Mock<ITwitchApiProxy>();
31+
var chat = new TwitchChatMessage(true, badString, "123", "456");
32+
33+
// Process the message and assert that we fail the message.
34+
var result = await rule.Handle("123", botProxy.Object, chat, _db);
35+
Assert.That(result, Is.False);
36+
}
37+
38+
/// <summary>
39+
/// Ensure that the rule doesn't fail just because it contains the word discord.
40+
/// </summary>
41+
/// <param name="message">The message.</param>
42+
[Test]
43+
[TestCase("I've heard of the application discord before and it sounds great")]
44+
[TestCase("I was talking on my discord the other day")]
45+
public async Task EnsureNoFalsePositives(string message)
46+
{
47+
var rule = new Discord();
48+
var botProxy = new Mock<ITwitchApiProxy>();
49+
var chat = new TwitchChatMessage(true, message, "123", "456");
50+
51+
// Process the message and assert that we do not fail the message.
52+
var result = await rule.Handle("123", botProxy.Object, chat, _db);
53+
Assert.That(result, Is.True);
1554
}
1655
}
Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
1+
using Moq;
2+
using Nullinside.Api.Common.Twitch;
13
using Nullinside.Api.TwitchBot.ChatRules;
24

35
namespace Nullinside.Api.TwitchBot.Tests.ChatRules;
46

5-
public class StreamViewersTests
7+
/// <summary>
8+
/// Tests the <see cref="StreamViewers" /> class.
9+
/// </summary>
10+
public class StreamViewersTests : AChatRuleUnitTestBase<StreamViewers>
611
{
12+
/// <summary>
13+
/// Tests the strings typed in chats.
14+
/// </summary>
15+
/// <param name="badString">The string that should fail.</param>
716
[Test]
8-
[TestCase("@jellynyeko dо уоu alrеady triеd strеamviewers оrg? Real viewеrs, fire works! Тhеy arе now giving оut а frее рackagе for streamers оО")]
9-
[TestCase("@kygaming98 dо уоu аlready tried streаmviewers оrg? Real viewers, firе works! Thеy arе now giving оut а freе package fоr streamers oО")]
10-
public void TestKnownStrings(string badString)
17+
[TestCase(
18+
"@jellynyeko dо уоu alrеady triеd strеamviewers оrg? Real viewеrs, fire works! Тhеy arе now giving оut а frее рackagе for streamers оО")]
19+
[TestCase(
20+
"@kygaming98 dо уоu аlready tried streаmviewers оrg? Real viewers, firе works! Thеy arе now giving оut а freе package fоr streamers oО")]
21+
public async Task TestKnownStrings(string badString)
1122
{
12-
// Need to put interfaces in front of the classes before we can do this.
13-
Assert.Pass();
23+
var rule = new StreamViewers();
24+
var botProxy = new Mock<ITwitchApiProxy>();
25+
var chat = new TwitchChatMessage(true, badString, "123", "456");
26+
27+
// Process the message and assert that we fail the message.
28+
var result = await rule.Handle("123", botProxy.Object, chat, _db);
29+
Assert.That(result, Is.False);
1430
}
1531
}

src/Nullinside.Api.TwitchBot.Tests/Nullinside.Api.TwitchBot.Tests.csproj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,26 @@
1111

1212
<ItemGroup>
1313
<PackageReference Include="coverlet.collector" Version="6.0.2">
14-
<PrivateAssets>all</PrivateAssets>
15-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>
17-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
18-
<PackageReference Include="NUnit" Version="4.2.2" />
17+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.8"/>
18+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
19+
<PackageReference Include="Moq" Version="4.20.72"/>
20+
<PackageReference Include="NUnit" Version="4.2.2"/>
1921
<PackageReference Include="NUnit.Analyzers" Version="4.3.0">
20-
<PrivateAssets>all</PrivateAssets>
21-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22+
<PrivateAssets>all</PrivateAssets>
23+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2224
</PackageReference>
23-
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
25+
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
2426
</ItemGroup>
2527

2628
<ItemGroup>
2729
<Using Include="NUnit.Framework"/>
2830
</ItemGroup>
2931

3032
<ItemGroup>
31-
<ProjectReference Include="..\Nullinside.Api.TwitchBot\Nullinside.Api.TwitchBot.csproj" />
33+
<ProjectReference Include="..\Nullinside.Api.TwitchBot\Nullinside.Api.TwitchBot.csproj"/>
3234
</ItemGroup>
3335

3436
</Project>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Diagnostics;
3+
using Nullinside.Api.Model;
4+
5+
namespace Nullinside.Api.TwitchBot.Tests;
6+
7+
/// <summary>
8+
/// A base class for all unit tests.
9+
/// </summary>
10+
public abstract class UnitTestBase
11+
{
12+
/// <summary>
13+
/// A fake database.
14+
/// </summary>
15+
protected INullinsideContext _db;
16+
17+
[SetUp]
18+
public virtual void Setup()
19+
{
20+
// Create an in-memory database to fake the SQL queries. Note that we generate a random GUID for the name
21+
// here. If you use the same name more than once you'll get collisions between tests.
22+
var contextOptions = new DbContextOptionsBuilder<NullinsideContext>()
23+
.UseInMemoryDatabase(Guid.NewGuid().ToString())
24+
.ConfigureWarnings(b => b.Ignore(InMemoryEventId.TransactionIgnoredWarning))
25+
.Options;
26+
_db = new NullinsideContext(contextOptions);
27+
}
28+
29+
[TearDown]
30+
public virtual async Task TearDown()
31+
{
32+
// Dispose since it has one.
33+
await _db.DisposeAsync();
34+
}
35+
}

src/Nullinside.Api.TwitchBot/ChatRules/AChatRule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public abstract class AChatRule : IChatRule {
1616
public abstract bool ShouldRun(TwitchUserConfig config);
1717

1818
/// <inheritdoc />
19-
public abstract Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, ChatMessage message,
19+
public abstract Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, TwitchChatMessage message,
2020
INullinsideContext db, CancellationToken stoppingToken = new());
2121

2222
/// <summary>

src/Nullinside.Api.TwitchBot/ChatRules/BestCheapViewers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public override bool ShouldRun(TwitchUserConfig config) {
2626
}
2727

2828
/// <inheritdoc />
29-
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, ChatMessage message,
29+
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, TwitchChatMessage message,
3030
INullinsideContext db, CancellationToken stoppingToken = new()) {
3131
if (!message.IsFirstMessage) {
3232
return true;

src/Nullinside.Api.TwitchBot/ChatRules/Discord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public override bool ShouldRun(TwitchUserConfig config) {
2222
}
2323

2424
/// <inheritdoc />
25-
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, ChatMessage message,
25+
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, TwitchChatMessage message,
2626
INullinsideContext db, CancellationToken stoppingToken = new()) {
2727
if (!message.IsFirstMessage) {
2828
return true;

src/Nullinside.Api.TwitchBot/ChatRules/Dogehype.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public override bool ShouldRun(TwitchUserConfig config) {
1616
}
1717

1818
/// <inheritdoc />
19-
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, ChatMessage message,
19+
public override async Task<bool> Handle(string channelId, ITwitchApiProxy botProxy, TwitchChatMessage message,
2020
INullinsideContext db, CancellationToken stoppingToken = new()) {
2121
// The number of spaces per message may chance, so normalize that and lowercase it for comparison.
2222
string normalized = string.Concat(message.Message.Split(" ").Where(s => !string.IsNullOrWhiteSpace(s)))

0 commit comments

Comments
 (0)