Skip to content

Commit

Permalink
Merge pull request #213 from annervisser/included-parsing-bug
Browse files Browse the repository at this point in the history
Bug including resource in multiple resources
  • Loading branch information
safo6m authored Jul 18, 2019
2 parents a3ef88a + a7b54fd commit 20a7790
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/models/json-api.model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ describe('JsonApiModel', () => {

});

it('should parse relationships included in more than one resource', () => {
const BOOK_NUMBER = 4;
const REL = 'books.category.books';
const DATA = getAuthorData(REL, BOOK_NUMBER);
author = new Author(datastore, DATA);
author.syncRelationships(DATA, getIncludedBooks(BOOK_NUMBER, REL));
author.books.forEach((book: Book) => {
expect(book.category).toBeDefined();
expect(book.category.books.length).toBe(BOOK_NUMBER);
});
});

it('should return the parsed relationships when two nested ones are included', () => {
const REL = 'books,books.chapters';
const BOOK_NUMBER = 2;
Expand Down
18 changes: 11 additions & 7 deletions src/models/json-api.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class JsonApiModel {
if (data) {
let modelsForProcessing = remainingModels;

if (!modelsForProcessing) {
if (modelsForProcessing === undefined) {
modelsForProcessing = [].concat(included);
}

Expand Down Expand Up @@ -202,16 +202,18 @@ export class JsonApiModel {
const relationshipList: Array<T> = [];

data.forEach((item: any) => {
const relationshipData: any = find(remainingModels, { id: item.id, type: typeName } as any);
const relationshipData: any = find(included, { id: item.id, type: typeName } as any);

if (relationshipData) {
const newObject: T = this.createOrPeek(modelType, relationshipData);

const indexOfNewlyFoundModel = remainingModels.indexOf(relationshipData);
const modelsForProcessing = remainingModels.concat([]);
modelsForProcessing.splice(indexOfNewlyFoundModel, 1);

newObject.syncRelationships(relationshipData, included, modelsForProcessing);
if (indexOfNewlyFoundModel !== -1) {
modelsForProcessing.splice(indexOfNewlyFoundModel, 1);
newObject.syncRelationships(relationshipData, included, modelsForProcessing);
}

relationshipList.push(newObject);
}
Expand All @@ -229,16 +231,18 @@ export class JsonApiModel {
): T | null {
const id: string = data.id;

const relationshipData: any = find(remainingModels, { id, type: typeName } as any);
const relationshipData: any = find(included, { id, type: typeName } as any);

if (relationshipData) {
const newObject: T = this.createOrPeek(modelType, relationshipData);

const indexOfNewlyFoundModel = remainingModels.indexOf(relationshipData);
const modelsForProcessing = remainingModels.concat([]);
modelsForProcessing.splice(indexOfNewlyFoundModel, 1);

newObject.syncRelationships(relationshipData, included, modelsForProcessing);
if (indexOfNewlyFoundModel !== -1) {
modelsForProcessing.splice(indexOfNewlyFoundModel, 1);
newObject.syncRelationships(relationshipData, included, modelsForProcessing);
}

return newObject;
}
Expand Down
2 changes: 2 additions & 0 deletions test/datastore.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Chapter } from './models/chapter.model';
import { Section } from './models/section.model';
import { Paragraph } from './models/paragraph.model';
import { Sentence } from './models/sentence.model';
import { Category } from './models/category.model';

export const BASE_URL = 'http://localhost:8080';
export const API_VERSION = 'v1';
Expand All @@ -18,6 +19,7 @@ export const API_VERSION = 'v1';
authors: Author,
books: Book,
chapters: Chapter,
categories: Category,
paragraphs: Paragraph,
sections: Section,
sentences: Sentence,
Expand Down
22 changes: 21 additions & 1 deletion test/fixtures/author.fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getSampleChapter } from './chapter.fixture';
import { getSampleSection } from './section.fixture';
import { getSampleParagraph } from './paragraph.fixture';
import { getSampleSentence } from './sentence.fixture';
import { getSampleCategory } from './category.fixture';

export const AUTHOR_ID = '1';
export const AUTHOR_NAME = 'J. R. R. Tolkien';
Expand All @@ -14,6 +15,8 @@ export const AUTHOR_UPDATED = '2016-09-26T21:12:45Z';
export const BOOK_TITLE = 'The Fellowship of the Ring';
export const BOOK_PUBLISHED = '1954-07-29';

export const CATEGORY_ID = '1';

export const CHAPTER_TITLE = 'The Return Journey';

export function getAuthorData(relationship?: string, total: number = 0): any {
Expand Down Expand Up @@ -59,7 +62,7 @@ export function getIncludedBooks(totalBooks: number, relationship?: string, tota
let chapterId = 0;

for (let i = 1; i <= totalBooks; i++) {
const book: any = getSampleBook(i, AUTHOR_ID);
const book: any = getSampleBook(i, AUTHOR_ID, CATEGORY_ID);
responseArray.push(book);

if (relationship && relationship.indexOf('books.chapters') !== -1) {
Expand All @@ -77,6 +80,23 @@ export function getIncludedBooks(totalBooks: number, relationship?: string, tota
}
}

if (relationship && relationship.indexOf('books.category') !== -1) {
let categoryInclude = responseArray.find((category) => {
return category.type === 'categories' && category.id === CATEGORY_ID;
});

if (!categoryInclude) {
categoryInclude = getSampleCategory(CATEGORY_ID);
categoryInclude.relationships.books = { data: [] };
responseArray.push(categoryInclude);
}

categoryInclude.relationships.books.data.push({
id: `${i}`,
type: 'books'
});
}

if (relationship && relationship.indexOf('books.firstChapter') !== -1) {
const firstChapterId = '1';

Expand Down
12 changes: 11 additions & 1 deletion test/fixtures/book.fixture.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BOOK_PUBLISHED, BOOK_TITLE } from './author.fixture';

export function getSampleBook(i: number, authorId: string) {
export function getSampleBook(i: number, authorId: string, categoryId: string = '1') {
return {
id: '' + i,
type: 'books',
Expand Down Expand Up @@ -32,6 +32,16 @@ export function getSampleBook(i: number, authorId: string) {
id: authorId,
type: 'authors'
}
},
category: {
links: {
self: '/v1/books/1/relationships/category',
related: '/v1/books/1/category'
},
data: {
id: categoryId,
type: 'categories'
}
}
},
links: {
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/category.fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function getSampleCategory(categoryId: string) {
return {
id: '' + categoryId,
type: 'categories',
attributes: {
name: 'Category_fiction',
created_at: '2018-04-02T21:12:41Z',
updated_at: '2016-04-02T21:12:41Z'
},
relationships: {
},
links: {
self: '/v1/categories/1'
}
};
}
4 changes: 4 additions & 0 deletions test/models/book.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Chapter } from './chapter.model';
import { Author } from './author.model';
import { Category } from './category.model';
import { JsonApiModelConfig } from '../../src/decorators/json-api-model-config.decorator';
import { JsonApiModel } from '../../src/models/json-api.model';
import { Attribute } from '../../src/decorators/attribute.decorator';
Expand Down Expand Up @@ -34,4 +35,7 @@ export class Book extends JsonApiModel {

@BelongsTo()
author: Author;

@BelongsTo()
category: Category;
}
23 changes: 23 additions & 0 deletions test/models/category.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Book } from './book.model';
import { JsonApiModelConfig } from '../../src/decorators/json-api-model-config.decorator';
import { JsonApiModel } from '../../src/models/json-api.model';
import { Attribute } from '../../src/decorators/attribute.decorator';
import { HasMany } from '../../src/decorators/has-many.decorator';

@JsonApiModelConfig({
type: 'categories'
})
export class Category extends JsonApiModel {

@Attribute()
name: string;

@Attribute()
created_at: Date;

@Attribute()
updated_at: Date;

@HasMany()
books: Book[];
}

0 comments on commit 20a7790

Please sign in to comment.