@@ -447,37 +447,176 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
447
447
448
448
responseDocument . Data . SingleValue . Should ( ) . NotBeNull ( ) ;
449
449
responseDocument . Data . SingleValue . Id . Should ( ) . Be ( blog . StringId ) ;
450
- responseDocument . Data . SingleValue . Attributes [ "title" ] . Should ( ) . Be ( blog . Title ) ;
450
+ responseDocument . Data . SingleValue . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
451
+ responseDocument . Data . SingleValue . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . StringId ) ;
451
452
452
453
responseDocument . Included . Should ( ) . HaveCount ( 7 ) ;
453
454
454
455
responseDocument . Included [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
455
456
responseDocument . Included [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . StringId ) ;
456
- responseDocument . Included [ 0 ] . Attributes [ "caption" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Caption ) ;
457
+ responseDocument . Included [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
458
+ responseDocument . Included [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . StringId ) ;
459
+ responseDocument . Included [ 0 ] . Relationships [ "comments" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "comments" ) ;
460
+ responseDocument . Included [ 0 ] . Relationships [ "comments" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . StringId ) ;
457
461
458
462
responseDocument . Included [ 1 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
459
463
responseDocument . Included [ 1 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . StringId ) ;
460
- responseDocument . Included [ 1 ] . Attributes [ "userName" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Author . UserName ) ;
464
+ responseDocument . Included [ 1 ] . Relationships [ "preferences" ] . Data . SingleValue . Type . Should ( ) . Be ( "accountPreferences" ) ;
465
+ responseDocument . Included [ 1 ] . Relationships [ "preferences" ] . Data . SingleValue . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . Preferences . StringId ) ;
466
+ responseDocument . Included [ 1 ] . Relationships [ "posts" ] . Data . Value . Should ( ) . BeNull ( ) ;
461
467
462
468
responseDocument . Included [ 2 ] . Type . Should ( ) . Be ( "accountPreferences" ) ;
463
469
responseDocument . Included [ 2 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . Preferences . StringId ) ;
464
- responseDocument . Included [ 2 ] . Attributes [ "useDarkTheme" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Author . Preferences . UseDarkTheme ) ;
465
470
466
471
responseDocument . Included [ 3 ] . Type . Should ( ) . Be ( "comments" ) ;
467
472
responseDocument . Included [ 3 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . StringId ) ;
468
- responseDocument . Included [ 3 ] . Attributes [ "text" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Text ) ;
473
+ responseDocument . Included [ 3 ] . Relationships [ "author" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
474
+ responseDocument . Included [ 3 ] . Relationships [ "author" ] . Data . SingleValue . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . StringId ) ;
469
475
470
476
responseDocument . Included [ 4 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
471
477
responseDocument . Included [ 4 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . StringId ) ;
472
- responseDocument . Included [ 4 ] . Attributes [ "userName" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . UserName ) ;
478
+ responseDocument . Included [ 4 ] . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
479
+ responseDocument . Included [ 4 ] . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . Posts [ 0 ] . StringId ) ;
480
+ responseDocument . Included [ 4 ] . Relationships [ "preferences" ] . Data . Value . Should ( ) . BeNull ( ) ;
473
481
474
482
responseDocument . Included [ 5 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
475
483
responseDocument . Included [ 5 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . Posts [ 0 ] . StringId ) ;
476
- responseDocument . Included [ 5 ] . Attributes [ "caption" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 0 ) . Author . Posts [ 0 ] . Caption ) ;
484
+ responseDocument . Included [ 5 ] . Relationships [ "author" ] . Data . Value . Should ( ) . BeNull ( ) ;
485
+ responseDocument . Included [ 5 ] . Relationships [ "comments" ] . Data . Value . Should ( ) . BeNull ( ) ;
477
486
478
487
responseDocument . Included [ 6 ] . Type . Should ( ) . Be ( "comments" ) ;
479
488
responseDocument . Included [ 6 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 1 ) . StringId ) ;
480
- responseDocument . Included [ 6 ] . Attributes [ "text" ] . Should ( ) . Be ( blog . Posts [ 0 ] . Comments . ElementAt ( 1 ) . Text ) ;
489
+ responseDocument . Included [ 5 ] . Relationships [ "author" ] . Data . Value . Should ( ) . BeNull ( ) ;
490
+ }
491
+
492
+ [ Fact ]
493
+ public async Task Can_include_chain_of_relationships_with_reused_resources ( )
494
+ {
495
+ WebAccount author = _fakers . WebAccount . Generate ( ) ;
496
+ author . Preferences = _fakers . AccountPreferences . Generate ( ) ;
497
+ author . LoginAttempts = _fakers . LoginAttempt . Generate ( 1 ) ;
498
+
499
+ WebAccount reviewer = _fakers . WebAccount . Generate ( ) ;
500
+ reviewer . Preferences = _fakers . AccountPreferences . Generate ( ) ;
501
+ reviewer . LoginAttempts = _fakers . LoginAttempt . Generate ( 1 ) ;
502
+
503
+ BlogPost post1 = _fakers . BlogPost . Generate ( ) ;
504
+ post1 . Author = author ;
505
+ post1 . Reviewer = reviewer ;
506
+
507
+ WebAccount person = _fakers . WebAccount . Generate ( ) ;
508
+ person . Preferences = _fakers . AccountPreferences . Generate ( ) ;
509
+ person . LoginAttempts = _fakers . LoginAttempt . Generate ( 1 ) ;
510
+
511
+ BlogPost post2 = _fakers . BlogPost . Generate ( ) ;
512
+ post2 . Author = person ;
513
+ post2 . Reviewer = person ;
514
+
515
+ await _testContext . RunOnDatabaseAsync ( async dbContext =>
516
+ {
517
+ await dbContext . ClearTableAsync < BlogPost > ( ) ;
518
+ dbContext . Posts . AddRange ( post1 , post2 ) ;
519
+ await dbContext . SaveChangesAsync ( ) ;
520
+ } ) ;
521
+
522
+ const string route = "/blogPosts?include=reviewer.loginAttempts,author.preferences" ;
523
+
524
+ // Act
525
+ ( HttpResponseMessage httpResponse , Document responseDocument ) = await _testContext . ExecuteGetAsync < Document > ( route ) ;
526
+
527
+ // Assert
528
+ httpResponse . Should ( ) . HaveStatusCode ( HttpStatusCode . OK ) ;
529
+
530
+ responseDocument . Data . ManyValue . Should ( ) . HaveCount ( 2 ) ;
531
+
532
+ responseDocument . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
533
+ responseDocument . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( post1 . StringId ) ;
534
+ responseDocument . Data . ManyValue [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
535
+ responseDocument . Data . ManyValue [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Id . Should ( ) . Be ( author . StringId ) ;
536
+ responseDocument . Data . ManyValue [ 0 ] . Relationships [ "reviewer" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
537
+ responseDocument . Data . ManyValue [ 0 ] . Relationships [ "reviewer" ] . Data . SingleValue . Id . Should ( ) . Be ( reviewer . StringId ) ;
538
+
539
+ responseDocument . Data . ManyValue [ 1 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
540
+ responseDocument . Data . ManyValue [ 1 ] . Id . Should ( ) . Be ( post2 . StringId ) ;
541
+ responseDocument . Data . ManyValue [ 1 ] . Relationships [ "author" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
542
+ responseDocument . Data . ManyValue [ 1 ] . Relationships [ "author" ] . Data . SingleValue . Id . Should ( ) . Be ( person . StringId ) ;
543
+ responseDocument . Data . ManyValue [ 1 ] . Relationships [ "reviewer" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
544
+ responseDocument . Data . ManyValue [ 1 ] . Relationships [ "reviewer" ] . Data . SingleValue . Id . Should ( ) . Be ( person . StringId ) ;
545
+
546
+ responseDocument . Included . Should ( ) . HaveCount ( 7 ) ;
547
+
548
+ responseDocument . Included [ 0 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
549
+ responseDocument . Included [ 0 ] . Id . Should ( ) . Be ( author . StringId ) ;
550
+ responseDocument . Included [ 0 ] . Relationships [ "preferences" ] . Data . SingleValue . Type . Should ( ) . Be ( "accountPreferences" ) ;
551
+ responseDocument . Included [ 0 ] . Relationships [ "preferences" ] . Data . SingleValue . Id . Should ( ) . Be ( author . Preferences . StringId ) ;
552
+ responseDocument . Included [ 0 ] . Relationships [ "loginAttempts" ] . Data . Value . Should ( ) . BeNull ( ) ;
553
+
554
+ responseDocument . Included [ 1 ] . Type . Should ( ) . Be ( "accountPreferences" ) ;
555
+ responseDocument . Included [ 1 ] . Id . Should ( ) . Be ( author . Preferences . StringId ) ;
556
+
557
+ responseDocument . Included [ 2 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
558
+ responseDocument . Included [ 2 ] . Id . Should ( ) . Be ( reviewer . StringId ) ;
559
+ responseDocument . Included [ 2 ] . Relationships [ "preferences" ] . Data . Value . Should ( ) . BeNull ( ) ;
560
+ responseDocument . Included [ 2 ] . Relationships [ "loginAttempts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "loginAttempts" ) ;
561
+ responseDocument . Included [ 2 ] . Relationships [ "loginAttempts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( reviewer . LoginAttempts [ 0 ] . StringId ) ;
562
+
563
+ responseDocument . Included [ 3 ] . Type . Should ( ) . Be ( "loginAttempts" ) ;
564
+ responseDocument . Included [ 3 ] . Id . Should ( ) . Be ( reviewer . LoginAttempts [ 0 ] . StringId ) ;
565
+
566
+ responseDocument . Included [ 4 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
567
+ responseDocument . Included [ 4 ] . Id . Should ( ) . Be ( person . StringId ) ;
568
+ responseDocument . Included [ 4 ] . Relationships [ "preferences" ] . Data . SingleValue . Type . Should ( ) . Be ( "accountPreferences" ) ;
569
+ responseDocument . Included [ 4 ] . Relationships [ "preferences" ] . Data . SingleValue . Id . Should ( ) . Be ( person . Preferences . StringId ) ;
570
+ responseDocument . Included [ 4 ] . Relationships [ "loginAttempts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "loginAttempts" ) ;
571
+ responseDocument . Included [ 4 ] . Relationships [ "loginAttempts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( person . LoginAttempts [ 0 ] . StringId ) ;
572
+
573
+ responseDocument . Included [ 5 ] . Type . Should ( ) . Be ( "accountPreferences" ) ;
574
+ responseDocument . Included [ 5 ] . Id . Should ( ) . Be ( person . Preferences . StringId ) ;
575
+
576
+ responseDocument . Included [ 6 ] . Type . Should ( ) . Be ( "loginAttempts" ) ;
577
+ responseDocument . Included [ 6 ] . Id . Should ( ) . Be ( person . LoginAttempts [ 0 ] . StringId ) ;
578
+ }
579
+
580
+ [ Fact ]
581
+ public async Task Can_include_chain_with_cyclic_dependency ( )
582
+ {
583
+ List < BlogPost > posts = _fakers . BlogPost . Generate ( 1 ) ;
584
+
585
+ Blog blog = _fakers . Blog . Generate ( ) ;
586
+ blog . Posts = posts ;
587
+ blog . Posts [ 0 ] . Author = _fakers . WebAccount . Generate ( ) ;
588
+ blog . Posts [ 0 ] . Author . Posts = posts ;
589
+
590
+ await _testContext . RunOnDatabaseAsync ( async dbContext =>
591
+ {
592
+ dbContext . Blogs . Add ( blog ) ;
593
+ await dbContext . SaveChangesAsync ( ) ;
594
+ } ) ;
595
+
596
+ string route = $ "/blogs/{ blog . StringId } ?include=posts.author.posts.author.posts.author";
597
+
598
+ // Act
599
+ ( HttpResponseMessage httpResponse , Document responseDocument ) = await _testContext . ExecuteGetAsync < Document > ( route ) ;
600
+
601
+ // Assert
602
+ httpResponse . Should ( ) . HaveStatusCode ( HttpStatusCode . OK ) ;
603
+
604
+ responseDocument . Data . SingleValue . Type . Should ( ) . Be ( "blogs" ) ;
605
+ responseDocument . Data . SingleValue . Id . Should ( ) . Be ( blog . StringId ) ;
606
+ responseDocument . Data . SingleValue . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
607
+ responseDocument . Data . SingleValue . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . StringId ) ;
608
+
609
+ responseDocument . Included . Should ( ) . HaveCount ( 2 ) ;
610
+
611
+ responseDocument . Included [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
612
+ responseDocument . Included [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . StringId ) ;
613
+ responseDocument . Included [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Type . Should ( ) . Be ( "webAccounts" ) ;
614
+ responseDocument . Included [ 0 ] . Relationships [ "author" ] . Data . SingleValue . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . StringId ) ;
615
+
616
+ responseDocument . Included [ 1 ] . Type . Should ( ) . Be ( "webAccounts" ) ;
617
+ responseDocument . Included [ 1 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . Author . StringId ) ;
618
+ responseDocument . Included [ 1 ] . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Type . Should ( ) . Be ( "blogPosts" ) ;
619
+ responseDocument . Included [ 1 ] . Relationships [ "posts" ] . Data . ManyValue [ 0 ] . Id . Should ( ) . Be ( blog . Posts [ 0 ] . StringId ) ;
481
620
}
482
621
483
622
[ Fact ]
0 commit comments