Importación de modelo o componente de un plugin en un plugin personalizado: fallo de las pruebas

Hola,
Usamos Discourse versión 3.5.0.
Tenemos nuestro propio plugin en el que sobrescribimos varios elementos de Discourse y agregamos nuestras propias funcionalidades.

En este plugin, queremos agregar específicamente el ícono para agregar un evento en la barra de herramientas del composer. Para hacer esto, necesitamos importar:

  • el modelo DiscoursePostEventEvent que se encuentra en plugins/discourse-calendar/assets/javascripts/discourse/models/discourse-post-event-event.js

  • el componente PostEventBuilder que se encuentra en plugins/discourse-calendar/assets/javascripts/discourse/components/modal/post-event-builder.js

Además, hemos escrito pruebas de integración para nuestras funcionalidades que hemos colocado en nuestro plugin bajo el directorio /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");
  });
});

Logramos hacer lo que queremos, pero las pruebas fallan independientemente del método de importación.

Importar al principio del archivo

Cuando importamos nuestro modelo y componente usando el método import al principio del archivo:

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";

Todo va bien en la ejecución, pero cuando ejecutamos nuestra prueba, no se ejecuta.

Require al principio del archivo

Cuando importamos nuestro modelo y componente usando el método require al principio del archivo:

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;

Todo va bien en la ejecución, pero cuando ejecutamos nuestra prueba, no se ejecuta.

Esto produce lo mismo que con import.

Require en el cuerpo del archivo

Cuando importamos nuestro modelo y componente usando el método require en el cuerpo de la función:

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;

  ... Resto del código
}

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

Todo va bien en la ejecución, pero cuando ejecutamos nuestra prueba, falla.

El modelo no fue encontrado.

En resumen, nos gustaría saber cómo importar modelos, componentes, etc. correctamente desde otros plugins para que podamos ejecutar las pruebas de integración.
¡Gracias!

2 Me gusta

Hola @Marine

Parece que el problema radica en la configuración incorrecta utilizada en el bloque needs.settings de nuestro código:

acceptance("Algunas pruebas", function (needs) {
  needs.settings({
    // Esto no habilitará la configuración correcta, por lo que el plugin del calendario no se cargará y los archivos que necesitamos no estarán disponibles
    // discourse_post_event_enabled: true, 
    // 
    // Habilitar el calendario resolverá el problema:
    calendar_enabled: true

    our_plugin_enabled: true
  });


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

Bueno, esto no es cierto. Como el plugin anula el formulario de eventos, necesitamos establecer discourse_post_event_enabled en true. Volvemos a la situación inicial en la que la importación en nuestro plugin falla.

¿Alguna idea?

Cuando pruebas un plugin en qunit, solo cargamos el JS para ese plugin específico. Esto ayuda a evitar problemas inesperados cuando varios plugins interactúan entre sí. También ayuda a garantizar que un plugin no dependa inesperadamente de otro.

En tu caso, parece que la interacción es deliberada y siempre esperas que tus usuarios tengan discourse-calendar habilitado. En ese caso, puedes agregar una configuración a un archivo about.json que hará que el JS de discourse-calendar esté disponible en las pruebas de tu propio plugin. Aquí tienes un ejemplo:

^^ en este caso, está agregando discourse-assign. Para tu caso, sería discourse-calendar.

4 Me gusta

¡Gracias! No sabía lo de about.json y eso solucionó el problema. Ahora, depende de nosotros recrear un contexto totalmente funcional :wink:

¡Gracias de nuevo!

2 Me gusta

También te pueden interesar las especificaciones del sistema para pruebas de extremo a extremo. De esa manera, la prueba se ejecuta contra un servidor Discourse real, por lo que no tienes que simular todas las solicitudes de red para el núcleo y ambos complementos.

La desventaja es que son mucho más lentas. Así que es mejor mantener las pruebas unitarias/de componentes en qunit si puedes.

2 Me gusta

¡Gracias por el consejo!

Me siento mucho más cómodo con las especificaciones del sistema, ya que normalmente uso RSpec o Cucumber para probar mis aplicaciones Rails :slight_smile:

Veré qué vale la pena probar con QUnit o RSpec, dependiendo del caso de prueba.

Por ahora, logré reproducir el error del frontend que queríamos solucionar, así que profundizaré un poco más en las pruebas de QUnit.

2 Me gusta