From a5f79955949ea39135db8d59845e2d29e9b6f9bd Mon Sep 17 00:00:00 2001 From: Keegan George Date: Wed, 12 Oct 2022 14:19:24 -0700 Subject: [PATCH] FEATURE: Add `` component --- .../app/components/route-control.hbs | 3 + .../discourse/app/components/route-control.js | 51 ++++++++ .../tests/acceptance/route-control-test.js | 117 ++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 app/assets/javascripts/discourse/app/components/route-control.hbs create mode 100644 app/assets/javascripts/discourse/app/components/route-control.js create mode 100644 app/assets/javascripts/discourse/tests/acceptance/route-control-test.js diff --git a/app/assets/javascripts/discourse/app/components/route-control.hbs b/app/assets/javascripts/discourse/app/components/route-control.hbs new file mode 100644 index 0000000000..83d2bf0af9 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/route-control.hbs @@ -0,0 +1,3 @@ +{{#if this.canDisplay}} + {{yield}} +{{/if}} diff --git a/app/assets/javascripts/discourse/app/components/route-control.js b/app/assets/javascripts/discourse/app/components/route-control.js new file mode 100644 index 0000000000..e1eee5b605 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/route-control.js @@ -0,0 +1,51 @@ +import Component from "@glimmer/component"; +import { inject as service } from "@ember/service"; +import { defaultHomepage } from "discourse/lib/utilities"; + +export default class RouteControl extends Component { + @service router; + @service siteSettings; + @service currentUser; + + get canDisplay() { + const currentRouteName = this.router.currentRouteName; + const showOn = this.args.showOn; + const minTrustLevel = this.args.options?.minTrustLevel; + const requireUser = this.args.options?.requireUser + ? this.args.options?.requireUser + : false; + + if (requireUser && !this.currentUser) { + return; + } + + if ( + (minTrustLevel && this.currentUser?.trust_level < minTrustLevel) || + (minTrustLevel && !this.currentUser) + ) { + return; + } + + if (showOn === "homepage") { + return this.#handleHomepageRoute(currentRouteName); + } else if (showOn === currentRouteName) { + return true; + } else { + return false; + } + } + + #handleHomepageRoute(currentRouteName) { + const topMenu = this.siteSettings.top_menu; + + if (currentRouteName === `discovery.${defaultHomepage()}`) { + return true; + } else if ( + topMenu.split("|").any((m) => `discovery.${m}` === currentRouteName) + ) { + return true; + } else { + return false; + } + } +} diff --git a/app/assets/javascripts/discourse/tests/acceptance/route-control-test.js b/app/assets/javascripts/discourse/tests/acceptance/route-control-test.js new file mode 100644 index 0000000000..d2d7d72c9a --- /dev/null +++ b/app/assets/javascripts/discourse/tests/acceptance/route-control-test.js @@ -0,0 +1,117 @@ +import { + acceptance, + exists, + updateCurrentUser, +} from "discourse/tests/helpers/qunit-helpers"; +import { visit } from "@ember/test-helpers"; +import { test } from "qunit"; +import { extraConnectorClass } from "discourse/lib/plugin-connectors"; +import { hbs } from "ember-cli-htmlbars"; + +const PREFIX = "javascripts/single-test/connectors"; + +acceptance("Route Control (as visitor)", function (needs) { + needs.settings({ + top_menu: "latest|categories|top|bookmarks", + }); + needs.hooks.beforeEach(() => { + extraConnectorClass("below-site-header/hello"); + + // eslint-disable-next-line no-undef + Ember.TEMPLATES[`${PREFIX}/below-site-header/hello`] = hbs` + +

This should only show on the category page

+
+ +

This should only show on the homepage

+
+ +

Only users can see this

+
`; + }); + + test("Category content only shows on category page", async function (assert) { + await visit("/categories"); + assert.ok( + exists( + "#only-category-page", + "The content is shown on the category page." + ) + ); + await visit("/latest"); + assert.ok( + !exists( + "#only-category-page", + "The content is not shown on the latest page." + ) + ); + }); + + test("Homepage Content only shows on all homepage routes", async function (assert) { + await visit("/"); + assert.ok( + exists("#only-homepage", "The content is shown on the homepage.") + ); + + await visit("/categories"); + assert.ok( + exists("#only-homepage", "The content is shown on a homepage route.") + ); + + await visit("/t/internationalization-localization/280"); + assert.ok( + !exists( + "#only-homepage", + "The content is not shown on the categories page." + ) + ); + }); + + test("User only content doesn't show for visitors", async function (assert) { + await visit("/latest"); + assert.ok(!exists("#only-users"), "The content is not shown for visitors."); + }); +}); + +acceptance("Route Control (as user)", function (needs) { + needs.user(); + needs.settings({ + top_menu: "latest|categories|top|bookmarks", + }); + needs.hooks.beforeEach(() => { + extraConnectorClass("below-site-header/hello"); + + // eslint-disable-next-line no-undef + Ember.TEMPLATES[`${PREFIX}/below-site-header/hello`] = hbs` + +

Only users can see this

+
+ +

This should only show for 3 or above trust level

+
+`; + }); + + test("User only content shows for users", async function (assert) { + await visit("/latest"); + assert.ok(exists("#only-users"), "The content is visible for users."); + }); + + test("Content shows for trust level 3 user", async function (assert) { + await visit("/"); + assert.ok( + exists("#only-trust-level"), + "The content is visible for adequate trust level user." + ); + }); + + test("Content doesn't show for trust level 2 user", async function (assert) { + updateCurrentUser({ trust_level: 2 }); + await visit("/"); + + assert.ok( + !exists("#only-trust-level"), + "The content is not shown for low trust level user." + ); + }); +});