DEV: Revisit skipped tests (#15769)

* Some are no longer flaky or easily fixed

* Some are out of date or test things we can't do accurately (scroll
  position) and are removed.

* Unwinds some uppy tests and makes sure all promises and runloops are
  resolved.

Everything has been run in legacy/ember cli multiple times to ensure no
obvious suite regressions.
This commit is contained in:
Robin Ward 2022-02-02 12:09:03 -05:00 committed by GitHub
parent f16f9171d0
commit 6f25f17360
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 261 additions and 555 deletions

View File

@ -20,6 +20,7 @@ import {
} from "discourse/lib/uploads"; } from "discourse/lib/uploads";
import { cacheShortUploadUrl } from "pretty-text/upload-short-url"; import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
import bootbox from "bootbox"; import bootbox from "bootbox";
import { run } from "@ember/runloop";
// Note: This mixin is used _in addition_ to the ComposerUpload mixin // Note: This mixin is used _in addition_ to the ComposerUpload mixin
// on the composer-editor component. It overrides some, but not all, // on the composer-editor component. It overrides some, but not all,
@ -206,112 +207,135 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
} }
this._uppyInstance.on("file-added", (file) => { this._uppyInstance.on("file-added", (file) => {
if (isPrivateMessage) { run(() => {
file.meta.for_private_message = true; if (isPrivateMessage) {
} file.meta.for_private_message = true;
}
});
}); });
this._uppyInstance.on("progress", (progress) => { this._uppyInstance.on("progress", (progress) => {
if (this.isDestroying || this.isDestroyed) { run(() => {
return; if (this.isDestroying || this.isDestroyed) {
} return;
}
this.set("uploadProgress", progress); this.set("uploadProgress", progress);
});
}); });
this._uppyInstance.on("file-removed", (file, reason) => { this._uppyInstance.on("file-removed", (file, reason) => {
// we handle the cancel-all event specifically, so no need run(() => {
// to do anything here. this event is also fired when some files // we handle the cancel-all event specifically, so no need
// are handled by an upload handler // to do anything here. this event is also fired when some files
if (reason === "cancel-all") { // are handled by an upload handler
return; if (reason === "cancel-all") {
} return;
}
file.meta.cancelled = true; file.meta.cancelled = true;
this._removeInProgressUpload(file.id); this._removeInProgressUpload(file.id);
this._resetUpload(file, { removePlaceholder: true }); this._resetUpload(file, { removePlaceholder: true });
if (this.inProgressUploads.length === 0) { if (this.inProgressUploads.length === 0) {
this.set("userCancelled", true); this.set("userCancelled", true);
this._uppyInstance.cancelAll(); this._uppyInstance.cancelAll();
} }
});
}); });
this._uppyInstance.on("upload-progress", (file, progress) => { this._uppyInstance.on("upload-progress", (file, progress) => {
if (this.isDestroying || this.isDestroyed) { run(() => {
return; if (this.isDestroying || this.isDestroyed) {
} return;
}
const upload = this.inProgressUploads.find((upl) => upl.id === file.id); const upload = this.inProgressUploads.find((upl) => upl.id === file.id);
if (upload) { if (upload) {
const percentage = Math.round( const percentage = Math.round(
(progress.bytesUploaded / progress.bytesTotal) * 100 (progress.bytesUploaded / progress.bytesTotal) * 100
); );
upload.set("progress", percentage); upload.set("progress", percentage);
} }
});
}); });
this._uppyInstance.on("upload", (data) => { this._uppyInstance.on("upload", (data) => {
this._addNeedProcessing(data.fileIDs.length); run(() => {
this._addNeedProcessing(data.fileIDs.length);
const files = data.fileIDs.map((fileId) => const files = data.fileIDs.map((fileId) =>
this._uppyInstance.getFile(fileId) this._uppyInstance.getFile(fileId)
);
this.setProperties({
isProcessingUpload: true,
isCancellable: false,
});
files.forEach((file) => {
// The inProgressUploads is meant to be used to display these uploads
// in a UI, and Ember will only update the array in the UI if pushObject
// is used to notify it.
this.inProgressUploads.pushObject(
EmberObject.create({
fileName: file.name,
id: file.id,
progress: 0,
extension: file.extension,
})
); );
const placeholder = this._uploadPlaceholder(file);
this.placeholders[file.id] = { this.setProperties({
uploadPlaceholder: placeholder, isProcessingUpload: true,
}; isCancellable: false,
this.appEvents.trigger(`${this.eventPrefix}:insert-text`, placeholder); });
this.appEvents.trigger(`${this.eventPrefix}:upload-started`, file.name);
files.forEach((file) => {
// The inProgressUploads is meant to be used to display these uploads
// in a UI, and Ember will only update the array in the UI if pushObject
// is used to notify it.
this.inProgressUploads.pushObject(
EmberObject.create({
fileName: file.name,
id: file.id,
progress: 0,
extension: file.extension,
})
);
const placeholder = this._uploadPlaceholder(file);
this.placeholders[file.id] = {
uploadPlaceholder: placeholder,
};
this.appEvents.trigger(
`${this.eventPrefix}:insert-text`,
placeholder
);
this.appEvents.trigger(
`${this.eventPrefix}:upload-started`,
file.name
);
});
}); });
}); });
this._uppyInstance.on("upload-success", (file, response) => { this._uppyInstance.on("upload-success", (file, response) => {
this._removeInProgressUpload(file.id); run(() => {
let upload = response.body; if (!this._uppyInstance) {
const markdown = this.uploadMarkdownResolvers.reduce( return;
(md, resolver) => resolver(upload) || md, }
getUploadMarkdown(upload) this._removeInProgressUpload(file.id);
); let upload = response.body;
const markdown = this.uploadMarkdownResolvers.reduce(
(md, resolver) => resolver(upload) || md,
getUploadMarkdown(upload)
);
cacheShortUploadUrl(upload.short_url, upload); cacheShortUploadUrl(upload.short_url, upload);
this.appEvents.trigger( this.appEvents.trigger(
`${this.eventPrefix}:replace-text`, `${this.eventPrefix}:replace-text`,
this.placeholders[file.id].uploadPlaceholder.trim(), this.placeholders[file.id].uploadPlaceholder.trim(),
markdown markdown
); );
this._resetUpload(file, { removePlaceholder: false }); this._resetUpload(file, { removePlaceholder: false });
this.appEvents.trigger( this.appEvents.trigger(
`${this.eventPrefix}:upload-success`, `${this.eventPrefix}:upload-success`,
file.name, file.name,
upload upload
); );
});
}); });
this._uppyInstance.on("upload-error", this._handleUploadError); this._uppyInstance.on("upload-error", this._handleUploadError);
this._uppyInstance.on("complete", () => { this._uppyInstance.on("complete", () => {
this.appEvents.trigger(`${this.eventPrefix}:all-uploads-complete`); run(() => {
this._reset(); this.appEvents.trigger(`${this.eventPrefix}:all-uploads-complete`);
this._reset();
});
}); });
this._uppyInstance.on("cancel-all", () => { this._uppyInstance.on("cancel-all", () => {
@ -319,11 +343,13 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
// only do the manual cancelling work if the user clicked cancel // only do the manual cancelling work if the user clicked cancel
if (this.userCancelled) { if (this.userCancelled) {
Object.values(this.placeholders).forEach((data) => { Object.values(this.placeholders).forEach((data) => {
this.appEvents.trigger( run(() => {
`${this.eventPrefix}:replace-text`, this.appEvents.trigger(
data.uploadPlaceholder, `${this.eventPrefix}:replace-text`,
"" data.uploadPlaceholder,
); ""
);
});
}); });
this.set("userCancelled", false); this.set("userCancelled", false);
@ -415,21 +441,25 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
this._onPreProcessComplete( this._onPreProcessComplete(
(file) => { (file) => {
let placeholderData = this.placeholders[file.id]; run(() => {
this.appEvents.trigger( let placeholderData = this.placeholders[file.id];
`${this.eventPrefix}:replace-text`, this.appEvents.trigger(
placeholderData.processingPlaceholder, `${this.eventPrefix}:replace-text`,
placeholderData.uploadPlaceholder placeholderData.processingPlaceholder,
); placeholderData.uploadPlaceholder
);
});
}, },
() => { () => {
this.setProperties({ run(() => {
isProcessingUpload: false, this.setProperties({
isCancellable: true, isProcessingUpload: false,
isCancellable: true,
});
this.appEvents.trigger(
`${this.eventPrefix}:uploads-preprocessing-complete`
);
}); });
this.appEvents.trigger(
`${this.eventPrefix}:uploads-preprocessing-complete`
);
} }
); );
}, },

View File

@ -4,8 +4,7 @@ import {
exists, exists,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, currentURL, visit } from "@ember/test-helpers"; import { click, currentURL, visit } from "@ember/test-helpers";
import { skip } from "qunit"; import { test } from "qunit";
// import { test } from "qunit";
acceptance("Click Track", function (needs) { acceptance("Click Track", function (needs) {
let tracked = false; let tracked = false;
@ -16,7 +15,7 @@ acceptance("Click Track", function (needs) {
}); });
}); });
skip("Do not track mentions", async function (assert) { test("Do not track mentions", async function (assert) {
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
assert.ok(!exists(".user-card.show"), "card should not appear"); assert.ok(!exists(".user-card.show"), "card should not appear");

View File

@ -9,7 +9,8 @@ import bootbox from "bootbox";
import { authorizedExtensions } from "discourse/lib/uploads"; import { authorizedExtensions } from "discourse/lib/uploads";
import { click, fillIn, visit } from "@ember/test-helpers"; import { click, fillIn, visit } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import { skip, test } from "qunit"; import { test } from "qunit";
import { Promise } from "rsvp";
function pretender(server, helper) { function pretender(server, helper) {
server.post("/uploads/lookup-urls", () => { server.post("/uploads/lookup-urls", () => {
@ -132,28 +133,17 @@ acceptance("Uppy Composer Attachment - Upload Placeholder", function (needs) {
appEvents.trigger("composer:add-files", [jsonFile]); appEvents.trigger("composer:add-files", [jsonFile]);
}); });
// TODO: Had to comment this out for now; it works fine in Ember CLI but lagging test("cancelling uploads clears the placeholders out", async function (assert) {
// UI updates sink it for the old Ember for some reason. Will re-enable
// when we make Ember CLI the primary.
skip("cancelling uploads clears the placeholders out", async function (assert) {
await visit("/"); await visit("/");
await click("#create-topic"); await click("#create-topic");
await fillIn(".d-editor-input", "The image:\n"); await fillIn(".d-editor-input", "The image:\n");
const image = createFile("avatar.png");
const image2 = createFile("avatar2.png");
const appEvents = loggedInUser().appEvents; const appEvents = loggedInUser().appEvents;
const done = assert.async();
appEvents.on("composer:uploads-cancelled", () => {
assert.strictEqual(
query(".d-editor-input").value,
"The image:\n",
"it should clear the cancelled placeholders"
);
done();
});
let uploadStarted = 0; let uploadStarted = 0;
appEvents.on("composer:upload-started", async () => { appEvents.on("composer:upload-started", () => {
uploadStarted++; uploadStarted++;
if (uploadStarted === 2) { if (uploadStarted === 2) {
@ -164,14 +154,21 @@ acceptance("Uppy Composer Attachment - Upload Placeholder", function (needs) {
); );
} }
}); });
appEvents.on("composer:uploads-cancelled", () => {
appEvents.on("composer:uploads-preprocessing-complete", async () => { assert.strictEqual(
await click("#cancel-file-upload"); query(".d-editor-input").value,
"The image:\n",
"it should clear the cancelled placeholders"
);
}); });
const image = createFile("avatar.png"); await new Promise(function (resolve) {
const image2 = createFile("avatar2.png"); appEvents.on("composer:uploads-preprocessing-complete", function () {
appEvents.trigger("composer:add-files", [image, image2]); resolve();
});
appEvents.trigger("composer:add-files", [image, image2]);
});
await click("#cancel-file-upload");
}); });
test("should insert a newline before and after an image when pasting in the end of the line", async function (assert) { test("should insert a newline before and after an image when pasting in the end of the line", async function (assert) {

View File

@ -5,7 +5,7 @@ import {
selectText, selectText,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers"; import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
import postFixtures from "discourse/tests/fixtures/post"; import postFixtures from "discourse/tests/fixtures/post";
import { cloneJSON } from "discourse-common/lib/object"; import { cloneJSON } from "discourse-common/lib/object";
@ -62,7 +62,7 @@ acceptance("Fast Edit", function (needs) {
assert.notOk(exists("#fast-edit-input"), "fast editor is closed"); assert.notOk(exists("#fast-edit-input"), "fast editor is closed");
}); });
skip("Opens full composer for multi-line selection", async function (assert) { test("Opens full composer for multi-line selection", async function (assert) {
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
const textNode = query("#post_2 .cooked"); const textNode = query("#post_2 .cooked");

View File

@ -1,6 +1,6 @@
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers"; import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
import { click, currentURL, fillIn, visit } from "@ember/test-helpers"; import { click, currentURL, fillIn, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
acceptance("Jump to", function (needs) { acceptance("Jump to", function (needs) {
needs.user(); needs.user();
@ -37,7 +37,7 @@ acceptance("Jump to", function (needs) {
); );
}); });
skip("invalid date", async function (assert) { test("invalid date", async function (assert) {
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await click("nav#topic-progress .nums"); await click("nav#topic-progress .nums");
await click("button.jump-to-post"); await click("button.jump-to-post");

View File

@ -6,7 +6,7 @@ import {
queryAll, queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, triggerKeyEvent, visit } from "@ember/test-helpers"; import { click, triggerKeyEvent, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
import I18n from "I18n"; import I18n from "I18n";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { run } from "@ember/runloop"; import { run } from "@ember/runloop";
@ -30,7 +30,7 @@ acceptance("Modal", function (needs) {
I18n.translations = _translations; I18n.translations = _translations;
}); });
skip("modal", async function (assert) { test("modal", async function (assert) {
await visit("/"); await visit("/");
assert.ok(!exists(".d-modal:visible"), "there is no modal at first"); assert.ok(!exists(".d-modal:visible"), "there is no modal at first");
@ -51,7 +51,7 @@ acceptance("Modal", function (needs) {
await click(".login-button"); await click(".login-button");
assert.strictEqual(count(".d-modal:visible"), 1, "modal should reappear"); assert.strictEqual(count(".d-modal:visible"), 1, "modal should reappear");
await triggerKeyEvent("#main-outlet", "keyup", 27); await triggerKeyEvent("#main-outlet", "keydown", 27);
assert.ok(!exists(".d-modal:visible"), "ESC should close the modal"); assert.ok(!exists(".d-modal:visible"), "ESC should close the modal");
Ember.TEMPLATES[ Ember.TEMPLATES[

View File

@ -4,7 +4,7 @@ import {
count, count,
query, query,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { skip } from "qunit"; import { test } from "qunit";
acceptance("Post - History", function (needs) { acceptance("Post - History", function (needs) {
needs.user(); needs.user();
@ -51,7 +51,7 @@ acceptance("Post - History", function (needs) {
}); });
}); });
skip("Shows highlighted tag changes", async function (assert) { test("Shows highlighted tag changes", async function (assert) {
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await click("article[data-post-id='419'] .edits button"); await click("article[data-post-id='419'] .edits button");
assert.equal(count(".discourse-tag"), 4); assert.equal(count(".discourse-tag"), 4);

View File

@ -5,10 +5,9 @@ import {
queryAll, queryAll,
selectDate, selectDate,
visible, visible,
waitFor,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers"; import { click, fillIn, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
import { import {
SEARCH_TYPE_CATS_TAGS, SEARCH_TYPE_CATS_TAGS,
SEARCH_TYPE_DEFAULT, SEARCH_TYPE_DEFAULT,
@ -150,45 +149,6 @@ acceptance("Search - Full Page", function (needs) {
); );
}); });
skip("update username through advanced search ui", async function (assert) {
await visit("/search");
await fillIn(".search-query", "none");
await fillIn(".search-advanced-options .user-selector", "admin");
await click(".search-advanced-options .user-selector");
await triggerKeyEvent(
".search-advanced-options .user-selector",
"keydown",
8
);
waitFor(assert, async () => {
assert.ok(
visible(".search-advanced-options .autocomplete"),
'"autocomplete" popup is visible'
);
assert.ok(
exists(
'.search-advanced-options .autocomplete ul li a span.username:contains("admin")'
),
'"autocomplete" popup has an entry for "admin"'
);
await click(
".search-advanced-options .autocomplete ul li a:nth-of-type(1)"
);
assert.ok(
exists('.search-advanced-options span:contains("admin")'),
'has "admin" pre-populated'
);
assert.strictEqual(
queryAll(".search-query").val(),
"none @admin",
'has updated search term to "none user:admin"'
);
});
});
test("update category through advanced search ui", async function (assert) { test("update category through advanced search ui", async function (assert) {
const categoryChooser = selectKit( const categoryChooser = selectKit(
".search-advanced-options .category-chooser" ".search-advanced-options .category-chooser"

View File

@ -5,7 +5,7 @@ import {
queryAll, queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, visit } from "@ember/test-helpers"; import { click, fillIn, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
acceptance("Signing In", function () { acceptance("Signing In", function () {
test("sign in", async function (assert) { test("sign in", async function (assert) {
@ -81,7 +81,7 @@ acceptance("Signing In", function () {
); );
}); });
skip("second factor", async function (assert) { test("second factor", async function (assert) {
await visit("/"); await visit("/");
await click("header .login-button"); await click("header .login-button");
@ -91,7 +91,6 @@ acceptance("Signing In", function () {
await fillIn("#login-account-password", "need-second-factor"); await fillIn("#login-account-password", "need-second-factor");
await click(".modal-footer .btn-primary"); await click(".modal-footer .btn-primary");
assert.not(exists("#modal-alert:visible"), "it hides the login error");
assert.not( assert.not(
exists("#credentials:visible"), exists("#credentials:visible"),
"it hides the username and password prompt" "it hides the username and password prompt"
@ -114,7 +113,7 @@ acceptance("Signing In", function () {
); );
}); });
skip("security key", async function (assert) { test("security key", async function (assert) {
await visit("/"); await visit("/");
await click("header .login-button"); await click("header .login-button");
@ -124,7 +123,6 @@ acceptance("Signing In", function () {
await fillIn("#login-account-password", "need-security-key"); await fillIn("#login-account-password", "need-security-key");
await click(".modal-footer .btn-primary"); await click(".modal-footer .btn-primary");
assert.not(exists("#modal-alert:visible"), "it hides the login error");
assert.not( assert.not(
exists("#credentials:visible"), exists("#credentials:visible"),
"it hides the username and password prompt" "it hides the username and password prompt"

View File

@ -1,19 +0,0 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { skip } from "qunit";
import { visit } from "@ember/test-helpers";
acceptance("Sticky Avatars", function () {
skip("Adds sticky avatars when scrolling up", async function (assert) {
const container = document.getElementById("ember-testing-container");
container.scrollTo(0, 0);
await visit("/t/internationalization-localization/280");
container.scrollTo(0, 800);
container.scrollTo(0, 700);
assert.ok(
query("#post_5").parentElement.classList.contains("sticky-avatar"),
"Sticky avatar is applied"
);
});
});

View File

@ -1,12 +1,13 @@
import { import {
acceptance, acceptance,
chromeTest,
exists, exists,
queryAll, queryAll,
selectText, selectText,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n"; import I18n from "I18n";
import { click, triggerKeyEvent, visit } from "@ember/test-helpers"; import { click, triggerKeyEvent, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
// This tests are flaky on Firefox. Fails with `calling set on destroyed object` // This tests are flaky on Firefox. Fails with `calling set on destroyed object`
acceptance("Topic - Quote button - logged in", function (needs) { acceptance("Topic - Quote button - logged in", function (needs) {
@ -16,42 +17,50 @@ acceptance("Topic - Quote button - logged in", function (needs) {
share_quote_buttons: "twitter|email", share_quote_buttons: "twitter|email",
}); });
// All these skips were chromeTest chromeTest(
skip("Does not show the quote share buttons by default", async function (assert) { "Does not show the quote share buttons by default",
await visit("/t/internationalization-localization/280"); async function (assert) {
await selectText("#post_5 blockquote"); await visit("/t/internationalization-localization/280");
assert.ok(exists(".insert-quote"), "it shows the quote button"); await selectText("#post_5 blockquote");
assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); assert.ok(exists(".insert-quote"), "it shows the quote button");
}); assert.ok(!exists(".quote-sharing"), "it does not show quote sharing");
}
);
skip("Shows quote share buttons with the right site settings", async function (assert) { chromeTest(
this.siteSettings.share_quote_visibility = "all"; "Shows quote share buttons with the right site settings",
async function (assert) {
this.siteSettings.share_quote_visibility = "all";
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await selectText("#post_5 blockquote"); await selectText("#post_5 blockquote");
assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); assert.ok(exists(".quote-sharing"), "it shows the quote sharing options");
assert.ok( assert.ok(
exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`),
"it includes the twitter share button" "it includes the twitter share button"
); );
assert.ok( assert.ok(
exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`),
"it includes the email share button" "it includes the email share button"
); );
}); }
);
skip("Quoting a Onebox should not copy the formatting of the rendered Onebox", async function (assert) { chromeTest(
await visit("/t/topic-for-group-moderators/2480"); "Quoting a Onebox should not copy the formatting of the rendered Onebox",
await selectText("#post_3 aside.onebox p"); async function (assert) {
await click(".insert-quote"); await visit("/t/topic-for-group-moderators/2480");
await selectText("#post_3 aside.onebox p");
await click(".insert-quote");
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-input").val().trim(), queryAll(".d-editor-input").val().trim(),
'[quote="group_moderator, post:3, topic:2480"]\nhttps://example.com/57350945\n[/quote]', '[quote="group_moderator, post:3, topic:2480"]\nhttps://example.com/57350945\n[/quote]',
"quote only contains a link" "quote only contains a link"
); );
}); }
);
}); });
acceptance("Topic - Quote button - anonymous", function (needs) { acceptance("Topic - Quote button - anonymous", function (needs) {
@ -60,48 +69,60 @@ acceptance("Topic - Quote button - anonymous", function (needs) {
share_quote_buttons: "twitter|email", share_quote_buttons: "twitter|email",
}); });
skip("Shows quote share buttons with the right site settings", async function (assert) { chromeTest(
await visit("/t/internationalization-localization/280"); "Shows quote share buttons with the right site settings",
await selectText("#post_5 blockquote"); async function (assert) {
await visit("/t/internationalization-localization/280");
await selectText("#post_5 blockquote");
assert.ok(queryAll(".quote-sharing"), "it shows the quote sharing options"); assert.ok(
assert.ok( queryAll(".quote-sharing"),
exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), "it shows the quote sharing options"
"it includes the twitter share button" );
); assert.ok(
assert.ok( exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`),
exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), "it includes the twitter share button"
"it includes the email share button" );
); assert.ok(
assert.ok(!exists(".insert-quote"), "it does not show the quote button"); exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`),
}); "it includes the email share button"
);
assert.ok(!exists(".insert-quote"), "it does not show the quote button");
}
);
skip("Shows single share button when site setting only has one item", async function (assert) { chromeTest(
this.siteSettings.share_quote_buttons = "twitter"; "Shows single share button when site setting only has one item",
async function (assert) {
this.siteSettings.share_quote_buttons = "twitter";
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await selectText("#post_5 blockquote"); await selectText("#post_5 blockquote");
assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); assert.ok(exists(".quote-sharing"), "it shows the quote sharing options");
assert.ok( assert.ok(
exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`),
"it includes the twitter share button" "it includes the twitter share button"
); );
assert.ok( assert.ok(
!exists(".quote-share-label"), !exists(".quote-share-label"),
"it does not show the Share label" "it does not show the Share label"
); );
}); }
);
skip("Shows nothing when visibility is disabled", async function (assert) { chromeTest(
this.siteSettings.share_quote_visibility = "none"; "Shows nothing when visibility is disabled",
async function (assert) {
this.siteSettings.share_quote_visibility = "none";
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await selectText("#post_5 blockquote"); await selectText("#post_5 blockquote");
assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); assert.ok(!exists(".quote-sharing"), "it does not show quote sharing");
assert.ok(!exists(".insert-quote"), "it does not show the quote button"); assert.ok(!exists(".insert-quote"), "it does not show the quote button");
}); }
);
}); });
acceptance("Topic - Quote button - keyboard shortcut", function (needs) { acceptance("Topic - Quote button - keyboard shortcut", function (needs) {

View File

@ -1,6 +1,6 @@
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers"; import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
import { click, currentURL, visit } from "@ember/test-helpers"; import { click, currentURL, visit } from "@ember/test-helpers";
import { skip, test } from "qunit"; import { test } from "qunit";
acceptance("Category 404", function (needs) { acceptance("Category 404", function (needs) {
needs.pretender((server, helper) => { needs.pretender((server, helper) => {
@ -12,7 +12,7 @@ acceptance("Category 404", function (needs) {
}); });
}); });
}); });
skip("Navigating to a bad category link does not break the router", async function (assert) { test("Navigating to a bad category link does not break the router", async function (assert) {
await visit("/t/internationalization-localization/280"); await visit("/t/internationalization-localization/280");
await click('[data-for-test="category-404"]'); await click('[data-for-test="category-404"]');

View File

@ -12,7 +12,7 @@ import {
import { forceMobile, resetMobile } from "discourse/lib/mobile"; import { forceMobile, resetMobile } from "discourse/lib/mobile";
import { getApplication, getContext, settled } from "@ember/test-helpers"; import { getApplication, getContext, settled } from "@ember/test-helpers";
import { getOwner } from "discourse-common/lib/get-owner"; import { getOwner } from "discourse-common/lib/get-owner";
import { later, run } from "@ember/runloop"; import { run } from "@ember/runloop";
import { setupApplicationTest } from "ember-qunit"; import { setupApplicationTest } from "ember-qunit";
import { Promise } from "rsvp"; import { Promise } from "rsvp";
import Site from "discourse/models/site"; import Site from "discourse/models/site";
@ -434,16 +434,6 @@ QUnit.assert.containsInstance = function (collection, klass, message) {
}); });
}; };
export function waitFor(assert, callback, timeout) {
timeout = timeout || 500;
const done = assert.async();
later(() => {
callback();
done();
}, timeout);
}
export async function selectDate(selector, date) { export async function selectDate(selector, date) {
return new Promise((resolve) => { return new Promise((resolve) => {
const elem = document.querySelector(selector); const elem = document.querySelector(selector);

View File

@ -12,50 +12,36 @@ discourseModule("Integration | Component | ace-editor", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("css editor", { componentTest("css editor", {
skip: true,
template: hbs`{{ace-editor mode="css"}}`, template: hbs`{{ace-editor mode="css"}}`,
test(assert) { test(assert) {
assert.expect(1);
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
}, },
}); });
componentTest("html editor", { componentTest("html editor", {
skip: true,
template: hbs`{{ace-editor mode="html" content="<b>wat</b>"}}`, template: hbs`{{ace-editor mode="html" content="<b>wat</b>"}}`,
test(assert) { test(assert) {
assert.expect(1);
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
}, },
}); });
componentTest("sql editor", { componentTest("sql editor", {
skip: true,
template: hbs`{{ace-editor mode="sql" content="SELECT * FROM users"}}`, template: hbs`{{ace-editor mode="sql" content="SELECT * FROM users"}}`,
test(assert) { test(assert) {
assert.expect(1);
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
}, },
}); });
componentTest("disabled editor", { componentTest("disabled editor", {
skip: true,
template: hbs` template: hbs`
{{ace-editor mode="sql" content="SELECT * FROM users" disabled=true}} {{ace-editor mode="sql" content="SELECT * FROM users" disabled=true}}
`, `,
test(assert) { test(assert) {
const $ace = queryAll(".ace_editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
assert.expect(3); assert.equal(
assert.ok($ace.length, "it renders the ace editor"); queryAll(".ace-wrapper[data-disabled]").length,
assert.strictEqual( 1,
$ace.parent().data().editor.getReadOnly(), "it has a data-disabled attr"
true,
"it sets ACE to read-only mode"
);
assert.strictEqual(
$ace.parent().attr("data-disabled"),
"true",
"ACE wrapper has `data-disabled` attribute set to true"
); );
}, },
}); });

View File

@ -16,8 +16,6 @@ discourseModule("Integration | Component | value-list", function (hooks) {
componentTest("adding a value", { componentTest("adding a value", {
template: hbs`{{value-list values=values}}`, template: hbs`{{value-list values=values}}`,
skip: true,
beforeEach() { beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
}, },
@ -132,8 +130,6 @@ discourseModule("Integration | Component | value-list", function (hooks) {
this.set("values", "vinkas|osama"); this.set("values", "vinkas|osama");
}, },
skip: true,
async test(assert) { async test(assert) {
await selectKit().expand(); await selectKit().expand();
await selectKit().fillInFilter("eviltrout"); await selectKit().fillInFilter("eviltrout");

View File

@ -24,7 +24,6 @@ discourseModule(
componentTest("basics", { componentTest("basics", {
template: hbs`{{mount-widget widget="home-logo" args=args}}`, template: hbs`{{mount-widget widget="home-logo" args=args}}`,
skip: true,
beforeEach() { beforeEach() {
this.siteSettings.site_logo_url = bigLogo; this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_small_url = smallLogo; this.siteSettings.site_logo_small_url = smallLogo;

View File

@ -1,107 +0,0 @@
import { fixture, logIn } from "discourse/tests/helpers/qunit-helpers";
import { module, skip } from "qunit";
import ClickTrack from "discourse/lib/click-track";
import DiscourseURL from "discourse/lib/url";
import User from "discourse/models/user";
import pretender from "discourse/tests/helpers/create-pretender";
import sinon from "sinon";
const track = ClickTrack.trackClick;
function generateClickEventOn(selector) {
return $.Event("click", { currentTarget: fixture(selector) });
}
module("Unit | Utility | click-track-edit-history", function (hooks) {
hooks.beforeEach(function () {
logIn();
let win = { focus: function () {} };
sinon.stub(window, "open").returns(win);
sinon.stub(win, "focus");
sinon.stub(DiscourseURL, "routeTo");
sinon.stub(DiscourseURL, "redirectTo");
sessionStorage.clear();
fixture().innerHTML = `<div id="topic" data-topic-id="1337">
</div>
<div id="revisions" data-post-id="42" class="">
<div class="row">
<div>
<a href="http://www.google.com">google.com</a>
<a class="lightbox back" href="http://www.google.com">google.com</a>
<div class="onebox-result">
<a id="inside-onebox" href="http://www.google.com">google.com<span class="badge">1</span></a>
<a id="inside-onebox-forced" class="track-link" href="http://www.google.com">google.com<span class="badge">1</span></a>
</div>
<a class="no-track-link" href="http://www.google.com">google.com</a>
<a id="same-site" href="http://discuss.domain.com">forum</a>
<a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>
<a class="hashtag" href="http://discuss.domain.com">#hashtag</a>
</div>
<div>
<a href="http://www.google.com">google.com</a>
<a class="lightbox back" href="http://www.google.com">google.com</a>
<div class="onebox-result">
<a id="inside-onebox" href="http://www.google.com">google.com<span class="badge">1</span></a>
<a id="inside-onebox-forced" class="track-link" href="http://www.google.com">google.com<span class="badge">1</span></a>
</div>
<a class="no-track-link" href="http://www.google.com">google.com</a>
<a id="same-site" href="http://discuss.domain.com">forum</a>
<a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>
<a class="hashtag" href="http://discuss.domain.com">#hashtag</a>
</div>
</div>
</div>`;
});
skip("tracks internal URLs", async function (assert) {
assert.expect(2);
sinon.stub(DiscourseURL, "origin").returns("http://discuss.domain.com");
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fdiscuss.domain.com&post_id=42&topic_id=1337"
);
done();
});
assert.notOk(track(generateClickEventOn("#same-site")));
});
skip("tracks external URLs", async function (assert) {
assert.expect(2);
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fwww.google.com&post_id=42&topic_id=1337"
);
done();
});
assert.notOk(track(generateClickEventOn("a")));
});
skip("tracks external URLs when opening in another window", async function (assert) {
assert.expect(3);
User.currentProp("external_links_in_new_tab", true);
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fwww.google.com&post_id=42&topic_id=1337"
);
done();
});
assert.notOk(track(generateClickEventOn("a")));
assert.ok(window.open.calledWith("http://www.google.com", "_blank"));
});
});

View File

@ -1,98 +0,0 @@
import { fixture, logIn } from "discourse/tests/helpers/qunit-helpers";
import { module, skip } from "qunit";
import ClickTrack from "discourse/lib/click-track";
import DiscourseURL from "discourse/lib/url";
import pretender from "discourse/tests/helpers/create-pretender";
import sinon from "sinon";
const track = ClickTrack.trackClick;
function generateClickEventOn(selector) {
return $.Event("click", { currentTarget: fixture(selector) });
}
module("Unit | Utility | click-track-profile-page", function (hooks) {
hooks.beforeEach(function () {
logIn();
let win = { focus: function () {} };
sinon.stub(window, "open").returns(win);
sinon.stub(win, "focus");
sinon.stub(DiscourseURL, "routeTo");
sinon.stub(DiscourseURL, "redirectTo");
sessionStorage.clear();
fixture().innerHTML = `<p class="excerpt first" data-post-id="42" data-topic-id="1337" data-user-id="3141">
<a href="http://www.google.com">google.com</a>
<a class="lightbox back" href="http://www.google.com">google.com</a>
<div class="onebox-result">
<a id="inside-onebox" href="http://www.google.com">google.com<span class="badge">1</span></a>
<a id="inside-onebox-forced" class="track-link" href="http://www.google.com">google.com<span class="badge">1</span></a>
</div>
<a class="no-track-link" href="http://www.google.com">google.com</a>
<a id="same-site" href="http://discuss.domain.com">forum</a>
<a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>
<a class="hashtag" href="http://discuss.domain.com">#hashtag</a>
</p>
<p class="excerpt second" data-post-id="24" data-topic-id="7331" data-user-id="1413">
<a href="http://www.google.com">google.com</a>
<a class="lightbox back" href="http://www.google.com">google.com</a>
<div class="onebox-result">
<a id="inside-onebox" href="http://www.google.com">google.com<span class="badge">1</span></a>
<a id="inside-onebox-forced" class="track-link" href="http://www.google.com">google.com<span class="badge">1</span></a>
</div>
<a class="no-track-link" href="http://www.google.com">google.com</a>
<a id="same-site" href="http://discuss.domain.com">forum</a>
<a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>
<a class="hashtag" href="http://discuss.domain.com">#hashtag</a>
</p>`;
});
skip("tracks internal URLs", async function (assert) {
assert.expect(2);
sinon.stub(DiscourseURL, "origin").returns("http://discuss.domain.com");
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fdiscuss.domain.com"
);
done();
});
assert.notOk(track(generateClickEventOn("#same-site")));
});
skip("tracks external URLs", async function (assert) {
assert.expect(2);
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fwww.google.com&post_id=42&topic_id=1337"
);
done();
});
assert.notOk(track(generateClickEventOn("a")));
});
skip("tracks external URLs in other posts", async function (assert) {
assert.expect(2);
const done = assert.async();
pretender.post("/clicks/track", (request) => {
assert.strictEqual(
request.requestBody,
"url=http%3A%2F%2Fwww.google.com&post_id=24&topic_id=7331"
);
done();
});
assert.notOk(track(generateClickEventOn(".second a")));
});
});

View File

@ -1,23 +1,8 @@
import { cacheBuster, loadScript } from "discourse/lib/load-script"; import { cacheBuster } from "discourse/lib/load-script";
import { module, skip, test } from "qunit"; import { module, test } from "qunit";
import { PUBLIC_JS_VERSIONS as jsVersions } from "discourse/lib/public-js-versions"; import { PUBLIC_JS_VERSIONS as jsVersions } from "discourse/lib/public-js-versions";
module("Unit | Utility | load-script", function () { module("Unit | Utility | load-script", function () {
skip("load with a script tag, and callbacks are only executed after script is loaded", async function (assert) {
assert.ok(
typeof window.ace === "undefined",
"ensures ace is not previously loaded"
);
const src = "/javascripts/ace/ace.js";
await loadScript(src);
assert.ok(
typeof window.ace !== "undefined",
"callbacks should only be executed after the script has fully loaded"
);
});
test("works when a value is not present", function (assert) { test("works when a value is not present", function (assert) {
assert.strictEqual( assert.strictEqual(
cacheBuster("/javascripts/my-script.js"), cacheBuster("/javascripts/my-script.js"),

View File

@ -3,7 +3,7 @@ import {
applyCachedInlineOnebox, applyCachedInlineOnebox,
deleteCachedInlineOnebox, deleteCachedInlineOnebox,
} from "pretty-text/inline-oneboxer"; } from "pretty-text/inline-oneboxer";
import QUnit, { module, skip, test } from "qunit"; import QUnit, { module, test } from "qunit";
import Post from "discourse/models/post"; import Post from "discourse/models/post";
import { buildQuote } from "discourse/lib/quote"; import { buildQuote } from "discourse/lib/quote";
import { deepMerge } from "discourse-common/lib/object"; import { deepMerge } from "discourse-common/lib/object";
@ -54,20 +54,6 @@ QUnit.assert.cookedPara = function (input, expected, message) {
}; };
module("Unit | Utility | pretty-text", function () { module("Unit | Utility | pretty-text", function () {
skip("Pending Engine fixes and spec fixes", function (assert) {
assert.cooked(
"Derpy: http://derp.com?_test_=1",
'<p>Derpy: <a href=https://derp.com?_test_=1"http://derp.com?_test_=1">http://derp.com?_test_=1</a></p>',
"works with underscores in urls"
);
assert.cooked(
"**a*_b**",
"<p><strong>a*_b</strong></p>",
"allows for characters within bold"
);
});
test("buildOptions", function (assert) { test("buildOptions", function (assert) {
assert.ok( assert.ok(
buildOptions({ siteSettings: { enable_emoji: true } }).discourse.features buildOptions({ siteSettings: { enable_emoji: true } }).discourse.features

View File

@ -15,7 +15,7 @@ import {
slugify, slugify,
toAsciiPrintable, toAsciiPrintable,
} from "discourse/lib/utilities"; } from "discourse/lib/utilities";
import { skip, test } from "qunit"; import { test } from "qunit";
import Handlebars from "handlebars"; import Handlebars from "handlebars";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
@ -282,21 +282,4 @@ discourseModule("Unit | Utilities", function () {
} }
}); });
}); });
skip("inCodeBlock - runs fast", function (assert) {
const phrase = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
const text = `${phrase}\n\n\`\`\`\n${phrase}\n\`\`\`\n\n${phrase}\n\n\`${phrase}\n${phrase}\n\n${phrase}\n\n[code]\n${phrase}\n[/code]\n\n${phrase}\n\n ${phrase}\n\n\`${phrase}\`\n\n${phrase}`;
let time = Number.MAX_VALUE;
for (let i = 0; i < 10; ++i) {
const start = performance.now();
inCodeBlock(text, text.length);
const end = performance.now();
time = Math.min(time, end - start);
}
// This runs in 'keyUp' event handler so it should run as fast as
// possible. It should take less than 1ms for the test text.
assert.ok(time < 10);
});
}); });