import test from 'ava'; import { AuthenticationError, UserInputError } from 'apollo-server-micro'; import { Factory } from '../../../database/factory'; import * as testUtils from '../../../test/utils'; import { createContext } from '../../../test/utils/create-mock-context'; import { defineUserAbility } from '../../../server/authorization/user-authorization'; import { RecipeCollection } from '../collection-model'; import { Recipe } from '../../recipe'; import { User } from '../../../app/user'; import { addFiltersToCollection } from '../schema/add-filters'; import { SmartRecipeCollection } from '../smart-collection-model'; test.before(testUtils.setupDB); test.afterEach.always(testUtils.cleanupDB); test.after.always(testUtils.tearDownDB); // // Tests // test.serial('Should return a RecipeCollection with added Filters', async t => { const user = await Factory.create('user'); const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const collection = await Factory.create( 'smartCollection', {}, { user } ); const recipe = await Factory.create('recipe', { ownerId: user.id, }); const updatedCollection = await addFiltersToCollection( null, { input: { recipeCollectionId: collection.id, filters: [ { attribute: 'TAG', action: 'INCLUDE', value: 'tasty', }, ], }, }, context, null ); t.is(updatedCollection.filters[0].value, 'tasty'); }); test.serial( 'Should return collection with updated recipes when filters are added', async t => { const user = await Factory.create('user'); const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const collection = await Factory.create( 'smartCollection', {}, { user } ); const recipe = await Factory.create('recipe', { ownerId: user.id, }); const updatedCollection = await addFiltersToCollection( null, { input: { recipeCollectionId: collection.id, filters: [ { attribute: 'TAG', action: 'INCLUDE', value: 'tasty', }, ], }, }, context, null ); const recipes = await updatedCollection.getRecipes(); t.is(recipes.length, 1); } ); test.serial( 'Should thow an error when an invalid filter is provided', async t => { const user = await Factory.create('user'); const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const collection = await Factory.create( 'smartCollection', {}, { user } ); await t.throwsAsync(async () => { return addFiltersToCollection( null, { input: { recipeCollectionId: collection.id, filters: [ { attribute: 'TAG', action: 'EQUAL', value: 'fun' }, { attribute: 'WRONG', action: 'EQUAL', value: 'sad' }, ], }, }, context, null ); }, UserInputError); const updatedCollection = await SmartRecipeCollection.findById( collection.id ); // no filters should have been added t.is(updatedCollection.filters.length, 0); } ); test.serial( 'Should not add a filter when the collection does not belong to the user', async t => { const user = await Factory.create('user'); const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const collection = await Factory.create( 'smartCollection', {} ); await t.throwsAsync(async () => { return addFiltersToCollection( null, { input: { recipeCollectionId: collection.id, filters: [{ attribute: 'TAG', action: 'EQUAL', value: 'tasty' }], }, }, context, null ); }, AuthenticationError); } ); test.serial( 'Should return an error when the user is not logged in', async t => { const context = createContext({ state: { user: null, abilities: defineUserAbility(null) }, }); await t.throwsAsync(async () => { return addFiltersToCollection( null, { input: { recipeCollectionId: '', filters: [], }, }, context, null ); }, AuthenticationError); } );