Importazione di modello o componente da un plugin in un plugin personalizzato: test falliti

Ciao,
Utilizziamo Discourse versione 3.5.0.
Abbiamo un nostro plugin in cui sovrascriviamo vari elementi di Discourse e aggiungiamo le nostre funzionalità.

In questo plugin, vogliamo in particolare aggiungere l’icona di aggiunta di un evento nella barra degli strumenti del composer. Per fare ciò, dobbiamo importare:

  • il modello DiscoursePostEventEvent che si trova in plugins/discourse-calendar/assets/javascripts/discourse/models/discourse-post-event-event.js

  • il componente PostEventBuilder che si trova in plugins/discourse-calendar/assets/javascripts/discourse/components/modal/post-event-builder.js

Inoltre, abbiamo scritto dei test di integrazione per le nostre funzionalità che abbiamo inserito nel nostro plugin nella directory /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");
  });
});

Riusciamo a fare ciò che vogliamo, ma i test falliscono indipendentemente dalla modalità di importazione.

Import in testa al file

Quando importiamo il nostro modello e componente tramite il metodo import in testa al file:

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

Tutto va bene durante l’esecuzione, ma quando avviamo il nostro test, questo non viene eseguito.

Require in testa al file

Quando importiamo il nostro modello e componente tramite il metodo require in testa al file:

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;

Tutto va bene durante l’esecuzione, ma quando avviamo il nostro test, questo non viene eseguito.

Ciò produce lo stesso risultato che con import.

Require nel corpo del file

Quando importiamo il nostro modello e componente tramite il metodo require nel corpo della funzione:

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 codice
}

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

Tutto va bene durante l’esecuzione, ma quando avviamo il nostro test, questo fallisce.

Il modello non è stato trovato.

Insomma, vorremmo sapere come importare correttamente modelli, componenti ecc. da altri plugin in modo da poter eseguire i test di integrazione.
Grazie!

2 Mi Piace

Ciao @Marine

Sembra che il problema risieda nelle impostazioni errate utilizzate nel blocco needs.settings del nostro codice:

acceptance("Alcuni test", function (needs) {
  needs.settings({
    // Questo non abiliterà le impostazioni corrette, quindi il plugin del calendario non verrà caricato e i file di cui abbiamo bisogno non saranno disponibili
    // discourse_post_event_enabled: true, 
    // 
    // Abilitare il calendario risolverà il problema:
    calendar_enabled: true

    our_plugin_enabled: true
  });


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

Beh, questo non è vero. Poiché il plugin sovrascrive il form dell’evento, dobbiamo impostare discourse_post_event_enabled su true. Si torna alla situazione iniziale in cui l’importazione nel nostro plugin fallisce.

Qualche idea?

Quando si testa un plugin in qunit, carichiamo solo il JS per quel plugin specifico. Ciò aiuta a evitare problemi imprevisti quando più plugin interagiscono tra loro. Aiuta anche a garantire che un plugin non diventi inaspettatamente dipendente da un altro.

Nel tuo caso, sembra che l’interazione sia deliberata e ti aspetti sempre che i tuoi utenti abbiano discourse-calendar abilitato. In tal caso, puoi aggiungere una configurazione a un file about.json che renderà il JS di discourse-calendar disponibile nei test del tuo plugin. Ecco un esempio:

^^ in questo caso sta aggiungendo discourse-assign. Nel tuo caso, sarebbe discourse-calendar.

4 Mi Piace

Grazie! Non sapevo di about.json e ha risolto il problema. Ora, sta a noi ricreare un contesto completamente funzionale :wink:

Grazie ancora!

2 Mi Piace

Potrebbe anche interessarti specifiche di sistema per il testing end-to-end. In questo modo, il test viene eseguito su un server Discourse reale, quindi non devi simulare tutte le richieste di rete per il core e per entrambi i plugin.

Lo svantaggio è che sono molto più lenti. Quindi è meglio mantenere eventuali test unitari/componenti in qunit, se possibile.

2 Mi Piace

Grazie per il suggerimento!

Mi sento molto più a mio agio con le specifiche di sistema dato che di solito uso RSpec o Cucumber per testare le mie app Rails :slight_smile:

Vedrò cosa vale la pena testare con QUnit o RSpec, a seconda del caso di test.

Per ora, sono riuscito a riprodurre il bug frontend che volevamo correggere, quindi approfondirò un po’ di più i test QUnit.

2 Mi Piace