Exemplo n.º 1
0
        public async Task Can_create_OneToOne_relationship_from_principal_side()
        {
            // Arrange
            WorkItemGroup existingGroup = _fakers.WorkItemGroup.Generate();

            existingGroup.Color = _fakers.RgbColor.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Groups.Add(existingGroup);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type          = "workItemGroups",
                    relationships = new
                    {
                        color = new
                        {
                            data = new
                            {
                                type = "rgbColors",
                                id   = existingGroup.Color.StringId
                            }
                        }
                    }
                }
            };

            const string route = "/workItemGroups";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes.Should().NotBeEmpty();
            responseDocument.SingleData.Relationships.Should().NotBeEmpty();

            string newGroupId = responseDocument.SingleData.Id;

            newGroupId.Should().NotBeNullOrEmpty();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                List <WorkItemGroup> groupsInDatabase = await dbContext.Groups.Include(group => group.Color).ToListAsync();

                WorkItemGroup newGroupInDatabase = groupsInDatabase.Single(group => group.StringId == newGroupId);
                newGroupInDatabase.Color.Should().NotBeNull();
                newGroupInDatabase.Color.Id.Should().Be(existingGroup.Color.Id);

                WorkItemGroup existingGroupInDatabase = groupsInDatabase.Single(group => group.Id == existingGroup.Id);
                existingGroupInDatabase.Color.Should().BeNull();
            });
        }
Exemplo n.º 2
0
        public async Task Can_create_user_with_password()
        {
            // Arrange
            var user = _fakers.User.Generate();

            var    serializer  = GetRequestSerializer <User>(p => new { p.Password, p.UserName });
            string requestBody = serializer.Serialize(user);

            var route = "/api/v1/users";

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

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

            var responseUser = GetResponseDeserializer().DeserializeSingle <User>(responseDocument).Data;
            var document     = JsonConvert.DeserializeObject <Document>(responseDocument);

            document.SingleData.Attributes.Should().NotContainKey("password");
            document.SingleData.Attributes["userName"].Should().Be(user.UserName);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var userInDatabase = await dbContext.Users.FirstAsync(u => u.Id == responseUser.Id);

                userInDatabase.UserName.Should().Be(user.UserName);
                userInDatabase.Password.Should().Be(user.Password);
            });
        }
Exemplo n.º 3
0
        public async Task Cannot_create_resource_with_omitted_required_attribute()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "systemDirectories",
                    attributes = new
                    {
                        isCaseSensitive = true
                    }
                }
            };

            const string route = "/systemDirectories";

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

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

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

            Error error = responseDocument.Errors[0];

            error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity);
            error.Title.Should().Be("Input validation failed.");
            error.Detail.Should().Be("The Name field is required.");
            error.Source.Pointer.Should().Be("/data/attributes/name");
        }
        public async Task Cannot_create_dependent_side_of_required_ManyToOne_relationship_without_providing_principal_side()
        {
            // Arrange
            var order = _fakers.Orders.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "orders",
                    attributes = new
                    {
                        order = order.Amount
                    }
                }
            };

            const string route = "/orders";

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

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

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

            var error = responseDocument.Errors[0];

            error.StatusCode.Should().Be(HttpStatusCode.InternalServerError);
            error.Title.Should().Be("An unhandled error occurred while processing this request.");
            error.Detail.Should().Be("Failed to persist changes in the underlying data store.");
        }
        public async Task Permits_no_Accept_headers_at_operations_endpoint()
        {
            // Arrange
            var requestBody = new
            {
                atomic__operations = new[]
                {
                    new
                    {
                        op   = "add",
                        data = new
                        {
                            type       = "policies",
                            attributes = new
                            {
                                name = "some"
                            }
                        }
                    }
                }
            };

            const string route       = "/operations";
            const string contentType = HeaderConstants.AtomicOperationsMediaType;

            // Act
            (HttpResponseMessage httpResponse, _) = await _testContext.ExecutePostAsync <ErrorDocument>(route, requestBody, contentType);

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
        }
