public async Task Can_filter_by_empty_ID_on_primary_resources()
        {
            // Arrange
            var maps = _fakers.Map.Generate(2);

            maps[0].Id = Guid.Empty;

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Map>();
                dbContext.Maps.AddRange(maps);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/maps?filter=equals(id,'00000000-0000-0000-0000-000000000000')";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be("00000000-0000-0000-0000-000000000000");
            responseDocument.ManyData[0].Links.Self.Should().Be("/maps/00000000-0000-0000-0000-000000000000");
        }
Пример #2
0
        public async Task Can_get_resource_at_custom_route()
        {
            // Arrange
            Town town = _fakers.Town.Generate();

            town.Civilians = _fakers.Civilian.Generate(1).ToHashSet();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Towns.Add(town);
                await dbContext.SaveChangesAsync();
            });

            string route = "/world-api/civilization/popular/towns/" + town.StringId;

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("towns");
            responseDocument.SingleData.Id.Should().Be(town.StringId);
            responseDocument.SingleData.Attributes["name"].Should().Be(town.Name);
            responseDocument.SingleData.Attributes["latitude"].Should().Be(town.Latitude);
            responseDocument.SingleData.Attributes["longitude"].Should().Be(town.Longitude);
            responseDocument.SingleData.Relationships["civilians"].Links.Self.Should().Be(HostPrefix + route + "/relationships/civilians");
            responseDocument.SingleData.Relationships["civilians"].Links.Related.Should().Be(HostPrefix + route + "/civilians");
            responseDocument.SingleData.Links.Self.Should().Be(HostPrefix + route);
            responseDocument.Links.Self.Should().Be(HostPrefix + route);
        }
Пример #3
0
        public async Task Returns_ETag_for_GET_request()
        {
            // Arrange
            List <Meeting> meetings = _fakers.Meeting.Generate(2);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Meeting>();
                dbContext.Meetings.AddRange(meetings);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/meetings";

            // Act
            (HttpResponseMessage httpResponse, string responseDocument) = await _testContext.ExecuteGetAsync <string>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            httpResponse.Headers.ETag.Should().NotBeNull();
            httpResponse.Headers.ETag.IsWeak.Should().BeFalse();
            httpResponse.Headers.ETag.Tag.Should().NotBeNullOrEmpty();

            responseDocument.Should().NotBeEmpty();
        }
Пример #4
0
        public async Task Can_filter_by_zero_ID_on_primary_resources()
        {
            // Arrange
            var games = _fakers.Game.Generate(2);

            games[0].Id = 0;

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Game>();
                dbContext.Games.AddRange(games);
                await dbContext.SaveChangesAsync();
            });

            var route = "/games?filter=equals(id,'0')";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be("0");
            responseDocument.ManyData[0].Links.Self.Should().Be("/games/0");
        }
        public async Task Can_get_resource_by_ID()
        {
            // Arrange
            var clock = (FrozenSystemClock)_testContext.Factory.Services.GetRequiredService <ISystemClock>();

            clock.UtcNow = 27.January(2021);

            GiftCertificate certificate = _fakers.GiftCertificate.Generate();

            certificate.IssueDate = 28.January(2020);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.GiftCertificates.Add(certificate);
                await dbContext.SaveChangesAsync();
            });

            string route = "/giftCertificates/" + certificate.StringId;

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Id.Should().Be(certificate.StringId);
            responseDocument.SingleData.Attributes["issueDate"].Should().BeCloseTo(certificate.IssueDate);
            responseDocument.SingleData.Attributes["hasExpired"].Should().Be(false);
        }
Пример #6
0
        public async Task Cannot_use_unknown_query_string_parameter()
        {
            // Arrange
            var options = (JsonApiOptions)_testContext.Factory.Services.GetRequiredService <IJsonApiOptions>();

            options.AllowUnknownQueryStringParameters = false;

            const string route = "/calendars?foo=bar";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest);

            responseDocument.Errors.Should().HaveCount(1);

            var error = responseDocument.Errors[0];

            error.StatusCode.Should().Be(HttpStatusCode.BadRequest);
            error.Title.Should().Be("Unknown query string parameter.");
            error.Detail.Should().Be("Query string parameter 'foo' is unknown. " +
                                     "Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters.");
            error.Source.Parameter.Should().Be("foo");
        }
