using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.Enums; using MagicCarpetContracts.Infrastructure.PostConfigurations; using MagicCarpetContracts.ViewModels; using MagicCarpetDatabase.Models; using MagicCarpetTests.Infrastructure; using System.Text.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Text.Json.Nodes; using System.Threading.Tasks; namespace MagicCarpetTests.WebApiControllersTests; [TestFixture] internal class PostControllerTests : BaseWebApiControllerTest { [TearDown] public void TearDown() { MagicCarpetDbContext.RemovePostsFromDatabase(); } [Test] public async Task GetRecords_WhenHaveRecords_ShouldSuccess_Test() { //Arrange var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 1"); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 2"); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 3"); //Act var response = await HttpClient.GetAsync("/api/posts"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); var data = await GetModelFromResponseAsync>(response); Assert.Multiple(() => { Assert.That(data, Is.Not.Null); Assert.That(data, Has.Count.EqualTo(3)); }); AssertElement(data.First(x => x.Id == post.PostId), post); } [Test] public async Task GetHistory_WhenHaveRecords_ShouldSuccess_Test() { //Arrange var postId = Guid.NewGuid().ToString(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 1", isActual: true); var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postId, "name 2", isActual: true); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postId, "name 2", isActual: false); //Act var response = await HttpClient.GetAsync($"/api/posthistory/{postId}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); var data = await GetModelFromResponseAsync>(response); Assert.Multiple(() => { Assert.That(data, Is.Not.Null); Assert.That(data, Has.Count.EqualTo(2)); }); AssertElement(data.First(x => x.Id == post.PostId), post); } [Test] public async Task GetHistory_WhenNoRecords_ShouldSuccess_Test() { //Arrange var postId = Guid.NewGuid().ToString(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 1", isActual: true); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postId, "name 2", isActual: true); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postId, "name 2", isActual: false); //Act var response = await HttpClient.GetAsync($"/api/posthistory/{Guid.NewGuid()}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); var data = await GetModelFromResponseAsync>(response); Assert.Multiple(() => { Assert.That(data, Is.Not.Null); Assert.That(data, Has.Count.EqualTo(0)); }); } [Test] public async Task GetRecords_WhenDifferentConfigTypes_ShouldSuccess_Test() { //Arrange var postSimple = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 1"); var postTravelAgent = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 2", config: new TravelAgentPostConfiguration() { SalePercent = 500 }); var postLoader = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: "name 3", config: new ChiefPostConfiguration() { PersonalCountTrendPremium = 20 }); //Act var response = await HttpClient.GetAsync("/api/posts"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); var data = await GetModelFromResponseAsync>(response); Assert.That(data, Is.Not.Null); AssertElement(data.First(x => x.Id == postSimple.PostId), postSimple); AssertElement(data.First(x => x.Id == postTravelAgent.PostId), postTravelAgent); AssertElement(data.First(x => x.Id == postLoader.PostId), postLoader); } [Test] public async Task GetHistory_WhenWrongData_ShouldBadRequest_Test() { //Act var response = await HttpClient.GetAsync($"/api/posthistory/id"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test() { //Arrange var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.GetAsync($"/api/posts/{post.PostId}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); AssertElement(await GetModelFromResponseAsync(response), post); } [Test] public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test() { //Arrange MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.GetAsync($"/api/posts/{Guid.NewGuid()}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } [Test] public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test() { //Arrange var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(isActual: false); //Act var response = await HttpClient.GetAsync($"/api/posts/{post.PostId}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } [Test] public async Task GetElement_ByName_WhenHaveRecord_ShouldSuccess_Test() { //Arrange var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.GetAsync($"/api/posts/{post.PostName}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); AssertElement(await GetModelFromResponseAsync(response), post); } [Test] public async Task GetElement_ByName_WhenNoRecord_ShouldNotFound_Test() { //Arrange MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.GetAsync($"/api/posts/New%20Name"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } [Test] public async Task GetElement_ByName_WhenRecordWasDeleted_ShouldNotFound_Test() { //Arrange var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(isActual: false); //Act var response = await HttpClient.GetAsync($"/api/posts/{post.PostName}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } [Test] public async Task Post_ShouldSuccess_Test() { //Arrange MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); var postModel = CreateModel(); //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); AssertElement(MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!), postModel); } [Test] public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test() { //Arrange var postModel = CreateModel(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postModel.Id); //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Post_WhenHaveRecordWithSameName_ShouldBadRequest_Test() { //Arrange var postModel = CreateModel(postName: "unique name"); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: postModel.PostName!); //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test() { //Arrange var postModelWithIdIncorrect = new PostBindingModel { Id = "Id", PostName = "name", PostType = PostType.TravelAgent.ToString(), ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithNameIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.TravelAgent.ToString(), ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithPostTypeIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = string.Empty, ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithSalaryIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.TravelAgent.ToString(), ConfigurationJson = null }; //Act var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithIdIncorrect)); var responseWithNameIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithNameIncorrect)); var responseWithPostTypeIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithPostTypeIncorrect)); var responseWithSalaryIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithSalaryIncorrect)); //Assert Assert.Multiple(() => { Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect"); Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Salary is incorrect"); }); } [Test] public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test() { //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(string.Empty)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Post_WhenSendWrongFormatData_ShouldBadRequest_Test() { //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(new { Data = "test", Position = 10 })); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Post_WithTravelAgentPostConfiguration_ShouldSuccess_Test() { //Arrange var salePercent = 10; var postModel = CreateModel(configuration: JsonSerializer.Serialize(new TravelAgentPostConfiguration() { SalePercent = salePercent, Rate = 10 })); //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); var element = MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!); Assert.That(element, Is.Not.Null); Assert.Multiple(() => { Assert.That(element.Configuration.Type, Is.EqualTo(typeof(TravelAgentPostConfiguration).Name)); Assert.That((element.Configuration as TravelAgentPostConfiguration)!.SalePercent, Is.EqualTo(salePercent)); }); } [Test] public async Task Post_WithLoaderPostConfiguration_ShouldSuccess_Test() { //Arrange var trendPremium = 20; var postModel = CreateModel(configuration: JsonSerializer.Serialize(new ChiefPostConfiguration() { PersonalCountTrendPremium = trendPremium, Rate = 10 })); //Act var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); var element = MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!); Assert.That(element, Is.Not.Null); Assert.Multiple(() => { Assert.That(element.Configuration.Type, Is.EqualTo(typeof(ChiefPostConfiguration).Name)); Assert.That((element.Configuration as ChiefPostConfiguration)!.PersonalCountTrendPremium, Is.EqualTo(trendPremium)); }); } [Test] public async Task Put_ShouldSuccess_Test() { //Arrange var postModel = CreateModel(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postModel.Id); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); MagicCarpetDbContext.ChangeTracker.Clear(); AssertElement(MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!), postModel); } [Test] public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test() { //Arrange var postModel = CreateModel(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Put_WhenRecordWasDeleted_ShouldBadRequest_Test() { //Arrange var postModel = CreateModel(); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postModel.Id, isActual: false); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Put_WhenHaveRecordWithSameName_ShouldBadRequest_Test() { //Arrange var postModel = CreateModel(postName: "unique name"); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postModel.Id); MagicCarpetDbContext.InsertPostToDatabaseAndReturn(postName: postModel.PostName!); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Put_WhenDataIsIncorrect_ShouldBadRequest_Test() { //Arrange var postModelWithIdIncorrect = new PostBindingModel { Id = "Id", PostName = "name", PostType = PostType.TravelAgent.ToString(), ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithNameIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.TravelAgent.ToString(), ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithPostTypeIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = string.Empty, ConfigurationJson = JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; var postModelWithSalaryIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.TravelAgent.ToString(), ConfigurationJson = null }; //Act var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithIdIncorrect)); var responseWithNameIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithNameIncorrect)); var responseWithPostTypeIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithPostTypeIncorrect)); var responseWithSalaryIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithSalaryIncorrect)); //Assert Assert.Multiple(() => { Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect"); Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Salary is incorrect"); }); } [Test] public async Task Put_WhenSendEmptyData_ShouldBadRequest_Test() { //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(string.Empty)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Put_WhenSendWrongFormatData_ShouldBadRequest_Test() { //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(new { Data = "test", Position = 10 })); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Put_WithTravelAgentPostConfiguration_ShouldSuccess_Test() { //Arrange var salePercent = 10; var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); var postModel = CreateModel(post.PostId, configuration: JsonSerializer.Serialize(new TravelAgentPostConfiguration() { SalePercent = salePercent, Rate = 10 })); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); MagicCarpetDbContext.ChangeTracker.Clear(); var element = MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!); Assert.That(element, Is.Not.Null); Assert.Multiple(() => { Assert.That(element.Configuration.Type, Is.EqualTo(typeof(TravelAgentPostConfiguration).Name)); Assert.That((element.Configuration as TravelAgentPostConfiguration)!.SalePercent, Is.EqualTo(salePercent)); }); } [Test] public async Task Put_WithSupervisorPostConfiguration_ShouldSuccess_Test() { //Arrange var trendPremium = 20; var post = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); var postModel = CreateModel(post.PostId, configuration: JsonSerializer.Serialize(new ChiefPostConfiguration() { PersonalCountTrendPremium = trendPremium, Rate = 10 })); //Act var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel)); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); MagicCarpetDbContext.ChangeTracker.Clear(); var element = MagicCarpetDbContext.GetPostFromDatabaseByPostId(postModel.Id!); Assert.That(element, Is.Not.Null); Assert.Multiple(() => { Assert.That(element.Configuration.Type, Is.EqualTo(typeof(ChiefPostConfiguration).Name)); Assert.That((element.Configuration as ChiefPostConfiguration)!.PersonalCountTrendPremium, Is.EqualTo(trendPremium)); }); } [Test] public async Task Delete_ShouldSuccess_Test() { //Arrange var postId = MagicCarpetDbContext.InsertPostToDatabaseAndReturn().PostId; //Act var response = await HttpClient.DeleteAsync($"/api/posts/{postId}"); //Assert Assert.Multiple(() => { Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); Assert.That(MagicCarpetDbContext.GetPostFromDatabaseByPostId(postId), Is.Null); }); } [Test] public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test() { //Arrange MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.DeleteAsync($"/api/posts/{Guid.NewGuid()}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Delete_WhenRecordWasDeleted_Test() { //Arrange var postId = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(isActual: false).PostId; //Act var response = await HttpClient.DeleteAsync($"/api/posts/{postId}"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Delete_WhenSendWrongFormatData_ShouldBadRequest_Test() { //Act var response = await HttpClient.DeleteAsync($"/api/posts/id"); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Patch_ShouldSuccess_Test() { //Arrange var postId = MagicCarpetDbContext.InsertPostToDatabaseAndReturn(isActual: false).PostId; //Act var response = await HttpClient.PatchAsync($"/api/posts/{postId}", null); //Assert Assert.Multiple(() => { Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); Assert.That(MagicCarpetDbContext.GetPostFromDatabaseByPostId(postId), Is.Not.Null); }); } [Test] public async Task Patch_WhenNoFoundRecord_ShouldBadRequest_Test() { //Arrange MagicCarpetDbContext.InsertPostToDatabaseAndReturn(); //Act var response = await HttpClient.PatchAsync($"/api/posts/{Guid.NewGuid()}", null); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } [Test] public async Task Patch_WhenRecordNotWasDeleted_ShouldSuccess_Test() { //Arrange var postId = MagicCarpetDbContext.InsertPostToDatabaseAndReturn().PostId; //Act var response = await HttpClient.PatchAsync($"/api/posts/{postId}", null); //Assert Assert.Multiple(() => { Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent)); Assert.That(MagicCarpetDbContext.GetPostFromDatabaseByPostId(postId), Is.Not.Null); }); } [Test] public async Task Patch_WhenSendWrongFormatData_ShouldBadRequest_Test() { //Act var response = await HttpClient.PatchAsync($"/api/posts/id", null); //Assert Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } private static void AssertElement(PostViewModel? actual, Post expected) { Assert.That(actual, Is.Not.Null); Assert.Multiple(() => { Assert.That(actual.Id, Is.EqualTo(expected.PostId)); Assert.That(actual.PostName, Is.EqualTo(expected.PostName)); Assert.That(actual.PostType, Is.EqualTo(expected.PostType.ToString())); Assert.That(JsonNode.Parse(actual.Configuration)!["Type"]!.GetValue(), Is.EqualTo(expected.Configuration.Type)); }); } private static PostBindingModel CreateModel(string? postId = null, string postName = "name", PostType postType = PostType.Manager, string? configuration = null) => new() { Id = postId ?? Guid.NewGuid().ToString(), PostName = postName, PostType = postType.ToString(), ConfigurationJson = configuration ?? JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 }) }; private static void AssertElement(Post? actual, PostBindingModel expected) { Assert.That(actual, Is.Not.Null); Assert.Multiple(() => { Assert.That(actual.PostId, Is.EqualTo(expected.Id)); Assert.That(actual.PostName, Is.EqualTo(expected.PostName)); Assert.That(actual.PostType.ToString(), Is.EqualTo(expected.PostType)); Assert.That(actual.Configuration.Type, Is.EqualTo(JsonNode.Parse(expected.ConfigurationJson!)!["Type"]!.GetValue())); }); } }