Exemplo n.º 6
0
        public async Task Denies_unknown_ContentType_header()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "policies",
                    attributes = new
                    {
                        name = "some"
                    }
                }
            };

            var route       = "/policies";
            var contentType = "text/html";

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

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

            responseDocument.Errors.Should().HaveCount(1);
            responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType);
            responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported.");
            responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'text/html' for the Content-Type header value.");
        }
        public async Task Sets_location_header_for_created_resource()
        {
            // Arrange
            WorkItem newWorkItem = _fakers.WorkItem.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "workItems",
                    attributes = new
                    {
                        description = newWorkItem.Description
                    }
                }
            };

            const string route = "/workItems";

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

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

            string newWorkItemId = responseDocument.SingleData.Id;

            httpResponse.Headers.Location.Should().Be("/workItems/" + newWorkItemId);

            responseDocument.Links.Self.Should().Be("http://localhost/workItems");
            responseDocument.Links.First.Should().BeNull();

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Links.Self.Should().Be("http://localhost" + httpResponse.Headers.Location);
        }
        public async Task Can_create_resource_with_inherited_attributes()
        {
            // Arrange
            var man = new Man
            {
                FamilyName = "Smith",
                IsRetired  = true,
                HasBeard   = true
            };

            var requestBody = new
            {
                data = new
                {
                    type       = "men",
                    attributes = new
                    {
                        familyName = man.FamilyName,
                        isRetired  = man.IsRetired,
                        hasBeard   = man.HasBeard
                    }
                }
            };

            var route = "/men";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("men");
            responseDocument.SingleData.Attributes["familyName"].Should().Be(man.FamilyName);
            responseDocument.SingleData.Attributes["isRetired"].Should().Be(man.IsRetired);
            responseDocument.SingleData.Attributes["hasBeard"].Should().Be(man.HasBeard);

            var newManId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var manInDatabase = await dbContext.Men
                                    .FirstAsync(m => m.Id == newManId);

                manInDatabase.FamilyName.Should().Be(man.FamilyName);
                manInDatabase.IsRetired.Should().Be(man.IsRetired);
                manInDatabase.HasBeard.Should().Be(man.HasBeard);
            });
        }
        public async Task Decrypts_on_create_resource()
        {
            // Arrange
            var encryptionService = _testContext.Factory.Services.GetRequiredService <IEncryptionService>();
            var hitCounter        = _testContext.Factory.Services.GetRequiredService <SerializationHitCounter>();

            string newName = _fakers.Student.Generate().Name;
            string newSocialSecurityNumber = _fakers.Student.Generate().SocialSecurityNumber;

            var requestBody = new
            {
                data = new
                {
                    type       = "students",
                    attributes = new
                    {
                        name = newName,
                        socialSecurityNumber = encryptionService.Encrypt(newSocialSecurityNumber)
                    }
                }
            };

            const string route = "/students";

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

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

            responseDocument.SingleData.Should().NotBeNull();

            string socialSecurityNumber = encryptionService.Decrypt((string)responseDocument.SingleData.Attributes["socialSecurityNumber"]);

            socialSecurityNumber.Should().Be(newSocialSecurityNumber);

            int newStudentId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                Student studentInDatabase = await dbContext.Students.FirstWithIdAsync(newStudentId);

                studentInDatabase.SocialSecurityNumber.Should().Be(newSocialSecurityNumber);
            });

            hitCounter.DeserializeCount.Should().Be(1);
            hitCounter.SerializeCount.Should().Be(1);
        }
Exemplo n.º 10
0
        public async Task Create_resource_with_side_effects_and_include_returns_relative_links()
        {
            // Arrange
            var existingPhoto = _fakers.Photo.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Photos.Add(existingPhoto);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type          = "photoAlbums",
                    relationships = new
                    {
                        photos = new
                        {
                            data = new[]
                            {
                                new
                                {
                                    type = "photos",
                                    id   = existingPhoto.StringId
                                }
                            }
                        }
                    }
                }
            };

            var route = "/api/photoAlbums?include=photos";

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

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

            responseDocument.Links.Self.Should().Be("/api/photoAlbums?include=photos");
            responseDocument.Links.Related.Should().BeNull();
            responseDocument.Links.First.Should().BeNull();
            responseDocument.Links.Last.Should().BeNull();
            responseDocument.Links.Prev.Should().BeNull();
            responseDocument.Links.Next.Should().BeNull();

            var newAlbumId = responseDocument.SingleData.Id;

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Links.Self.Should().Be($"/api/photoAlbums/{newAlbumId}");
            responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{newAlbumId}/relationships/photos");
            responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{newAlbumId}/photos");

            responseDocument.Included.Should().HaveCount(1);
            responseDocument.Included[0].Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}");
            responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}/relationships/album");
            responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"/api/photos/{existingPhoto.StringId}/album");
        }
        public async Task Cannot_create_resource()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "beds",
                    attributes = new
                    {
                    }
                }
            };

            var route = "/beds";

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

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

            responseDocument.Errors.Should().HaveCount(1);
            responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed);
            responseDocument.Errors[0].Title.Should().Be("The request method is not allowed.");
            responseDocument.Errors[0].Detail.Should().Be("Resource does not support POST requests.");
        }
