Skip to content

Commit

Permalink
feat(core): relation filtering (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
ondratra committed Sep 1, 2021
1 parent 92f9224 commit 9e0b550
Show file tree
Hide file tree
Showing 12 changed files with 786 additions and 111 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@joystream/warthog",
"version": "2.38.0",
"version": "2.39.0",
"description": "Opinionated set of tools for setting up GraphQL backed by TypeORM",
"main": "dist/index.js",
"types": "dist/types/index.d.ts",
Expand Down
132 changes: 132 additions & 0 deletions src/core/BaseService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import { Container } from 'typedi';
import { createDBConnection } from '../torm';

import { MyBase, MyBaseService } from './tests/entity/MyBase.model';
import {
Book,
BookService,
Author,
AuthorService,
Library,
LibraryService,
BookMetadata,
BookMetadataService
} from './tests/entity/Relations.model';

describe('BaseService', () => {
let connection: Connection;
Expand Down Expand Up @@ -276,4 +286,126 @@ describe('BaseService', () => {

expect(bases.length).toEqual(3);
});

describe('RelationFiltering', () => {
let bookService: BookService;
let authorService: AuthorService;
let libraryService: LibraryService;
let bookMetadataService: BookMetadataService;

let books: Book[];
let authors: Author[];
let libraries: Library[];
let bookMetadatas: BookMetadata[];

beforeAll(async () => {
bookService = Container.get('BookService');
authorService = Container.get('AuthorService');
libraryService = Container.get('LibraryService');
bookMetadataService = Container.get('BookMetadataService');
});

beforeEach(async () => {
authors = await authorService.createMany(
[{ name: 'F. Herbert' }, { name: 'J.R.R. Tolkien' }, { name: 'P.K. Dick' }].map(
(item: Partial<Author>, index) => ((item.id = 'author' + index), item)
),
'1'
);

books = await bookService.createMany(
[
{ name: 'Dune', author: authors[0], starRating: 5 },
{ name: 'The Lord of the Rings', author: authors[1], starRating: 5 },
{ name: 'Do Androids Dream of Electric Sheep?', author: authors[2], starRating: 5 },

{ name: 'Dune Messiah', author: authors[0], starRating: 4 },
{ name: 'The Hobbit', author: authors[1], starRating: 4 },
{ name: 'A Scanner Darkly', author: authors[2], starRating: 5 },

{ name: 'Children of Dune', author: authors[0], starRating: 1 },
{ name: 'The Silmarillion', author: authors[1], starRating: 3 },
{ name: 'The Minority Report', author: authors[2], starRating: 5 }
].map((item: Partial<Book>, index) => ((item.id = 'book' + index), item)),
'1'
);

libraries = await libraryService.createMany(
[
{ name: 'Berlin Library', books },
{ name: 'Prague Library', books: books.slice(0, 6) },
{ name: 'Dallas Library', books: books.slice(0, 3) }
].map((item: Partial<Library>, index) => ((item.id = 'library' + index), item)),
'1'
);

bookMetadatas = await bookMetadataService.createMany(
[
{ ISBN: 'Dummy ISBN 0', book: books[0] },
{ ISBN: 'Dummy ISBN 1', book: books[1] },
{ ISBN: 'Dummy ISBN 2', book: books[2] },
{ ISBN: 'Dummy ISBN 3', book: books[3] },
{ ISBN: 'Dummy ISBN 4', book: books[4] },
{ ISBN: 'Dummy ISBN 5', book: books[5] },
{ ISBN: 'Dummy ISBN 6', book: books[6] },
{ ISBN: 'Dummy ISBN 7', book: books[7] },
{ ISBN: 'Dummy ISBN 8', book: books[8] }
].map((item: Partial<BookMetadata>, index) => ((item.id = 'bookMetadata' + index), item)),
'1'
);
});

test('N:1', async () => {
// find all books with author's name being X
const results = await bookService.find({ author: { name: authors[0].name } });

expect(results.map(item => item.name)).toEqual([books[0].name, books[3].name, books[6].name]);
});

test('1:1', async () => {
// find all books' metadata containing ISBN X
const results1 = await bookService.find({ bookMetadata: { ISBN: bookMetadatas[1].ISBN } });

expect(results1.map(item => item.name)).toEqual([books[1].name]);

// inverse query
const results2 = await bookMetadataService.find({ book: { name: books[2].name } });

expect(results2.map(item => item.ISBN)).toEqual([bookMetadatas[2].ISBN]);
});

test('1:N', async () => {
// find authors that have written at least one book called X
const results1 = await authorService.find({ books_some: { name: books[4].name } });

expect(results1.map(item => item.name)).toEqual([authors[1].name]);

// find authors that have only written books with star rating higher than 1
const results2 = await authorService.find({ books_none: { starRating: 1 } });

expect(results2.map(item => item.name)).toEqual([authors[1].name, authors[2].name]);

// find authors that have written only 5 star rated books
const results3 = await authorService.find({ books_every: { starRating: 5 } });

expect(results3.map(item => item.name)).toEqual([authors[2].name]);
});

test('N:M', async () => {
// find all books that are present in library X
const results1 = await bookService.find({ libraries_some: { name: libraries[1].name } });

expect(results1.map(item => item.name)).toEqual(books.slice(0, 6).map(item => item.name));

// find all libraries that don't contain 1 star rated book
const results2 = await libraryService.find({ books_none: { starRating: 1 } });

expect(results2.map(item => item.name)).toEqual([libraries[1].name, libraries[2].name]);

// find all libraries that contains only 5 star rated books
const results3 = await libraryService.find({ books_every: { starRating_eq: 5 } });

expect(results3.map(item => item.name)).toEqual([libraries[2].name]);
});
});
});

0 comments on commit 9e0b550

Please sign in to comment.