Integration Tests - Simulating Strapi Admin GUI Requests (User Actions)

System Information
  • Strapi Version: 3.4.3
  • Operating System: ubuntu
  • Database: postgres
  • Node Version: 14
  • NPM Version: 6.14

Integration Tests - Simulating Requests via Strapi Admin GUI

I have a cache middleware which busts the cache when a POST/PUT request is made via /content-manager/collection-types/:scope. I would now like to write an integration test.

How can I use the global Strapi object or send a request to the Strapi backend endpoint to simulate a user action in the Strapi Admin GUI? My intention is to simulate a user action in the Strapi Admin GUI.

I have tried the following…

const result = await strapi.plugins['content-manager'].controllers['collection-types'].create({
      state: { user: 2, userAbility: { can: () => true, cannot: () => false } },
      params: { model: 'application::ad.ad' },
      request: { body: { description: 'test' } },
    });

but it fails…

  1) [Redis Cache]: Integration Tests
       REST - Cache Bust via Admin:
     TypeError: n.possibleRulesFor is not a function
      at n.permittedFieldsOf (node_modules/@casl/ability/src/extra.ts:101:32)
      at Object.sanitize (node_modules/strapi-admin/services/permission/permissions-manager/index.js:52:29)
      at sanitizeInput (node_modules/strapi-plugin-content-manager/services/permission-checker.js:38:31)
      at sanitizeCreateInput (node_modules/strapi-plugin-content-manager/services/permission-checker.js:45:39)
      at .../backend/node_modules/lodash/lodash.min.js:56:306
      at Object.create (node_modules/strapi-plugin-content-manager/controllers/collection-types.js:82:61)
      at _callee7$ (test/integration/cache/cache.test.js:115:92)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:63:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:293:22)
      at Generator.next (node_modules/regenerator-runtime/runtime.js:118:21)
      at asyncGeneratorStep (test/integration/cache/cache.test.js:3:103)
      at _next (test/integration/cache/cache.test.js:5:194)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

Question

Has someone done something like this? And/or is there a better way to do it? For example, is there a function to create a proper userAbility object instead of this mock version.

Answer / Possible Solution

I think I have found an answer to the question myself.

The simplest solution I was able to come up with was to:

  1. Create the necessary Users
  • create an API user with all privileges just for test purposes
  • create an Admin Super user just for test purposes
  1. Backup/dump the database to a file (e.g., backup.sql) or save the sqlite database.

  2. Before you run the integration tests, run a command along the lines of: npm run db:setup:from:file or point to the respective sqlite database.

  3. Inside the tests where one wants to use both Super User (Admin GUI) or normal API user, use the following function to issue a token (avoid having to login via the API):

    • const apiUserToken = strapi.plugins['users-permissions'].services.jwt.issue({ id: "API_USER_ID" });
    • const superUserToken = strapi.admin.services.token.createJwtToken({ id: "SUPER_USER_ID" });
  4. Requests that are sent from the Admin GUI can be performed as well.

    const result= await post(
      '/content-manager/collection-types/application::user:user', // url/target
      { name: 'change-my-name' }, // body
      adminJwt // token
    );
    

I hope this helps others when they’re trying to write integration tests that target routes only accessible with super user privileges. @DMehaffy should I add a version of this to the documentation section on testing?