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);
            }
        }
Esempio n. 2
0
        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));
            }
        }
Esempio n. 7
0
        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());
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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));
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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());
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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);
            }
        }
Esempio n. 17
0
        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}");
        }
Esempio n. 18
0
        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 !);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
        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);
            }
        }
Esempio n. 21
0
        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;
            }
        }
Esempio n. 22
0
        public async Task FailedReadTests(string relativeUri, HttpStatusCode expectedStatusCode)
        {
            var response = await MovieServer.SendRequest(HttpMethod.Get, relativeUri);

            Assert.Equal(expectedStatusCode, response.StatusCode);
        }