Пример #7
0
        public async Task Can_get_primary_resource_with_eager_loads()
        {
            // Arrange
            Building building = _fakers.Building.Generate();

            building.Windows       = _fakers.Window.Generate(4);
            building.PrimaryDoor   = _fakers.Door.Generate();
            building.SecondaryDoor = _fakers.Door.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Buildings.Add(building);
                await dbContext.SaveChangesAsync();
            });

            string route = "/buildings/" + building.StringId;

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Id.Should().Be(building.StringId);
            responseDocument.SingleData.Attributes["number"].Should().Be(building.Number);
            responseDocument.SingleData.Attributes["windowCount"].Should().Be(4);
            responseDocument.SingleData.Attributes["primaryDoorColor"].Should().Be(building.PrimaryDoor.Color);
            responseDocument.SingleData.Attributes["secondaryDoorColor"].Should().Be(building.SecondaryDoor.Color);
        }
Пример #8
0
        public async Task Can_filter_on_ID_in_primary_resources()
        {
            // Arrange
            var car = new Car
            {
                RegionId     = 123,
                LicensePlate = "AA-BB-11"
            };

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Car>();
                dbContext.Cars.Add(car);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/cars?filter=any(id,'123:AA-BB-11','999:XX-YY-22')";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be(car.StringId);
        }
        public async Task Get_primary_resources_hides_other_tenants()
        {
            // Arrange
            List <WebShop> shops = _fakers.WebShop.Generate(2);

            shops[0].TenantId = OtherTenantId;
            shops[1].TenantId = ThisTenantId;

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <WebShop>();
                dbContext.WebShops.AddRange(shops);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/nld/shops";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be(shops[1].StringId);
        }
        public async Task Can_get_resource_at_custom_route()
        {
            // Arrange
            var town = _fakers.Town.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Towns.Add(town);
                await dbContext.SaveChangesAsync();
            });

            var route = "/world-api/civilization/popular/towns/" + town.StringId;

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("towns");
            responseDocument.SingleData.Id.Should().Be(town.StringId);
            responseDocument.SingleData.Attributes["name"].Should().Be(town.Name);
            responseDocument.SingleData.Attributes["latitude"].Should().Be(town.Latitude);
            responseDocument.SingleData.Attributes["longitude"].Should().Be(town.Longitude);
            responseDocument.SingleData.Relationships["civilians"].Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}/relationships/civilians");
            responseDocument.SingleData.Relationships["civilians"].Links.Related.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}/civilians");
            responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}");
            responseDocument.Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}");
        }
