Skip to content

Commit

Permalink
Merge pull request #27 from pureooze/ushamim/notice-message
Browse files Browse the repository at this point in the history
  • Loading branch information
pureooze authored Oct 14, 2023
2 parents e98509a + cd12b4c commit 64b92eb
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Message message

switch( message.MessageType ) {
case MessageType.ClearChat: {
ClearChat privMsg = (ClearChat)message;
ClearChat msg = (ClearChat)message;
ClearChat? expectedPrivMessage = (ClearChat)expectedMessage;
ClearChatMessageCallback( privMsg, expectedPrivMessage );
ClearChatMessageCallback( msg, expectedPrivMessage );
break;
}
case MessageType.PrivMsg:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ Message message

switch( message.MessageType ) {
case MessageType.ClearMsg: {
ClearMsg privMsg = (ClearMsg)message;
ClearMsg msg = (ClearMsg)message;
ClearMsg? expectedPrivMessage = (ClearMsg)expectedMessage;
ClearMsgMessageCallback( privMsg, expectedPrivMessage );
ClearMsgMessageCallback( msg, expectedPrivMessage );
break;
}
case MessageType.PrivMsg:
Expand Down
99 changes: 99 additions & 0 deletions TwitchEverywhere.UnitTests/TwitchConnectorTests/NoticeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System.Collections.Immutable;
using Moq;
using NUnit.Framework.Internal;
using TwitchEverywhere.Implementation;
using TwitchEverywhere.Types;

namespace TwitchEverywhere.UnitTests.TwitchConnectorTests;

[TestFixture]
public class NoticeTests {
private readonly TwitchConnectionOptions m_options = new(
"channel",
"access_token",
"refresh_token",
"client_id",
"client_secret",
"client_name"
);

private readonly DateTime m_startTime = DateTimeOffset.FromUnixTimeMilliseconds(1507246572675).UtcDateTime;

private ITwitchConnector m_twitchConnector;

[Test]
[TestCaseSource(nameof(NoticeMessages))]
public async Task Notice( IImmutableList<string> messages, Message? expectedMessage ) {
Mock<IAuthorizer> authorizer = new( behavior: MockBehavior.Strict );
Mock<IDateTimeService> dateTimeService = new( MockBehavior.Strict );
dateTimeService.Setup( dts => dts.GetStartTime() ).Returns( m_startTime );

IWebSocketConnection webSocket = new TestWebSocketConnection( messages );

void MessageCallback(
Message message
) {
Assert.That( message, Is.Not.Null );

switch( message.MessageType ) {
case MessageType.Notice: {
Notice msg = (Notice)message;
Notice? expectedPrivMessage = (Notice)expectedMessage;
NoticeMessageCallback( msg, expectedPrivMessage );
break;
}
case MessageType.PrivMsg:
case MessageType.ClearMsg:
case MessageType.ClearChat:
case MessageType.GlobalUserState:
case MessageType.RoomState:
case MessageType.UserNotice:
case MessageType.UserState:
case MessageType.Whisper:
default:
throw new ArgumentOutOfRangeException();
}
}

authorizer.Setup( expression: a => a.GetToken() ).ReturnsAsync( value: "token" );
m_twitchConnector = new TwitchConnector(
authorizer: authorizer.Object,
webSocketConnection: webSocket,
dateTimeService: dateTimeService.Object
);

bool result = await m_twitchConnector.TryConnect( m_options, MessageCallback );
Assert.That( result, Is.True );
}

private void NoticeMessageCallback(
Notice notice,
Notice? expectedNoticeMessage
) {
Assert.That( notice.MsgId, Is.EqualTo( expectedNoticeMessage?.MsgId ), "MsgId was not equal to expected value");
Assert.That( notice.TargetUserId, Is.EqualTo( expectedNoticeMessage?.TargetUserId ), "TargetUserId was not equal to expected value");
Assert.That( notice.MessageType, Is.EqualTo( expectedNoticeMessage?.MessageType ), "MessageType was not equal to expected value");
}

private static IEnumerable<TestCaseData> NoticeMessages() {
yield return new TestCaseData(
new List<string> {
$"@msg-id=delete_message_success :tmi.twitch.tv NOTICE #channel :The message from foo is now deleted."
}.ToImmutableList(),
new Notice(
MsgId: "delete_message_success",
TargetUserId: ""
)
).SetName("Message Delete Success, No User ID");

yield return new TestCaseData(
new List<string> {
$"@msg-id=whisper_restricted;target-user-id=12345678 :tmi.twitch.tv NOTICE #channel :Your settings prevent you from sending this whisper."
}.ToImmutableList(),
new Notice(
MsgId: "whisper_restricted",
TargetUserId: "12345678"
)
).SetName("Whisper Restricted, With User ID");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Message message

switch( message.MessageType ) {
case MessageType.PrivMsg: {
PrivMsg privMsg = (PrivMsg)message;
PrivMsg msg = (PrivMsg)message;
PrivMsg? expectedPrivMessage = (PrivMsg)expectedMessage;
PrivMessageCallback( privMsg, expectedPrivMessage );
PrivMessageCallback( msg, expectedPrivMessage );
break;
}
case MessageType.ClearChat:
Expand Down
29 changes: 23 additions & 6 deletions TwitchEverywhere/Implementation/TwitchConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,27 @@ await ws.CloseAsync(
Message chat = GetClearChatMessage( response, options.Channel );
m_messageCallback( chat );
} else if( response.Contains( $" CLEARMSG #{options.Channel}" ) ) {
Message chat = GetClearMsgMessage( response, options.Channel );
Message chat = GetClearMsgMessage( response );
m_messageCallback( chat );
} else if( response.Contains( $" NOTICE #{options.Channel}" ) ) {
Message chat = GetNoticeMsgMessage( response );
m_messageCallback( chat );
}
}
}
private Message GetNoticeMsgMessage(
string response
) {
string targetMessageId = GetValueFromResponse( response, MsgIdPattern );
string targetUserId = GetValueFromResponse( response, TargetUserIdPattern );

return new Notice(
MsgId: targetMessageId,
TargetUserId: targetUserId
);
}
private Message GetClearMsgMessage(
string response,
string channel
string response
) {
string login = LoginPattern
.Match( response )
Expand Down Expand Up @@ -169,7 +182,10 @@ string channel
);
}

private Message GetUserMessage( string response, string channel ) {
private Message GetUserMessage(
string response,
string channel
) {
string[] segments = response.Split( $"PRIVMSG #{channel} :" );

string displayName = GetValueFromResponse( response, DisplayNamePattern );
Expand Down Expand Up @@ -268,7 +284,7 @@ string emotesText
if( string.IsNullOrEmpty( emotesText ) ) {
return null;
}
// 25 : 0-4 , 12-16 / 1902 : 6-10

List<Emote> emotes = new();
string[] separatedRawEmotes = emotesText.Split( "/" );

Expand Down Expand Up @@ -399,5 +415,6 @@ await socketConnection.SendAsync(
private readonly static Regex UserTypePattern = new("user-type=([^; ]+)");
private readonly static Regex VipPattern = new("vip=([^;]*)");
private readonly static Regex BanDurationPattern = new("ban-duration=([^;]*)");
private readonly static Regex TargetUserIdPattern = new("target-user-id=([^;]*)");
private readonly static Regex TargetUserIdPattern = new("target-user-id=([^ ;]*)");
private readonly static Regex MsgIdPattern = new("msg-id=([^ ;]*)");
}
7 changes: 0 additions & 7 deletions TwitchEverywhere/Implementation/UserMessage.cs

This file was deleted.

8 changes: 6 additions & 2 deletions TwitchEverywhere/TwitchEverywhere.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>11</LangVersion>
<Version>0.1.0</Version>
<PackageReadmeFile>../README.md</PackageReadmeFile>
<Version>0.1.1</Version>
<PackageReadmeFile>README.md</PackageReadmeFile>
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions TwitchEverywhere/Types/Notice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace TwitchEverywhere.Types;

public record Notice(
string MsgId,
string TargetUserId
) : Message ( MessageType.Notice );

0 comments on commit 64b92eb

Please sign in to comment.