import test from 'ava'; import { Error, Types } from 'mongoose'; import { UserInputError } from 'apollo-server-micro'; import { Factory } from '../../../database/factory'; import * as testUtils from '../../../test/utils'; import { RecipeCollection } from '../collection-model'; import { Recipe } from '../../recipe'; import { User } from '../../../app/user'; import { SmartRecipeCollection } from '../smart-collection-model'; import { RecipeFilterAttribute, RecipeFilterAction } from '../filters'; test.before(testUtils.setupDB); test.afterEach.always(testUtils.cleanupDB); test.after.always(testUtils.tearDownDB); // Add Filter test.serial('can add filters to a SmartCollection', async t => { const collection = await Factory.create( 'smartCollection' ); collection.addFilters([ { attribute: 'TAG', action: 'INCLUDE', value: 'tasty', }, ]); t.is(collection.filters.length, 1); t.is(collection.filters[0].attribute, 'TAG'); t.is(collection.filters[0].action, 'INCLUDE'); t.is(collection.filters[0].value, 'tasty'); }); // Remove Filter test.serial('can remove filters from a Smart Collection', async t => { const collection = await Factory.create( 'smartCollection' ); collection.addFilters([ { attribute: 'TAG', action: 'INCLUDE', value: 'tasty', }, ]); t.is(collection.filters.length, 1); const filterId = collection.filters[0].id; collection.removeFilter(filterId); t.is(collection.filters.length, 0); }); test.serial( 'should throw an error when *removing* a Filter that isnt present in the Collection', async t => { const collection = await Factory.create( 'smartCollection' ); await t.throwsAsync(async () => { return collection.removeFilter(Types.ObjectId); }, Error.ValidatorError); } ); // Update Filter test.serial('can update the order of Filter within a Collection', async t => { const collection = await Factory.create( 'smartCollection', {}, { filterCount: 4 } ); if (collection.filters.length !== 4) { t.fail('didnt initialize collection correctly'); } const filterId = collection.filters[0].id; collection.updateFilter({ id: filterId, value: 'test' }, { order: 3 }); t.is(collection.filters[3].id, filterId); t.is(collection.filters[3].value, 'test'); }); test.serial( 'should throw an error when *updating* a Filter that isnt present in the Collection', async t => { const collection = await Factory.create( 'smartCollection', {}, { filterCount: 4 } ); if (collection.filters.length !== 4) { t.fail('didnt initialize collection correctly'); } await t.throwsAsync(async () => { return collection.updateFilter(Types.ObjectId, { order: 0 }); }, Error.ValidatorError); } ); // Get Recipes test.serial('returns correct recipes from getRecipes', async t => { const user = await Factory.create('user'); // this recipe should be part of the collection const recipe = await Factory.create('recipe', { ownerId: user.id, tags: ['test'], }); // this recipe should not be part of the collection const recipe2 = await Factory.create('recipe', { ownerId: user.id, tags: [], }); const collection = await Factory.create( 'smartCollection', { ownerId: user.id } ); await collection.addFilters([ { attribute: RecipeFilterAttribute.TAG, action: RecipeFilterAction.INCLUDE, value: 'test', }, ]); const recipes = await collection.getRecipes(); t.is(recipes.length, 1); t.is(recipes[0].id, recipe.id); }); test.serial( 'returns empty array from getRecipes when there are no filters', async t => { const collection = await Factory.create( 'smartCollection', {}, { recipeCount: 4 } ); const recipes = await collection.getRecipes(); t.is(recipes.length, 0); } );