Merge pull request #14 from Klemek/dev

v1.2.3
This commit is contained in:
Klemek
2019-06-26 21:03:49 +02:00
committed by GitHub
10 changed files with 90 additions and 59 deletions
+1 -3
View File
@@ -145,9 +145,7 @@ In your template, the following data is sent :
* `path` : the URL path for the folder of the article (without the title)
* `realPath` : the system's path for the folder
* `escapedTitle` : the code with alphanumeric and underscore characters only
* `error` (error pages only)
* `error` : the error code
* `path` : the resource that caused the error
* `error` (error pages only) : the error code
#### 5. Create and init your git source
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "gitblog.md",
"version": "1.2.2",
"version": "1.2.3",
"description": "A static blog using Markdown pulled from your git repository.",
"main": "src/server.js",
"dependencies": {
@@ -48,6 +48,7 @@
]
},
"nodemonConfig": {
"verbose": true,
"ignore": [
"test/*",
"sample_data/*",
@@ -55,7 +56,6 @@
"uml/*",
"*.log",
"README.md"
],
"delay": "2500"
]
}
}
+1 -2
View File
@@ -1,9 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= info.title %> - Error <%= error %></title>
<%- include('head'); %>
<title><%= info.title %> - Error <%= error %></title>
</head>
<body>
<main>
+12 -7
View File
@@ -1,21 +1,26 @@
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<META NAME="ROBOTS" CONTENT="INDEX, FOLLOW">
<meta name="twitter:card" content="summary_large_image">
<%- `<meta property="og:description" content="${info.description}">` %>
<%- `<meta property="twitter:description" content="${info.description}">` %>
<% if(locals.article){ %>
<%- `<meta property="org:url" content="${info.host + article.url}">` %>
<%- `<meta property="og:title" content="${info.title} - ${article.title}">` %>
<%- `<meta property="twitter:title" content="${info.title} - ${article.title}">` %>
<%- `<meta property="og:description" content="${info.description}">` %>
<%- `<meta property="twitter:description" content="${info.description}">` %>
<%- `<meta property="org:url" content="${info.host + article.url}">` %>
<% if (article.thumbnail) { %>
<%- `<meta property="og:image" content="${info.host}/${article.thumbnail}">` %>
<%- `<meta property="twitter:image" content="${info.host}/${article.thumbnail}">` %>
<% } %>
<link rel="stylesheet" type="text/css" href="/prism.css">
<link rel="stylesheet" type="text/css" href="/css/prism.css">
<% } else { %>
<%- `<meta property="org:url" content="${info.host}/">` %>
<%- `<meta property="og:title" content="${info.title} - Home">` %>
<%- `<meta property="twitter:title" content="${info.title} - Home">` %>
<%- `<meta property="og:description" content="${info.description}">` %>
<%- `<meta property="twitter:description" content="${info.description}">` %>
<%- `<meta property="org:url" content="${info.host}/">` %>
<%- `<meta property="description" content="${info.description}">` %>
<% } %>
<link rel="alternate" type="application/rss+xml" title="RSS feed" href="/rss"/>
+1 -2
View File
@@ -1,9 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= info.title %> - Home</title>
<%- include('head'); %>
<title><%= info.title %> - Home</title>
</head>
<body>
<main>
+1 -2
View File
@@ -1,9 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= info.title %> - <%= article.title %></title>
<%- include('head'); %>
<title><%= info.title %> - <%= article.title %></title>
</head>
<body>
<main class="article">
+34 -29
View File
@@ -26,6 +26,28 @@ const cons = {
};
module.exports = (config) => {
/**
* Fetch articles from the data folder and send success as a response
* @param success
* @param error
*/
let reload;
/**
* Render the page with the view engine and catch errors
* @param req
* @param res
* @param vPath - path of the view
* @param data - data to pass to the view
* @param code - code to send along the page
*/
let render;
/**
* Show an error with the correct page
* @param req
* @param res
* @param code - error code
*/
let showError;
const fw = require('./file_walker')(config);
const renderer = require('./renderer')(config);
@@ -38,12 +60,7 @@ module.exports = (config) => {
let lastRSS = '';
let host = config['host'];
/**
* Fetch articles from the data folder and send success as a response
* @param success
* @param error
*/
const reload = (success, error) => {
reload = (success, error) => {
fw.fetchArticles((err, dict) => {
if (err) {
console.error(cons.error, 'error loading articles : ' + err);
@@ -65,15 +82,7 @@ module.exports = (config) => {
if (config['test'])
app.reload = reload;
/**
* Render the page with the view engine and catch errors
* @param req
* @param res
* @param vPath - path of the view
* @param data - data to pass to the view
* @param code - code to send along the page
*/
const render = (req, res, vPath, data, code = 200) => {
render = (req, res, vPath, data, code = 200) => {
data.info = {
title: config['home']['title'],
description: config['home']['description'],
@@ -83,27 +92,24 @@ module.exports = (config) => {
config: config
};
res.render(vPath, data, (err, html) => {
if (err) {
if (err && vPath !== path.join(config['data_dir'], config['home']['error'])) {
console.log(cons.error, `failed to render page ${vPath} : ${err}`);
showError(req, res, 500);
} else if (err) {
res.sendStatus(500);
console.log(cons.error, `failed to render ${vPath} : ${err}`);
console.log(cons.error, `failed to render error page : ${err}`);
} else
res.status(code).send(html);
});
};
/**
* Show an error with the correct page
* @param req
* @param res
* @param code - error code
*/
const showError = (req, res, code) => {
showError = (req, res, code) => {
const errorPath = path.join(config['data_dir'], config['home']['error']);
fs.access(errorPath, fs.constants.R_OK, (err) => {
if (err)
res.sendStatus(code);
else
render(req, res, errorPath, {error: code, path: req.path}, code);
render(req, res, errorPath, {error: code}, code);
});
};
@@ -232,11 +238,10 @@ module.exports = (config) => {
});
// catch all hidden file type and return 404
app.get('*', (req, res, next) => {
if (config['home']['hidden'].includes(path.extname(req.path)))
config['home']['hidden'].forEach(pathMatcher => {
app.get(pathMatcher, (req, res) => {
showError(req, res, 404);
else
next();
});
});
// serve all static files via get
+2 -1
View File
@@ -18,7 +18,8 @@
"index": "index.ejs",
"error": "error.ejs",
"hidden": [
".ejs"
"*.ejs",
"/.git*"
]
},
"article": {
+34 -9
View File
@@ -16,16 +16,15 @@ config['data_dir'] = dataDir;
config['webhook']['endpoint'] = '/webhooktest';
config['rss']['endpoint'] = '/rsstest';
config['rss']['length'] = 2;
config['home']['index'] = testIndex;
config['home']['error'] = testError;
config['article']['template'] = testTemplate;
const app = require('../src/app')(config);
beforeEach((done, fail) => {
config['home']['index'] = testIndex;
config['data_dir'] = dataDir;
config['article']['index'] = 'index.md';
config['home']['hidden'] = ['.ejs', '.test'];
config['access_log'] = '';
config['error_log'] = '';
config['modules']['rss'] = true;
@@ -93,20 +92,20 @@ describe('Test request logging', () => {
describe('Test error logging', () => {
test('test no log', (done) => {
config['home']['hidden'] = null;
request(app).get('/somefile.txt').then(() => {
config['home']['index'] = null;
request(app).get('/').then(() => {
expect(fs.existsSync(path.join(dataDir, 'error.log'))).toBe(false);
done();
});
});
test('test null error ', (done) => {
config['home']['hidden'] = null;
config['home']['index'] = null;
config['error_log'] = path.join(dataDir, 'error.log');
request(app).get('/somefile.txt').then(() => {
request(app).get('/').then(() => {
fs.readFile(path.join(dataDir, 'error.log'), {encoding: 'UTF-8'}, (err, data) => {
expect(err).toBeNull();
const start = data.split('\n').slice(0, 2).join('\n');
const expected = '500 GET /somefile.txt ' + new Date().toUTCString() + ' ::ffff:127.0.0.1\nTypeError: Cannot read property \'includes\' of null';
const expected = '500 GET / ' + new Date().toUTCString() + ' ::ffff:127.0.0.1\nTypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type object';
expect(start).toBe(expected);
done();
});
@@ -136,6 +135,23 @@ describe('Test root path', () => {
done();
});
});
test('500 render error with page', (done) => {
fs.writeFileSync(path.join(dataDir, testIndex), 'articles <%= null.length %>');
fs.writeFileSync(path.join(dataDir, testError), 'error <%= error %>');
request(app).get('/').then((response) => {
expect(response.statusCode).toBe(500);
expect(response.text).toBe('error 500');
done();
});
});
test('500 render error with failing page', (done) => {
fs.writeFileSync(path.join(dataDir, testIndex), 'articles <%= null.length %>');
fs.writeFileSync(path.join(dataDir, testError), 'error <%= null.error %>');
request(app).get('/').then((response) => {
expect(response.statusCode).toBe(500);
done();
});
});
test('200 no articles', (done) => {
fs.writeFileSync(path.join(dataDir, testIndex), 'articles <%= articles.length %>');
request(app).get('/').then((response) => {
@@ -386,8 +402,17 @@ describe('Test static files', () => {
});
});
test('404 hidden file', (done) => {
fs.writeFileSync(path.join(dataDir, 'somefile.test'), '');
request(app).get('/somefile.test').then((response) => {
utils.createEmptyDirs([path.join(dataDir, 'tmp')]);
fs.writeFileSync(path.join(dataDir, 'tmp', 'somefile.ejs'), '');
request(app).get('/tmp/somefile.ejs').then((response) => {
expect(response.statusCode).toBe(404);
done();
});
});
test('404 hidden folder', (done) => {
utils.createEmptyDirs([path.join(dataDir, '.git')]);
fs.writeFileSync(path.join(dataDir, '.git', 'file.txt'), '');
request(app).get('/.git/file.txt').then((response) => {
expect(response.statusCode).toBe(404);
done();
});
+1 -1
View File
@@ -77,5 +77,5 @@ test('array fix', () => {
fs.writeFileSync(configFile, '{"home":{"hidden":{}}}');
const config = require('../src/config')();
expect(config).toBeDefined();
expect(config['home']['hidden']).toEqual(['.ejs']);
expect(config['home']['hidden']).toEqual(['*.ejs', '/.git*']);
});