为Strapi项目设置测试环境

时间:2020-04-25 16:52:48

标签: node.js unit-testing jestjs strapi

我正在尝试为Strapi项目设置单元测试,我的代码如下所示

test_utils.js

const Strapi = require("strapi");
const http = require('http');

let instance; // singleton 
jest.setTimeout(10000)

async function setupStrapi() {
  if (!instance) {
    instance = Strapi()
    await instance.load();

    // Run bootstrap function.
    await instance.runBootstrapFunctions();
    // Freeze object.
    await instance.freeze();

    instance.app.use(instance.router.routes()).use(instance.router.allowedMethods());
    instance.server = http.createServer(instance.app.callback());
  }
  return instance;
}

module.exports = { setupStrapi }

controllers.test.js

const request = require("supertest")
const {setupStrapi, setupUser} = require("../../test_utils")

describe("chat-group controllers", ()=>{
    let strapi
    beforeAll(async ()=>{
        strapi = await setupStrapi()
    })

    test("endpoint tasks", async (done)=>{
        app = strapi

        app.server.listen(app.config.port, app.config.host)
        const resp = await request(app.server).get("/testpublics")
        .expect(200)

        console.log(resp.body)
        done()
    })
})

运行测试时,“ / testpublics”出现403错误。请注意,“ / testpublics”是公共api,我可以从浏览器访问它。

我认为问题出在setupStrapi函数中,我从node_modules/strapi/lib/strapi.js文件中获取了代码。

为Strapi项目设置单元测试的更好方法是什么。我想实现关注

  • 每次都使用干净的数据库开始测试
  • 测试公共和经过身份验证的api端点

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。转到./api/name-of-your-api/config/routes.json并删除每个端点的config属性。

应该是这样:

{
  "routes": [
    {
      "method": "GET",
      "path": "/testpublics",
      "handler": "testpublics.index"
    },
}

与此相反:

{
  "routes": [
    {
      "method": "GET",
      "path": "/testpublics",
      "handler": "testpublics.index",
      "config": {
        "policies": []
      }
    },
}

答案 1 :(得分:0)

如果您希望按照政策将这条路线公开,则@ sama-bala的回答将解决所有问题。

对于Strapi,必须将非公共的自定义路由和控制器(在Request标头中需要JWT令牌)分配给角色-否则即使是有效的令牌控制器也将引发Forbidden 403错误。认证请求tutorial on Strapi documentation page中描述了整个过程。此信息仅保存在数据库中。通常,您是在管理面板中执行此操作,而不是从源代码执行。

看看下面的代码段

/**
 * Grants database `permissions` table that role can access an endpoint/controllers
 *
 * @param {int} roleID, 1 Autentihected, 2 Public, etc
 * @param {string} value, in form or dot string eg `"permissions.users-permissions.controllers.auth.changepassword"`
 * @param {boolean} enabled, default true
 * @param {string} policy, default ''
 */
const grantPrivilage = async (
  roleID = 1,
  value,
  enabled = true,
  policy = ""
) => {
  const updateObj = value
    .split(".")
    .reduceRight((obj, next) => ({ [next]: obj }), { enabled, policy });

  return await strapi.plugins[
    "users-permissions"
  ].services.userspermissions.updateRole(roleID, updateObj);
};

它允许您通过更新数据库以编程方式为角色分配路由。对于您的代码,解决方案可能看起来像这样

  await grantPrivilage(2, "permissions.application.controllers.testpublics.index"); // 1 is default role for Autheticated user, 2 is Public role. 

您可以在beforeAllbootstrap.js中添加它,例如

beforeAll(async (done) => {
  user = await userFactory.createUser(strapi);
  await grantPrivilage(1, "permissions.application.controllers.hello.hi");
  done();
});

我试图在my blog post

中探讨这个主题