From e7f16782910548aae1830b1606202d15a451fc43 Mon Sep 17 00:00:00 2001 From: trojanh Date: Fri, 13 Dec 2019 19:27:53 +0530 Subject: [PATCH 1/2] test: add navigation tree update integration test Signed-off-by: trojanh --- .../mutations/updateNavigationTree.js | 12 +- .../UpdateNavigationTreeMutation.graphql | 23 ++++ .../updateNavigationTree.test.js.snap | 28 +++++ .../updateNavigationTree.test.js | 117 ++++++++++++++++++ tests/util/factory.js | 9 ++ 5 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 tests/integration/api/mutations/navigationTree/UpdateNavigationTreeMutation.graphql create mode 100644 tests/integration/api/mutations/navigationTree/__snapshots__/updateNavigationTree.test.js.snap create mode 100644 tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js diff --git a/src/plugins/navigation/mutations/updateNavigationTree.js b/src/plugins/navigation/mutations/updateNavigationTree.js index 16a01287d5b..068415d3797 100644 --- a/src/plugins/navigation/mutations/updateNavigationTree.js +++ b/src/plugins/navigation/mutations/updateNavigationTree.js @@ -18,6 +18,12 @@ export default async function updateNavigationTree(context, input) { const { NavigationTrees } = collections; const { navigationTreeId, shopId, navigationTree } = input; + const treeSelector = { _id: navigationTreeId, shopId }; + const existingNavigationTree = await NavigationTrees.findOne(treeSelector); + if (!existingNavigationTree) { + throw new ReactionError("navigation-tree-not-found", "No navigation tree was found"); + } + const { shouldNavigationTreeItemsBeAdminOnly, shouldNavigationTreeItemsBePubliclyVisible, @@ -46,12 +52,6 @@ export default async function updateNavigationTree(context, input) { await context.validatePermissions(`reaction:navigationTrees:${navigationTreeId}`, "update", { shopId, legacyRoles: ["core"] }); - const treeSelector = { _id: navigationTreeId, shopId }; - const existingNavigationTree = await NavigationTrees.findOne(treeSelector); - if (!existingNavigationTree) { - throw new ReactionError("navigation-tree-not-found", "No navigation tree was found"); - } - const update = {}; if (draftItems) { diff --git a/tests/integration/api/mutations/navigationTree/UpdateNavigationTreeMutation.graphql b/tests/integration/api/mutations/navigationTree/UpdateNavigationTreeMutation.graphql new file mode 100644 index 00000000000..b6922ccc543 --- /dev/null +++ b/tests/integration/api/mutations/navigationTree/UpdateNavigationTreeMutation.graphql @@ -0,0 +1,23 @@ +mutation UpdateNavigationTree($updateNavigationTreeInput: UpdateNavigationTreeInput!) { + updateNavigationTree(input: $updateNavigationTreeInput) { + navigationTree { + ...NavigationTree + } + } +} + +fragment NavigationTree on NavigationTree { + _id + draftItems { + expanded + isPrivate + isSecondary + isVisible + navigationItem { + _id + } + } + hasUnpublishedChanges + name + shopId +} \ No newline at end of file diff --git a/tests/integration/api/mutations/navigationTree/__snapshots__/updateNavigationTree.test.js.snap b/tests/integration/api/mutations/navigationTree/__snapshots__/updateNavigationTree.test.js.snap new file mode 100644 index 00000000000..33022ccedb9 --- /dev/null +++ b/tests/integration/api/mutations/navigationTree/__snapshots__/updateNavigationTree.test.js.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`an unauthorized user should not be able to update the navigation tree 1`] = ` +Array [ + Object { + "extensions": Object { + "code": "FORBIDDEN", + "exception": Object { + "details": Object {}, + "error": "access-denied", + "eventData": Object {}, + "isClientSafe": true, + "reason": "Access Denied", + }, + }, + "locations": Array [ + Object { + "column": 3, + "line": 2, + }, + ], + "message": "Access Denied", + "path": Array [ + "updateNavigationTree", + ], + }, +] +`; diff --git a/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js b/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js new file mode 100644 index 00000000000..fd08751cc41 --- /dev/null +++ b/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js @@ -0,0 +1,117 @@ +import encodeOpaqueId from "@reactioncommerce/api-utils/encodeOpaqueId.js"; +import importAsString from "@reactioncommerce/api-utils/importAsString.js"; +import Factory from "/tests/util/factory.js"; +import TestApp from "/tests/util/TestApp.js"; + +const UpdateNavigationTreeMutation = importAsString("./UpdateNavigationTreeMutation.graphql"); + +jest.setTimeout(300000); + +const internalShopId = "123"; +const opaqueShopId = "cmVhY3Rpb24vc2hvcDoxMjM="; // reaction/shop:123 +const shopName = "Test Shop"; +const encodeNavigationTreeOpaqueId = encodeOpaqueId("reaction/navigationTree"); +const encodeNavigationItemOpaqueId = encodeOpaqueId("reaction/navigationItem"); + +const mockAdminAccount = Factory.Account.makeOne({ + roles: { + [internalShopId]: ["admin", "core"] + } +}); + +const mockNavigationTree = Factory.NavigationTree.makeOne({ + _id: "1001", + name: "Default Navigation", + shopId: internalShopId, + draftItems: Factory.NavigationTreeItem.makeMany(2, { + isPrivate: false, + isSecondary: false, + isVisible: false + }) +}); + +const mockNavigationItem = Factory.NavigationItem.makeOne({ + shopId: internalShopId +}); + +const updateNavigationTreeInput = { + shopId: opaqueShopId, + navigationTree: { + name: "Not Default Navigation", + draftItems: [ + { + navigationItemId: encodeNavigationItemOpaqueId(mockNavigationItem._id), + isPrivate: false, + isSecondary: false, + isVisible: true + } + ] + }, + id: encodeNavigationTreeOpaqueId(mockNavigationTree._id) +}; + +let testApp; +let updateNavigationTree; + +beforeAll(async () => { + testApp = new TestApp(); + await testApp.start(); + await testApp.insertPrimaryShop({ _id: internalShopId, name: shopName }); + await testApp.createUserAndAccount(mockAdminAccount); + await testApp.setLoggedInUser(mockAdminAccount); + await testApp.collections.NavigationTrees.insertOne(mockNavigationTree); + await testApp.collections.NavigationItems.insertOne(mockNavigationItem); + + updateNavigationTree = await testApp.mutate(UpdateNavigationTreeMutation); +}); + +beforeEach(async () => { + await testApp.clearLoggedInUser(); +}); + +afterAll(async () => { + await testApp.collections.NavigationItems.deleteMany({}); + await testApp.collections.Shops.deleteMany({}); + await testApp.stop(); +}); + +test("an authorized user should be able to update the navigation tree", async () => { + let result; + try { + await testApp.setLoggedInUser(mockAdminAccount); + result = await updateNavigationTree({ + updateNavigationTreeInput + }); + } catch (error) { + expect(error).toBeUndefined(); + } + + expect(result.updateNavigationTree.navigationTree).toEqual({ + _id: encodeNavigationTreeOpaqueId(mockNavigationTree._id), + draftItems: [ + { + expanded: null, + isPrivate: false, + isSecondary: false, + isVisible: true, + navigationItem: { + _id: encodeNavigationItemOpaqueId(mockNavigationItem._id) + } + } + ], + hasUnpublishedChanges: true, + name: "Not Default Navigation", + shopId: opaqueShopId + }); + +}); + +test("an unauthorized user should not be able to update the navigation tree", async () => { + try { + await updateNavigationTree({ + updateNavigationTreeInput + }); + } catch (error) { + expect(error).toMatchSnapshot(); + } +}); diff --git a/tests/util/factory.js b/tests/util/factory.js index d278b572bfe..e1e89103537 100644 --- a/tests/util/factory.js +++ b/tests/util/factory.js @@ -74,6 +74,12 @@ import { extendSimplePricingSchemas } from "../../src/plugins/simple-pricing/simpleSchemas.js"; +import { + NavigationItem, + NavigationTree, + NavigationTreeItem +} from "../../src/plugins/navigation/simpleSchemas.js"; + const schemasToAddToFactory = { Account, AccountProfileAddress, @@ -91,6 +97,9 @@ const schemasToAddToFactory = { Email, EmailTemplates, Group, + NavigationItem, + NavigationTree, + NavigationTreeItem, Order, OrderAddress, OrderFulfillmentGroup, From 5a436de8fb6b4a292a70b576fc87927f1215181d Mon Sep 17 00:00:00 2001 From: trojanh Date: Tue, 17 Dec 2019 12:39:12 +0530 Subject: [PATCH 2/2] test: fix eslint issue Signed-off-by: trojanh --- .../api/mutations/navigationTree/updateNavigationTree.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js b/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js index fd08751cc41..dea2c9cd510 100644 --- a/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js +++ b/tests/integration/api/mutations/navigationTree/updateNavigationTree.test.js @@ -103,7 +103,6 @@ test("an authorized user should be able to update the navigation tree", async () name: "Not Default Navigation", shopId: opaqueShopId }); - }); test("an unauthorized user should not be able to update the navigation tree", async () => {