diff --git a/app/assets/javascripts/discourse/app/mapping-router.js b/app/assets/javascripts/discourse/app/mapping-router.js index d5f1e1874b..cb000cc1f3 100644 --- a/app/assets/javascripts/discourse/app/mapping-router.js +++ b/app/assets/javascripts/discourse/app/mapping-router.js @@ -141,10 +141,8 @@ export function mapRoutes() { this.route("unknown", { path: "*path" }); }); } -export function teardownRouter(container) { - const router = container.lookup("router:main"); - const constructor = Object.getPrototypeOf(router).constructor; - constructor.dslCallbacks.splice(0, constructor.dslCallbacks.length); +export function teardownRouter(routerClass) { + routerClass.dslCallbacks.splice(0, routerClass.dslCallbacks.length); } export function registerRouter(registry) { diff --git a/app/assets/javascripts/discourse/app/pre-initializers/map-routes.js b/app/assets/javascripts/discourse/app/pre-initializers/map-routes.js index 85bb8d2ace..19933c1480 100644 --- a/app/assets/javascripts/discourse/app/pre-initializers/map-routes.js +++ b/app/assets/javascripts/discourse/app/pre-initializers/map-routes.js @@ -9,8 +9,9 @@ export default { after: "inject-discourse-objects", initialize(container, app) { - let router = registerRouter(app); - container.registry.register("router:main", router); + let routerClass = registerRouter(app); + container.registry.register("router:main", routerClass); + this.routerClass = routerClass; if (isLegacyEmber()) { // HACK to fix: https://github.com/emberjs/ember.js/issues/10310 @@ -24,7 +25,7 @@ export default { } }, - teardown(container) { - teardownRouter(container); + teardown() { + teardownRouter(this.routerClass); }, }; diff --git a/app/assets/javascripts/discourse/tests/setup-tests.js b/app/assets/javascripts/discourse/tests/setup-tests.js index 4c3d16b564..30b36fda8d 100644 --- a/app/assets/javascripts/discourse/tests/setup-tests.js +++ b/app/assets/javascripts/discourse/tests/setup-tests.js @@ -73,9 +73,29 @@ function createApplication(config, settings) { setApplication(app); setResolver(buildResolver("discourse").create({ namespace: app })); + // Modern Ember only sets up a container when the ApplicationInstance + // is booted. We have legacy code which relies on having access to a container + // before boot (e.g. during pre-initializers) + // + // This hack sets up a container early, then stubs the container setup method + // so that Ember will use the same container instance when it boots the ApplicationInstance + // + // Note that this hack is not required in production because we use the default `autoboot` flag, + // which triggers the internal `_globalsMode` flag, which sets up an ApplicationInstance immediately when + // an Application is initialized (via the `_buildDeprecatedInstance` method). + // + // In the future, we should move away from relying on the `container` before the ApplicationInstance + // is booted, and then remove this hack. let container = app.__registry__.container(); app.__container__ = container; setDefaultOwner(container); + sinon + .stub(Object.getPrototypeOf(app.__registry__), "container") + .callsFake((opts) => { + container.owner = opts.owner; + container.registry = opts.owner.__registry__; + return container; + }); if (!started) { app.start(); @@ -395,6 +415,7 @@ export default function setupTests(config) { let settings = resetSettings(); app = createApplication(config, settings); setupTestsCommon(app, app.__container__, config); + sinon.restore(); } function getUrlParameter(name) {