public async Task BasicV2QueryTest(string query, int expectedItemCount, string[] firstExpectedItems) { Dictionary <string, string> headers = new() { { "ZUMO-API-VERSION", "2.0.0" } }; var response = await MovieServer.SendRequest(HttpMethod.Get, query, headers).ConfigureAwait(false); await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); // Response payload can be decoded var result = response.DeserializeContent <List <ClientMovie> >(); Assert.NotNull(result); // Payload has the right content Assert.Equal(expectedItemCount, result !.Count); // The first n items must match what is expected Assert.True(result.Count >= firstExpectedItems.Length); Assert.Equal(firstExpectedItems, result.Take(firstExpectedItems.Length).Select(m => m.Id).ToArray()); for (int idx = 0; idx < firstExpectedItems.Length; idx++) { var expected = MovieServer.GetMovieById(firstExpectedItems[idx]); var actual = result[idx]; Assert.Equal <IMovie>(expected !, actual); AssertEx.SystemPropertiesMatch(expected, actual); } }
public async Task BasicCreateTests([CombinatorialValues("movies", "movies_pagesize")] string table, bool hasId) { var movieToAdd = GetSampleMovie <ClientMovie>(); if (hasId) { movieToAdd.Id = Guid.NewGuid().ToString("N"); } var response = await MovieServer.SendRequest <ClientMovie>(HttpMethod.Post, $"tables/{table}", movieToAdd); await AssertResponseWithLoggingAsync(HttpStatusCode.Created, response); var result = response.DeserializeContent <ClientMovie>(); Assert.NotNull(result); Assert.True(Guid.TryParse(result !.Id, out _)); if (hasId) { Assert.Equal(movieToAdd.Id, result !.Id); } Assert.Equal(TestData.Movies.Count + 1, MovieServer.GetMovieCount()); var entity = MovieServer.GetMovieById(result !.Id); Assert.NotNull(entity); AssertEx.SystemPropertiesSet(entity, StartTime); AssertEx.SystemPropertiesMatch(entity, result); Assert.Equal <IMovie>(movieToAdd, result !); Assert.Equal <IMovie>(movieToAdd, entity !); AssertEx.ResponseHasConditionalHeaders(entity, response); AssertEx.HasHeader(response, "Location", $"https://localhost/tables/{table}/{result.Id}"); }
public async Task BasicPatchTests([CombinatorialValues("movies", "movies_pagesize")] string table) { var id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; expected.Title = "Test Movie Title"; expected.Rating = "PG-13"; var patchDoc = new Dictionary <string, object>() { { "title", "Test Movie Title" }, { "rating", "PG-13" } }; var response = await MovieServer.SendRequest(HttpMethod.Patch, $"tables/{table}/{id}", patchDoc, "application/json", null); await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var result = response.DeserializeContent <ClientMovie>(); Assert.NotNull(result); var stored = MovieServer.GetMovieById(id); Assert.NotNull(stored); AssertEx.SystemPropertiesSet(stored, StartTime); AssertEx.SystemPropertiesChanged(expected, stored); AssertEx.SystemPropertiesMatch(stored, result); Assert.Equal <IMovie>(expected, result !); AssertEx.ResponseHasConditionalHeaders(stored, response); }
[InlineData("tables/movies_legal/id-113", HttpStatusCode.NotFound, "X-Auth", "success")] // Any movie that is not R-rated in the DB will do here. public async Task FailedReplaceTests(string relativeUri, HttpStatusCode expectedStatusCode, string?headerName = null, string?headerValue = null) { var id = relativeUri.Split('/').Last(); var expected = MovieServer.GetMovieById(id) !; ClientMovie blackPantherMovie = new() { Id = id, BestPictureWinner = true, Duration = 134, Rating = "PG-13", ReleaseDate = DateTimeOffset.Parse("16-Feb-2018"), Title = "Black Panther", Year = 2018 }; Dictionary <string, string> headers = new(); if (headerName != null && headerValue != null) { headers.Add(headerName, headerValue); } // Act var response = await MovieServer.SendRequest(HttpMethod.Put, relativeUri, blackPantherMovie, headers); // Assert await AssertResponseWithLoggingAsync(expectedStatusCode, response); var entity = MovieServer.GetMovieById(id); if (entity != null) { Assert.Equal <IMovie>(expected, entity); Assert.Equal <ITableData>(expected, entity); } }
public async Task Delete_OnVersion(string headerName, string?headerValue, HttpStatusCode expectedStatusCode) { const string id = "id-107"; var expected = MovieServer.GetMovieById(id) !; Dictionary <string, string> headers = new() { { headerName, headerValue ?? expected.GetETag() } }; var response = await MovieServer.SendRequest(HttpMethod.Delete, $"tables/movies/{id}", headers); await AssertResponseWithLoggingAsync(expectedStatusCode, response); switch (expectedStatusCode) { case HttpStatusCode.NoContent: Assert.Equal(TestData.Movies.Count - 1, MovieServer.GetMovieCount()); Assert.Null(MovieServer.GetMovieById(id)); break; case HttpStatusCode.PreconditionFailed: var actual = response.DeserializeContent <ClientMovie>(); Assert.NotNull(actual); Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); break; } }
public async Task AuthenticatedDeleteTests( [CombinatorialValues(0, 1, 2, 3, 7, 14, 25)] int index, [CombinatorialValues(null, "failed", "success")] string userId, [CombinatorialValues("movies_rated", "movies_legal")] string table) { string id = Utils.GetMovieId(index); Dictionary <string, string> headers = new(); Utils.AddAuthHeaders(headers, userId); var response = await MovieServer.SendRequest(HttpMethod.Delete, $"tables/{table}/{id}", headers); if (userId != "success") { var statusCode = table.Contains("legal") ? HttpStatusCode.UnavailableForLegalReasons : HttpStatusCode.Unauthorized; await AssertResponseWithLoggingAsync(statusCode, response); Assert.Equal(TestData.Movies.Count, MovieServer.GetMovieCount()); Assert.NotNull(MovieServer.GetMovieById(id)); } else { await AssertResponseWithLoggingAsync(HttpStatusCode.NoContent, response); Assert.Equal(TestData.Movies.Count - 1, MovieServer.GetMovieCount()); Assert.Null(MovieServer.GetMovieById(id)); } }
public async Task AuthenticatedReadTests( [CombinatorialValues(0, 1, 2, 3, 7, 14, 25)] int index, [CombinatorialValues(null, "failed", "success")] string userId, [CombinatorialValues("movies_rated", "movies_legal")] string table) { string id = Utils.GetMovieId(index); var expected = MovieServer.GetMovieById(id) !; Dictionary <string, string> headers = new(); Utils.AddAuthHeaders(headers, userId); var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/{table}/{id}", headers); if (userId != "success") { var statusCode = table.Contains("legal") ? HttpStatusCode.UnavailableForLegalReasons : HttpStatusCode.Unauthorized; await AssertResponseWithLoggingAsync(statusCode, response); } else { await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var actual = response.DeserializeContent <ClientMovie>(); Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); } }
public async Task FailedDeleteTests(string relativeUri, HttpStatusCode expectedStatusCode) { var response = await MovieServer.SendRequest(HttpMethod.Delete, relativeUri); await AssertResponseWithLoggingAsync(expectedStatusCode, response); Assert.Equal(TestData.Movies.Count, MovieServer.GetMovieCount()); }
public async Task ReadSoftDeletedItem_ReturnsGoneIfDeleted([CombinatorialValues("soft", "soft_logged")] string table) { var id = GetRandomId(); await MovieServer.SoftDeleteMoviesAsync(x => x.Id == id); var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/{table}/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.Gone, response); }
public async Task BasicDeleteTests() { var id = GetRandomId(); var response = await MovieServer.SendRequest(HttpMethod.Delete, $"tables/movies/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.NoContent, response); Assert.Equal(TestData.Movies.Count - 1, MovieServer.GetMovieCount()); Assert.Null(MovieServer.GetMovieById(id)); }
public async Task SoftDeleteItem_SetsDeletedFlag([CombinatorialValues("soft", "soft_logged")] string table) { var id = GetRandomId(); var response = await MovieServer.SendRequest(HttpMethod.Delete, $"tables/{table}/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.NoContent, response); Assert.Equal(TestData.Movies.Count, MovieServer.GetMovieCount()); var entity = MovieServer.GetMovieById(id) !; Assert.True(entity.Deleted); }
public async Task BasicReadTests([CombinatorialValues("movies", "movies_pagesize")] string table) { string id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/{table}/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var actual = response.DeserializeContent <ClientMovie>(); Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); }
public async Task ReadSoftDeletedItem_WorksIfNotDeleted([CombinatorialValues("soft", "soft_logged")] string table) { var id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/{table}/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var actual = response.DeserializeContent <ClientMovie>(); Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); }
public async Task UpdatedAt_CorrectFormat() { string id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; var expectedDTO = expected.UpdatedAt.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"); var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/movies/{id}"); await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var actual = response.DeserializeContent <Dictionary <string, object> >(); Assert.True(actual.ContainsKey("updatedAt")); Assert.Equal(expectedDTO, actual["updatedAt"].ToString()); }
public async Task ReplacementValidationTests(string propName, object propValue) { string id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; var entity = expected.ToDictionary(); entity[propName] = propValue; var response = await MovieServer.SendRequest(HttpMethod.Put, $"tables/movies/{id}", entity); var stored = MovieServer.GetMovieById(id) !; await AssertResponseWithLoggingAsync(HttpStatusCode.BadRequest, response); Assert.Equal <IMovie>(expected, stored); Assert.Equal <ITableData>(expected, stored); }
public async Task AuthenticatedPatchTests( [CombinatorialValues(0, 1, 2, 3, 7, 14, 25)] int index, [CombinatorialValues(null, "failed", "success")] string userId, [CombinatorialValues("movies_rated", "movies_legal")] string table) { var id = Utils.GetMovieId(index); var original = MovieServer.GetMovieById(id) !; var expected = original.Clone(); expected.Title = "TEST MOVIE TITLE"; // Upper Cased because of the PreCommitHook expected.Rating = "PG-13"; var replacement = MovieServer.GetMovieById(id) !; replacement.Title = "Test Movie Title"; replacement.Rating = "PG-13"; Dictionary <string, string> headers = new(); Utils.AddAuthHeaders(headers, userId); var response = await MovieServer.SendRequest(HttpMethod.Put, $"tables/{table}/{id}", replacement, headers); var stored = MovieServer.GetMovieById(id); if (userId != "success") { var statusCode = table.Contains("legal") ? HttpStatusCode.UnavailableForLegalReasons : HttpStatusCode.Unauthorized; await AssertResponseWithLoggingAsync(statusCode, response); Assert.Equal <IMovie>(original, stored !); Assert.Equal <ITableData>(original, stored !); } else { await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); var result = response.DeserializeContent <ClientMovie>(); AssertEx.SystemPropertiesSet(stored, StartTime); AssertEx.SystemPropertiesChanged(expected, stored); AssertEx.SystemPropertiesMatch(stored, result); Assert.Equal <IMovie>(expected, result !); AssertEx.ResponseHasConditionalHeaders(stored, response); } }
public async Task CreateOverwriteSystemProperties(bool useUpdatedAt, bool useVersion) { var movieToAdd = GetSampleMovie <ClientMovie>(); movieToAdd.Id = Guid.NewGuid().ToString("N"); if (useUpdatedAt) { movieToAdd.UpdatedAt = DateTimeOffset.Parse("2018-12-31T01:01:01.000Z"); } if (useVersion) { movieToAdd.Version = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); } var response = await MovieServer.SendRequest <ClientMovie>(HttpMethod.Post, "tables/movies", movieToAdd); await AssertResponseWithLoggingAsync(HttpStatusCode.Created, response); var result = response.DeserializeContent <ClientMovie>(); Assert.NotNull(result); Assert.Equal(movieToAdd.Id, result !.Id); Assert.Equal(TestData.Movies.Count + 1, MovieServer.GetMovieCount()); var entity = MovieServer.GetMovieById(result.Id); Assert.NotNull(entity); AssertEx.SystemPropertiesSet(entity, StartTime); AssertEx.SystemPropertiesMatch(entity, result); if (useUpdatedAt) { Assert.NotEqual(movieToAdd.UpdatedAt, result.UpdatedAt); } if (useVersion) { Assert.NotEqual(movieToAdd.Version, result.Version); } Assert.Equal <IMovie>(movieToAdd, result); Assert.Equal <IMovie>(movieToAdd, entity !); AssertEx.ResponseHasConditionalHeaders(entity, response); AssertEx.HasHeader(response, "Location", $"https://localhost/tables/movies/{movieToAdd.Id}"); }
public async Task ReplaceSoftDeleted_ReturnsGone([CombinatorialValues("soft", "soft_logged")] string table) { var id = GetRandomId(); await MovieServer.SoftDeleteMoviesAsync(x => x.Id == id); var original = MovieServer.GetMovieById(id) !; var expected = MovieServer.GetMovieById(id) !; expected.Title = "Replacement Title"; expected.Rating = "PG-13"; var response = await MovieServer.SendRequest(HttpMethod.Put, $"tables/{table}/{id}", expected); var stored = MovieServer.GetMovieById(id); await AssertResponseWithLoggingAsync(HttpStatusCode.Gone, response); Assert.Equal <IMovie>(original, stored !); Assert.Equal <ITableData>(original, stored !); }
public async Task BasicReplaceTests([CombinatorialValues("movies", "movies_pagesize")] string table) { string id = GetRandomId(); var original = MovieServer.GetMovieById(id) !; var expected = original.Clone(); expected.Title = "Replacement Title"; expected.Rating = "PG-13"; var response = await MovieServer.SendRequest(HttpMethod.Put, $"tables/{table}/{id}", expected); var stored = MovieServer.GetMovieById(id) !; await AssertResponseWithLoggingAsync(HttpStatusCode.OK, response); Assert.Equal <IMovie>(expected, stored); AssertEx.SystemPropertiesSet(stored, StartTime); AssertEx.SystemPropertiesChanged(original, stored); AssertEx.ResponseHasConditionalHeaders(stored, response); }
public async Task ConditionalReadTests(string headerName, int offset, HttpStatusCode expectedStatusCode) { var id = GetRandomId(); var expected = MovieServer.GetMovieById(id) !; Dictionary <string, string> headers = new() { { headerName, expected.UpdatedAt.AddHours(offset).ToString("R") } }; var response = await MovieServer.SendRequest(HttpMethod.Get, $"tables/movies/{id}", headers); await AssertResponseWithLoggingAsync(expectedStatusCode, response); if (expectedStatusCode == HttpStatusCode.OK || expectedStatusCode == HttpStatusCode.PreconditionFailed) { var actual = response.DeserializeContent <ClientMovie>(); Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); } }
public async Task ConditionalPatchTests(string headerName, int offset, HttpStatusCode expectedStatusCode) { string id = GetRandomId(); var entity = MovieServer.GetMovieById(id) !; Dictionary <string, string> headers = new() { { headerName, entity.UpdatedAt.AddHours(offset).ToString("R") } }; var expected = MovieServer.GetMovieById(id) !; var replacement = expected.Clone(); replacement.Title = "Test Movie Title"; replacement.Rating = "PG-13"; var response = await MovieServer.SendRequest(HttpMethod.Put, $"tables/movies/{id}", replacement, headers); var stored = MovieServer.GetMovieById(id); await AssertResponseWithLoggingAsync(expectedStatusCode, response); var actual = response.DeserializeContent <ClientMovie>(); switch (expectedStatusCode) { case HttpStatusCode.OK: AssertEx.SystemPropertiesSet(stored, StartTime); AssertEx.SystemPropertiesChanged(expected, stored); AssertEx.SystemPropertiesMatch(stored, actual); Assert.Equal <IMovie>(replacement, actual !); AssertEx.ResponseHasConditionalHeaders(stored, response); break; case HttpStatusCode.PreconditionFailed: Assert.Equal <IMovie>(expected, actual !); AssertEx.SystemPropertiesMatch(expected, actual); AssertEx.ResponseHasConditionalHeaders(expected, response); break; } }
public async Task FailedReadTests(string relativeUri, HttpStatusCode expectedStatusCode) { var response = await MovieServer.SendRequest(HttpMethod.Get, relativeUri); Assert.Equal(expectedStatusCode, response.StatusCode); }