From e9017498a0bd87e2a5ae457c00f9ddee35809c29 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 15 May 2021 16:01:21 +0800 Subject: feat: Timeline post change notification with signalr. --- .../IntegratedTests/IntegratedTestBase.cs | 16 +++++ .../IntegratedTests/TimelineHubTest.cs | 82 ++++++++++++++++++++++ .../IntegratedTests/TimelinePostTest.cs | 2 +- 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 BackEnd/Timeline.Tests/IntegratedTests/TimelineHubTest.cs (limited to 'BackEnd/Timeline.Tests/IntegratedTests') diff --git a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs index 588f2f93..259ebfa1 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs @@ -105,6 +105,14 @@ namespace Timeline.Tests.IntegratedTests return Task.FromResult(client); } + public async Task CreateTokenWithCredentialAsync(string username, string password) + { + var client = await CreateDefaultClient(); + var res = await client.TestPostAsync("token/create", + new HttpCreateTokenRequest { Username = username, Password = password }); + return res.Token; + } + public async Task CreateClientWithCredential(string username, string password, bool setApiBase = true) { var client = await CreateDefaultClient(setApiBase); @@ -115,6 +123,14 @@ namespace Timeline.Tests.IntegratedTests return client; } + public Task CreateTokenAsync(int userNumber) + { + if (userNumber == 0) + return CreateTokenWithCredentialAsync("admin", "adminpw"); + else + return CreateTokenWithCredentialAsync($"user{userNumber}", $"user{userNumber}pw"); + } + public Task CreateClientAs(int userNumber, bool setApiBase = true) { if (userNumber < 0) diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelineHubTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelineHubTest.cs new file mode 100644 index 00000000..66df74d7 --- /dev/null +++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelineHubTest.cs @@ -0,0 +1,82 @@ +using FluentAssertions; +using Microsoft.AspNetCore.SignalR.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Timeline.SignalRHub; +using Xunit; + +namespace Timeline.Tests.IntegratedTests +{ + public class TimelineHubTest : BaseTimelineTest + { + private HubConnection CreateConnection(string? token) + { + return new HubConnectionBuilder().WithUrl($"http://localhost/api/hub/timeline{(token is null ? "" : "?token=" + token)}", + options => options.HttpMessageHandlerFactory = _ => TestApp.Server.CreateHandler()).Build(); + } + + [Theory] + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task TimelinePostUpdate_Should_Work(TimelineNameGenerator generator) + { + var token = await CreateTokenAsync(1); + + await using var connection = CreateConnection(token); + + var changed = false; + + connection.On(nameof(ITimelineClient.OnTimelinePostChanged), (timelineName) => + { + timelineName.Should().Be(generator(1)); + changed = true; + }); + + await connection.StartAsync(); + connection.State.Should().Be(HubConnectionState.Connected); + + using var client = await CreateClientAsUser(); + + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelinePostTest.CreateTextPostRequest("aaa")); + changed.Should().BeFalse(); + + await connection.InvokeAsync(nameof(TimelineHub.SubscribeTimelinePostChange), generator(1)); + + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelinePostTest.CreateTextPostRequest("bbb")); + changed.Should().BeTrue(); + + changed = false; + + await connection.InvokeAsync(nameof(TimelineHub.UnsubscribeTimelinePostChange), generator(1)); + + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelinePostTest.CreateTextPostRequest("ccc")); + changed.Should().BeFalse(); + } + + [Fact] + public async Task TimelinePostUpdate_InvalidName() + { + await using var connection = CreateConnection(null); + await connection.StartAsync(); + await connection.Awaiting(c => c.InvokeAsync(nameof(TimelineHub.SubscribeTimelinePostChange), "!!!")).Should().ThrowAsync(); + } + + [Fact] + public async Task TimelinePostUpdate_NotExist() + { + await using var connection = CreateConnection(null); + await connection.StartAsync(); + await connection.Awaiting(c => c.InvokeAsync(nameof(TimelineHub.SubscribeTimelinePostChange), "timelinenotexist")).Should().ThrowAsync(); + } + + [Fact] + public async Task TimelinePostUpdate_Forbid() + { + await using var connection = CreateConnection(null); + await connection.StartAsync(); + await connection.Awaiting(c => c.InvokeAsync(nameof(TimelineHub.SubscribeTimelinePostChange), "t1")).Should().ThrowAsync(); + } + } +} + diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs index 097275b0..ab8f6f66 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs @@ -19,7 +19,7 @@ namespace Timeline.Tests.IntegratedTests { public class TimelinePostTest : BaseTimelineTest { - private static HttpTimelinePostCreateRequest CreateTextPostRequest(string text, DateTime? time = null, string? color = null) + public static HttpTimelinePostCreateRequest CreateTextPostRequest(string text, DateTime? time = null, string? color = null) { return new HttpTimelinePostCreateRequest() { -- cgit v1.2.3