Пример #11
0
        public async Task Returns_resource_meta_from_ResourceDefinition()
        {
            // Arrange
            List <SupportTicket> tickets = _fakers.SupportTicket.Generate(3);

            tickets[0].Description = "Critical: " + tickets[0].Description;
            tickets[2].Description = "Critical: " + tickets[2].Description;

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <SupportTicket>();
                dbContext.SupportTickets.AddRange(tickets);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/supportTickets";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(3);
            responseDocument.ManyData[0].Meta.Should().ContainKey("hasHighPriority");
            responseDocument.ManyData[1].Meta.Should().BeNull();
            responseDocument.ManyData[2].Meta.Should().ContainKey("hasHighPriority");
        }
        public async Task Can_get_primary_resources()
        {
            // Arrange
            var departments = new List <Department>
            {
                new Department
                {
                    Name          = "Sales",
                    IsSoftDeleted = true
                },
                new Department
                {
                    Name = "Marketing"
                }
            };

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Department>();
                dbContext.Departments.AddRange(departments);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/departments";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be(departments[1].StringId);
        }
        public async Task Can_get_HasOne_relationship()
        {
            var workItem = _fakers.WorkItem.Generate();

            workItem.Assignee = _fakers.UserAccount.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.WorkItems.Add(workItem);
                await dbContext.SaveChangesAsync();
            });

            var route = $"/workItems/{workItem.StringId}/relationships/assignee";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("userAccounts");
            responseDocument.SingleData.Id.Should().Be(workItem.Assignee.StringId);
            responseDocument.SingleData.Attributes.Should().BeNull();
            responseDocument.SingleData.Relationships.Should().BeNull();
        }
        public async Task Can_filter_equality_on_type(string propertyName, object value)
        {
            // Arrange
            var resource = new FilterableResource();
            var property = typeof(FilterableResource).GetProperty(propertyName);

            property?.SetValue(resource, value);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <FilterableResource>();
                dbContext.FilterableResources.AddRange(resource, new FilterableResource());
                await dbContext.SaveChangesAsync();
            });

            var attributeName = propertyName.Camelize();
            var route         = $"/filterableResources?filter=equals({attributeName},'{value}')";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Attributes[attributeName].Should().Be(value is Enum ? value.ToString() : value);
        }
        public async Task Permits_no_Accept_headers()
        {
            // Arrange
            const string route = "/policies";

            // Act
            (HttpResponseMessage httpResponse, _) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
        public async Task Can_use_page_number_below_maximum()
        {
            // Arrange
            const int pageNumber = MaximumPageNumber - 1;
            string    route      = "/blogs?page[number]=" + pageNumber;

            // Act
            (HttpResponseMessage httpResponse, _) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
Пример #17
0
        public async Task Permits_no_Accept_headers()
        {
            // Arrange
            var route = "/policies";

            var acceptHeaders = new MediaTypeWithQualityHeaderValue[0];

            // Act
            var(httpResponse, _) = await _testContext.ExecuteGetAsync <Document>(route, acceptHeaders);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
        public async Task Can_use_Queryable_handler_on_resource_endpoint()
        {
            // Arrange
            var musicTracks = _fakers.MusicTrack.Generate(3);

            musicTracks[0].ReleasedAt = FrozenTime.AddMonths(5);
            musicTracks[1].ReleasedAt = FrozenTime.AddMonths(-5);
            musicTracks[2].ReleasedAt = FrozenTime.AddMonths(-1);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <MusicTrack>();
                dbContext.MusicTracks.AddRange(musicTracks);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/musicTracks?isRecentlyReleased=true";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be(musicTracks[2].StringId);
        }
        public async Task Encrypts_on_get_primary_resources()
        {
            // Arrange
            var encryptionService = _testContext.Factory.Services.GetRequiredService <IEncryptionService>();
            var hitCounter        = _testContext.Factory.Services.GetRequiredService <ResourceDefinitionHitCounter>();

            List <Student> students = _fakers.Student.Generate(2);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Student>();
                dbContext.Students.AddRange(students);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/students";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(2);

            string socialSecurityNumber1 = encryptionService.Decrypt((string)responseDocument.ManyData[0].Attributes["socialSecurityNumber"]);

            socialSecurityNumber1.Should().Be(students[0].SocialSecurityNumber);

            string socialSecurityNumber2 = encryptionService.Decrypt((string)responseDocument.ManyData[1].Attributes["socialSecurityNumber"]);

            socialSecurityNumber2.Should().Be(students[1].SocialSecurityNumber);

            hitCounter.HitExtensibilityPoints.Should().BeEquivalentTo(new[]
Пример #20
0
        public async Task Returns_top_level_meta()
        {
            // Arrange
            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <SupportTicket>();
            });

            const string route = "/supportTickets";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <string>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.Should().BeJson(@"{
  ""meta"": {
    ""license"": ""MIT"",
    ""projectUrl"": ""https://github.com/json-api-dotnet/JsonApiDotNetCore/"",
    ""versions"": [
      ""v4.0.0"",
      ""v3.1.0"",
      ""v2.5.2"",
      ""v1.3.1""
    ]
  },
  ""links"": {
    ""self"": ""http://localhost/supportTickets"",
    ""first"": ""http://localhost/supportTickets""
  },
  ""data"": []
}");
        }
Пример #21
0
        public async Task Cannot_filter_in_unknown_scope()
        {
            // Arrange
            var route = "/webAccounts?filter[doesNotExist]=equals(title,null)";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest);

            responseDocument.Errors.Should().HaveCount(1);
            responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest);
            responseDocument.Errors[0].Title.Should().Be("The specified filter is invalid.");
            responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'.");
            responseDocument.Errors[0].Source.Parameter.Should().Be("filter[doesNotExist]");
        }
Пример #22
0
        public async Task Cannot_sort_if_query_string_parameter_is_blocked_by_controller()
        {
            // Arrange
            var route = "/sofas?sort=id";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest);

            responseDocument.Errors.Should().HaveCount(1);
            responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest);
            responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint.");
            responseDocument.Errors[0].Detail.Should().Be("The parameter 'sort' cannot be used at this endpoint.");
            responseDocument.Errors[0].Source.Parameter.Should().Be("sort");
        }
