import ava, { TestInterface } from 'ava'; import { Mongoose } from 'mongoose'; import { ForbiddenError, UserInputError } from 'apollo-server-micro'; import { Factory } from '../../../database/factory'; import * as testUtils from '../../../test/utils'; import { User } from '../../user'; import { Recipe } from '../../recipe'; import { createContext } from '../../../test/utils/create-mock-context'; import { gqlCall } from '../../../test/utils/gqlCall'; import { defineUserAbility } from '../../../server/authorization/user-authorization'; import { isIngredientGroup } from '../utils'; // // Setup // const test = ava as TestInterface<{ db: Mongoose }>; test.before(async t => { await testUtils.setupDB(t); }); test.afterEach.always(async t => { await testUtils.cleanupDB(t); }); test.after.always(async t => { await testUtils.tearDownDB(t); }); // ** Constants const removeIngredientGroupMutation = ` mutation RemoveIngredientGroup($input: RemoveIngredientGroupInput!) { removeIngredientGroup(input: $input) { id heading } } `; // // Tests // test.serial('Should property delete and return an IngredientGroup', async t => { const user = await Factory.create('user'); const recipe = await Factory.create( 'recipe', { ownerId: user.id }, { ingredientCount: 0, ingredientGroupCount: 1 } ); const ingredientGroup = recipe.ingredientList.nodes[0]; const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); let ingredientCount = recipe.ingredientList.nodes.length; t.is(ingredientCount, 1); const response = await gqlCall({ source: removeIngredientGroupMutation, contextValue: context, variableValues: { input: { recipeId: recipe.id, groupId: ingredientGroup.id, }, }, }); // Properly returned the removed IngredientGroup t.falsy(response.errors); if (isIngredientGroup(ingredientGroup)) { t.is(response.data.removeIngredientGroup.id, ingredientGroup.id); } else { t.fail('got a single ingredient :('); } // IngrdientGroup was removed from recipe doc ingredientCount = await Recipe.findById(recipe.id).then(r => { return r.ingredientList.nodes.length; }); t.is(ingredientCount, 0); }); test.serial( 'Should thrown an error if you try and delete a single Ingredient item', async t => { const user = await Factory.create('user'); const recipe = await Factory.create( 'recipe', { ownerId: user.id }, { ingredientCount: 1 } ); const ingredient = recipe.ingredientList.nodes[0]; const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const response = await gqlCall({ source: removeIngredientGroupMutation, contextValue: context, variableValues: { input: { recipeId: recipe.id, groupId: ingredient.id, }, }, }); // IngrdientGroup was removed from recipe doc // Should retrun forbidden error t.truthy(response.errors.length > 0); t.true(response.errors[0].originalError instanceof UserInputError); } ); test.serial( 'Should return an error if you dont have permission to edit the recipe', async t => { const user = await Factory.create('user'); const recipe = await Factory.create('recipe'); const context = createContext({ state: { user, abilities: defineUserAbility(user) }, }); const response = await gqlCall({ source: removeIngredientGroupMutation, contextValue: context, variableValues: { input: { recipeId: recipe.id, groupId: recipe.ingredientList.nodes[0].id, }, }, }); // Should retrun forbidden error t.truthy(response.errors.length > 0); t.true(response.errors[0].originalError instanceof ForbiddenError); } );