diff --git a/src/tests/backend/specs/Pad.js b/src/tests/backend/specs/Pad.js new file mode 100644 index 000000000..0e385097e --- /dev/null +++ b/src/tests/backend/specs/Pad.js @@ -0,0 +1,122 @@ +'use strict'; + +const Pad = require('../../../node/db/Pad'); +const assert = require('assert').strict; +const authorManager = require('../../../node/db/AuthorManager'); +const common = require('../common'); +const padManager = require('../../../node/db/PadManager'); +const plugins = require('../../../static/js/pluginfw/plugin_defs'); +const settings = require('../../../node/utils/Settings'); + +describe(__filename, function () { + const backups = {}; + let pad; + let padId; + + before(async function () { + backups.hooks = { + padDefaultContent: plugins.hooks.padDefaultContent, + }; + backups.defaultPadText = settings.defaultPadText; + }); + + beforeEach(async function () { + backups.hooks.padDefaultContent = []; + padId = common.randomString(); + assert(!(await padManager.doesPadExist(padId))); + }); + + afterEach(async function () { + Object.assign(plugins.hooks, backups.hooks); + if (pad != null) await pad.remove(); + pad = null; + }); + + describe('cleanText', function () { + const testCases = [ + ['', ''], + ['\n', '\n'], + ['x', 'x'], + ['x\n', 'x\n'], + ['x\ny\n', 'x\ny\n'], + ['x\ry\n', 'x\ny\n'], + ['x\r\ny\n', 'x\ny\n'], + ['x\r\r\ny\n', 'x\n\ny\n'], + ]; + for (const [input, want] of testCases) { + it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () { + assert.equal(Pad.cleanText(input), want); + }); + } + }); + + describe('padDefaultContent hook', function () { + it('runs when a pad is created without specific text', async function () { + const p = new Promise((resolve) => { + plugins.hooks.padDefaultContent.push({hook_fn: () => resolve()}); + }); + pad = await padManager.getPad(padId); + await p; + }); + + it('not run if pad is created with specific text', async function () { + plugins.hooks.padDefaultContent.push( + {hook_fn: () => { throw new Error('should not be called'); }}); + pad = await padManager.getPad(padId, ''); + }); + + it('defaults to settings.defaultPadText', async function () { + const p = new Promise((resolve, reject) => { + plugins.hooks.padDefaultContent.push({hook_fn: async (hookName, ctx) => { + try { + assert.equal(ctx.type, 'text'); + assert.equal(ctx.content, settings.defaultPadText); + } catch (err) { + return reject(err); + } + resolve(); + }}); + }); + pad = await padManager.getPad(padId); + await p; + }); + + it('passes the pad object', async function () { + const gotP = new Promise((resolve) => { + plugins.hooks.padDefaultContent.push({hook_fn: async (hookName, {pad}) => resolve(pad)}); + }); + pad = await padManager.getPad(padId); + assert.equal(await gotP, pad); + }); + + it('passes empty authorId if not provided', async function () { + const gotP = new Promise((resolve) => { + plugins.hooks.padDefaultContent.push( + {hook_fn: async (hookName, {authorId}) => resolve(authorId)}); + }); + pad = await padManager.getPad(padId); + assert.equal(await gotP, ''); + }); + + it('passes provided authorId', async function () { + const want = await authorManager.getAuthor4Token(`t.${padId}`); + const gotP = new Promise((resolve) => { + plugins.hooks.padDefaultContent.push( + {hook_fn: async (hookName, {authorId}) => resolve(authorId)}); + }); + pad = await padManager.getPad(padId, null, want); + assert.equal(await gotP, want); + }); + + it('uses provided content', async function () { + const want = 'hello world'; + assert.notEqual(want, settings.defaultPadText); + plugins.hooks.padDefaultContent.push({hook_fn: async (hookName, ctx) => { + ctx.type = 'text'; + ctx.content = want; + }}); + pad = await padManager.getPad(padId); + assert.equal(pad.text(), `${want}\n`); + }); + }); +});