@@ -532,17 +532,186 @@ public void Sets_Attribute_Values_On_Included_HasOne_Relationships()
532532 Assert . Equal ( expectedName , result . Independent . Name ) ;
533533 }
534534
535+
536+ [ Fact ]
537+ public void Can_Deserialize_Nested_Included_HasMany_Relationships ( )
538+ {
539+ // arrange
540+ var contextGraphBuilder = new ContextGraphBuilder ( ) ;
541+ contextGraphBuilder . AddResource < OneToManyIndependent > ( "independents" ) ;
542+ contextGraphBuilder . AddResource < OneToManyDependent > ( "dependents" ) ;
543+ contextGraphBuilder . AddResource < ManyToManyNested > ( "many-to-manys" ) ;
544+
545+ var deserializer = GetDeserializer ( contextGraphBuilder ) ;
546+
547+ var contentString =
548+ @"{
549+ ""data"": {
550+ ""type"": ""independents"",
551+ ""id"": ""1"",
552+ ""attributes"": { },
553+ ""relationships"": {
554+ ""many-to-manys"": {
555+ ""data"": [{
556+ ""type"": ""many-to-manys"",
557+ ""id"": ""2""
558+ }, {
559+ ""type"": ""many-to-manys"",
560+ ""id"": ""3""
561+ }]
562+ }
563+ }
564+ },
565+ ""included"": [
566+ {
567+ ""type"": ""many-to-manys"",
568+ ""id"": ""2"",
569+ ""attributes"": {},
570+ ""relationships"": {
571+ ""dependent"": {
572+ ""data"": {
573+ ""type"": ""dependents"",
574+ ""id"": ""4""
575+ }
576+ },
577+ ""independent"": {
578+ ""data"": {
579+ ""type"": ""independents"",
580+ ""id"": ""5""
581+ }
582+ }
583+ }
584+ },
585+ {
586+ ""type"": ""many-to-manys"",
587+ ""id"": ""3"",
588+ ""attributes"": {},
589+ ""relationships"": {
590+ ""dependent"": {
591+ ""data"": {
592+ ""type"": ""dependents"",
593+ ""id"": ""4""
594+ }
595+ },
596+ ""independent"": {
597+ ""data"": {
598+ ""type"": ""independents"",
599+ ""id"": ""6""
600+ }
601+ }
602+ }
603+ },
604+ {
605+ ""type"": ""dependents"",
606+ ""id"": ""4"",
607+ ""attributes"": {},
608+ ""relationships"": {
609+ ""many-to-manys"": {
610+ ""data"": [{
611+ ""type"": ""many-to-manys"",
612+ ""id"": ""2""
613+ }, {
614+ ""type"": ""many-to-manys"",
615+ ""id"": ""3""
616+ }]
617+ }
618+ }
619+ }
620+ ,
621+ {
622+ ""type"": ""independents"",
623+ ""id"": ""5"",
624+ ""attributes"": {},
625+ ""relationships"": {
626+ ""many-to-manys"": {
627+ ""data"": [{
628+ ""type"": ""many-to-manys"",
629+ ""id"": ""2""
630+ }]
631+ }
632+ }
633+ }
634+ ,
635+ {
636+ ""type"": ""independents"",
637+ ""id"": ""6"",
638+ ""attributes"": {},
639+ ""relationships"": {
640+ ""many-to-manys"": {
641+ ""data"": [{
642+ ""type"": ""many-to-manys"",
643+ ""id"": ""3""
644+ }]
645+ }
646+ }
647+ }
648+ ]
649+ }" ;
650+
651+ // act
652+ var result = deserializer . Deserialize < OneToManyIndependent > ( contentString ) ;
653+
654+ // assert
655+ Assert . NotNull ( result ) ;
656+ Assert . Equal ( 1 , result . Id ) ;
657+ Assert . NotNull ( result . ManyToManys ) ;
658+ Assert . Equal ( 2 , result . ManyToManys . Count ) ;
659+
660+ // TODO: not sure if this should be a thing that works?
661+ // could this cause cycles in the graph?
662+ // Assert.NotNull(result.ManyToManys[0].Dependent);
663+ // Assert.NotNull(result.ManyToManys[0].Independent);
664+ // Assert.NotNull(result.ManyToManys[1].Dependent);
665+ // Assert.NotNull(result.ManyToManys[1].Independent);
666+
667+ // Assert.Equal(result.ManyToManys[0].Dependent, result.ManyToManys[1].Dependent);
668+ // Assert.NotEqual(result.ManyToManys[0].Independent, result.ManyToManys[1].Independent);
669+ }
670+
671+ private JsonApiDeSerializer GetDeserializer ( ContextGraphBuilder contextGraphBuilder )
672+ {
673+ var contextGraph = contextGraphBuilder . Build ( ) ;
674+
675+ var jsonApiContextMock = new Mock < IJsonApiContext > ( ) ;
676+ jsonApiContextMock . SetupAllProperties ( ) ;
677+ jsonApiContextMock . Setup ( m => m . ContextGraph ) . Returns ( contextGraph ) ;
678+ jsonApiContextMock . Setup ( m => m . AttributesToUpdate ) . Returns ( new Dictionary < AttrAttribute , object > ( ) ) ;
679+ jsonApiContextMock . Setup ( m => m . RelationshipsToUpdate ) . Returns ( new Dictionary < RelationshipAttribute , object > ( ) ) ;
680+ jsonApiContextMock . Setup ( m => m . HasManyRelationshipPointers ) . Returns ( new HasManyRelationshipPointers ( ) ) ;
681+ jsonApiContextMock . Setup ( m => m . HasOneRelationshipPointers ) . Returns ( new HasOneRelationshipPointers ( ) ) ;
682+
683+ var jsonApiOptions = new JsonApiOptions ( ) ;
684+ jsonApiContextMock . Setup ( m => m . Options ) . Returns ( jsonApiOptions ) ;
685+
686+ var deserializer = new JsonApiDeSerializer ( jsonApiContextMock . Object ) ;
687+
688+ return deserializer ;
689+ }
690+
691+ private class ManyToManyNested : Identifiable
692+ {
693+ [ Attr ( "name" ) ] public string Name { get ; set ; }
694+ [ HasOne ( "dependent" ) ] public OneToManyDependent Dependent { get ; set ; }
695+ public int DependentId { get ; set ; }
696+ [ HasOne ( "independent" ) ] public OneToManyIndependent Independent { get ; set ; }
697+ public int InependentId { get ; set ; }
698+ }
699+
535700 private class OneToManyDependent : Identifiable
536701 {
537702 [ Attr ( "name" ) ] public string Name { get ; set ; }
538703 [ HasOne ( "independent" ) ] public OneToManyIndependent Independent { get ; set ; }
539704 public int IndependentId { get ; set ; }
705+
706+ [ HasMany ( "many-to-manys" ) ] public List < ManyToManyNested > ManyToManys { get ; set ; }
540707 }
541708
542709 private class OneToManyIndependent : Identifiable
543710 {
544711 [ Attr ( "name" ) ] public string Name { get ; set ; }
545712 [ HasMany ( "dependents" ) ] public List < OneToManyDependent > Dependents { get ; set ; }
713+
714+ [ HasMany ( "many-to-manys" ) ] public List < ManyToManyNested > ManyToManys { get ; set ; }
546715 }
547716 }
548717}
0 commit comments