Strange QUnit behaviour?: test failing because setting value doesn't survive

I have a strange issue with QUnit.

This test is extremely simple and should be straightforward … but …

A plugin setting is changing from those I have set up.

When the javascript runs as a result of the Composer loading, the setting value set earlier in the acceptance block is no longer the same!

It should be “user” as set in the test code, but if console logged, this is what I see, and why the test fails:

Am I doing something stupid here? Why is the value of location_topic_default changing from user to none?

Please note the default:

The scope of needs.settings is presumably correct here?

It’s almost as if the needs.settings are running out of order and beyond the acceptance scope …

2 Likes

I took this for a spin locally. Looks like there a few factors at play:

The siteSettings object you’re referencing is being obtained by the initializer, and then used in a modifyClass call:

Initializers are re-run for each test. Problem is, we have no way to ‘reset’ any modifyClass calls that were made by previous tests. Our solution is the pluginId parameter - it means that only the first modifyClass call in the whole test suite is actually used. Calls to modifyClass from initializers in future tests are ignored.

Normally that’s fine - code inside a modifyClass invocation doesn’t tend to change in each test run. However, in this case you’re referencing the siteSettings reference from the initializers scope.

The tl;dr here is: in tests, this implementation means that the modifyClass will be stuck with the site settings from whichever test was the first to run.

The solution is to use a siteSettings reference ‘at runtime’ rather than at ‘initializer’ time. We can use the one from model:composer itself. This diff gets the tests passing for me:

diff --git a/assets/javascripts/discourse/initializers/location-edits.js.es6 b/assets/javascripts/discourse/initializers/location-edits.js.es6
index 19e50c0..9d5f882 100644
--- a/assets/javascripts/discourse/initializers/location-edits.js.es6
+++ b/assets/javascripts/discourse/initializers/location-edits.js.es6
@@ -83,7 +83,7 @@ export default {
         @observes("draftKey")
         _setupDefaultLocation() {
           if (this.draftKey === "new_topic") {
-            const topicDefaultLocation = siteSettings.location_topic_default;
+            const topicDefaultLocation = this.siteSettings.location_topic_default;
             if (
               topicDefaultLocation === "user" &&
               currentUser.custom_fields.geo_location &&
2 Likes

David, thanks so much! That’s quite a gotcha!

1 Like

David,

FYI

There’s another issue here which I suspect is for the same reason:

currentUser is also defined in the initialiser.

If the wrong test runs second this is evaluated and this is no longer defined so the tests when run together can fail “half” of the time.

I think the Composer model has user so I’ll switch to that …

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.