Skip to content

Feature/#39 deserializer unit test #390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Bogus;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCoreExample;
using JsonApiDotNetCoreExample.Data;
using JsonApiDotNetCoreExample.Models;
using JsonApiDotNetCoreExampleTests.Helpers.Extensions;
using Microsoft.AspNetCore.Hosting;
using Newtonsoft.Json;
using Xunit;
Expand All @@ -22,6 +25,14 @@ public DeeplyNestedInclusionTests(TestFixture<TestStartup> fixture)
_fixture = fixture;
}

private void ResetContext(AppDbContext context)
{
context.TodoItems.RemoveRange(context.TodoItems);
context.TodoItemCollections.RemoveRange(context.TodoItemCollections);
context.People.RemoveRange(context.People);
context.PersonRoles.RemoveRange(context.PersonRoles);
}

[Fact]
public async Task Can_Include_Nested_Relationships()
{
Expand Down Expand Up @@ -53,5 +64,253 @@ public async Task Can_Include_Nested_Relationships()
Assert.NotNull(responseTodoItem.Collection);
Assert.NotNull(responseTodoItem.Collection.Owner);
}

[Fact]
public async Task Can_Include_Nested_HasMany_Relationships()
{
// arrange
const string route = "/api/v1/todo-items?include=collection.todo-items";

var todoItem = new TodoItem {
Collection = new TodoItemCollection {
Owner = new Person(),
TodoItems = new List<TodoItem> {
new TodoItem(),
new TodoItem()
}
}
};


var context = _fixture.GetService<AppDbContext>();
ResetContext(context);

context.TodoItems.Add(todoItem);
await context.SaveChangesAsync();

// act
var response = await _fixture.Client.GetAsync(route);

// assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var body = await response.Content.ReadAsStringAsync();
var documents = JsonConvert.DeserializeObject<Documents>(body);
var included = documents.Included;

Assert.Equal(4, included.Count);

Assert.Equal(3, included.CountOfType("todo-items"));
Assert.Equal(1, included.CountOfType("todo-collections"));
}

[Fact]
public async Task Can_Include_Nested_HasMany_Relationships_BelongsTo()
{
// arrange
const string route = "/api/v1/todo-items?include=collection.todo-items.owner";

var todoItem = new TodoItem {
Collection = new TodoItemCollection {
Owner = new Person(),
TodoItems = new List<TodoItem> {
new TodoItem {
Owner = new Person()
},
new TodoItem()
}
}
};

var context = _fixture.GetService<AppDbContext>();
ResetContext(context);

context.TodoItems.Add(todoItem);
await context.SaveChangesAsync();

// act
var response = await _fixture.Client.GetAsync(route);

// assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var body = await response.Content.ReadAsStringAsync();
var documents = JsonConvert.DeserializeObject<Documents>(body);
var included = documents.Included;

Assert.Equal(5, included.Count);

Assert.Equal(3, included.CountOfType("todo-items"));
Assert.Equal(1, included.CountOfType("people"));
Assert.Equal(1, included.CountOfType("todo-collections"));
}

[Fact]
public async Task Can_Include_Nested_Relationships_With_Multiple_Paths()
{
// arrange
const string route = "/api/v1/todo-items?include=collection.owner.role,collection.todo-items.owner";

var todoItem = new TodoItem {
Collection = new TodoItemCollection {
Owner = new Person {
Role = new PersonRole()
},
TodoItems = new List<TodoItem> {
new TodoItem {
Owner = new Person()
},
new TodoItem()
}
}
};

var context = _fixture.GetService<AppDbContext>();
ResetContext(context);

context.TodoItems.Add(todoItem);
await context.SaveChangesAsync();

// act
var response = await _fixture.Client.GetAsync(route);

// assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var body = await response.Content.ReadAsStringAsync();
var documents = JsonConvert.DeserializeObject<Documents>(body);
var included = documents.Included;

Assert.Equal(7, included.Count);

Assert.Equal(3, included.CountOfType("todo-items"));
Assert.Equal(2, included.CountOfType("people"));
Assert.Equal(1, included.CountOfType("person-roles"));
Assert.Equal(1, included.CountOfType("todo-collections"));
}

