From 48d53341db4953b3d583dd825b48d854c0a166e9 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 13 Nov 2020 17:08:20 +0800 Subject: ... --- BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs') diff --git a/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs index 39a6e545..86cde11f 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs @@ -14,7 +14,9 @@ namespace Timeline.Tests.IntegratedTests using var client = await CreateDefaultClient(false); var res = await client.GetAsync("index.html"); res.Should().HaveStatusCode(200); - res.Content.Headers.ContentType.MediaType.Should().Be(MediaTypeNames.Text.Html); + var contentTypeHeader = res.Content.Headers.ContentType; + contentTypeHeader.Should().NotBeNull(); + contentTypeHeader!.MediaType.Should().Be(MediaTypeNames.Text.Html); } [Fact] @@ -23,7 +25,9 @@ namespace Timeline.Tests.IntegratedTests using var client = await CreateDefaultClient(false); var res = await client.GetAsync("aaaaaaaaaaaaaaa"); res.Should().HaveStatusCode(200); - res.Content.Headers.ContentType.MediaType.Should().Be(MediaTypeNames.Text.Html); + var contentTypeHeader = res.Content.Headers.ContentType; + contentTypeHeader.Should().NotBeNull(); + contentTypeHeader!.MediaType.Should().Be(MediaTypeNames.Text.Html); } } } -- cgit v1.2.3 From f5ccd0d9855f82e14c6b765eee6a04b22c50dc8a Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 15 Nov 2020 01:44:48 +0800 Subject: ... --- .../IntegratedTests/CacheTestHelper.cs | 47 ++- .../Timeline.Tests/IntegratedTests/FrontEndTest.cs | 6 +- .../IntegratedTests/HttpClientExtensions.cs | 48 --- .../IntegratedTests/HttpClientTestExtensions.cs | 192 +++++++++++ .../HttpClientTimelineExtensions.cs | 26 +- .../IntegratedTests/HttpClientUserExtensions.cs | 8 +- .../IntegratedTests/HttpResponseAssertions.cs | 136 -------- .../IntegratedTests/HttpResponseExtensions.cs | 14 - .../IntegratedTests/IntegratedTestBase.cs | 5 +- .../Timeline.Tests/IntegratedTests/TimelineTest.cs | 358 ++++++--------------- 10 files changed, 320 insertions(+), 520 deletions(-) delete mode 100644 BackEnd/Timeline.Tests/IntegratedTests/HttpClientExtensions.cs create mode 100644 BackEnd/Timeline.Tests/IntegratedTests/HttpClientTestExtensions.cs delete mode 100644 BackEnd/Timeline.Tests/IntegratedTests/HttpResponseAssertions.cs delete mode 100644 BackEnd/Timeline.Tests/IntegratedTests/HttpResponseExtensions.cs (limited to 'BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs') diff --git a/BackEnd/Timeline.Tests/IntegratedTests/CacheTestHelper.cs b/BackEnd/Timeline.Tests/IntegratedTests/CacheTestHelper.cs index bafb2fcf..8308eca8 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/CacheTestHelper.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/CacheTestHelper.cs @@ -13,9 +13,10 @@ namespace Timeline.Tests.IntegratedTests public static async Task TestCache(HttpClient client, string getUrl) { EntityTagHeaderValue eTag; + { var res = await client.GetAsync(getUrl); - res.Should().HaveStatusCode(200); + res.StatusCode.Should().Be(HttpStatusCode.OK); var cacheControlHeader = res.Headers.CacheControl; cacheControlHeader.Should().NotBeNull(); cacheControlHeader!.NoCache.Should().BeTrue(); @@ -28,39 +29,27 @@ namespace Timeline.Tests.IntegratedTests eTag = res.Headers.ETag!; } - { - using var request = new HttpRequestMessage() + await client.TestSendAssertErrorAsync(HttpMethod.Get, getUrl, + expectedStatusCode: HttpStatusCode.BadRequest, + errorCode: ErrorCodes.Common.Header.IfNonMatch_BadFormat, + headerSetup: static (headers, _) => { - RequestUri = new Uri(client.BaseAddress!, getUrl), - Method = HttpMethod.Get, - }; - request.Headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd"); - var res = await client.SendAsync(request); - await res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.HaveCommonBodyWithCodeAsync(ErrorCodes.Common.Header.IfNonMatch_BadFormat); - } + headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd"); + }); - { - using var request = new HttpRequestMessage() + await client.TestSendAsync(HttpMethod.Get, getUrl, + expectedStatusCode: HttpStatusCode.OK, + headerSetup: static (headers, _) => { - RequestUri = new Uri(client.BaseAddress!, getUrl), - Method = HttpMethod.Get, - }; - request.Headers.TryAddWithoutValidation("If-None-Match", "\"aaa\""); - var res = await client.SendAsync(request); - res.Should().HaveStatusCode(HttpStatusCode.OK); - } + headers.TryAddWithoutValidation("If-None-Match", "\"aaa\""); + }); - { - using var request = new HttpRequestMessage() + await client.TestSendAsync(HttpMethod.Get, getUrl, + expectedStatusCode: HttpStatusCode.NotModified, + headerSetup: (headers, _) => { - RequestUri = new Uri(client.BaseAddress!, getUrl), - Method = HttpMethod.Get, - }; - request.Headers.Add("If-None-Match", eTag.ToString()); - var res = await client.SendAsync(request); - res.Should().HaveStatusCode(HttpStatusCode.NotModified); - } + headers.Add("If-None-Match", eTag.ToString()); + }); } } } diff --git a/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs index 86cde11f..1843c412 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/FrontEndTest.cs @@ -1,7 +1,7 @@ using FluentAssertions; +using System.Net; using System.Net.Mime; using System.Threading.Tasks; -using Timeline.Tests.Helpers; using Xunit; namespace Timeline.Tests.IntegratedTests @@ -13,7 +13,7 @@ namespace Timeline.Tests.IntegratedTests { using var client = await CreateDefaultClient(false); var res = await client.GetAsync("index.html"); - res.Should().HaveStatusCode(200); + res.StatusCode.Should().Be(HttpStatusCode.OK); var contentTypeHeader = res.Content.Headers.ContentType; contentTypeHeader.Should().NotBeNull(); contentTypeHeader!.MediaType.Should().Be(MediaTypeNames.Text.Html); @@ -24,7 +24,7 @@ namespace Timeline.Tests.IntegratedTests { using var client = await CreateDefaultClient(false); var res = await client.GetAsync("aaaaaaaaaaaaaaa"); - res.Should().HaveStatusCode(200); + res.StatusCode.Should().Be(HttpStatusCode.OK); var contentTypeHeader = res.Content.Headers.ContentType; contentTypeHeader.Should().NotBeNull(); contentTypeHeader!.MediaType.Should().Be(MediaTypeNames.Text.Html); diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientExtensions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientExtensions.cs deleted file mode 100644 index 9258e644..00000000 --- a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientExtensions.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Net.Mime; -using System.Text; -using System.Threading.Tasks; - -namespace Timeline.Tests.IntegratedTests -{ - public static class HttpClientExtensions - { - public static async Task PatchAsJsonAsync(this HttpClient client, string url, T body) - { - using var reqContent = JsonContent.Create(body, options: CommonJsonSerializeOptions.Options); - return await client.PatchAsync(url, reqContent); - } - - public static Task PutAsync(this HttpClient client, string url) - { - return client.PutAsync(url, null!); - } - - public static Task PutByteArrayAsync(this HttpClient client, string url, byte[] body, string mimeType) - { - return client.PutByteArrayAsync(new Uri(url, UriKind.RelativeOrAbsolute), body, mimeType); - } - - public static async Task PutByteArrayAsync(this HttpClient client, Uri url, byte[] body, string mimeType) - { - using var content = new ByteArrayContent(body); - content.Headers.ContentLength = body.Length; - content.Headers.ContentType = new MediaTypeHeaderValue(mimeType); - return await client.PutAsync(url, content); - } - - public static Task PutStringAsync(this HttpClient client, string url, string body, string? mimeType = null) - { - return client.PutStringAsync(new Uri(url, UriKind.RelativeOrAbsolute), body, mimeType); - } - - public static async Task PutStringAsync(this HttpClient client, Uri url, string body, string? mimeType = null) - { - using var content = new StringContent(body, Encoding.UTF8, mimeType ?? MediaTypeNames.Text.Plain); - return await client.PutAsync(url, content); - } - } -} diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTestExtensions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTestExtensions.cs new file mode 100644 index 00000000..18334622 --- /dev/null +++ b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTestExtensions.cs @@ -0,0 +1,192 @@ +using FluentAssertions; +using System; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Threading.Tasks; +using Timeline.Models.Http; + +namespace Timeline.Tests.IntegratedTests +{ + public delegate void HeaderSetup(HttpRequestHeaders requestHeaders, HttpContentHeaders? contentHeaders); + + public static class HttpClientTestExtensions + { + public static async Task TestSendAsync(this HttpClient client, HttpMethod method, string url, HttpContent? body = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, HeaderSetup? headerSetup = null) + { + using var req = new HttpRequestMessage + { + Method = method, + RequestUri = new Uri(url, UriKind.Relative), + Content = body + }; + headerSetup?.Invoke(req.Headers, body?.Headers); + var res = await client.SendAsync(req); + res.StatusCode.Should().Be(expectedStatusCode); + return res; + } + + public static async Task AssertJsonBodyAsync(HttpResponseMessage response) + { + var body = await response.Content.ReadFromJsonAsync(CommonJsonSerializeOptions.Options); + body.Should().NotBeNull($"Body is not json format of type {typeof(T).FullName}"); + return body!; + } + + public static async Task TestJsonSendAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, HeaderSetup? headerSetup = null) + { + using JsonContent? reqContent = jsonBody == null ? null : JsonContent.Create(jsonBody, options: CommonJsonSerializeOptions.Options); + await client.TestSendAsync(method, url, reqContent, expectedStatusCode, headerSetup); + } + + public static async Task TestJsonSendAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, HeaderSetup? headerSetup = null) + { + using JsonContent? reqContent = jsonBody == null ? null : JsonContent.Create(jsonBody, options: CommonJsonSerializeOptions.Options); + var res = await client.TestSendAsync(method, url, reqContent, expectedStatusCode, headerSetup); + var resBody = await AssertJsonBodyAsync(res); + return resBody; + } + + public static async Task TestGetAsync(this HttpClient client, string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + await client.TestJsonSendAsync(HttpMethod.Get, url, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestGetAsync(this HttpClient client, string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + return await client.TestJsonSendAsync(HttpMethod.Get, url, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestPostAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + await client.TestJsonSendAsync(HttpMethod.Post, url, jsonBody, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestPostAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + return await client.TestJsonSendAsync(HttpMethod.Post, url, jsonBody, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestPutAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + await client.TestJsonSendAsync(HttpMethod.Put, url, jsonBody, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestPutAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + return await client.TestJsonSendAsync(HttpMethod.Put, url, jsonBody, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestPatchAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + return await client.TestJsonSendAsync(HttpMethod.Patch, url, jsonBody, expectedStatusCode: expectedStatusCode); + } + + public static async Task TestDeleteAsync(this HttpClient client, string url, bool? delete = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + var body = await client.TestJsonSendAsync(HttpMethod.Delete, url, expectedStatusCode: expectedStatusCode); + if (delete.HasValue) + body.Data.Delete.Should().Be(delete.Value); + } + + public static async Task TestSendAssertErrorAsync(this HttpClient client, HttpMethod method, string url, HttpContent? body = null, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest, int? errorCode = null, HeaderSetup? headerSetup = null) + { + var res = await client.TestSendAsync(method, url, body, expectedStatusCode, headerSetup); + if (errorCode.HasValue) + { + var resBody = await AssertJsonBodyAsync(res); + resBody.Code.Should().Be(errorCode.Value); + } + } + + public static async Task TestJsonSendAssertErrorAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest, int? errorCode = null, HeaderSetup? headerSetup = null) + { + using JsonContent? reqContent = jsonBody == null ? null : JsonContent.Create(jsonBody, options: CommonJsonSerializeOptions.Options); + await client.TestSendAssertErrorAsync(method, url, reqContent, expectedStatusCode, errorCode, headerSetup); + } + + public static async Task TestPostAssertErrorAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertErrorAsync(HttpMethod.Post, url, jsonBody, expectedStatusCode, errorCode, headerSetup); + } + + public static async Task TestPutAssertErrorAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertErrorAsync(HttpMethod.Put, url, jsonBody, expectedStatusCode, errorCode, headerSetup); + } + + public static async Task TestDeleteAssertErrorAsync(this HttpClient client, string url, object? jsonBody = null, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertErrorAsync(HttpMethod.Delete, url, jsonBody, expectedStatusCode, errorCode, headerSetup); + } + + public static async Task TestJsonSendAssertInvalidModelAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null) + { + await client.TestJsonSendAssertErrorAsync(method, url, jsonBody, expectedStatusCode: HttpStatusCode.BadRequest, errorCode: ErrorCodes.Common.InvalidModel); + } + + public static async Task TestGetAssertInvalidModelAsync(this HttpClient client, string url) + { + await client.TestJsonSendAssertInvalidModelAsync(HttpMethod.Get, url); + } + + public static async Task TestPostAssertInvalidModelAsync(this HttpClient client, string url, object? jsonBody = null) + { + await client.TestJsonSendAssertInvalidModelAsync(HttpMethod.Post, url, jsonBody); + } + + public static async Task TestDeleteAssertInvalidModelAsync(this HttpClient client, string url, object? jsonBody = null) + { + await client.TestJsonSendAssertInvalidModelAsync(HttpMethod.Delete, url, jsonBody); + } + + public static async Task TestJsonSendAssertUnauthorizedAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertErrorAsync(method, url, jsonBody, HttpStatusCode.Unauthorized, errorCode, headerSetup); + } + + public static async Task TestGetAssertUnauthorizedAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertUnauthorizedAsync(HttpMethod.Get, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestPostAssertUnauthorizedAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertUnauthorizedAsync(HttpMethod.Post, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestDeleteAssertUnauthorizedAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertUnauthorizedAsync(HttpMethod.Delete, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestJsonSendAssertForbiddenAsync(this HttpClient client, HttpMethod method, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertErrorAsync(method, url, jsonBody, HttpStatusCode.Forbidden, errorCode, headerSetup); + } + + public static async Task TestGetAssertForbiddenAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertForbiddenAsync(HttpMethod.Get, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestPostAssertForbiddenAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertForbiddenAsync(HttpMethod.Post, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestDeleteAssertForbiddenAsync(this HttpClient client, string url, object? jsonBody = null, int? errorCode = null, HeaderSetup? headerSetup = null) + { + await client.TestJsonSendAssertForbiddenAsync(HttpMethod.Delete, url, jsonBody, errorCode, headerSetup); + } + + public static async Task TestPutByteArrayAsync(this HttpClient client, string url, byte[] body, string mimeType, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + using var content = new ByteArrayContent(body); + content.Headers.ContentLength = body.Length; + content.Headers.ContentType = new MediaTypeHeaderValue(mimeType); + return await client.TestSendAsync(HttpMethod.Put, url, content); + } + } +} diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTimelineExtensions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTimelineExtensions.cs index 125435f9..992889e3 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTimelineExtensions.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientTimelineExtensions.cs @@ -7,24 +7,16 @@ namespace Timeline.Tests.IntegratedTests { public static class HttpClientTimelineExtensions { - public static async Task GetTimelineAsync(this HttpClient client, string timelineName) - { - var res = await client.GetAsync($"timelines/{timelineName}"); - res.Should().HaveStatusCode(HttpStatusCode.OK); - return await res.Should().HaveAndGetJsonBodyAsync(); - } + public static Task GetTimelineAsync(this HttpClient client, string timelineName) + => client.TestGetAsync($"timelines/{timelineName}"); - public static async Task PatchTimelineAsync(this HttpClient client, string timelineName, TimelinePatchRequest body) - { - var res = await client.PatchAsJsonAsync($"timelines/{timelineName}", body); - res.Should().HaveStatusCode(HttpStatusCode.OK); - return await res.Should().HaveAndGetJsonBodyAsync(); - } + public static Task PatchTimelineAsync(this HttpClient client, string timelineName, TimelinePatchRequest body) + => client.TestPatchAsync($"timelines/{timelineName}", body); - public static async Task PutTimelineMemberAsync(this HttpClient client, string timelineName, string memberUsername) - { - var res = await client.PutAsync($"timelines/{timelineName}/members/{memberUsername}"); - res.Should().HaveStatusCode(HttpStatusCode.OK); - } + public static Task PutTimelineMemberAsync(this HttpClient client, string timelineName, string memberUsername) + => client.TestPutAsync($"timelines/{timelineName}/members/{memberUsername}"); + + public static Task DeleteTimelineMemberAsync(this HttpClient client, string timelineName, string memberUsername, bool? delete) + => client.TestDeleteAsync($"timelines/{timelineName}/members/{memberUsername}", delete); } } diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientUserExtensions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientUserExtensions.cs index 0ce2325f..0ccefa55 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/HttpClientUserExtensions.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/HttpClientUserExtensions.cs @@ -7,11 +7,7 @@ namespace Timeline.Tests.IntegratedTests { public static class HttpClientUserExtensions { - public static async Task GetUserAsync(this HttpClient client, string username) - { - var res = await client.GetAsync($"users/{username}"); - res.Should().HaveStatusCode(HttpStatusCode.OK); - return await res.Should().HaveAndGetJsonBodyAsync(); - } + public static Task GetUserAsync(this HttpClient client, string username) + => client.TestGetAsync($"users/{username}"); } } diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseAssertions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseAssertions.cs deleted file mode 100644 index 166cde09..00000000 --- a/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseAssertions.cs +++ /dev/null @@ -1,136 +0,0 @@ -using FluentAssertions; -using FluentAssertions.Execution; -using FluentAssertions.Formatting; -using FluentAssertions.Primitives; -using System; -using System.Globalization; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Timeline.Models.Http; - -namespace Timeline.Tests.IntegratedTests -{ - public class HttpResponseMessageValueFormatter : IValueFormatter - { - public bool CanHandle(object value) - { - return value is HttpResponseMessage; - } - - public string Format(object value, FormattingContext context, FormatChild formatChild) - { - string newline = context.UseLineBreaks ? Environment.NewLine : ""; - string padding = new string('\t', context.Depth); - - var res = (HttpResponseMessage)value; - return $"{newline}{padding} Status Code: {res.StatusCode}"; - } - } - - public class HttpResponseMessageAssertions - : ReferenceTypeAssertions - { - static HttpResponseMessageAssertions() - { - Formatter.AddFormatter(new HttpResponseMessageValueFormatter()); - } - - public HttpResponseMessageAssertions(HttpResponseMessage instance) - { - Subject = instance; - } - - protected override string Identifier => "HttpResponseMessage"; - - public AndConstraint HaveStatusCode(int expected, string because = "", params object[] becauseArgs) - { - return HaveStatusCode((HttpStatusCode)expected, because, becauseArgs); - } - - public AndConstraint HaveStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs) - { - Execute.Assertion.BecauseOf(because, becauseArgs) - .ForCondition(Subject.StatusCode == expected) - .FailWith("Expected status code of {context:HttpResponseMessage} to be {0}{reason}, but found {1}.", expected, Subject.StatusCode); - return new AndConstraint(this); - } - - public async Task HaveAndGetJsonBodyAsync(string because = "", params object[] becauseArgs) - { - var a = Execute.Assertion.BecauseOf(because, becauseArgs); - - var body = await Subject.ReadBodyAsJsonAsync(); - if (body == null) - { - a.FailWith("Expected response body of {context:HttpResponseMessage} to be json string of type {0}{reason}, but failed to read it or it was not a valid json string.", typeof(T).FullName); - return default!; - } - return body; - } - - public async Task> HaveJsonBodyAsync(string because = "", params object[] becauseArgs) - { - var a = Execute.Assertion.BecauseOf(because, becauseArgs); - - var body = await Subject.ReadBodyAsJsonAsync(); - if (body == null) - { - a.FailWith("Expected response body of {context:HttpResponseMessage} to be json string of type {0}{reason}, but failed to read it or it was not a valid json string.", typeof(T).FullName); - return new(Subject, null); - } - return new(Subject, body); - } - } - - public static class AssertionResponseExtensions - { - public static HttpResponseMessageAssertions Should(this HttpResponseMessage instance) - { - return new HttpResponseMessageAssertions(instance); - } - - public static Task HaveAndGetCommonBodyAsync(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) - { - return assertions.HaveAndGetJsonBodyAsync(because, becauseArgs); - } - - public static async Task HaveCommonBodyWithCodeAsync(this HttpResponseMessageAssertions assertions, int code, string? message = null, params object[] messageArgs) - { - message = string.IsNullOrEmpty(message) ? "" : ", " + string.Format(CultureInfo.CurrentCulture, message, messageArgs); - var body = await assertions.HaveAndGetCommonBodyAsync("Response body should be CommonResponse{0}", message); - body.Code.Should().Be(code, "Response body code is not the specified one{0}", message); - } - - public static Task> HaveAndGetCommonDataBodyAsync(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) - { - return assertions.HaveAndGetJsonBodyAsync>(because, becauseArgs); - } - - public static async Task BePutAsync(this HttpResponseMessageAssertions assertions, bool create, string because = "", params object[] becauseArgs) - { - var body = await assertions.HaveStatusCode(create ? 201 : 200, because, becauseArgs) - .And.HaveAndGetJsonBodyAsync(because, becauseArgs); - body.Code.Should().Be(0); - body.Data.Create.Should().Be(create); - } - - public static async Task BeDeleteAsync(this HttpResponseMessageAssertions assertions, bool delete, string because = "", params object[] becauseArgs) - { - var body = await assertions.HaveStatusCode(200, because, becauseArgs) - .And.HaveAndGetJsonBodyAsync(because, becauseArgs); - body.Code.Should().Be(0); - body.Data.Delete.Should().Be(delete); - } - - public static async Task BeInvalidModelAsync(this HttpResponseMessageAssertions assertions, string? message = null) - { - message = string.IsNullOrEmpty(message) ? "" : ", " + message; - var body = await assertions.HaveStatusCode(400, "Invalid Model Error must have 400 status code{0}", message) - .And.HaveAndGetCommonBodyAsync("Invalid Model Error must have CommonResponse body{0}", message); - body.Code.Should().Be(ErrorCodes.Common.InvalidModel, - "Invalid Model Error must have code {0} in body{1}", - ErrorCodes.Common.InvalidModel, message); - } - } -} diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseExtensions.cs b/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseExtensions.cs deleted file mode 100644 index 097fefd1..00000000 --- a/BackEnd/Timeline.Tests/IntegratedTests/HttpResponseExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Net.Http; -using System.Net.Http.Json; -using System.Threading.Tasks; - -namespace Timeline.Tests.IntegratedTests -{ - public static class HttpResponseExtensions - { - public static async Task ReadBodyAsJsonAsync(this HttpResponseMessage response) - { - return await response.Content.ReadFromJsonAsync(CommonJsonSerializeOptions.Options); - } - } -} diff --git a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs index 070b456f..72480dc6 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs @@ -104,10 +104,9 @@ namespace Timeline.Tests.IntegratedTests public async Task CreateClientWithCredential(string username, string password, bool setApiBase = true) { var client = await CreateDefaultClient(setApiBase); - var response = await client.PostAsJsonAsync("token/create", + var res = await client.TestPostAsync("token/create", new CreateTokenRequest { Username = username, Password = password }); - var token = (await response.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync()).Token; + var token = res.Token; client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); return client; } diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs index e996be45..fbcdb3fc 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Net; using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; @@ -15,7 +14,6 @@ using Timeline.Entities; using Timeline.Models; using Timeline.Models.Http; using Timeline.Tests.Helpers; -using Timeline.Tests.IntegratedTests; using Xunit; namespace Timeline.Tests.IntegratedTests @@ -61,8 +59,7 @@ namespace Timeline.Tests.IntegratedTests for (int i = 0; i <= 3; i++) { using var client = await CreateClientAs(i); - var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = $"t{i}" }); - res.Should().HaveStatusCode(200); + await client.TestPostAsync("timelines", new TimelineCreateRequest { Name = $"t{i}" }); } } @@ -71,20 +68,12 @@ namespace Timeline.Tests.IntegratedTests { using var client = await CreateDefaultClient(); - { - var res = await client.GetAsync("timelines/@!!!"); - await res.Should().BeInvalidModelAsync(); - } + await client.TestGetAssertInvalidModelAsync("timelines/@!!!"); + await client.TestGetAssertInvalidModelAsync("timelines/!!!"); - { - var res = await client.GetAsync("timelines/!!!"); - await res.Should().BeInvalidModelAsync(); - } { - var res = await client.GetAsync("timelines/@user1"); - var body = await res.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync(); + var body = await client.TestGetAsync("timelines/@user1"); body.Owner.Should().BeEquivalentTo(await client.GetUserAsync("user1")); body.Visibility.Should().Be(TimelineVisibility.Register); body.Description.Should().Be(""); @@ -96,9 +85,7 @@ namespace Timeline.Tests.IntegratedTests } { - var res = await client.GetAsync("timelines/t1"); - var body = await res.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync(); + var body = await client.TestGetAsync("timelines/t1"); body.Owner.Should().BeEquivalentTo(await client.GetUserAsync("user1")); body.Visibility.Should().Be(TimelineVisibility.Register); body.Description.Should().Be(""); @@ -126,10 +113,7 @@ namespace Timeline.Tests.IntegratedTests } - var res = await client.GetAsync("timelines"); - var body = res.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync>(); - + var body = await client.TestGetAsync>("timelines"); body.Should().BeEquivalentTo(result); } @@ -139,15 +123,9 @@ namespace Timeline.Tests.IntegratedTests { using var client = await CreateDefaultClient(); - async Task TestAgainst(string url) - { - var res = await client.GetAsync(url); - await res.Should().BeInvalidModelAsync(); - } - - await TestAgainst("timelines?relate=us!!"); - await TestAgainst("timelines?relateType=aaa"); - await TestAgainst("timelines?visibility=aaa"); + await client.TestGetAssertInvalidModelAsync("timelines?relate=us!!"); + await client.TestGetAssertInvalidModelAsync("timelines?relateType=aaa"); + await client.TestGetAssertInvalidModelAsync("timelines?visibility=aaa"); } var testResultRelate = new List(); @@ -231,9 +209,7 @@ namespace Timeline.Tests.IntegratedTests async Task TestAgainst(string url, List against) { - var res = await client.GetAsync(url); - var body = await res.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync>(); + var body = await client.TestGetAsync>(url); body.Should().BeEquivalentTo(against); } @@ -252,30 +228,20 @@ namespace Timeline.Tests.IntegratedTests { { using var client = await CreateDefaultClient(); - var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" }); - res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + await client.TestPostAssertUnauthorizedAsync("timelines", new TimelineCreateRequest { Name = "aaa" }); } { using var client = await CreateClientAsUser(); - { - var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "!!!" }); - await res.Should().BeInvalidModelAsync(); - } + await client.TestPostAssertInvalidModelAsync("timelines", new TimelineCreateRequest { Name = "!!!" }); { - var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" }); - var body = await res.Should().HaveStatusCode(200) - .And.HaveAndGetJsonBodyAsync(); + var body = await client.TestPostAsync("timelines", new TimelineCreateRequest { Name = "aaa" }); body.Should().BeEquivalentTo(await client.GetTimelineAsync("aaa")); } - { - var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" }); - await res.Should().HaveStatusCode(400) - .And.HaveCommonBodyWithCodeAsync(ErrorCodes.TimelineController.NameConflict); - } + await client.TestPostAssertErrorAsync("timelines", new TimelineCreateRequest { Name = "aaa" }, errorCode: ErrorCodes.TimelineController.NameConflict); } } @@ -284,61 +250,49 @@ namespace Timeline.Tests.IntegratedTests { { using var client = await CreateDefaultClient(); - var res = await client.DeleteAsync("timelines/t1"); - res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + await client.TestDeleteAssertUnauthorizedAsync("timelines/t1"); } { using var client = await CreateClientAs(2); - var res = await client.DeleteAsync("timelines/t1"); - res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + await client.TestDeleteAssertForbiddenAsync("timelines/t1"); } { using var client = await CreateClientAsAdministrator(); - { - var res = await client.DeleteAsync("timelines/!!!"); - await res.Should().BeInvalidModelAsync(); - } - - { - var res = await client.DeleteAsync("timelines/t2"); - await res.Should().BeDeleteAsync(true); - } - - { - var res = await client.DeleteAsync("timelines/t2"); - await res.Should().BeDeleteAsync(false); - } + await client.TestDeleteAssertInvalidModelAsync("timelines/!!!"); + await client.TestDeleteAsync("timelines/t2", true); + await client.TestDeleteAsync("timelines/t2", false); } { using var client = await CreateClientAs(1); - { - var res = await client.DeleteAsync("timelines/!!!"); - await res.Should().BeInvalidModelAsync(); - } + await client.TestDeleteAssertInvalidModelAsync("timelines/!!!"); + await client.TestDeleteAsync("timelines/t1", true); + await client.TestDeleteAssertErrorAsync("timelines/t1"); + } + } - { - var res = await client.DeleteAsync("timelines/t1"); - await res.Should().BeDeleteAsync(true); - } + public static string CreatePersonalTimelineName(int i) => i == 0 ? "@admin" : $"@user{i}"; + public static string CreateOrdinaryTimelineName(int i) => $"t{i}"; + public delegate string TimelineNameGenerator(int i); - { - var res = await client.DeleteAsync("timelines/t1"); - res.Should().HaveStatusCode(400); - } - } + public static IEnumerable TimelineNameGeneratorTestData() + { + yield return new object[] { new TimelineNameGenerator(CreatePersonalTimelineName) }; + yield return new object[] { new TimelineNameGenerator(CreateOrdinaryTimelineName) }; } [Theory] - [InlineData("@user1")] - [InlineData("t1")] - public async Task TimelineDescription_Should_Work(string timelineName) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task TimelineDescription_Should_Work(TimelineNameGenerator generator) { + // TODO! Permission tests. + using var client = await CreateClientAsUser(); + var timelineName = generator(1); { var timeline = await client.GetTimelineAsync(timelineName); @@ -379,309 +333,185 @@ namespace Timeline.Tests.IntegratedTests } [Theory] - [MemberData(nameof(TimelineUrlGeneratorData))] - public async Task Member_Should_Work(TimelineUrlGenerator generator) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task Member_Should_Work(TimelineNameGenerator generator) { - var getUrl = generator(1, null); + // TODO! Invalid model tests. + // TODO! Permission tests. + using var client = await CreateClientAsUser(); - async Task AssertMembers(IList members) + var timelineName = generator(1); + + async Task AssertMembers(List members) { - var res = await client.GetAsync(getUrl); - res.Should().HaveStatusCode(200) - .And.HaveJsonBody() - .Which.Members.Should().NotBeNull().And.BeEquivalentTo(members); + var body = await client.GetTimelineAsync(timelineName); + body.Members.Should().NotBeNull().And.BeEquivalentTo(members); } async Task AssertEmptyMembers() { - var res = await client.GetAsync(getUrl); - res.Should().HaveStatusCode(200) - .And.HaveJsonBody() - .Which.Members.Should().NotBeNull().And.BeEmpty(); + var body = await client.GetTimelineAsync(timelineName); + body.Members.Should().NotBeNull().And.BeEmpty(); } await AssertEmptyMembers(); - { - var res = await client.PutAsync(generator(1, "members/usernotexist"), null); - res.Should().HaveStatusCode(400) - .And.HaveCommonBody(ErrorCodes.TimelineController.MemberPut_NotExist); - } + await client.TestPutAssertErrorAsync($"timelines/{timelineName}/members/usernotexist", errorCode: ErrorCodes.TimelineController.MemberPut_NotExist); await AssertEmptyMembers(); - { - var res = await client.PutAsync(generator(1, "members/user2"), null); - res.Should().HaveStatusCode(200); - } - await AssertMembers(new List { UserInfos[2] }); - { - var res = await client.DeleteAsync(generator(1, "members/user2")); - res.Should().BeDelete(true); - } + await client.PutTimelineMemberAsync(timelineName, "user2"); + await AssertMembers(new List { await client.GetUserAsync("user2") }); + await client.DeleteTimelineMemberAsync(timelineName, "user2", true); await AssertEmptyMembers(); - { - var res = await client.DeleteAsync(generator(1, "members/aaa")); - res.Should().BeDelete(false); - } + await client.DeleteTimelineMemberAsync(timelineName, "aaa", false); await AssertEmptyMembers(); } - public static IEnumerable Permission_Timeline_Data() - { - yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), -1, 200, 401, 401, 401, 401 }; - yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), 1, 200, 200, 403, 200, 403 }; - yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), 0, 200, 200, 200, 200, 200 }; - yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), -1, 200, 401, 401, 401, 401 }; - yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), 1, 200, 200, 403, 200, 403 }; - yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), 0, 200, 200, 200, 200, 200 }; - } - - [Theory] - [MemberData(nameof(Permission_Timeline_Data))] - public async Task Permission_Timeline(TimelineUrlGenerator generator, int userNumber, int get, int opPatchUser, int opPatchAdmin, int opMemberUser, int opMemberAdmin) - { - using var client = await CreateClientAs(userNumber); - { - var res = await client.GetAsync("timelines/t1"); - res.Should().HaveStatusCode(get); - } - - { - var res = await client.PatchAsJsonAsync(generator(1, null), new TimelinePatchRequest { Description = "hahaha" }); - res.Should().HaveStatusCode(opPatchUser); - } - - { - var res = await client.PatchAsJsonAsync(generator(0, null), new TimelinePatchRequest { Description = "hahaha" }); - res.Should().HaveStatusCode(opPatchAdmin); - } - - { - var res = await client.PutAsync(generator(1, "members/user2"), null); - res.Should().HaveStatusCode(opMemberUser); - } - - { - var res = await client.DeleteAsync(generator(1, "members/user2")); - res.Should().HaveStatusCode(opMemberUser); - } - - { - var res = await client.PutAsync(generator(0, "members/user2"), null); - res.Should().HaveStatusCode(opMemberAdmin); - } - - { - var res = await client.DeleteAsync(generator(0, "members/user2")); - res.Should().HaveStatusCode(opMemberAdmin); - } - } - [Theory] - [MemberData(nameof(TimelineUrlGeneratorData))] - public async Task Visibility_Test(TimelineUrlGenerator generator) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task GetPostsAndVisibility_Should_Work(TimelineNameGenerator generator) { - var userUrl = generator(1, "posts"); - var adminUrl = generator(0, "posts"); - { - - using var client = await CreateClientAsUser(); - using var content = new StringContent(@"{""visibility"":""abcdefg""}", System.Text.Encoding.UTF8, System.Net.Mime.MediaTypeNames.Application.Json); - var res = await client.PatchAsync(generator(1, null), content); - res.Should().BeInvalidModel(); - } { // default visibility is registered { using var client = await CreateDefaultClient(); - var res = await client.GetAsync(userUrl); - res.Should().HaveStatusCode(403); + await client.TestGetAssertForbiddenAsync($"timelines/{generator(1)}/posts"); } { using var client = await CreateClientAsUser(); - var res = await client.GetAsync(adminUrl); - res.Should().HaveStatusCode(200); + await client.TestGetAsync($"timelines/{generator(0)}/posts"); } } { // change visibility to public { using var client = await CreateClientAsUser(); - var res = await client.PatchAsJsonAsync(generator(1, null), - new TimelinePatchRequest { Visibility = TimelineVisibility.Public }); - res.Should().HaveStatusCode(200); + await client.PatchTimelineAsync(generator(1), new() { Visibility = TimelineVisibility.Public }); } + { using var client = await CreateDefaultClient(); - var res = await client.GetAsync(userUrl); - res.Should().HaveStatusCode(200); + await client.TestGetAsync($"timelines/{generator(1)}/posts"); } } { // change visibility to private { using var client = await CreateClientAsAdministrator(); - { - var res = await client.PatchAsJsonAsync(generator(1, null), - new TimelinePatchRequest { Visibility = TimelineVisibility.Private }); - res.Should().HaveStatusCode(200); - } - { - var res = await client.PatchAsJsonAsync(generator(0, null), - new TimelinePatchRequest { Visibility = TimelineVisibility.Private }); - res.Should().HaveStatusCode(200); - } + await client.PatchTimelineAsync(generator(1), new() { Visibility = TimelineVisibility.Private }); + await client.PatchTimelineAsync(generator(0), new() { Visibility = TimelineVisibility.Private }); } { using var client = await CreateDefaultClient(); - var res = await client.GetAsync(userUrl); - res.Should().HaveStatusCode(403); + await client.TestGetAssertForbiddenAsync($"timelines/{generator(1)}/posts"); } { // user can't read admin's using var client = await CreateClientAsUser(); - var res = await client.GetAsync(adminUrl); - res.Should().HaveStatusCode(403); + await client.TestGetAssertForbiddenAsync($"timelines/{generator(0)}/posts"); } { // admin can read user's using var client = await CreateClientAsAdministrator(); - var res = await client.GetAsync(userUrl); - res.Should().HaveStatusCode(200); + await client.TestGetAsync($"timelines/{generator(1)}/posts"); } { // add member using var client = await CreateClientAsAdministrator(); - var res = await client.PutAsync(generator(0, "members/user1"), null); - res.Should().HaveStatusCode(200); + await client.PutTimelineMemberAsync(generator(0), "user1"); } { // now user can read admin's using var client = await CreateClientAsUser(); - var res = await client.GetAsync(adminUrl); - res.Should().HaveStatusCode(200); + await client.TestGetAsync($"timelines/{generator(0)}/posts"); } } } [Theory] - [MemberData(nameof(TimelineUrlGeneratorData))] - public async Task Permission_Post_Create(TimelineUrlGenerator generator) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task CreatePostPermission_Should_Work(TimelineNameGenerator generator) { using (var client = await CreateClientAsUser()) { - var res = await client.PutAsync(generator(1, "members/user2"), null); - res.Should().HaveStatusCode(200); + await client.PutTimelineMemberAsync(generator(1), "user2"); } using (var client = await CreateDefaultClient()) - { - { // no auth should get 401 - var res = await client.PostAsJsonAsync(generator(1, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - res.Should().HaveStatusCode(401); - } + { // no auth should get 401 + await client.TestPostAssertUnauthorizedAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); } using (var client = await CreateClientAsUser()) { - { // post self's - var res = await client.PostAsJsonAsync(generator(1, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - res.Should().HaveStatusCode(200); - } - { // post other not as a member should get 403 - var res = await client.PostAsJsonAsync(generator(0, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - res.Should().HaveStatusCode(403); - } + // post self's + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); + // post other not as a member should get 403 + await client.TestPostAssertForbiddenAsync($"timelines/{generator(0)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); } using (var client = await CreateClientAsAdministrator()) - { - { // post as admin - var res = await client.PostAsJsonAsync(generator(1, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - res.Should().HaveStatusCode(200); - } + { // post as admin + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); } using (var client = await CreateClientAs(2)) - { - { // post as member - var res = await client.PostAsJsonAsync(generator(1, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - res.Should().HaveStatusCode(200); - } + { // post as member + await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); } } [Theory] - [MemberData(nameof(TimelineUrlGeneratorData))] - public async Task Permission_Post_Delete(TimelineUrlGenerator generator) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task DeletePostPermission_Should_Work(TimelineNameGenerator generator) { async Task CreatePost(int userNumber) { using var client = await CreateClientAs(userNumber); - var res = await client.PostAsJsonAsync(generator(1, "posts"), - TimelineHelper.TextPostCreateRequest("aaa")); - return res.Should().HaveStatusCode(200) - .And.HaveJsonBody() - .Which.Id; + var body = await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa")); + return body.Id; } using (var client = await CreateClientAsUser()) { - { - var res = await client.PutAsync(generator(1, "members/user2"), null); - res.Should().HaveStatusCode(200); - } - { - var res = await client.PutAsync(generator(1, "members/user3"), null); - res.Should().HaveStatusCode(200); - } + await client.PutTimelineMemberAsync(generator(1), "user2"); + await client.PutTimelineMemberAsync(generator(1), "user3"); } { // no auth should get 401 using var client = await CreateDefaultClient(); - var res = await client.DeleteAsync(generator(1, "posts/12")); - res.Should().HaveStatusCode(401); + await client.TestDeleteAssertUnauthorizedAsync($"timelines/{generator(1)}/posts/12"); } { // self can delete self var postId = await CreatePost(1); using var client = await CreateClientAsUser(); - var res = await client.DeleteAsync(generator(1, $"posts/{postId}")); - res.Should().HaveStatusCode(200); + await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{postId}"); } { // admin can delete any var postId = await CreatePost(1); using var client = await CreateClientAsAdministrator(); - var res = await client.DeleteAsync(generator(1, $"posts/{postId}")); - res.Should().HaveStatusCode(200); + await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{postId}"); } { // owner can delete other var postId = await CreatePost(2); using var client = await CreateClientAsUser(); - var res = await client.DeleteAsync(generator(1, $"posts/{postId}")); - res.Should().HaveStatusCode(200); + await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{postId}"); } { // author can delete self var postId = await CreatePost(2); using var client = await CreateClientAs(2); - var res = await client.DeleteAsync(generator(1, $"posts/{postId}")); - res.Should().HaveStatusCode(200); + await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{postId}"); } { // otherwise is forbidden var postId = await CreatePost(2); using var client = await CreateClientAs(3); - var res = await client.DeleteAsync(generator(1, $"posts/{postId}")); - res.Should().HaveStatusCode(403); + await client.TestDeleteAssertForbiddenAsync($"timelines/{generator(1)}/posts/{postId}"); } } [Theory] - [MemberData(nameof(TimelineUrlGeneratorData))] - public async Task TextPost_ShouldWork(TimelineUrlGenerator generator) + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task TextPost_Should_Work(TimelineNameGenerator generator) { { using var client = await CreateClientAsUser(); -- cgit v1.2.3