Skip to content

Commit ae3444d

Browse files
committed
Merge pull request #195 from arjansingh/redirect
FastBootLocation API
2 parents 377748d + 892854a commit ae3444d

18 files changed

Lines changed: 320 additions & 1 deletion

app/locations/none.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import Ember from 'ember';
2+
3+
const {
4+
computed,
5+
computed: { reads },
6+
inject: { service },
7+
get,
8+
getOwner
9+
} = Ember;
10+
11+
export default Ember.NoneLocation.extend({
12+
implementation: 'fastboot',
13+
fastboot: service(),
14+
15+
_fastbootHeadersEnabled: computed(function () {
16+
const config = getOwner(this).resolveRegistration('config:environment');
17+
return !!get(config, 'fastboot.fastbootHeaders');
18+
}),
19+
20+
_redirectCode: computed(function () {
21+
const TEMPORARY_REDIRECT_CODE = 307;
22+
const config = getOwner(this).resolveRegistration('config:environment');
23+
return get(config, 'fastboot.redirectCode') || TEMPORARY_REDIRECT_CODE;
24+
}),
25+
26+
_response: reads('fastboot.response'),
27+
_request: reads('fastboot.request'),
28+
29+
setURL(path) {
30+
if (get(this, 'fastboot.isFastBoot')) {
31+
const currentPath = get(this, 'path');
32+
const isInitialPath = !currentPath || currentPath.length === 0;
33+
const isTransitioning = currentPath !== path;
34+
let response = get(this, '_response');
35+
36+
if (isTransitioning && !isInitialPath) {
37+
let protocol = get(this, '_request.protocol');
38+
let host = get(this, '_request.host');
39+
let redirectURL = `${protocol}://${host}${path}`;
40+
41+
response.statusCode = this.get('_redirectCode');
42+
response.headers.set('location', redirectURL);
43+
}
44+
45+
// for testing and debugging
46+
if(get(this, '_fastbootHeadersEnabled')) {
47+
response.headers.set('x-fastboot-path', path);
48+
}
49+
}
50+
51+
this._super(...arguments);
52+
}
53+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"broccoli-merge-trees": "^1.1.1",
6666
"broccoli-plugin": "^1.2.1",
6767
"broccoli-stew": "^1.2.0",
68-
"fastboot-express-middleware": "1.0.0-beta.5",
68+
"fastboot-express-middleware": "1.0.0-beta.6",
6969
"ember-cli-babel": "^5.1.5",
7070
"ember-test-helpers": "^0.5.22",
7171
"express": "^4.8.5",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
var chai = require('chai');
2+
var expect = chai.expect;
3+
var RSVP = require('rsvp');
4+
var AddonTestApp = require('ember-cli-addon-tests').AddonTestApp;
5+
var request = require('request');
6+
var get = RSVP.denodeify(request);
7+
8+
describe('FastBootLocation Configuration', function () {
9+
this.timeout(300000);
10+
11+
before(function () {
12+
app = new AddonTestApp();
13+
14+
return app.create('fastboot-location-config')
15+
.then(function () {
16+
return app.startServer({
17+
command: 'fastboot',
18+
additionalArguments: ['--serve-assets']
19+
});
20+
});
21+
});
22+
23+
after(function () {
24+
return app.stopServer();
25+
});
26+
27+
it('should use the redirect code provided by the EmberApp', function () {
28+
return get({
29+
url: 'http://localhost:49741/redirect-on-transition-to',
30+
followRedirect: false
31+
})
32+
.then(function (response) {
33+
if (response.statusCode === 500) throw new Error (response.body);
34+
expect(response.statusCode).to.equal(302);
35+
});
36+
});
37+
38+
describe('when fastboot.fastbootHeaders is false', function () {
39+
it('should not send the "x-fastboot-path" header on a redirect', function () {
40+
return get({
41+
url: 'http://localhost:49741/redirect-on-transition-to',
42+
followRedirect: false
43+
})
44+
.then(function (response) {
45+
if (response.statusCode === 500) throw new Error (response.body);
46+
expect(response.headers).to.not.include.keys([
47+
'x-fastboot-path'
48+
]);
49+
});
50+
});
51+
});
52+
});

test/fastboot-location-test.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
var chai = require('chai');
2+
var expect = chai.expect;
3+
var RSVP = require('rsvp');
4+
var AddonTestApp = require('ember-cli-addon-tests').AddonTestApp;
5+
var request = require('request');
6+
var get = RSVP.denodeify(request);
7+
8+
describe('FastBootLocation', function () {
9+
this.timeout(300000);
10+
11+
before(function () {
12+
app = new AddonTestApp();
13+
14+
return app.create('fastboot-location')
15+
.then(function () {
16+
return app.startServer({
17+
command: 'fastboot',
18+
additionalArguments: ['--serve-assets']
19+
});
20+
});
21+
});
22+
23+
after(function () {
24+
return app.stopServer();
25+
});
26+
27+
it('should NOT redirect when no transition is called', function () {
28+
return get({
29+
url: 'http://localhost:49741/test-passed',
30+
followRedirect: false
31+
})
32+
.then(function (response) {
33+
if (response.statusCode === 500) throw new Error (response.body);
34+
expect(response.statusCode).to.equal(200);
35+
36+
expect(response.headers).to.not.include.keys('location');
37+
expect(response.headers).to.include.keys('x-fastboot-path');
38+
expect(response.headers['x-fastboot-path']).to.equal('/test-passed');
39+
40+
expect(response.body).to.contain('The Test Passed!');
41+
});
42+
});
43+
44+
it.skip('should NOT redirect when intermediateTransitionTo is called', function () {
45+
return get({
46+
url: 'http://localhost:49741/redirect-on-intermediate-transition-to',
47+
followRedirect: false
48+
})
49+
.then(function (response) {
50+
if (response.statusCode === 500) throw new Error (response.body);
51+
expect(response.statusCode).to.equal(200);
52+
53+
expect(response.headers).to.not.include.keys('location');
54+
expect(response.headers).to.include.keys('x-fastboot-path');
55+
expect(response.headers['x-fastboot-path']).to.equal('/redirect-on-intermediate-transition-to');
56+
57+
expect(response.body).to.not.contain('Welcome to Ember');
58+
expect(response.body).to.not.contain('The Test Passed!');
59+
});
60+
});
61+
62+
it('should redirect when transitionTo is called', function () {
63+
return get({
64+
url: 'http://localhost:49741/redirect-on-transition-to',
65+
followRedirect: false
66+
})
67+
.then(function (response) {
68+
if (response.statusCode === 500) throw new Error (response.body);
69+
expect(response.statusCode).to.equal(307);
70+
71+
expect(response.headers).to.include.keys([
72+
'location',
73+
'x-fastboot-path'
74+
]);
75+
expect(response.headers.location).to.equal('http://localhost:49741/test-passed');
76+
expect(response.body).to.contain('Redirecting to');
77+
expect(response.body).to.contain('/test-passed');
78+
});
79+
});
80+
81+
it('should redirect when replaceWith is called', function () {
82+
return get({
83+
url: 'http://localhost:49741/redirect-on-replace-with',
84+
followRedirect: false
85+
})
86+
.then(function (response) {
87+
if (response.statusCode === 500) throw new Error (response.body);
88+
expect(response.statusCode).to.equal(307);
89+
90+
expect(response.headers).to.include.keys([
91+
'location',
92+
'x-fastboot-path'
93+
]);
94+
expect(response.headers.location).to.equal('http://localhost:49741/test-passed');
95+
expect(response.body).to.contain('Redirecting to');
96+
expect(response.body).to.contain('/test-passed');
97+
});
98+
});
99+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Ember from 'ember';
2+
3+
let Router = Ember.Router;
4+
5+
Router.map(function() {
6+
this.route('redirect-on-transition-to');
7+
this.route('test-passed');
8+
});
9+
10+
export default Router;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Ember from 'ember';
2+
3+
export default Ember.Route.extend({
4+
beforeModel() {
5+
this.transitionTo('test-passed');
6+
}
7+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Ember from 'ember';
2+
3+
export default Ember.Route.extend({});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<h1>The Test Passed!</h1>
2+
3+
<p>All redirection tests should be set up to redirect here.</p>
4+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
module.exports = function(environment) {
4+
var ENV = {
5+
baseUrl: '/',
6+
environment: environment,
7+
modulePrefix: 'fastboot-location-config',
8+
fastboot: {
9+
fastbootHeaders: false,
10+
hostWhitelist: [/localhost:\d+/],
11+
redirectCode: 302,
12+
}
13+
};
14+
15+
return ENV;
16+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Ember from 'ember';
2+
3+
let Router = Ember.Router;
4+
5+
Router.map(function() {
6+
this.route('redirect-on-intermediate-transition-to');
7+
this.route('redirect-on-transition-to');
8+
this.route('redirect-on-replace-with');
9+
this.route('test-passed');
10+
});
11+
12+
export default Router;

0 commit comments

Comments
 (0)