-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTeamChatRelayTests.cs
More file actions
139 lines (114 loc) · 5.59 KB
/
Copy pathTeamChatRelayTests.cs
File metadata and controls
139 lines (114 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using RustPlusBot.Abstractions.Events;
using RustPlusBot.Abstractions.Time;
using RustPlusBot.Features.Chat.Relaying;
using RustPlusBot.Features.Chat.Webhooks;
using RustPlusBot.Features.Workspace.Locating;
using RustPlusBot.Persistence.Commands;
namespace RustPlusBot.Features.Chat.Tests;
public sealed class TeamChatRelayTests
{
private static (TeamChatRelay Relay, ITeamChatWebhookPoster Poster, RelayDedupBuffer Dedup, ITeamChatChannelLocator
Locator)
Build(string prefix = "!")
{
var clock = Substitute.For<IClock>();
clock.UtcNow.Returns(DateTimeOffset.UnixEpoch);
var dedup = new RelayDedupBuffer(clock);
var poster = Substitute.For<ITeamChatWebhookPoster>();
var locator = Substitute.For<ITeamChatChannelLocator>();
locator.GetChannelIdAsync(Arg.Any<ulong>(), Arg.Any<Guid>(), Arg.Any<CancellationToken>())
.Returns((ulong?)777UL);
var muteStore = Substitute.For<IMuteStore>();
muteStore.GetPrefixAsync(Arg.Any<ulong>(), Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(prefix);
var scopeFactory = Substitute.For<IServiceScopeFactory>();
var scope = Substitute.For<IServiceScope>();
var scopeProvider = Substitute.For<IServiceProvider>();
scopeProvider.GetService(typeof(IMuteStore)).Returns(muteStore);
scope.ServiceProvider.Returns(scopeProvider);
scopeFactory.CreateScope().Returns(scope);
var relay = new TeamChatRelay(locator, poster, dedup, scopeFactory);
return (relay, poster, dedup, locator);
}
[Fact]
public async Task Posts_a_normal_message_via_webhook()
{
var (relay, poster, _, _) = Build();
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", "hello", FromActivePlayer: false);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.Received(1).PostAsync(777UL, "Bob", "hello", Arg.Any<CancellationToken>());
}
[Fact]
public async Task Drops_our_own_echo()
{
var (relay, poster, dedup, _) = Build();
var key = (10UL, Guid.Empty);
dedup.Record(key, "[Alice] hello");
var echo = new TeamMessageReceivedEvent(10UL, Guid.Empty, 555UL, "BotPlayer", "[Alice] hello",
FromActivePlayer: true);
await relay.RelayAsync(echo, CancellationToken.None);
await poster.DidNotReceive().PostAsync(Arg.Any<ulong>(), Arg.Any<string>(), Arg.Any<string>(),
Arg.Any<CancellationToken>());
}
[Fact]
public async Task Posts_active_player_message_that_is_not_an_echo()
{
var (relay, poster, _, _) = Build();
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 555UL, "BotPlayer", "genuine", FromActivePlayer: true);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.Received(1).PostAsync(777UL, "BotPlayer", "genuine", Arg.Any<CancellationToken>());
}
[Fact]
public async Task Skips_when_channel_not_provisioned()
{
var (relay, poster, _, locator) = Build();
locator.GetChannelIdAsync(Arg.Any<ulong>(), Arg.Any<Guid>(), Arg.Any<CancellationToken>())
.Returns((ulong?)null);
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", "hello", FromActivePlayer: false);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.DidNotReceive().PostAsync(Arg.Any<ulong>(), Arg.Any<string>(), Arg.Any<string>(),
Arg.Any<CancellationToken>());
}
[Fact]
public async Task Drops_bot_originated_echo_by_prefix()
{
var (relay, poster, _, _) = Build();
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 555UL, "BotPlayer", "[R+] Cargo Ship entered the map",
FromActivePlayer: true);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.DidNotReceive().PostAsync(Arg.Any<ulong>(), Arg.Any<string>(), Arg.Any<string>(),
Arg.Any<CancellationToken>());
}
[Fact]
public async Task Posts_teammate_message_even_with_prefix()
{
var (relay, poster, _, _) = Build();
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", "[R+] hi", FromActivePlayer: false);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.Received(1).PostAsync(777UL, "Bob", "[R+] hi", Arg.Any<CancellationToken>());
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task Drops_command_shaped_player_lines(bool fromActivePlayer)
{
var (relay, poster, _, _) = Build();
var evt = new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", "!pop", fromActivePlayer);
await relay.RelayAsync(evt, CancellationToken.None);
await poster.DidNotReceive().PostAsync(Arg.Any<ulong>(), Arg.Any<string>(), Arg.Any<string>(),
Arg.Any<CancellationToken>());
}
[Fact]
public async Task Command_drop_honors_custom_prefix()
{
var (relay, poster, _, _) = Build(prefix: ".");
await relay.RelayAsync(new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", ".pop", false),
CancellationToken.None);
await relay.RelayAsync(new TeamMessageReceivedEvent(10UL, Guid.Empty, 999UL, "Bob", "!not a command", false),
CancellationToken.None);
await poster.Received(1).PostAsync(777UL, "Bob", "!not a command", Arg.Any<CancellationToken>());
await poster.DidNotReceive().PostAsync(Arg.Any<ulong>(), Arg.Any<string>(), ".pop",
Arg.Any<CancellationToken>());
}
}