Exemplo n.º 12
0
        public async Task Can_create_resource_with_invalid_attribute_value()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "systemDirectories",
                    attributes = new
                    {
                        name            = "!@#$%^&*().-",
                        isCaseSensitive = "false"
                    }
                }
            };

            const string route = "/systemDirectories";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["name"].Should().Be("!@#$%^&*().-");
        }
Exemplo n.º 13
0
        public async Task Returns_no_ETag_for_POST_request()
        {
            // Arrange
            string newTitle = _fakers.Meeting.Generate().Title;

            var requestBody = new
            {
                data = new
                {
                    type       = "meetings",
                    attributes = new
                    {
                        title = newTitle
                    }
                }
            };

            const string route = "/meetings";

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

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

            httpResponse.Headers.ETag.Should().BeNull();

            responseDocument.Should().NotBeEmpty();
        }
        public async Task Hides_resource_count_in_create_resource_response()
        {
            // Arrange
            var newDescription = _fakers.SupportTicket.Generate().Description;

            var requestBody = new
            {
                data = new
                {
                    type       = "supportTickets",
                    attributes = new
                    {
                        description = newDescription
                    }
                }
            };

            var route = "/supportTickets";

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

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

            responseDocument.Meta.Should().BeNull();
        }
Exemplo n.º 15
0
        public async Task Can_create_in_valid_stage()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "workflows",
                    attributes = new
                    {
                        stage = WorkflowStage.Created
                    }
                }
            };

            const string route = "/workflows";

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

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

            responseDocument.SingleData.Should().NotBeNull();
        }
Exemplo n.º 16
0
        public async Task Can_create_unarchived_resource()
        {
            // Arrange
            TelevisionBroadcast newBroadcast = _fakers.TelevisionBroadcast.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "televisionBroadcasts",
                    attributes = new
                    {
                        title   = newBroadcast.Title,
                        airedAt = newBroadcast.AiredAt
                    }
                }
            };

            const string route = "/televisionBroadcasts";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["title"].Should().Be(newBroadcast.Title);
            responseDocument.SingleData.Attributes["airedAt"].Should().BeCloseTo(newBroadcast.AiredAt);
            responseDocument.SingleData.Attributes["archivedAt"].Should().BeNull();
        }
        public async Task Can_create_resource_with_client_generated_guid_ID_having_side_effects()
        {
            // Arrange
            var newGroup = _fakers.WorkItemGroup.Generate();

            newGroup.Id = Guid.NewGuid();

            var requestBody = new
            {
                data = new
                {
                    type       = "workItemGroups",
                    id         = newGroup.StringId,
                    attributes = new
                    {
                        name = newGroup.Name
                    }
                }
            };

            var route = "/workItemGroups";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("workItemGroups");
            responseDocument.SingleData.Id.Should().Be(newGroup.StringId);
            responseDocument.SingleData.Attributes["name"].Should().Be(newGroup.Name);
            responseDocument.SingleData.Relationships.Should().NotBeEmpty();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var groupInDatabase = await dbContext.Groups
                                      .FirstAsync(group => group.Id == newGroup.Id);

                groupInDatabase.Name.Should().Be(newGroup.Name);
            });

            var property = typeof(WorkItemGroup).GetProperty(nameof(Identifiable.Id));

            property.Should().NotBeNull().And.Subject.PropertyType.Should().Be(typeof(Guid));
        }
Exemplo n.º 18
0
        public async Task Can_create_resource_with_zero_ID()
        {
            // Arrange
            var newTitle = _fakers.Game.Generate().Title;

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

            var requestBody = new
            {
                data = new
                {
                    type       = "games",
                    id         = "0",
                    attributes = new
                    {
                        title = newTitle
                    }
                }
            };

            var route = "/games";

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

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

            httpResponse.Headers.Location.Should().Be("/games/0");

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Id.Should().Be("0");

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var gameInDatabase = await dbContext.Games
                                     .FirstAsync(game => game.Id == 0);

                gameInDatabase.Should().NotBeNull();
                gameInDatabase.Title.Should().Be(newTitle);
            });
        }