[Fact]
public async Task Included_Resources_Are_Correct()
{
// arrange
var role = new PersonRole();
var assignee = new Person { Role = role };
var collectionOwner = new Person();
var someOtherOwner = new Person();
var collection = new TodoItemCollection { Owner = collectionOwner };
var todoItem1 = new TodoItem { Collection = collection, Assignee = assignee };
var todoItem2 = new TodoItem { Collection = collection, Assignee = assignee };
var todoItem3 = new TodoItem { Collection = collection, Owner = someOtherOwner };
var todoItem4 = new TodoItem { Collection = collection, Owner = assignee };

var context = _fixture.GetService<AppDbContext>();
ResetContext(context);

context.TodoItems.Add(todoItem1);
context.TodoItems.Add(todoItem2);
context.TodoItems.Add(todoItem3);
context.TodoItems.Add(todoItem4);
context.PersonRoles.Add(role);
context.People.Add(assignee);
context.People.Add(collectionOwner);
context.People.Add(someOtherOwner);
context.TodoItemCollections.Add(collection);


await context.SaveChangesAsync();

string route =
"/api/v1/todo-items/" + todoItem1.Id + "?include=" +
"collection.owner," +
"assignee.role," +
"assignee.assigned-todo-items";

// act
var response = await _fixture.Client.GetAsync(route);

// assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var body = await response.Content.ReadAsStringAsync();
var documents = JsonConvert.DeserializeObject<Document>(body);
var included = documents.Included;

// 1 collection, 1 owner,
// 1 assignee, 1 assignee role,
// 2 assigned todo items (including the primary resource)
Assert.Equal(6, included.Count);

var collectionDocument = included.FindResource("todo-collections", collection.Id);
var ownerDocument = included.FindResource("people", collectionOwner.Id);
var assigneeDocument = included.FindResource("people", assignee.Id);
var roleDocument = included.FindResource("person-roles", role.Id);
var assignedTodo1 = included.FindResource("todo-items", todoItem1.Id);
var assignedTodo2 = included.FindResource("todo-items", todoItem2.Id);

Assert.NotNull(assignedTodo1);
Assert.Equal(todoItem1.Id.ToString(), assignedTodo1.Id);

Assert.NotNull(assignedTodo2);
Assert.Equal(todoItem2.Id.ToString(), assignedTodo2.Id);

Assert.NotNull(collectionDocument);
Assert.Equal(collection.Id.ToString(), collectionDocument.Id);

Assert.NotNull(ownerDocument);
Assert.Equal(collectionOwner.Id.ToString(), ownerDocument.Id);

Assert.NotNull(assigneeDocument);
Assert.Equal(assignee.Id.ToString(), assigneeDocument.Id);

Assert.NotNull(roleDocument);
Assert.Equal(role.Id.ToString(), roleDocument.Id);
}

[Fact]
public async Task Can_Include_Doubly_HasMany_Relationships()
{
// arrange
var person = new Person {
TodoItemCollections = new List<TodoItemCollection> {
new TodoItemCollection {
TodoItems = new List<TodoItem> {
new TodoItem(),
new TodoItem()
}
},
new TodoItemCollection {
TodoItems = new List<TodoItem> {
new TodoItem(),
new TodoItem(),
new TodoItem()
}
}
}
};

var context = _fixture.GetService<AppDbContext>();
ResetContext(context);

context.People.Add(person);

await context.SaveChangesAsync();

string route = "/api/v1/people/" + person.Id + "?include=todo-collections.todo-items";

// act
var response = await _fixture.Client.GetAsync(route);

// assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var body = await response.Content.ReadAsStringAsync();
var documents = JsonConvert.DeserializeObject<Document>(body);
var included = documents.Included;

Assert.Equal(7, included.Count);

Assert.Equal(5, included.CountOfType("todo-items"));
Assert.Equal(2, included.CountOfType("todo-collections"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JsonApiDotNetCore.Models;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Database = Microsoft.EntityFrameworkCore.Storage.Database;

namespace JsonApiDotNetCoreExampleTests.Helpers.Extensions
{
public static class DocumentExtensions
{
public static DocumentData FindResource<TId>(this List<DocumentData> included, string type, TId id)
{
var document = included.Where(documentData => (
documentData.Type == type
&& documentData.Id == id.ToString()
)).FirstOrDefault();

return document;
}

public static int CountOfType(this List<DocumentData> included, string type) {
return included.Where(documentData => documentData.Type == type).Count();
}
}
}
Loading