From a1109e9ac3f059e27089d981972f53bfe61e8f46 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Thu, 31 Oct 2019 14:15:37 +0800 Subject: Complete integrated tests. --- Timeline.Tests/Helpers/ResponseAssertions.cs | 27 ++++---- Timeline.Tests/IntegratedTests/TokenTest.cs | 12 ++-- Timeline.Tests/IntegratedTests/UserAvatarTest.cs | 30 ++++----- Timeline.Tests/IntegratedTests/UserDetailTest.cs | 81 ++++++++++++++++++++++++ Timeline.Tests/IntegratedTests/UserTest.cs | 16 ++--- 5 files changed, 121 insertions(+), 45 deletions(-) diff --git a/Timeline.Tests/Helpers/ResponseAssertions.cs b/Timeline.Tests/Helpers/ResponseAssertions.cs index db86ff59..0e6f215b 100644 --- a/Timeline.Tests/Helpers/ResponseAssertions.cs +++ b/Timeline.Tests/Helpers/ResponseAssertions.cs @@ -61,20 +61,20 @@ namespace Timeline.Tests.Helpers protected override string Identifier => "HttpResponseMessage"; - public AndConstraint HaveStatusCode(int expected, string because = "", params object[] becauseArgs) + 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) + 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(Subject); + return new AndConstraint(this); } - public AndWhichConstraint HaveJsonBody(string because = "", params object[] becauseArgs) + public AndWhichConstraint HaveJsonBody(string because = "", params object[] becauseArgs) { var a = Execute.Assertion.BecauseOf(because, becauseArgs); string body; @@ -85,16 +85,11 @@ namespace Timeline.Tests.Helpers catch (AggregateException e) { a.FailWith("Expected response body of {context:HttpResponseMessage} to be json string{reason}, but failed to read it or it was not a string. Exception is {0}.", e.InnerExceptions); - return new AndWhichConstraint(Subject, null); + return new AndWhichConstraint(this, null); } var result = JsonConvert.DeserializeObject(body); - return new AndWhichConstraint(Subject, result); - } - - internal void HaveStatusCode(object statusCode) - { - throw new NotImplementedException(); + return new AndWhichConstraint(this, result); } } @@ -105,12 +100,12 @@ namespace Timeline.Tests.Helpers return new HttpResponseMessageAssertions(instance); } - public static AndWhichConstraint HaveCommonBody(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + public static AndWhichConstraint HaveCommonBody(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) { return assertions.HaveJsonBody(because, becauseArgs); } - public static AndWhichConstraint> HaveCommonDataBody(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) + public static AndWhichConstraint> HaveCommonDataBody(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs) { return assertions.HaveJsonBody>(because, becauseArgs); } @@ -118,7 +113,7 @@ namespace Timeline.Tests.Helpers public static void BePut(this HttpResponseMessageAssertions assertions, bool create, string because = "", params object[] becauseArgs) { var body = assertions.HaveStatusCode(create ? 201 : 200, because, becauseArgs) - .And.Should().HaveJsonBody(because, becauseArgs) + .And.HaveJsonBody(because, becauseArgs) .Which; body.Code.Should().Be(0); body.Data.Create.Should().Be(create); @@ -127,7 +122,7 @@ namespace Timeline.Tests.Helpers public static void BeDelete(this HttpResponseMessageAssertions assertions, bool delete, string because = "", params object[] becauseArgs) { var body = assertions.HaveStatusCode(200, because, becauseArgs) - .And.Should().HaveJsonBody(because, becauseArgs) + .And.HaveJsonBody(because, becauseArgs) .Which; body.Code.Should().Be(0); body.Data.Delete.Should().Be(delete); @@ -137,7 +132,7 @@ namespace Timeline.Tests.Helpers { message = string.IsNullOrEmpty(message) ? "" : ", " + message; assertions.HaveStatusCode(400, "Invalid Model Error must have 400 status code{0}", message) - .And.Should().HaveCommonBody("Invalid Model Error must have CommonResponse body{0}", message) + .And.HaveCommonBody("Invalid Model Error must have CommonResponse body{0}", message) .Which.Code.Should().Be(ErrorCodes.Http.Common.InvalidModel, "Invalid Model Error must have code {0} in body{1}", ErrorCodes.Http.Common.InvalidModel, message); diff --git a/Timeline.Tests/IntegratedTests/TokenTest.cs b/Timeline.Tests/IntegratedTests/TokenTest.cs index e9b6e1e9..111e8d8e 100644 --- a/Timeline.Tests/IntegratedTests/TokenTest.cs +++ b/Timeline.Tests/IntegratedTests/TokenTest.cs @@ -69,7 +69,7 @@ namespace Timeline.Tests.IntegratedTests var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password }); response.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Create.BadCredential); } @@ -80,7 +80,7 @@ namespace Timeline.Tests.IntegratedTests var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = MockUser.User.Username, Password = MockUser.User.Password }); var body = response.Should().HaveStatusCode(200) - .And.Should().HaveJsonBody().Which; + .And.HaveJsonBody().Which; body.Token.Should().NotBeNullOrWhiteSpace(); body.User.Should().BeEquivalentTo(MockUser.User.Info); } @@ -100,7 +100,7 @@ namespace Timeline.Tests.IntegratedTests var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = "bad token hahaha" }); response.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Verify.BadFormat); } @@ -120,7 +120,7 @@ namespace Timeline.Tests.IntegratedTests (await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token })) .Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Verify.OldVersion); } @@ -139,7 +139,7 @@ namespace Timeline.Tests.IntegratedTests (await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token })) .Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Verify.UserNotExist); } @@ -169,7 +169,7 @@ namespace Timeline.Tests.IntegratedTests var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = createTokenResult.Token }); response.Should().HaveStatusCode(200) - .And.Should().HaveJsonBody() + .And.HaveJsonBody() .Which.User.Should().BeEquivalentTo(MockUser.User.Info); } } diff --git a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs index b338665e..2310fc66 100644 --- a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs +++ b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs @@ -53,7 +53,7 @@ namespace Timeline.Tests.IntegratedTests { var res = await client.GetAsync("users/usernotexist/avatar"); res.Should().HaveStatusCode(404) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Get.UserNotExist); } @@ -94,7 +94,7 @@ namespace Timeline.Tests.IntegratedTests request.Headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd"); var res = await client.SendAsync(request); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Header.IfNonMatch.BadFormat); + .And.HaveCommonBody().Which.Code.Should().Be(Header.IfNonMatch.BadFormat); } { @@ -124,7 +124,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Missing); ; + .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Missing); ; } { @@ -132,7 +132,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentLength = 1; var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentType.Missing); + .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentType.Missing); } { @@ -141,7 +141,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Zero); + .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Zero); } { @@ -155,7 +155,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Content.TooBig); + .And.HaveCommonBody().Which.Code.Should().Be(Content.TooBig); } { @@ -164,7 +164,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Smaller); + .And.HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Smaller); } { @@ -173,25 +173,25 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Bigger); + .And.HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Bigger); } { var res = await client.PutByteArrayAsync("users/user/avatar", new[] { (byte)0x00 }, "image/png"); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_CantDecode); + .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_CantDecode); } { var res = await client.PutByteArrayAsync("users/user/avatar", mockAvatar.Data, "image/jpeg"); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_UnmatchedFormat); + .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_UnmatchedFormat); } { var res = await client.PutByteArrayAsync("users/user/avatar", ImageHelper.CreatePngWithSize(100, 200), "image/png"); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_BadSize); + .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_BadSize); } { @@ -221,13 +221,13 @@ namespace Timeline.Tests.IntegratedTests { var res = await client.PutByteArrayAsync("users/admin/avatar", new[] { (byte)0x00 }, "image/png"); res.Should().HaveStatusCode(HttpStatusCode.Forbidden) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Put.Forbid); + .And.HaveCommonBody().Which.Code.Should().Be(Put.Forbid); } { var res = await client.DeleteAsync("users/admin/avatar"); res.Should().HaveStatusCode(HttpStatusCode.Forbidden) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Delete.Forbid); + .And.HaveCommonBody().Which.Code.Should().Be(Delete.Forbid); } for (int i = 0; i < 2; i++) // double delete should work. @@ -254,14 +254,14 @@ namespace Timeline.Tests.IntegratedTests { var res = await client.PutByteArrayAsync("users/usernotexist/avatar", new[] { (byte)0x00 }, "image/png"); res.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Put.UserNotExist); } { var res = await client.DeleteAsync("users/usernotexist/avatar"); res.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody().Which.Code.Should().Be(Delete.UserNotExist); + .And.HaveCommonBody().Which.Code.Should().Be(Delete.UserNotExist); } } diff --git a/Timeline.Tests/IntegratedTests/UserDetailTest.cs b/Timeline.Tests/IntegratedTests/UserDetailTest.cs index ff2c03a5..8f2b6925 100644 --- a/Timeline.Tests/IntegratedTests/UserDetailTest.cs +++ b/Timeline.Tests/IntegratedTests/UserDetailTest.cs @@ -2,6 +2,8 @@ using Microsoft.AspNetCore.Mvc.Testing; using System; using System.Net; +using System.Net.Http.Headers; +using System.Net.Mime; using System.Threading.Tasks; using Timeline.Tests.Helpers; using Timeline.Tests.Helpers.Authentication; @@ -79,5 +81,84 @@ namespace Timeline.Tests.IntegratedTests } } } + + [Fact] + public async Task FunctionTest() + { + var url = $"users/{MockUser.User.Username}/nickname"; + var userNotExistUrl = "users/usernotexist/nickname"; + { + using var client = await _factory.CreateClientAsUser(); + { + var res = await client.GetAsync(userNotExistUrl); + res.Should().HaveStatusCode(HttpStatusCode.NotFound) + .And.HaveCommonBody() + .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist); + + } + { + var res = await client.GetAsync(url); + res.Should().HaveStatusCode(HttpStatusCode.OK); + res.Content.Headers.ContentType.Should().Be(new MediaTypeHeaderValue(MediaTypeNames.Text.Plain) { CharSet = "utf-8" }); + var body = await res.Content.ReadAsStringAsync(); + body.Should().Be(MockUser.User.Username); + } + { + var res = await client.PutStringAsync(url, ""); + res.Should().BeInvalidModel(); + } + { + var res = await client.PutStringAsync(url, new string('a', 11)); + res.Should().BeInvalidModel(); + } + var nickname1 = "nnn"; + var nickname2 = "nn2"; + { + var res = await client.PutStringAsync(url, nickname1); + res.Should().HaveStatusCode(HttpStatusCode.OK); + (await client.GetStringAsync(url)).Should().Be(nickname1); + } + { + var res = await client.PutStringAsync(url, nickname2); + res.Should().HaveStatusCode(HttpStatusCode.OK); + (await client.GetStringAsync(url)).Should().Be(nickname2); + } + { + var res = await client.DeleteAsync(url); + res.Should().HaveStatusCode(HttpStatusCode.OK); + (await client.GetStringAsync(url)).Should().Be(MockUser.User.Username); + } + { + var res = await client.DeleteAsync(url); + res.Should().HaveStatusCode(HttpStatusCode.OK); + } + } + { + using var client = await _factory.CreateClientAsAdmin(); + { + var res = await client.PutStringAsync(userNotExistUrl, "aaa"); + res.Should().HaveStatusCode(HttpStatusCode.BadRequest) + .And.HaveCommonBody() + .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist); + } + { + var res = await client.DeleteAsync(userNotExistUrl); + res.Should().HaveStatusCode(HttpStatusCode.BadRequest) + .And.HaveCommonBody() + .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist); + } + var nickname = "nnn"; + { + var res = await client.PutStringAsync(url, nickname); + res.Should().HaveStatusCode(HttpStatusCode.OK); + (await client.GetStringAsync(url)).Should().Be(nickname); + } + { + var res = await client.DeleteAsync(url); + res.Should().HaveStatusCode(HttpStatusCode.OK); + (await client.GetStringAsync(url)).Should().Be(MockUser.User.Username); + } + } + } } } diff --git a/Timeline.Tests/IntegratedTests/UserTest.cs b/Timeline.Tests/IntegratedTests/UserTest.cs index ec70b7e8..7e99ddba 100644 --- a/Timeline.Tests/IntegratedTests/UserTest.cs +++ b/Timeline.Tests/IntegratedTests/UserTest.cs @@ -36,7 +36,7 @@ namespace Timeline.Tests.IntegratedTests using var client = await _factory.CreateClientAsAdmin(); var res = await client.GetAsync("users"); res.Should().HaveStatusCode(200) - .And.Should().HaveJsonBody() + .And.HaveJsonBody() .Which.Should().BeEquivalentTo(MockUser.UserInfoList); } @@ -46,7 +46,7 @@ namespace Timeline.Tests.IntegratedTests using var client = await _factory.CreateClientAsAdmin(); var res = await client.GetAsync("users/" + MockUser.User.Username); res.Should().HaveStatusCode(200) - .And.Should().HaveJsonBody() + .And.HaveJsonBody() .Which.Should().BeEquivalentTo(MockUser.User.Info); } @@ -64,7 +64,7 @@ namespace Timeline.Tests.IntegratedTests using var client = await _factory.CreateClientAsAdmin(); var res = await client.GetAsync("users/usernotexist"); res.Should().HaveStatusCode(404) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Get.NotExist); } @@ -89,7 +89,7 @@ namespace Timeline.Tests.IntegratedTests { var res = await client.GetAsync("users/" + username); res.Should().HaveStatusCode(200) - .And.Should().HaveJsonBody() + .And.HaveJsonBody() .Which.Administrator.Should().Be(administrator); } @@ -128,7 +128,7 @@ namespace Timeline.Tests.IntegratedTests using var client = await _factory.CreateClientAsAdmin(); var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { }); res.Should().HaveStatusCode(404) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Patch.NotExist); } @@ -208,7 +208,7 @@ namespace Timeline.Tests.IntegratedTests var res = await client.PostAsJsonAsync(changeUsernameUrl, new ChangeUsernameRequest { OldUsername = "usernotexist", NewUsername = "newUsername" }); res.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Op.ChangeUsername.NotExist); } @@ -219,7 +219,7 @@ namespace Timeline.Tests.IntegratedTests var res = await client.PostAsJsonAsync(changeUsernameUrl, new ChangeUsernameRequest { OldUsername = MockUser.User.Username, NewUsername = MockUser.Admin.Username }); res.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Op.ChangeUsername.AlreadyExist); } @@ -258,7 +258,7 @@ namespace Timeline.Tests.IntegratedTests using var client = await _factory.CreateClientAsUser(); var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" }); res.Should().HaveStatusCode(400) - .And.Should().HaveCommonBody() + .And.HaveCommonBody() .Which.Code.Should().Be(Op.ChangePassword.BadOldPassword); } -- cgit v1.2.3