Exemplo n.º 19
0
        public async Task Can_create_resource()
        {
            // Arrange
            var newPool = _fakers.SwimmingPool.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "swimming-pools",
                    attributes = new Dictionary <string, object>
                    {
                        ["is-indoor"] = newPool.IsIndoor
                    }
                }
            };

            const string route = "/public-api/swimming-pools";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Type.Should().Be("swimming-pools");
            responseDocument.SingleData.Attributes["is-indoor"].Should().Be(newPool.IsIndoor);

            var    newPoolId = int.Parse(responseDocument.SingleData.Id);
            string poolLink  = route + $"/{newPoolId}";

            responseDocument.SingleData.Relationships.Should().NotBeEmpty();
            responseDocument.SingleData.Relationships["water-slides"].Links.Self.Should().Be(poolLink + "/relationships/water-slides");
            responseDocument.SingleData.Relationships["water-slides"].Links.Related.Should().Be(poolLink + "/water-slides");
            responseDocument.SingleData.Relationships["diving-boards"].Links.Self.Should().Be(poolLink + "/relationships/diving-boards");
            responseDocument.SingleData.Relationships["diving-boards"].Links.Related.Should().Be(poolLink + "/diving-boards");

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var poolInDatabase = await dbContext.SwimmingPools.FirstWithIdAsync(newPoolId);

                poolInDatabase.IsIndoor.Should().Be(newPool.IsIndoor);
            });
        }
Exemplo n.º 20
0
        public async Task Can_create_resource_with_empty_ID()
        {
            // Arrange
            var newName = _fakers.Map.Generate().Name;

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

            var requestBody = new
            {
                data = new
                {
                    type       = "maps",
                    id         = "00000000-0000-0000-0000-000000000000",
                    attributes = new
                    {
                        name = newName
                    }
                }
            };

            var route = "/maps";

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

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

            httpResponse.Headers.Location.Should().Be("/maps/00000000-0000-0000-0000-000000000000");

            responseDocument.Should().BeEmpty();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var mapInDatabase = await dbContext.Maps
                                    .FirstAsync(map => map.Id == Guid.Empty);

                mapInDatabase.Should().NotBeNull();
                mapInDatabase.Name.Should().Be(newName);
            });
        }
Exemplo n.º 21
0
        public async Task Can_create_resource()
        {
            // Arrange
            Building newBuilding = _fakers.Building.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "buildings",
                    attributes = new
                    {
                        number = newBuilding.Number
                    }
                }
            };

            const string route = "/buildings";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["number"].Should().Be(newBuilding.Number);
            responseDocument.SingleData.Attributes["windowCount"].Should().Be(0);
            responseDocument.SingleData.Attributes["primaryDoorColor"].Should().BeNull();
            responseDocument.SingleData.Attributes["secondaryDoorColor"].Should().BeNull();

            int newBuildingId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                // @formatter:wrap_chained_method_calls chop_always
                // @formatter:keep_existing_linebreaks true

                Building buildingInDatabase = await dbContext.Buildings
                                              .Include(building => building.PrimaryDoor)
                                              .Include(building => building.SecondaryDoor)
                                              .Include(building => building.Windows)
                                              .FirstWithIdOrDefaultAsync(newBuildingId);

                // @formatter:keep_existing_linebreaks restore
                // @formatter:wrap_chained_method_calls restore

                buildingInDatabase.Should().NotBeNull();
                buildingInDatabase.Number.Should().Be(newBuilding.Number);
                buildingInDatabase.PrimaryDoor.Should().NotBeNull();
                buildingInDatabase.SecondaryDoor.Should().BeNull();
                buildingInDatabase.Windows.Should().BeEmpty();
            });
        }
Exemplo n.º 22
0
        public async Task Can_create_resource()
        {
            // Arrange
            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                await dbContext.ClearTableAsync <Car>();
            });

            var requestBody = new
            {
                data = new
                {
                    type       = "cars",
                    attributes = new
                    {
                        regionId     = 123,
                        licensePlate = "AA-BB-11"
                    }
                }
            };

            const string route = "/cars";

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

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

            responseDocument.Should().BeEmpty();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var carInDatabase = await dbContext.Cars
                                    .FirstOrDefaultAsync(car => car.RegionId == 123 && car.LicensePlate == "AA-BB-11");

                carInDatabase.Should().NotBeNull();
                carInDatabase.Id.Should().Be("123:AA-BB-11");
            });
        }
