Импорт модели или компонента из плагина в пользовательский плагин: тесты не проходят

Здравствуйте,
Мы используем версию Discourse 3.5.0.
У нас есть собственный плагин, в котором мы переопределяем различные элементы Discourse и добавляем свои собственные функции.

В этом плагине мы хотим, в частности, добавить иконку создания события в панель инструментов композера. Для этого нам необходимо импортировать:

  • модель DiscoursePostEventEvent, которая находится в plugins/discourse-calendar/assets/javascripts/discourse/models/discourse-post-event-event.js

  • компонент PostEventBuilder, который находится в plugins/discourse-calendar/assets/javascripts/discourse/components/modal/post-event-builder.js

Кроме того, мы написали интеграционные тесты для наших функций и разместили их в нашем плагине в директории /test.

import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";

acceptance("TOTO", function (needs) {
  test("coopaname integration - composer", async function (assert) {
    await visit("/");
    assert
      .equal(1, 1, "OK")
  });

});

Нам удаётся сделать то, что мы хотим, но тесты не выполняются, независимо от способа импорта.

Импорт в начале файла

Когда мы импортируем наши модель и компонент с помощью метода import в начале файла:

import DiscoursePostEventEvent from "discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event";
import PostEventBuilder from "discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder";

Всё работает корректно при выполнении, но при запуске нашего теста он не выполняется.

Require в начале файла

Когда мы импортируем наши модель и компонент с помощью метода require в начале файла:

const DiscoursePostEventEvent = require("discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event").default;
const PostEventBuilder = require("discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder").default;

Всё работает корректно при выполнении, но при запуске нашего теста он не выполняется.

Это приводит к тому же результату, что и с import.

Require в теле файла

Когда мы импортируем наши модель и компонент с помощью метода require внутри функции:

import { withPluginApi } from "discourse/lib/plugin-api";

function initializeEventBuilder(api) {
  const DiscoursePostEventEvent =
     require("discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event").default;
  const PostEventBuilder =
     require("discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder").default;

  ... Продолжение кода
}

export default {
  name: "add-custom-create-event-button",
  initialize(container) {
    withPluginApi(initializeEventBuilder);
  },
};

Всё работает корректно при выполнении, но при запуске нашего теста он не проходит.

Модель не найдена.

В общем, мы хотели бы узнать, как правильно импортировать модели, компоненты и т.д. из других плагинов, чтобы можно было выполнять интеграционные тесты.
Спасибо!

Привет, @Marine

Кажется, проблема заключается в неправильных настройках, используемых в блоке needs.settings нашего кода:

acceptance("Some tests", function (needs) {
  needs.settings({
    // Это не включит нужные настройки, поэтому плагин календаря не будет загружен, и необходимые файлы будут недоступны
    // discourse_post_event_enabled: true, 
    // 
    // Включение календаря решит проблему:
    calendar_enabled: true

    our_plugin_enabled: true
  });


  test("The test", async function (assert) {
    await visit("/");
    assert.equal(1, 1);
  });
});

Что ж, это не совсем так. Поскольку плагин переопределяет форму события, нам нужно установить discourse_post_event_enabled в true. Возвращаемся к исходной ситуации, когда импорт в нашем плагине не работает.

Есть какие-либо идеи?

Когда вы тестируете плагин в QUnit, загружается только JS-код этого конкретного плагина. Это помогает избежать неожиданных проблем при взаимодействии нескольких плагинов друг с другом. Также это гарантирует, что плагин не станет непреднамеренно зависимым от другого.

В вашем случае, похоже, такое взаимодействие намеренное, и вы всегда ожидаете, что у ваших пользователей будет включен плагин discourse-calendar. В такой ситуации вы можете добавить конфигурацию в файл about.json, чтобы сделать JS-код discourse-calendar доступным для тестов вашего собственного плагина. Вот пример:

^^ В данном примере добавляется discourse-assign. В вашем случае нужно указать discourse-calendar.

Спасибо! Я не знал о about.json, и это решило проблему. Теперь нам предстоит воссоздать полностью функциональный контекст :wink:

Ещё раз спасибо!

Вам также может быть интересно ознакомиться с системными спецификациями для сквозного тестирования. В этом случае тест запускается против реального сервера Discourse, поэтому вам не нужно эмулировать все сетевые запросы для ядра и обоих плагинов.

Недостаток в том, что они работают значительно медленнее. Поэтому, если возможно, лучше оставлять любые модульные или компонентные тесты в QUnit.

Спасибо за подсказку!

Я чувствую себя гораздо увереннее с системными спецификациями, так как обычно использую RSpec или Cucumber для тестирования своих приложений на Rails :slight_smile:

Я посмотрю, что стоит тестировать с помощью QUnit или RSpec, в зависимости от конкретного случая.

На данный момент мне удалось воспроизвести ошибку на фронтенде, которую мы хотели исправить, поэтому я немного глубже изучу тесты QUnit.