diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js
index 230b65a5adf..535d4897f0f 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js
@@ -1,5 +1,11 @@
-import { moduleFor, ApplicationTestCase, RenderingTestCase, runTask } from 'internal-test-helpers';
-
+import {
+ moduleFor,
+ ApplicationTestCase,
+ RenderingTestCase,
+ RouterNonApplicationTestCase,
+ runTask,
+} from 'internal-test-helpers';
+import { Router, Route } from '@ember/-internals/routing';
import Controller from '@ember/controller';
import { set } from '@ember/-internals/metal';
import { LinkComponent } from '@ember/-internals/glimmer';
@@ -92,6 +98,38 @@ moduleFor(
this.assertText('Hello');
});
}
+
+ ['@test able to pupolate innermost dynamic segment when immediate parent route is active']() {
+ this.addTemplate('application', '{{outlet}}');
+ this.addTemplate('parents', '{{outlet}}');
+ this.addTemplate(
+ 'parents.parent',
+ 'Link To Child'
+ );
+ this.addTemplate(
+ 'parents.parent.child',
+ 'Link To Parent'
+ );
+ this.add(
+ 'route:parents.parent',
+ class extends Route {
+ async model({ id }) {
+ return { value: id };
+ }
+ }
+ );
+ this.router.map(function () {
+ this.route('parents', function () {
+ this.route('parent', { path: '/:parent_id' }, function () {
+ this.route('children');
+ this.route('child', { path: '/child/:child_id' });
+ });
+ });
+ });
+ return this.visit('/parents/1').then(() => {
+ this.assertText('Link To Child');
+ });
+ }
}
);
@@ -103,9 +141,40 @@ moduleFor(
this.assertComponentElement(this.element.firstChild, {
tagName: 'a',
- attrs: { href: '#/' },
+ attrs: { href: null },
content: 'Go to Index',
});
}
}
);
+
+moduleFor(
+ ' component (rendering tests, with router not started)',
+ class extends RouterNonApplicationTestCase {
+ constructor() {
+ super(...arguments);
+ this.resolver.add('router:main', Router.extend(this.routerOptions));
+ this.router.map(function () {
+ this.route('dynamicWithChild', { path: '/dynamic-with-child/:dynamic_id' }, function () {
+ this.route('child');
+ });
+ });
+ }
+ get routerOptions() {
+ return {
+ location: 'none',
+ };
+ }
+ get router() {
+ return this.owner.resolveRegistration('router:main');
+ }
+
+ ['@test should be able to be inserted in DOM when router is setup but not started']() {
+ this.render(`Link`);
+ this.assertComponentElement(this.element.firstChild, {
+ tagName: 'a',
+ content: 'Link',
+ });
+ }
+ }
+);
diff --git a/packages/@ember/-internals/routing/lib/services/routing.ts b/packages/@ember/-internals/routing/lib/services/routing.ts
index d459c07bacd..23d850e855d 100644
--- a/packages/@ember/-internals/routing/lib/services/routing.ts
+++ b/packages/@ember/-internals/routing/lib/services/routing.ts
@@ -54,8 +54,9 @@ export default class RoutingService extends Service {
generateURL(routeName: string, models: {}[], queryParams: {}) {
let router = this.router;
- // return early when the router microlib is not present, which is the case for {{link-to}} in integration tests
- if (!router._routerMicrolib) {
+ // Return early when transition has not started, when rendering in tests without visit(),
+ // we cannot infer the route context which needs be aware of
+ if (!router._initialTransitionStarted) {
return;
}
diff --git a/packages/@ember/-internals/routing/lib/system/router.ts b/packages/@ember/-internals/routing/lib/system/router.ts
index a9439cb8643..1fa016d866a 100644
--- a/packages/@ember/-internals/routing/lib/system/router.ts
+++ b/packages/@ember/-internals/routing/lib/system/router.ts
@@ -130,6 +130,7 @@ class EmberRouter extends EmberObject {
rootURL!: string;
_routerMicrolib!: Router;
_didSetupRouter = false;
+ _initialTransitionStarted = false;
currentURL: string | null = null;
currentRouteName: string | null = null;
@@ -507,6 +508,7 @@ class EmberRouter extends EmberObject {
}
_doURLTransition(routerJsMethod: string, url: string) {
+ this._initialTransitionStarted = true;
let transition = this._routerMicrolib[routerJsMethod](url || '/');
didBeginTransition(transition, this);
return transition;
@@ -621,6 +623,7 @@ class EmberRouter extends EmberObject {
*/
reset() {
this._didSetupRouter = false;
+ this._initialTransitionStarted = false;
if (this._routerMicrolib) {
this._routerMicrolib.reset();
}
@@ -842,6 +845,8 @@ class EmberRouter extends EmberObject {
Boolean(targetRouteName) && this._routerMicrolib.hasRoute(targetRouteName)
);
+ this._initialTransitionStarted = true;
+
let queryParams = {};
this._processActiveTransitionQueryParams(targetRouteName, models, queryParams, _queryParams);