Exemplo n.º 23
0
        public async Task Logs_request_body_at_Trace_level()
        {
            // Arrange
            var loggerFactory = _testContext.Factory.Services.GetRequiredService <FakeLoggerFactory>();

            loggerFactory.Logger.Clear();

            var newEntry = _fakers.AuditEntry.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "auditEntries",
                    attributes = new
                    {
                        userName  = newEntry.UserName,
                        createdAt = newEntry.CreatedAt
                    }
                }
            };

            // Arrange
            const string route = "/auditEntries";

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

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

            loggerFactory.Logger.Messages.Should().NotBeEmpty();

            loggerFactory.Logger.Messages.Should().ContainSingle(message => message.LogLevel == LogLevel.Trace &&
                                                                 message.Text.StartsWith("Received request at 'http://localhost/auditEntries' with body: <<", StringComparison.Ordinal));
        }
        public async Task Can_create_resource()
        {
            // Arrange
            var newBuilding = _fakers.Building.Generate();

            var requestBody = new
            {
                data = new
                {
                    type       = "buildings",
                    attributes = new
                    {
                        number = newBuilding.Number
                    }
                }
            };

            var route = "/buildings";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["number"].Should().Be(newBuilding.Number);
            responseDocument.SingleData.Attributes["windowCount"].Should().Be(0);
            responseDocument.SingleData.Attributes["primaryDoorColor"].Should().BeNull();
            responseDocument.SingleData.Attributes["secondaryDoorColor"].Should().BeNull();

            var newId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var buildingInDatabase = await dbContext.Buildings
                                         .Include(building => building.PrimaryDoor)
                                         .Include(building => building.SecondaryDoor)
                                         .Include(building => building.Windows)
                                         .FirstOrDefaultAsync(building => building.Id == newId);

                buildingInDatabase.Should().NotBeNull();
                buildingInDatabase.Number.Should().Be(newBuilding.Number);
                buildingInDatabase.PrimaryDoor.Should().NotBeNull();
                buildingInDatabase.SecondaryDoor.Should().BeNull();
                buildingInDatabase.Windows.Should().BeEmpty();
            });
        }
Exemplo n.º 25
0
        public async Task Can_create_resource()
        {
            // Arrange
            var requestBody = new
            {
                data = new
                {
                    type       = "chairs",
                    attributes = new
                    {
                    }
                }
            };

            var route = "/chairs";

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

            // Assert
            httpResponse.Should().HaveStatusCode(HttpStatusCode.Created);
        }
Exemplo n.º 26
0
        public async Task Can_create_resource()
        {
            // Arrange
            string newShopUrl = _fakers.WebShop.Generate().Url;

            var requestBody = new
            {
                data = new
                {
                    type       = "webShops",
                    attributes = new
                    {
                        url = newShopUrl
                    }
                }
            };

            const string route = "/nld/shops";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["url"].Should().Be(newShopUrl);
            responseDocument.SingleData.Relationships.Should().NotBeNull();

            int newShopId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                WebShop shopInDatabase = await dbContext.WebShops.IgnoreQueryFilters().FirstWithIdAsync(newShopId);

                shopInDatabase.Url.Should().Be(newShopUrl);
                shopInDatabase.TenantId.Should().Be(ThisTenantId);
            });
        }
Exemplo n.º 27
0
        public async Task Cannot_add_to_HasOne_relationship()
        {
            // Arrange
            WorkItem    existingWorkItem    = _fakers.WorkItem.Generate();
            UserAccount existingUserAccount = _fakers.UserAccount.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.AddRange(existingWorkItem, existingUserAccount);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type = "userAccounts",
                    id   = existingUserAccount.StringId
                }
            };

            string route = $"/workItems/{existingWorkItem.StringId}/relationships/assignee";

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

            // 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("Only to-many relationships can be updated through this endpoint.");
            error.Detail.Should().Be("Relationship 'assignee' must be a to-many relationship.");
        }
