1717using Microsoft . EntityFrameworkCore ;
1818using Newtonsoft . Json ;
1919using Xunit ;
20+ using Person = JsonApiDotNetCoreExample . Models . Person ;
2021
2122namespace JsonApiDotNetCoreExampleTests . Acceptance . Spec
2223{
@@ -26,6 +27,7 @@ public class CreatingDataTests
2627 private TestFixture < TestStartup > _fixture ;
2728 private IJsonApiContext _jsonApiContext ;
2829 private Faker < TodoItem > _todoItemFaker ;
30+ private Faker < Person > _personFaker ;
2931
3032 public CreatingDataTests ( TestFixture < TestStartup > fixture )
3133 {
@@ -35,6 +37,10 @@ public CreatingDataTests(TestFixture<TestStartup> fixture)
3537 . RuleFor ( t => t . Description , f => f . Lorem . Sentence ( ) )
3638 . RuleFor ( t => t . Ordinal , f => f . Random . Number ( ) )
3739 . RuleFor ( t => t . CreatedDate , f => f . Date . Past ( ) ) ;
40+ _personFaker = new Faker < Person > ( )
41+ . RuleFor ( t => t . FirstName , f => f . Name . FirstName ( ) )
42+ . RuleFor ( t => t . LastName , f => f . Name . LastName ( ) ) ;
43+
3844 }
3945
4046 [ Fact ]
@@ -586,5 +592,113 @@ public async Task Respond_409_ToIncorrectEntityType()
586592 // assert
587593 Assert . Equal ( HttpStatusCode . Conflict , response . StatusCode ) ;
588594 }
595+
596+ [ Fact ]
597+ public async Task Create_With_ToOne_Relationship_With_Implicit_Remove ( )
598+ {
599+ // Arrange
600+ var context = _fixture . GetService < AppDbContext > ( ) ;
601+ var passport = new Passport ( ) ;
602+ var person1 = _personFaker . Generate ( ) ;
603+ person1 . Passport = passport ;
604+ context . People . AddRange ( new List < Person > ( ) { person1 } ) ;
605+ await context . SaveChangesAsync ( ) ;
606+ var passportId = person1 . PassportId ;
607+ var content = new
608+ {
609+ data = new
610+ {
611+ type = "people" ,
612+ attributes = new Dictionary < string , string > ( ) { { "first-name" , "Joe" } } ,
613+ relationships = new Dictionary < string , object >
614+ {
615+ { "passport" , new
616+ {
617+ data = new { type = "passports" , id = $ "{ passportId } " }
618+ }
619+ }
620+ }
621+ }
622+ } ;
623+
624+ var httpMethod = new HttpMethod ( "POST" ) ;
625+ var route = $ "/api/v1/people";
626+ var request = new HttpRequestMessage ( httpMethod , route ) ;
627+
628+ string serializedContent = JsonConvert . SerializeObject ( content ) ;
629+ request . Content = new StringContent ( serializedContent ) ;
630+ request . Content . Headers . ContentType = new MediaTypeHeaderValue ( "application/vnd.api+json" ) ;
631+
632+ // Act
633+ var response = await _fixture . Client . SendAsync ( request ) ;
634+ var body = await response . Content . ReadAsStringAsync ( ) ;
635+ var personResult = _fixture . GetService < IJsonApiDeSerializer > ( ) . Deserialize < Person > ( body ) ;
636+
637+ // Assert
638+
639+ Assert . True ( HttpStatusCode . Created == response . StatusCode , $ "{ route } returned { response . StatusCode } status code with payload: { body } ") ;
640+ var dbPerson = context . People . AsNoTracking ( ) . Where ( p => p . Id == personResult . Id ) . Include ( "Passport" ) . FirstOrDefault ( ) ;
641+ Assert . Equal ( passportId , dbPerson . Passport . Id ) ;
642+ }
643+
644+ [ Fact ]
645+ public async Task Create_With_ToMany_Relationship_With_Implicit_Remove ( )
646+ {
647+ // Arrange
648+ var context = _fixture . GetService < AppDbContext > ( ) ;
649+ var person1 = _personFaker . Generate ( ) ;
650+ person1 . TodoItems = _todoItemFaker . Generate ( 3 ) . ToList ( ) ;
651+ context . People . AddRange ( new List < Person > ( ) { person1 } ) ;
652+ await context . SaveChangesAsync ( ) ;
653+ var todoItem1Id = person1 . TodoItems [ 0 ] . Id ;
654+ var todoItem2Id = person1 . TodoItems [ 1 ] . Id ;
655+
656+ var content = new
657+ {
658+ data = new
659+ {
660+ type = "people" ,
661+ attributes = new Dictionary < string , string > ( ) { { "first-name" , "Joe" } } ,
662+ relationships = new Dictionary < string , object >
663+ {
664+ { "todo-items" , new
665+ {
666+ data = new List < object >
667+ {
668+ new {
669+ type = "todo-items" ,
670+ id = $ "{ todoItem1Id } "
671+ } ,
672+ new {
673+ type = "todo-items" ,
674+ id = $ "{ todoItem2Id } "
675+ }
676+ }
677+ }
678+ }
679+ }
680+ }
681+ } ;
682+
683+ var httpMethod = new HttpMethod ( "POST" ) ;
684+ var route = $ "/api/v1/people";
685+ var request = new HttpRequestMessage ( httpMethod , route ) ;
686+
687+ string serializedContent = JsonConvert . SerializeObject ( content ) ;
688+ request . Content = new StringContent ( serializedContent ) ;
689+ request . Content . Headers . ContentType = new MediaTypeHeaderValue ( "application/vnd.api+json" ) ;
690+
691+ // Act
692+ var response = await _fixture . Client . SendAsync ( request ) ;
693+ var body = await response . Content . ReadAsStringAsync ( ) ;
694+ var personResult = _fixture . GetService < IJsonApiDeSerializer > ( ) . Deserialize < Person > ( body ) ;
695+
696+ // Assert
697+ Assert . True ( HttpStatusCode . Created == response . StatusCode , $ "{ route } returned { response . StatusCode } status code with payload: { body } ") ;
698+ var dbPerson = context . People . AsNoTracking ( ) . Where ( p => p . Id == personResult . Id ) . Include ( "TodoItems" ) . FirstOrDefault ( ) ;
699+ Assert . Equal ( 2 , dbPerson . TodoItems . Count ) ;
700+ Assert . NotNull ( dbPerson . TodoItems . SingleOrDefault ( ti => ti . Id == todoItem1Id ) ) ;
701+ Assert . NotNull ( dbPerson . TodoItems . SingleOrDefault ( ti => ti . Id == todoItem2Id ) ) ;
702+ }
589703 }
590704}
0 commit comments