DEV: Update plugin-outlet tests (#27630)

qunit-dom, reformat hbs blocks, use `<template>` where possible
This commit is contained in:
Jarek Radosz 2024-06-27 19:36:55 +02:00 committed by GitHub
parent 57eecbef4b
commit 3ce618e57a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 181 additions and 104 deletions

View File

@ -1,16 +1,18 @@
import Component from "@glimmer/component";
import { getOwner } from "@ember/application";
import templateOnly from "@ember/component/template-only";
import { hash } from "@ember/helper";
import { getOwner } from "@ember/owner";
import { click, render, settled } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit";
import sinon from "sinon";
import PluginOutlet from "discourse/components/plugin-outlet";
import {
extraConnectorClass,
extraConnectorComponent,
} from "discourse/lib/plugin-connectors";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
import { query } from "discourse/tests/helpers/qunit-helpers";
import { registerTemporaryModule } from "discourse/tests/helpers/temporary-module-helper";
import {
withSilencedDeprecations,
@ -60,25 +62,49 @@ module("Integration | Component | plugin-outlet", function (hooks) {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/test-name/hello`,
hbs`<span class='hello-username'>{{this.username}}</span>
<button type="button" class='say-hello' {{on "click" (action "sayHello")}}></button>
<button type="button" class='say-hello-using-this' {{on "click" this.sayHello}}></button>
<span class='hello-result'>{{this.hello}}</span>`
hbs`
<span class="hello-username">{{this.username}}</span>
<button
type="button"
class="say-hello"
{{on "click" (action "sayHello")}}
></button>
<button
type="button"
class="say-hello-using-this"
{{on "click" this.sayHello}}
></button>
<span class="hello-result">{{this.hello}}</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/test-name/hi`,
hbs`<button type="button" class='say-hi' {{on "click" (action "sayHi")}}></button>
<span class='hi-result'>{{this.hi}}</span>`
hbs`
<button
type="button"
class="say-hi"
{{on "click" (action "sayHi")}}
></button>
<span class="hi-result">{{this.hi}}</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/test-name/conditional-render`,
hbs`<span class="conditional-render">I only render sometimes</span>`
hbs`
<span class="conditional-render">I only render sometimes</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default/my-connector`,
hbs`<span class='result'>Plugin implementation{{#if @outletArgs.yieldCore}} {{yield}}{{/if}}</span>`
hbs`
<span class="result">Plugin implementation{{#if @outletArgs.yieldCore}}
{{yield}}{{/if}}</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default/clashing-connector`,
hbs`This will override my-connector and raise an error`
@ -86,35 +112,28 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("Renders a template into the outlet", async function (assert) {
this.set("shouldDisplay", false);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash shouldDisplay=this.shouldDisplay}} />`
);
assert.strictEqual(count(".hello-username"), 1, "renders the hello outlet");
assert.false(
exists(".conditional-render"),
"doesn't render conditional outlet"
);
await render(hbs`<PluginOutlet @name="test-name" />`);
assert
.dom(".hello-username")
.exists({ count: 1 }, "renders the hello outlet");
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
await click(".say-hello");
assert.strictEqual(
query(".hello-result").innerText,
"hello!",
"actions delegate properly"
);
assert.dom(".hello-result").hasText("hello!", "actions delegate properly");
await click(".say-hello-using-this");
assert.strictEqual(
query(".hello-result").innerText,
"hello!hello!",
"actions are made available on `this` and are bound correctly"
);
assert
.dom(".hello-result")
.hasText(
"hello!hello!",
"actions are made available on `this` and are bound correctly"
);
await click(".say-hi");
assert.strictEqual(
query(".hi-result").innerText,
"hi!",
"actions delegate properly"
);
assert.dom(".hi-result").hasText("hi!", "actions delegate properly");
});
module(
@ -146,10 +165,17 @@ module("Integration | Component | plugin-outlet", function (hooks) {
);
this.template = hbs`
<PluginOutlet @name="outlet-with-default" @outletArgs={{hash shouldDisplay=this.shouldDisplay yieldCore=this.yieldCore enableClashingConnector=this.enableClashingConnector}}>
<span class='result'>Core implementation</span>
</PluginOutlet>
`;
<PluginOutlet
@name="outlet-with-default"
@outletArgs={{hash
shouldDisplay=this.shouldDisplay
yieldCore=this.yieldCore
enableClashingConnector=this.enableClashingConnector
}}
>
<span class="result">Core implementation</span>
</PluginOutlet>
`;
});
test("Can act as a wrapper around core implementation", async function (assert) {
@ -230,12 +256,17 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("can render content in a automatic outlet generated before the wrapped content", async function (assert) {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__before/my-connector`,
hbs`<span class='before-result'>Before wrapped content</span>`
hbs`
<span class="before-result">Before wrapped content</span>
`
);
await render(hbs`
<PluginOutlet @name="outlet-with-default" @outletArgs={{hash shouldDisplay=true}}>
<span class='result'>Core implementation</span>
<PluginOutlet
@name="outlet-with-default"
@outletArgs={{hash shouldDisplay=true}}
>
<span class="result">Core implementation</span>
</PluginOutlet>
`);
@ -246,16 +277,25 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("can render multiple connector `before` the same wrapped content", async function (assert) {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__before/my-connector`,
hbs`<span class='before-result'>First connector before the wrapped content</span>`
hbs`
<span class="before-result">First connector before the wrapped
content</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__before/my-connector2`,
hbs`<span class='before-result2'>Second connector before the wrapped content</span>`
hbs`
<span class="before-result2">Second connector before the wrapped
content</span>
`
);
await render(hbs`
<PluginOutlet @name="outlet-with-default" @outletArgs={{hash shouldDisplay=true}}>
<span class='result'>Core implementation</span>
<PluginOutlet
@name="outlet-with-default"
@outletArgs={{hash shouldDisplay=true}}
>
<span class="result">Core implementation</span>
</PluginOutlet>
`);
@ -271,12 +311,17 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("can render content in a automatic outlet generated after the wrapped content", async function (assert) {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__after/my-connector`,
hbs`<span class='after-result'>After wrapped content</span>`
hbs`
<span class="after-result">After wrapped content</span>
`
);
await render(hbs`
<PluginOutlet @name="outlet-with-default" @outletArgs={{hash shouldDisplay=true}}>
<span class='result'>Core implementation</span>
<PluginOutlet
@name="outlet-with-default"
@outletArgs={{hash shouldDisplay=true}}
>
<span class="result">Core implementation</span>
</PluginOutlet>
`);
@ -287,16 +332,24 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("can render multiple connector `after` the same wrapped content", async function (assert) {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__after/my-connector`,
hbs`<span class='after-result'>First connector after the wrapped content</span>`
hbs`
<span class="after-result">First connector after the wrapped content</span>
`
);
registerTemporaryModule(
`${TEMPLATE_PREFIX}/outlet-with-default__after/my-connector2`,
hbs`<span class='after-result2'>Second connector after the wrapped content</span>`
hbs`
<span class="after-result2">Second connector after the wrapped
content</span>
`
);
await render(hbs`
<PluginOutlet @name="outlet-with-default" @outletArgs={{hash shouldDisplay=true}}>
<span class='result'>Core implementation</span>
<PluginOutlet
@name="outlet-with-default"
@outletArgs={{hash shouldDisplay=true}}
>
<span class="result">Core implementation</span>
</PluginOutlet>
`);
@ -312,59 +365,58 @@ module("Integration | Component | plugin-outlet", function (hooks) {
);
test("Renders wrapped implementation if no connectors are registered", async function (assert) {
await render(
hbs`
<PluginOutlet @name="outlet-with-no-registrations">
<span class='result'>Core implementation</span>
</PluginOutlet>
`
);
await render(<template>
<PluginOutlet @name="outlet-with-no-registrations">
<span class="result">Core implementation</span>
</PluginOutlet>
</template>);
assert.dom(".result").hasText("Core implementation");
});
test("Reevaluates shouldRender for argument changes", async function (assert) {
this.set("shouldDisplay", false);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash shouldDisplay=this.shouldDisplay}} />`
);
assert.false(
exists(".conditional-render"),
"doesn't render conditional outlet"
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash shouldDisplay=this.shouldDisplay}}
/>
`);
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
this.set("shouldDisplay", true);
await settled();
assert.true(exists(".conditional-render"), "renders conditional outlet");
assert.dom(".conditional-render").exists("renders conditional outlet");
});
test("Reevaluates shouldRender for other autotracked changes", async function (assert) {
this.set("shouldDisplay", false);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash shouldDisplay=this.shouldDisplay}} />`
);
assert.false(
exists(".conditional-render"),
"doesn't render conditional outlet"
);
await render(hbs`<PluginOutlet @name="test-name" />`);
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
getOwner(this).lookup("service:site-settings").always_display = true;
await settled();
assert.true(exists(".conditional-render"), "renders conditional outlet");
assert.dom(".conditional-render").exists("renders conditional outlet");
});
test("Other outlets are not re-rendered", async function (assert) {
this.set("shouldDisplay", false);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash shouldDisplay=this.shouldDisplay}} />`
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash shouldDisplay=this.shouldDisplay}}
/>
`);
const otherOutletElement = query(".hello-username");
otherOutletElement.someUniqueProperty = true;
this.set("shouldDisplay", true);
await settled();
assert.true(exists(".conditional-render"), "renders conditional outlet");
assert.dom(".conditional-render").exists("renders conditional outlet");
assert.true(
query(".hello-username").someUniqueProperty,
@ -381,23 +433,31 @@ module(
hooks.beforeEach(function () {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/test-name/my-connector`,
hbs`<span class='outletArgHelloValue'>{{@outletArgs.hello}}</span><span class='thisHelloValue'>{{this.hello}}</span>`
hbs`
<span class="outletArgHelloValue">{{@outletArgs.hello}}</span><span
class="thisHelloValue"
>{{this.hello}}</span>
`
);
});
test("uses classic PluginConnector by default", async function (assert) {
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world"}} />`
);
await render(hbs`
<PluginOutlet @name="test-name" @outletArgs={{hash hello="world"}} />
`);
assert.dom(".outletArgHelloValue").hasText("world");
assert.dom(".thisHelloValue").hasText("world");
});
test("uses templateOnly by default when @defaultGlimmer=true", async function (assert) {
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world"}} @defaultGlimmer={{true}} />`
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash hello="world"}}
@defaultGlimmer={{true}}
/>
`);
assert.dom(".outletArgHelloValue").hasText("world");
assert.dom(".thisHelloValue").hasText(""); // `this.` unavailable in templateOnly components
@ -420,9 +480,12 @@ module(
},
});
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world" someBoolean=this.someBoolean}} />`
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash hello="world" someBoolean=this.someBoolean}}
/>
`);
assert.dom(".outletArgHelloValue").hasText("world");
assert.dom(".thisHelloValue").hasText("world from setupComponent");
@ -447,9 +510,13 @@ module(
await withSilencedDeprecationsAsync(
"discourse.plugin-outlet-classic-hooks",
async () => {
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world"}} @defaultGlimmer={{true}} />`
);
await render(<template>
<PluginOutlet
@name="test-name"
@outletArgs={{hash hello="world"}}
@defaultGlimmer={{true}}
/>
</template>);
}
);
@ -473,9 +540,12 @@ module(
}
);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world" someBoolean=this.someBoolean}} />`
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash hello="world" someBoolean=this.someBoolean}}
/>
`);
assert.dom(".outletArgHelloValue").hasText("world");
assert.dom(".thisHelloValue").hasText("world from custom component");
@ -498,9 +568,12 @@ module(
})
);
await render(
hbs`<PluginOutlet @name="test-name" @outletArgs={{hash hello="world" someBoolean=this.someBoolean}} />`
);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{hash hello="world" someBoolean=this.someBoolean}}
/>
`);
assert.dom(".outletArgHelloValue").hasText("world");
assert.dom(".thisHelloValue").hasText(""); // `this.` unavailable in templateOnly components
@ -526,7 +599,7 @@ module(
});
test("detects a gjs connector with no associated template file", async function (assert) {
await render(hbs`<PluginOutlet @name="test-name" />`);
await render(<template><PluginOutlet @name="test-name" /></template>);
assert.dom(".gjs-test").hasText("Hello world");
});
@ -545,7 +618,7 @@ module(
});
test("renders the component in the outlet", async function (assert) {
await render(hbs`<PluginOutlet @name="test-name" />`);
await render(<template><PluginOutlet @name="test-name" /></template>);
assert.dom(".gjs-test").hasText("Hello world from gjs");
});
@ -574,7 +647,9 @@ module("Integration | Component | plugin-outlet | tagName", function (hooks) {
await withSilencedDeprecationsAsync(
"discourse.plugin-outlet-tag-name",
async () =>
await render(hbs`<PluginOutlet @name="test-name" @tagName="div" />`)
await render(<template>
<PluginOutlet @name="test-name" @tagName="div" />
</template>)
);
assert.dom("div").exists();
});
@ -588,7 +663,9 @@ module(
hooks.beforeEach(function () {
registerTemporaryModule(
`${TEMPLATE_PREFIX}/test-name/my-legacy-connector`,
hbs`<span class='legacy-test'>Hello world {{this.someVar}}</span>`
hbs`
<span class="legacy-test">Hello world {{this.someVar}}</span>
`
);
withSilencedDeprecations(