From b57ecbcc4a224857e12d53ab52f510cec0d66a53 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Mon, 30 Mar 2020 16:26:47 +0100 Subject: [PATCH] Move tests from core to root (#11700) - move all test files from core/test to test/ - updated all imports and other references - all code inside of core/ is then application code - tests are correctly at the root level - consistent with other repos/projects Co-authored-by: Kevin Ansfield --- ghost/security/test/password_spec.js | 18 ++++ ghost/security/test/string_spec.js | 94 ++++++++++++++++++ ghost/security/test/tokens_spec.js | 136 +++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 ghost/security/test/password_spec.js create mode 100644 ghost/security/test/string_spec.js create mode 100644 ghost/security/test/tokens_spec.js diff --git a/ghost/security/test/password_spec.js b/ghost/security/test/password_spec.js new file mode 100644 index 00000000000..e728034bcf9 --- /dev/null +++ b/ghost/security/test/password_spec.js @@ -0,0 +1,18 @@ +const should = require('should'), + security = require('../../../../core/server/lib/security'); + +describe('Lib: Security - Password', function () { + it('hash plain password', function () { + return security.password.hash('test') + .then(function (hash) { + hash.should.match(/^\$2[ayb]\$.{56}$/); + }); + }); + + it('compare password', function () { + return security.password.compare('test', '$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG') + .then(function (valid) { + valid.should.be.true; + }); + }); +}); diff --git a/ghost/security/test/string_spec.js b/ghost/security/test/string_spec.js new file mode 100644 index 00000000000..c95ef90cd54 --- /dev/null +++ b/ghost/security/test/string_spec.js @@ -0,0 +1,94 @@ +var should = require('should'), + security = require('../../../../core/server/lib/security'); + +describe('Lib: Security - String', function () { + describe('Safe String', function () { + var options = {}; + + it('should remove beginning and ending whitespace', function () { + var result = security.string.safe(' stringwithspace ', options); + result.should.equal('stringwithspace'); + }); + + it('can handle null strings', function () { + var result = security.string.safe(null); + result.should.equal(''); + }); + + it('should remove non ascii characters', function () { + var result = security.string.safe('howtowin✓', options); + result.should.equal('howtowin'); + }); + + it('should replace spaces with dashes', function () { + var result = security.string.safe('how to win', options); + result.should.equal('how-to-win'); + }); + + it('should replace most special characters with dashes', function () { + var result = security.string.safe('a:b/c?d#e[f]g!h$i&j(k)l*m+n,o;{p}=q\\r%su|v^w~x£y"z@1.2`3', options); + result.should.equal('a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-1-2-3'); + }); + + it('should replace all of the html4 compat symbols in ascii except hyphen and underscore', function () { + // note: This is missing the soft-hyphen char that isn't much-liked by linters/browsers/etc, + // it passed the test before it was removed + var result = security.string.safe('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿'); + result.should.equal('_-c-y-ss-c-a-r-deg-23up-1o-1-41-23-4'); + }); + + it('should replace all of the foreign chars in ascii', function () { + var result = security.string.safe('ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'); + result.should.equal('aaaaaaaeceeeeiiiidnoooooxouuuuuthssaaaaaaaeceeeeiiiidnooooo-ouuuuythy'); + }); + + it('should remove special characters at the beginning of a string', function () { + var result = security.string.safe('.Not special', options); + result.should.equal('not-special'); + }); + + it('should remove apostrophes ', function () { + var result = security.string.safe('how we shouldn\'t be', options); + result.should.equal('how-we-shouldnt-be'); + }); + + it('should convert to lowercase', function () { + var result = security.string.safe('This has Upper Case', options); + result.should.equal('this-has-upper-case'); + }); + + it('should convert multiple dashes into a single dash', function () { + var result = security.string.safe('This :) means everything', options); + result.should.equal('this-means-everything'); + }); + + it('should remove trailing dashes from the result', function () { + var result = security.string.safe('This.', options); + result.should.equal('this'); + }); + + it('should handle pound signs', function () { + var result = security.string.safe('WHOOPS! I spent all my £ again!', options); + result.should.equal('whoops-i-spent-all-my-again'); + }); + + it('should properly handle unicode punctuation conversion', function () { + var result = security.string.safe('に間違いがないか、再度確認してください。再読み込みしてください。', options); + result.should.equal('nijian-wei-iganaika-zai-du-que-ren-sitekudasai-zai-du-miip-misitekudasai'); + }); + + it('should not lose or convert dashes if options are passed with truthy importing flag', function () { + var result, + options = {importing: true}; + result = security.string.safe('-slug-with-starting-ending-and---multiple-dashes-', options); + result.should.equal('-slug-with-starting-ending-and---multiple-dashes-'); + }); + + it('should still remove/convert invalid characters when passed options with truthy importing flag', function () { + var result, + options = {importing: true}; + result = security.string.safe('-slug-&with-✓-invalid-characters-に\'', options); + result.should.equal('-slug--with--invalid-characters-ni'); + }); + }); +}); diff --git a/ghost/security/test/tokens_spec.js b/ghost/security/test/tokens_spec.js new file mode 100644 index 00000000000..319f4aa7e21 --- /dev/null +++ b/ghost/security/test/tokens_spec.js @@ -0,0 +1,136 @@ +var should = require('should'), + uuid = require('uuid'), + security = require('../../../../core/server/lib/security'); + +describe('Utils: tokens', function () { + it('generate', function () { + var expires = Date.now() + 60 * 1000, + dbHash = uuid.v4(), token; + + token = security.tokens.resetToken.generateHash({ + email: 'test1@ghost.org', + expires: expires, + password: 'password', + dbHash: dbHash + }); + + should.exist(token); + token.length.should.be.above(0); + }); + + it('compare: success', function () { + var expires = Date.now() + 60 * 1000, + dbHash = uuid.v4(), token, tokenIsCorrect; + + token = security.tokens.resetToken.generateHash({ + email: 'test1@ghost.org', + expires: expires, + password: '12345678', + dbHash: dbHash + }); + + tokenIsCorrect = security.tokens.resetToken.compare({ + token: token, + dbHash: dbHash, + password: '12345678' + }); + + tokenIsCorrect.should.eql(true); + }); + + it('compare: error', function () { + var expires = Date.now() + 60 * 1000, + dbHash = uuid.v4(), token, tokenIsCorrect; + + token = security.tokens.resetToken.generateHash({ + email: 'test1@ghost.org', + expires: expires, + password: '12345678', + dbHash: dbHash + }); + + tokenIsCorrect = security.tokens.resetToken.compare({ + token: token, + dbHash: dbHash, + password: '123456' + }); + + tokenIsCorrect.should.eql(false); + }); + + it('extract', function () { + var expires = Date.now() + 60 * 1000, + dbHash = uuid.v4(), token, parts, email = 'test1@ghost.org'; + + token = security.tokens.resetToken.generateHash({ + email: email, + expires: expires, + password: '12345678', + dbHash: dbHash + }); + + parts = security.tokens.resetToken.extract({ + token: token + }); + + parts.email.should.eql(email); + parts.expires.should.eql(expires); + should.not.exist(parts.password); + should.not.exist(parts.dbHash); + }); + + it('extract', function () { + var expires = Date.now() + 60 * 1000, + dbHash = uuid.v4(), token, parts, email = 'test3@ghost.org'; + + token = security.tokens.resetToken.generateHash({ + email: email, + expires: expires, + password: '$2a$10$t5dY1uRRdjvqfNlXhae3uuc0nuhi.Rd7/K/9JaHHwSkLm6UUa3NsW', + dbHash: dbHash + }); + + parts = security.tokens.resetToken.extract({ + token: token + }); + + parts.email.should.eql(email); + parts.expires.should.eql(expires); + should.not.exist(parts.password); + should.not.exist(parts.dbHash); + }); + + it('can validate an URI encoded reset token', function () { + var expires = Date.now() + 60 * 1000, + email = 'test1@ghost.org', + dbHash = uuid.v4(), token, tokenIsCorrect, parts; + + token = security.tokens.resetToken.generateHash({ + email: email, + expires: expires, + password: '12345678', + dbHash: dbHash + }); + + token = security.url.encodeBase64(token); + token = encodeURIComponent(token); + token = decodeURIComponent(token); + token = security.url.decodeBase64(token); + + parts = security.tokens.resetToken.extract({ + token: token + }); + + parts.email.should.eql(email); + parts.expires.should.eql(expires); + + tokenIsCorrect = security.tokens.resetToken.compare({ + token: token, + dbHash: dbHash, + password: '12345678' + }); + + tokenIsCorrect.should.eql(true); + }); +}); +