ייבוא מודל או קומפוננטה מתוך פלאגין לפלאגין מותאם אישית: כישלון בדיקות

Hello,
We are using Discourse version 3.5.0.
We have our own plugin in which we override various Discourse elements and add our own features.

In this plugin, we want to add the event creation icon to the composer’s toolbar. To do this, we need to import:

  • the model DiscoursePostEventEvent located at plugins/discourse-calendar/assets/javascripts/discourse/models/discourse-post-event-event.js

  • the component PostEventBuilder located at plugins/discourse-calendar/assets/javascripts/discourse/components/modal/post-event-builder.js

Furthermore, we have written integration tests for our features, which we have placed in our plugin under the /test directory.

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

We are able to do what we want, but the tests fail regardless of the import method.

Import at the top of the file

When we import our model and component using the import method at the top of the 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";

Everything works fine at runtime, but when we run our test, it is not executed.

image

image

Require at the top of the file

When we import our model and component using the require method at the top of the 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;

Everything works fine at runtime, but when we run our test, it is not executed.

image

image

This produces the same result as with import.

Require in the body of the file

When we import our model and component using the require method in the body of the function:

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;

  // ... rest of the code
}

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

Everything works fine at runtime, but when we run our test, it fails.

image

The model was not found.

In short, we would like to know how to correctly import models, components, etc. from other plugins so that we can run integration tests.
Thank you!

2 לייקים

שלום @Marine

נראה שהבעיה נעוצה בהגדרות שגויות בבלוק needs.settings בקוד שלנו:

acceptance("Some tests", function (needs) {
  needs.settings({
    // This won't enable the right settings, so the calendar plugin won't be loaded, and the files we need won't be available
    // discourse_post_event_enabled: true,
    //
    // Enabling the calendar will solve the issue:
    calendar_enabled: true

    our_plugin_enabled: true
  });


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

ובכן, זה לא נכון. מכיוון שהתוסף מחליף את טופס האירוע, עלינו להגדיר את discourse_post_event_enabled ל-true. חזרה למצב ההתחלתי שבו הייבוא בתוסף שלנו נכשל.

יש לך רעיון?

When you test a plugin in qunit, we only load the JS for that specific plugin. That helps to avoid surprise issues when multiple plugins interact with each other. It also helps to ensure that a plugin doesn’t unexpectedly become dependent on another.

In your case, it sounds like the interaction is deliberate, and you always expect your users to have discourse-calendar enabled. In that case, you can add some config to an about.json file which will make the discourse-calendar JS available in the tests of your own plugin. Here’s an example:

^^ in this case it’s adding discourse-assign. For your case, you would make it discourse-calendar

4 לייקים

Thanks! I didn’t know about about.json and it solved the issue. Now, it’s up to us to re-create a fully functional context :wink:

Thanks again!

2 לייקים

You may also be interested in system specs for end-to-end testing. That way, the test is run against a real Discourse server, so you don’t have to fake all of the network requests for core & both plugins.

The downside is that they’re much slower. So best to keep any unit/component tests in qunit if you can.

2 לייקים

Thanks for the tip!

I’m really more comfortable with system specs as I usually use RSpec or Cucumber to test my Rails apps :slight_smile:

I’ll see what’s worth testing with QUnit or RSpec, depending on the test case.

For now, I managed to reproduce the frontend bug we wanted to fix, so I’ll dig a bit more in QUnit tests.

2 לייקים