Пример #23
0
        public async Task Get_primary_resources_with_include_returns_links()
        {
            // Arrange
            ArtGallery gallery = _fakers.ArtGallery.Generate();

            gallery.Paintings = _fakers.Painting.Generate(1).ToHashSet();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <ArtGallery>();
                dbContext.ArtGalleries.Add(gallery);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/iis-application-virtual-directory/public-api/artGalleries?include=paintings";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.Links.Self.Should().Be(HostPrefix + route);
            responseDocument.Links.Related.Should().BeNull();
            responseDocument.Links.First.Should().Be(HostPrefix + route);
            responseDocument.Links.Last.Should().Be(HostPrefix + route);
            responseDocument.Links.Prev.Should().BeNull();
            responseDocument.Links.Next.Should().BeNull();

            string galleryLink = HostPrefix + $"/iis-application-virtual-directory/public-api/artGalleries/{gallery.StringId}";

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Links.Self.Should().Be(galleryLink);
            responseDocument.ManyData[0].Relationships["paintings"].Links.Self.Should().Be(galleryLink + "/relationships/paintings");
            responseDocument.ManyData[0].Relationships["paintings"].Links.Related.Should().Be(galleryLink + "/paintings");

            // TODO: The next link is wrong: it should use the custom route.
            // https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/956
            string paintingLink = HostPrefix + $"/iis-application-virtual-directory/public-api/paintings/{gallery.Paintings.ElementAt(0).StringId}";

            responseDocument.Included.Should().HaveCount(1);
            responseDocument.Included[0].Links.Self.Should().Be(paintingLink);
            responseDocument.Included[0].Relationships["exposedAt"].Links.Self.Should().Be(paintingLink + "/relationships/exposedAt");
            responseDocument.Included[0].Relationships["exposedAt"].Links.Related.Should().Be(paintingLink + "/exposedAt");
        }
        public async Task Get_primary_resources_excludes_soft_deleted()
        {
            // Arrange
            List <Department> departments = _fakers.Department.Generate(2);

            departments[0].SoftDeletedAt = SoftDeletionTime;

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Department>();
                dbContext.Departments.AddRange(departments);
                await dbContext.SaveChangesAsync();
            });

            const string route = "/departments";

            // Act
            (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);

            responseDocument.ManyData.Should().HaveCount(1);
            responseDocument.ManyData[0].Id.Should().Be(departments[1].StringId);
        }
Пример #25
0
        public async Task Can_block_access_to_resource_from_GetSingle_endpoint_using_BeforeRead_hook()
        {
            // Arrange
            const string route = "/api/v1/todoItems/1337";

            // Act
            (HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden);

            responseDocument.Errors.Should().HaveCount(1);

            Error error = responseDocument.Errors[0];

            error.StatusCode.Should().Be(HttpStatusCode.Forbidden);
            error.Title.Should().Be("You are not allowed to update the author of todo items.");
            error.Detail.Should().BeNull();
        }
Пример #26
0
        public async Task Can_get_resources()
        {
            // Arrange
            var route = "/chairs";

            // Act
            var(httpResponse, _) = await _testContext.ExecuteGetAsync <string>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
        public async Task Can_get_resources()
        {
            // Arrange
            const string route = "/tables";

            // Act
            (HttpResponseMessage httpResponse, _) = await _testContext.ExecuteGetAsync <string>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
Пример #28
0
        public async Task Cannot_use_negative_page_number()
        {
            // Arrange
            const string route = "/blogs?page[number]=-1";

            // Act
            (HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest);

            responseDocument.Errors.Should().HaveCount(1);

            Error error = responseDocument.Errors[0];

            error.StatusCode.Should().Be(HttpStatusCode.BadRequest);
            error.Title.Should().Be("The specified paging is invalid.");
            error.Detail.Should().Be("Page number cannot be negative or zero.");
            error.Source.Parameter.Should().Be("page[number]");
        }
Пример #29
0
        public async Task Returns_JsonApi_ContentType_header()
        {
            // Arrange
            var route = "/policies";

            // Act
            var(httpResponse, _) = await _testContext.ExecuteGetAsync <Document>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
            httpResponse.Content.Headers.ContentType.ToString().Should().Be(HeaderConstants.MediaType);
        }
Пример #30
0
        public async Task Cannot_override_from_query_string()
        {
            // Arrange
            var options = (JsonApiOptions)_testContext.Factory.Services.GetRequiredService <IJsonApiOptions>();

            options.AllowQueryStringOverrideForSerializerNullValueHandling = false;

            var route = "/calendars?nulls=true";

            // Act
            var(httpResponse, responseDocument) = await _testContext.ExecuteGetAsync <ErrorDocument>(route);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest);

            responseDocument.Errors.Should().HaveCount(1);
            responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest);
            responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint.");
            responseDocument.Errors[0].Detail.Should().Be("The parameter 'nulls' cannot be used at this endpoint.");
            responseDocument.Errors[0].Source.Parameter.Should().Be("nulls");
        }