From 7f2794b9f80ac8783e34561ac80ff5906ea9ed4d Mon Sep 17 00:00:00 2001 From: Raymond Ho Date: Sun, 18 Oct 2015 10:14:28 +0800 Subject: [PATCH 1/2] 404 Capability Added Test Cases and Modified Edge Example --- examples/edge/index.js | 11 ++---- examples/edge/public/views/account.jsx | 8 +++-- lib/server.js | 7 ++++ lib/views/Page404.js | 30 ++++++++++++++++ test/fixtures/assertions.json | 4 ++- test/fixtures/views/page404.js | 31 +++++++++++++++++ test/server.js | 47 ++++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 lib/views/Page404.js create mode 100644 test/fixtures/views/page404.js diff --git a/examples/edge/index.js b/examples/edge/index.js index a3d6034..d28ccf0 100644 --- a/examples/edge/index.js +++ b/examples/edge/index.js @@ -27,7 +27,8 @@ var app = express(); // create the view engine with `react-engine` var engine = renderer.server.create({ routes: require(path.join(__dirname, '/public/routes.jsx')), - routesFilePath: path.join(__dirname, '/public/routes.jsx') + routesFilePath: path.join(__dirname, '/public/routes.jsx'), + page404: require(path.join(__dirname, '/public/views/404.jsx')) }); // set the engine @@ -69,14 +70,6 @@ app.use('/', function(req, res, next) { next(); }); -// 404 template -app.use(function(req, res) { - res.render('404', { - title: 'React Engine Express Sample App', - url: req.url - }); -}); - var server = app.listen(3000, function() { var host = server.address().address; diff --git a/examples/edge/public/views/account.jsx b/examples/edge/public/views/account.jsx index 333448f..d4b0744 100644 --- a/examples/edge/public/views/account.jsx +++ b/examples/edge/public/views/account.jsx @@ -25,9 +25,11 @@ export default React.createClass({

{this.props.name}

I am a React Router rendered view
- Click to go to an unhandled route - Messages - Redirects to /messages +
); } diff --git a/lib/server.js b/lib/server.js index d84c8d7..2e334c9 100644 --- a/lib/server.js +++ b/lib/server.js @@ -41,6 +41,8 @@ var TEMPLATE = ['", "PROFILE_OUTPUT_WITH_REACT_ATTRS": "Hello, world!

Joshua

", - "ACCOUNT_OUTPUT": "Hello, world!

Joshua

" + "ACCOUNT_OUTPUT": "Hello, world!

Joshua

", + "DEFAULT404_OUTPUT": "

404 Page Not Found

", + "CUSTOM404_OUTPUT": "

Custom 404 Page Not Found - SorryJoshua

" } diff --git a/test/fixtures/views/page404.js b/test/fixtures/views/page404.js new file mode 100644 index 0000000..0edd9c2 --- /dev/null +++ b/test/fixtures/views/page404.js @@ -0,0 +1,31 @@ +'use strict'; + +var React = require('react'); + +module.exports = React.createClass({ + + render: function render() { + + return React.createElement( + 'html', + null, + React.createElement( + 'head', + null, + React.createElement('meta', { + charSet: 'utf-8' + }) + ), + React.createElement( + 'body', + null, + React.createElement( + 'h1', + null, + 'Custom 404 Page Not Found - Sorry', + this.props.name + ) + ) + ); + } +}); diff --git a/test/server.js b/test/server.js index 090a52f..68e02e1 100644 --- a/test/server.js +++ b/test/server.js @@ -297,3 +297,50 @@ test('all keys in express render `renderOptionsKeysToFilter` should be used to f }; setup(options); }); + +test('route not found and a default 404 is rendered', function(t) { + + var options = { + engine: renderer.create({ + routes: require(path.join(__dirname + '/fixtures/reactRoutes')) + }), + expressRoutes: function(req, res) { + res.render(req.url, DATA_MODEL); + }, + + onSetup: function(done) { + inject('/nonexistentpath', function(err, data) { + t.error(err); + var $ = cheerio.load(data); + $('*').removeAttr('data-reactid').removeAttr('data-react-checksum'); + t.strictEqual($.html(), assertions.DEFAULT404_OUTPUT); + done(t); + }); + } + }; + setup(options); +}); + +test('route not found and a custom 404 is rendered with data', function(t) { + + var options = { + engine: renderer.create({ + routes: require(path.join(__dirname + '/fixtures/reactRoutes')), + page404: require(path.join(__dirname + '/fixtures/views/page404')) + }), + expressRoutes: function(req, res) { + res.render(req.url, DATA_MODEL); + }, + + onSetup: function(done) { + inject('/nonexistentpath', function(err, data) { + t.error(err); + var $ = cheerio.load(data); + $('*').removeAttr('data-reactid').removeAttr('data-react-checksum'); + t.strictEqual($.html(), assertions.CUSTOM404_OUTPUT); + done(t); + }); + } + }; + setup(options); +}); From d490465c6d398292f5820ca17ad70397b4fa8967 Mon Sep 17 00:00:00 2001 From: Raymond Ho Date: Sun, 18 Oct 2015 11:37:16 +0800 Subject: [PATCH 2/2] README updated --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bc70ba3..cb23498 100644 --- a/README.md +++ b/README.md @@ -75,11 +75,12 @@ The options object can contain properties from [react router's create configurat Additionally, it can contain the following **optional** properties, -- `routesFilePath`: - path for the file that contains the react router routes. +- `routesFilePath`: \ - path for the file that contains the react router routes. react-engine uses this behind the scenes to reload the routes file in cases where [express's app property](http://expressjs.com/api.html#app.set) `view cache` is false, this way you don't need to restart the server every time a change is made in the view files or routes file. -- `renderOptionsKeysToFilter`: - an array of keys that need to be filtered out from the data object that gets fed into the react component for rendering. [more info](#data-for-component-rendering) -- `performanceCollector`: - to collects [perf stats](#performance-profiling) +- `renderOptionsKeysToFilter`: \ - an array of keys that need to be filtered out from the data object that gets fed into the react component for rendering. [more info](#data-for-component-rendering) +- `performanceCollector`: \ - to collects [perf stats](#performance-profiling) +- `page404`: \ - This option allows you to define a custom 404 page when a URL is not matched in your routes. If left undeclared, a default 404 page, interally provided by this library, is rendered. ###### Rendering views on server side ```js