using Moq; using NFluent; using RestEase; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using WireMock.Admin.Mappings; using WireMock.Admin.Settings; using WireMock.Client; using WireMock.Handlers; using WireMock.Logging; using WireMock.Server; using WireMock.Settings; using Xunit; namespace WireMock.Net.Tests { public class FluentMockServerAdminRestClientTests { [Fact] public async Task IFluentMockServerAdmin_GetSettingsAsync() { // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var settings = await api.GetSettingsAsync(); Check.That(settings).IsNotNull(); } [Fact] public async Task IFluentMockServerAdmin_PostSettingsAsync() { // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var settings = new SettingsModel(); var status = await api.PostSettingsAsync(settings); Check.That(status.Status).Equals("Settings updated"); } [Fact] public async Task IFluentMockServerAdmin_PutSettingsAsync() { // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var settings = new SettingsModel(); var status = await api.PutSettingsAsync(settings); Check.That(status.Status).Equals("Settings updated"); } [Fact] public async Task IFluentMockServerAdmin_PostMappingAsync() { // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var model = new MappingModel { Request = new RequestModel { Path = "/1" }, Response = new ResponseModel { Body = "txt", StatusCode = 200 }, Priority = 500, Title = "test" }; var result = await api.PostMappingAsync(model); // Assert Check.That(result).IsNotNull(); Check.That(result.Status).IsNotNull(); Check.That(result.Guid).IsNotNull(); var mapping = server.Mappings.Single(m => m.Priority == 500); Check.That(mapping).IsNotNull(); Check.That(mapping.Title).Equals("test"); server.Stop(); } [Fact] public async Task IFluentMockServerAdmin_PostMappingsAsync() { // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var model1 = new MappingModel { Request = new RequestModel { Path = "/1" }, Response = new ResponseModel { Body = "txt 1" }, Title = "test 1" }; var model2 = new MappingModel { Request = new RequestModel { Path = "/2" }, Response = new ResponseModel { Body = "txt 2" }, Title = "test 2" }; var result = await api.PostMappingsAsync(new[] { model1, model2 }); // Assert Check.That(result).IsNotNull(); Check.That(result.Status).IsNotNull(); Check.That(result.Guid).IsNull(); Check.That(server.Mappings.Where(m => !m.IsAdminInterface)).HasSize(2); server.Stop(); } [Fact] public async Task IFluentMockServerAdmin_FindRequestsAsync() { // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() }); var serverUrl = "http://localhost:" + server.Ports[0]; await new HttpClient().GetAsync(serverUrl + "/foo"); var api = RestClient.For(serverUrl); // Act var requests = await api.FindRequestsAsync(new RequestModel { Methods = new[] { "GET" } }); // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("GET"); Check.That(requestLogged.Request.Body).IsNull(); Check.That(requestLogged.Request.Path).IsEqualTo("/foo"); } [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync() { // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() }); var serverUrl = "http://localhost:" + server.Ports[0]; await new HttpClient().GetAsync(serverUrl + "/foo"); var api = RestClient.For(serverUrl); // Act var requests = await api.GetRequestsAsync(); // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("GET"); Check.That(requestLogged.Request.Body).IsNull(); Check.That(requestLogged.Request.Path).IsEqualTo("/foo"); } [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync_JsonApi() { // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() }); string serverUrl = server.Urls[0]; string data = "{\"data\":[{\"type\":\"program\",\"attributes\":{\"alias\":\"T000001\",\"title\":\"Title Group Entity\"}}]}"; string jsonApiAcceptHeader = "application/vnd.api+json"; string jsonApiContentType = "application/vnd.api+json"; var request = new HttpRequestMessage(HttpMethod.Post, serverUrl); request.Headers.Accept.Clear(); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonApiAcceptHeader)); request.Content = new StringContent(data); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(jsonApiContentType); var response = await new HttpClient().SendAsync(request); Check.That(response).IsNotNull(); var api = RestClient.For(serverUrl); // Act var requests = await api.GetRequestsAsync(); // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("POST"); Check.That(requestLogged.Request.Body).IsNotNull(); Check.That(requestLogged.Request.Body).Contains("T000001"); } [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync_Json() { // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() }); string serverUrl = server.Urls[0]; string data = "{\"alias\": \"T000001\"}"; string jsonAcceptHeader = "application/json"; string jsonApiContentType = "application/json"; var request = new HttpRequestMessage(HttpMethod.Post, serverUrl); request.Headers.Accept.Clear(); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonAcceptHeader)); request.Content = new StringContent(data); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(jsonApiContentType); var response = await new HttpClient().SendAsync(request); Check.That(response).IsNotNull(); var api = RestClient.For(serverUrl); // Act var requests = await api.GetRequestsAsync(); // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("POST"); Check.That(requestLogged.Request.Body).IsNotNull(); Check.That(requestLogged.Request.Body).Contains("T000001"); } [Fact] public async Task IFluentMockServerAdmin_PostFileAsync_Ascii() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("__admin/mappings"); filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny())).Returns(true); filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny(), It.IsAny())); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act var request = await api.PostFileAsync("filename.txt", "abc"); // Assert Check.That(request.Guid).IsNull(); Check.That(request.Status).Contains("File"); // Verify filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once); filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny()), Times.Once); filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is(p => p == "filename.txt"), It.IsAny()), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public async Task IFluentMockServerAdmin_PutFileAsync_Ascii() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny(), It.IsAny())); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act var request = await api.PutFileAsync("filename.txt", "abc-abc"); // Assert Check.That(request.Guid).IsNull(); Check.That(request.Status).Contains("File"); // Verify filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is(p => p == "filename.txt"), It.IsAny()), Times.Once); filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public void IFluentMockServerAdmin_PutFileAsync_NotFound() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act and Assert Check.ThatAsyncCode(() => api.PutFileAsync("filename.txt", "xxx")).Throws(); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public void IFluentMockServerAdmin_GetFileAsync_NotFound() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny())).Returns(Encoding.ASCII.GetBytes("Here's a string.")); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act and Assert Check.ThatAsyncCode(() => api.GetFileAsync("filename.txt")).Throws(); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public async Task IFluentMockServerAdmin_GetFileAsync_Found() { // Arrange string data = "Here's a string."; var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny())).Returns(Encoding.ASCII.GetBytes(data)); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act string file = await api.GetFileAsync("filename.txt"); // Assert Check.That(file).Equals(data); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public async Task IFluentMockServerAdmin_DeleteFileAsync_Ok() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); filesystemHandlerMock.Setup(fs => fs.DeleteFile(It.IsAny())); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act await api.DeleteFileAsync("filename.txt"); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.Verify(fs => fs.DeleteFile(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public void IFluentMockServerAdmin_DeleteFileAsync_NotFound() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); filesystemHandlerMock.Setup(fs => fs.DeleteFile(It.IsAny())); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act and Assert Check.ThatAsyncCode(() => api.DeleteFileAsync("filename.txt")).Throws(); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } [Fact] public void IFluentMockServerAdmin_FileExistsAsync_NotFound() { // Arrange var filesystemHandlerMock = new Mock(MockBehavior.Strict); filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); var server = FluentMockServer.Start(new FluentMockServerSettings { UseSSL = false, StartAdminInterface = true, FileSystemHandler = filesystemHandlerMock.Object }); var api = RestClient.For(server.Urls[0]); // Act and Assert Check.ThatAsyncCode(() => api.FileExistsAsync("filename.txt")).Throws(); // Verify filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is(p => p == "filename.txt")), Times.Once); filesystemHandlerMock.VerifyNoOtherCalls(); server.Stop(); } } }