Exemplo n.º 28
0
        public async Task Can_create_HasMany_relationship()
        {
            // Arrange
            var existingUserAccounts = _fakers.UserAccount.Generate(2);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.UserAccounts.AddRange(existingUserAccounts);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type          = "workItems",
                    relationships = new
                    {
                        subscribers = new
                        {
                            data = new[]
                            {
                                new
                                {
                                    type = "userAccounts",
                                    id   = existingUserAccounts[0].StringId
                                },
                                new
                                {
                                    type = "userAccounts",
                                    id   = existingUserAccounts[1].StringId
                                }
                            }
                        }
                    }
                }
            };

            var route = "/workItems";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes.Should().NotBeEmpty();
            responseDocument.SingleData.Relationships.Should().NotBeEmpty();
            responseDocument.Included.Should().BeNull();

            var newWorkItemId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var workItemInDatabase = await dbContext.WorkItems
                                         .Include(workItem => workItem.Subscribers)
                                         .FirstAsync(workItem => workItem.Id == newWorkItemId);

                workItemInDatabase.Subscribers.Should().HaveCount(2);
                workItemInDatabase.Subscribers.Should().ContainSingle(subscriber => subscriber.Id == existingUserAccounts[0].Id);
                workItemInDatabase.Subscribers.Should().ContainSingle(subscriber => subscriber.Id == existingUserAccounts[1].Id);
            });
        }
Exemplo n.º 29
0
        public async Task Can_create_resource_with_relationship()
        {
            // Arrange
            var existingBankAccount = _fakers.BankAccount.Generate();
            var newDebitCard        = _fakers.DebitCard.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.BankAccounts.Add(existingBankAccount);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type       = "debitCards",
                    attributes = new
                    {
                        ownerName = newDebitCard.OwnerName,
                        pinCode   = newDebitCard.PinCode
                    },
                    relationships = new
                    {
                        account = new
                        {
                            data = new
                            {
                                type = "bankAccounts",
                                id   = existingBankAccount.StringId
                            }
                        }
                    }
                }
            };

            var route = "/debitCards";

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

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

            responseDocument.SingleData.Attributes["ownerName"].Should().Be(newDebitCard.OwnerName);
            responseDocument.SingleData.Attributes["pinCode"].Should().Be(newDebitCard.PinCode);

            var newDebitCardId = HexadecimalCodec.Decode(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                var debitCardInDatabase = await dbContext.DebitCards
                                          .Include(debitCard => debitCard.Account)
                                          .FirstAsync(debitCard => debitCard.Id == newDebitCardId);

                debitCardInDatabase.OwnerName.Should().Be(newDebitCard.OwnerName);
                debitCardInDatabase.PinCode.Should().Be(newDebitCard.PinCode);

                debitCardInDatabase.Account.Should().NotBeNull();
                debitCardInDatabase.Account.Id.Should().Be(existingBankAccount.Id);
                debitCardInDatabase.Account.StringId.Should().Be(existingBankAccount.StringId);
            });
        }
        public async Task Can_create_resource_with_ToOne_relationship_and_include()
        {
            // Arrange
            var clock = (FrozenSystemClock)_testContext.Factory.Services.GetRequiredService <ISystemClock>();

            clock.UtcNow = 19.March(1998).At(6, 34);

            PostOffice existingOffice = _fakers.PostOffice.Generate();

            var newIssueDate = 18.March(1997).ToDateTimeOffset();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.PostOffice.Add(existingOffice);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type       = "giftCertificates",
                    attributes = new
                    {
                        issueDate = newIssueDate
                    },
                    relationships = new
                    {
                        issuer = new
                        {
                            data = new
                            {
                                type = "postOffices",
                                id   = existingOffice.StringId
                            }
                        }
                    }
                }
            };

            const string route = "/giftCertificates?include=issuer";

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

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

            responseDocument.SingleData.Should().NotBeNull();
            responseDocument.SingleData.Attributes["issueDate"].Should().BeCloseTo(newIssueDate);
            responseDocument.SingleData.Attributes["hasExpired"].Should().Be(true);
            responseDocument.SingleData.Relationships["issuer"].SingleData.Id.Should().Be(existingOffice.StringId);

            responseDocument.Included.Should().HaveCount(1);
            responseDocument.Included[0].Id.Should().Be(existingOffice.StringId);
            responseDocument.Included[0].Attributes["address"].Should().Be(existingOffice.Address);
            responseDocument.Included[0].Attributes["isOpen"].Should().Be(false);

            int newCertificateId = int.Parse(responseDocument.SingleData.Id);

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                GiftCertificate certificateInDatabase = await dbContext.GiftCertificates
                                                        .Include(certificate => certificate.Issuer).FirstWithIdAsync(newCertificateId);

                certificateInDatabase.IssueDate.Should().Be(newIssueDate);

                certificateInDatabase.Issuer.Should().NotBeNull();
                certificateInDatabase.Issuer.Id.Should().Be(existingOffice.Id);
            });
        }