public async Task Can_get_HasOne_relationship()
        {
            // Arrange
            MeetingAttendee attendee = _fakers.MeetingAttendee.Generate();

            attendee.Meeting = _fakers.Meeting.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Attendees.Add(attendee);
                await dbContext.SaveChangesAsync();
            });

            string route = $"/meetingAttendees/{attendee.StringId}/relationships/meeting";

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

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

            responseDocument.Should().BeJson(@"{
  ""links"": {
    ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/relationships/meeting"",
    ""related"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting""
  },
  ""data"": {
    ""type"": ""meetings"",
    ""id"": """ + attendee.Meeting.StringId + @"""
  }
}");
        }
        public async Task Can_get_unknown_secondary_resource()
        {
            // Arrange
            MeetingAttendee attendee = _fakers.MeetingAttendee.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Attendees.Add(attendee);
                await dbContext.SaveChangesAsync();
            });

            string route = $"/meetingAttendees/{attendee.StringId}/meeting";

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

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

            responseDocument.Should().BeJson(@"{
  ""links"": {
    ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting""
  },
  ""data"": null
}");
        }
        public async Task Includes_version_on_resource_endpoint()
        {
            // Arrange
            var options = (JsonApiOptions)_testContext.Factory.Services.GetRequiredService <IJsonApiOptions>();

            options.IncludeJsonApiVersion = true;

            MeetingAttendee attendee = _fakers.MeetingAttendee.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Attendees.Add(attendee);
                await dbContext.SaveChangesAsync();
            });

            string route = $"/meetingAttendees/{attendee.StringId}/meeting";

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

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

            responseDocument.Should().BeJson(@"{
  ""jsonapi"": {
    ""version"": ""1.1""
  },
  ""links"": {
    ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting""
  },
  ""data"": null
}");
        }
        public async Task Can_update_resource_with_side_effects()
        {
            // Arrange
            MeetingAttendee existingAttendee = _fakers.MeetingAttendee.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Attendees.Add(existingAttendee);
                await dbContext.SaveChangesAsync();
            });

            var requestBody = new
            {
                data = new
                {
                    type       = "meetingAttendees",
                    id         = existingAttendee.StringId,
                    attributes = new
                    {
                        displayName = existingAttendee.DisplayName
                    }
                }
            };

            string route = "/meetingAttendees/" + existingAttendee.StringId;

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

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

            responseDocument.Should().BeJson(@"{
  ""links"": {
    ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"""
  },
  ""data"": {
    ""type"": ""meetingAttendees"",
    ""id"": """ + existingAttendee.StringId + @""",
    ""attributes"": {
      ""displayName"": """ + existingAttendee.DisplayName + @"""
    },
    ""relationships"": {
      ""meeting"": {
        ""links"": {
          ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"/relationships/meeting"",
          ""related"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"/meeting""
        }
      }
    },
    ""links"": {
      ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"""
    }
  }
}");
        }
        public async Task Can_get_secondary_resource()
        {
            // Arrange
            MeetingAttendee attendee = _fakers.MeetingAttendee.Generate();

            attendee.Meeting = _fakers.Meeting.Generate();

            await _testContext.RunOnDatabaseAsync(async dbContext =>
            {
                dbContext.Attendees.Add(attendee);
                await dbContext.SaveChangesAsync();
            });

            string route = $"/meetingAttendees/{attendee.StringId}/meeting";

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

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

            responseDocument.Should().BeJson(@"{
  ""links"": {
    ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting""
  },
  ""data"": {
    ""type"": ""meetings"",
    ""id"": """ + attendee.Meeting.StringId + @""",
    ""attributes"": {
      ""title"": """ + attendee.Meeting.Title + @""",
      ""startTime"": """ + attendee.Meeting.StartTime.ToString("O") + @""",
      ""duration"": """ + attendee.Meeting.Duration + @""",
      ""location"": {
        ""lat"": " + attendee.Meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @",
        ""lng"": " + attendee.Meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @"
      }
    },
    ""relationships"": {
      ""attendees"": {
        ""links"": {
          ""self"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @"/relationships/attendees"",
          ""related"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @"/attendees""
        }
      }
    },
    ""links"": {
      ""self"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @"""
    }
  }
}");
        }