DEV: prevents test timeout (#12631)

Clock manipulation seems not reliable in component tests. This blog post does a great job of explaining it: https://dockyard.com/blog/2018/04/18/bending-time-in-ember-tests

Sadly, we don't have all the "recent" ember test helpers and can't use things like `getSettledState()`.

For now this pattern seems the most reliable and easy to apply, albeit not great.

Note if you wish to reproduce the current timeout, the following command should do it: `QUNIT_SEED=215263717493121190480103670124734840282 rake qunit:test`
This commit is contained in:
Joffrey JAFFEUX 2021-04-07 15:50:06 +02:00 committed by GitHub
parent 2308a58113
commit 68a032a734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 35 deletions

View File

@ -1,7 +1,9 @@
import getURL from "discourse-common/lib/get-url"; import getURL from "discourse-common/lib/get-url";
import { later } from "@ember/runloop"; import { cancel, later } from "@ember/runloop";
import discourseComputed, { on } from "discourse-common/utils/decorators"; import discourseComputed, { on } from "discourse-common/utils/decorators";
import Component from "@ember/component"; import Component from "@ember/component";
import { not } from "@ember/object/computed";
import { isTesting } from "discourse-common/config/environment";
export default Component.extend({ export default Component.extend({
showPrompt: false, showPrompt: false,
@ -14,9 +16,13 @@ export default Component.extend({
return getURL("/"); return getURL("/");
}, },
isHidden: not("showPrompt"),
_timeoutHandler: null,
@discourseComputed("showPrompt") @discourseComputed("showPrompt")
getClassNames(showPrompt) { getClassNames(showPrompt) {
let classes = ["software-update-prompt"]; const classes = ["software-update-prompt"];
if (showPrompt) { if (showPrompt) {
classes.push("require-software-refresh"); classes.push("require-software-refresh");
@ -25,32 +31,36 @@ export default Component.extend({
return classes.join(" "); return classes.join(" ");
}, },
@discourseComputed("showPrompt")
isHidden(showPrompt) {
return !showPrompt;
},
@on("init") @on("init")
initSubscribtions() { initSubscribtions() {
let timeout;
this.messageBus.subscribe("/refresh_client", () => { this.messageBus.subscribe("/refresh_client", () => {
this.session.requiresRefresh = true; this.session.requiresRefresh = true;
}); });
let updatePrompt = this;
this.messageBus.subscribe("/global/asset-version", (version) => { this.messageBus.subscribe("/global/asset-version", (version) => {
if (this.session.assetVersion !== version) { if (this.session.assetVersion !== version) {
this.session.requiresRefresh = true; this.session.requiresRefresh = true;
} }
if (!timeout && this.session.requiresRefresh) { if (!this._timeoutHandler && this.session.requiresRefresh) {
// Since we can do this transparently for people browsing the forum if (isTesting) {
// hold back the message 24 hours. this.set("showPrompt", true);
timeout = later(() => { } else {
updatePrompt.set("showPrompt", true); // Since we can do this transparently for people browsing the forum
}, 1000 * 60 * 24 * 60); // hold back the message 24 hours.
this._timeoutHandler = later(() => {
this.set("showPrompt", true);
}, 1000 * 60 * 24 * 60);
}
} }
}); });
}, },
willDestroyElement() {
this._super(...arguments);
this._timeoutHandler && cancel(this._timeoutHandler);
this._timeoutHandler = null;
},
}); });

View File

@ -1,30 +1,19 @@
import componentTest, { import componentTest, {
setupRenderingTest, setupRenderingTest,
} from "discourse/tests/helpers/component-test"; } from "discourse/tests/helpers/component-test";
import sinon from "sinon";
import { import {
discourseModule, discourseModule,
fakeTime,
publishToMessageBus, publishToMessageBus,
queryAll, queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { later } from "@ember/runloop";
let clock = null;
discourseModule( discourseModule(
"Integration | Component | software-update-prompt", "Integration | Component | software-update-prompt",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () {
clock = fakeTime("2019-12-10T08:00:00", "Australia/Brisbane", true);
});
hooks.afterEach(function () {
clock.restore();
sinon.restore();
});
componentTest( componentTest(
"software-update-prompt gets correct CSS class after messageBus message", "software-update-prompt gets correct CSS class after messageBus message",
{ {
@ -36,6 +25,7 @@ discourseModule(
.length === 0, .length === 0,
"it does not have the class to show the prompt" "it does not have the class to show the prompt"
); );
assert.equal( assert.equal(
queryAll("div.software-update-prompt")[0].getAttribute( queryAll("div.software-update-prompt")[0].getAttribute(
"aria-hidden" "aria-hidden"
@ -46,13 +36,15 @@ discourseModule(
publishToMessageBus("/global/asset-version", "somenewversion"); publishToMessageBus("/global/asset-version", "somenewversion");
clock.tick(1000 * 60 * 24 * 60 + 10); const done = assert.async();
later(() => {
assert.ok( assert.ok(
queryAll("div.software-update-prompt.require-software-refresh") queryAll("div.software-update-prompt.require-software-refresh")
.length === 1, .length === 1,
"it does have the class to show the prompt" "it does have the class to show the prompt"
); );
done();
}, 10);
}, },
} }
); );