diff --git a/.travis.yml b/.travis.yml index 43695b3b5..cb5a4de59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,10 @@ jobs: - name: "Run the Backend tests" install: - "bin/installDeps.sh" + # Set soffice to /usr/bin/soffice + - "sed 's/\"soffice\": null,/\"soffice\": "/usr/bin/soffice",/g' settings.json.template > settings.json" + # Set allowAnyoneToImport to true + - "sed 's/\"allowAnyoneToImport\": false,/\"allowAnyoneToInput\": true,/g' settings.json > settings.json" - "cd src && npm install && cd -" script: - "tests/frontend/travis/runnerBackend.sh" diff --git a/src/node/hooks/express/importexport.js b/src/node/hooks/express/importexport.js index bf85ae13e..9ddefe8a0 100644 --- a/src/node/hooks/express/importexport.js +++ b/src/node/hooks/express/importexport.js @@ -71,12 +71,12 @@ exports.expressCreateServer = function (hook_name, args, cb) { * * See: https://github.com/ether/etherpad-lite/pull/3833#discussion_r407490205 */ - if (!req.cookies) { + if (!req.cookies && !settings.allowAnyoneToImport) { console.warn(`Unable to import file into "${req.params.pad}". No cookies included in request`); return next(); } - if (!req.cookies.token) { + if (!req.cookies.token && !settings.allowAnyoneToImport) { console.warn(`Unable to import file into "${req.params.pad}". No token in the cookies`); return next(); } diff --git a/tests/backend/specs/api/importexportGetPost.js b/tests/backend/specs/api/importexportGetPost.js index 7bbe88139..aad5fd3ce 100644 --- a/tests/backend/specs/api/importexportGetPost.js +++ b/tests/backend/specs/api/importexportGetPost.js @@ -3,10 +3,14 @@ * Executed using request. Designed to find flaws and bugs */ +// import wont work due to sessions missing +// Waiting on https://github.com/ether/etherpad-lite/pull/4012/files to be merged to be fully functional +// Logic for creating sessions is the sessionandGroups.js test spec + const assert = require('assert'); const supertest = require(__dirname+'/../../../../src/node_modules/supertest'); const fs = require('fs'); -const settings = require(__dirname+'/../../../../tests/container/loadSettings.js').loadSettings(); +const settings = require(__dirname+'/../../../../src/node/utils/Settings'); const host = 'http://127.0.0.1:'+settings.port; const api = supertest('http://'+settings.ip+":"+settings.port); const path = require('path'); @@ -14,6 +18,9 @@ const async = require(__dirname+'/../../../../src/node_modules/async'); const request = require(__dirname+'/../../../../src/node_modules/request'); const padText = fs.readFileSync("../tests/backend/specs/api/test.txt"); const wordDoc = fs.readFileSync("../tests/backend/specs/api/test.doc"); +const wordXDoc = fs.readFileSync("../tests/backend/specs/api/test.docx"); +const odtDoc = fs.readFileSync("../tests/backend/specs/api/test.odt"); +const pdfDoc = fs.readFileSync("../tests/backend/specs/api/test.pdf"); var filePath = path.join(__dirname, '../../../../APIKEY.txt'); var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'}); @@ -59,13 +66,6 @@ Test. Test. / Try to import an unsupported file to a pad that exists -TODO: Test. - / Try to import a file that depends on Abiword / soffice if it exists - / Try to export a file that depends on Abiword / soffice if it exists - --- TODO: Test. - Try to import to a pad without a session (currently will pass but IMHO in future should fail) - -- TODO: Test. Try to import to a file and abort it half way through @@ -79,39 +79,188 @@ Example Curl command for testing import URI: describe('Imports and Exports', function(){ it('creates a new Pad, imports content to it, checks that content', function(done) { + if(!settings.allowAnyoneToImport){ + console.log("not anyone can import so not testing -- to include this test set allowAnyoneToImport to true in settings.json"); + done(); + }else{ + api.get(endPoint('createPad')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to create new Pad"); - api.get(endPoint('createPad')+"&padID="+testPadId) - .expect(function(res){ - if(res.body.code !== 0) throw new Error("Unable to create new Pad"); + var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { + if (err) { + throw new Error("Failed to import", err); + } else { + api.get(endPoint('getText')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.data.text !== padText.toString()){ + throw new Error("text is wrong on export"); + } + }) + } + }); - var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { - if (err) { - throw new Error("Failed to import", err); - } else { + let form = req.form(); - api.get(endPoint('getText')+"&padID="+testPadId) - .expect(function(res){ - if(res.body.data.text === padText.toString()){ - console.log("yay it matches"); - } - }) - .expect(200) - } - }); + form.append('file', padText, { + filename: '/test.txt', + contentType: 'text/plain' + }); - let form = req.form(); - - form.append('file', padText, { - filename: '/test.txt', - contentType: 'text/plain' - }); - - }) - .expect('Content-Type', /json/) - .expect(200, done) + }) + .expect('Content-Type', /json/) + .expect(200, done) + } }); - it('tries to import to a pad that does not exist', function(done) { + // For some reason word import does not work in testing.. + // TODO: fix support for .doc files.. + xit('Tries to import .doc that uses soffice or abiword', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + + var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { + if (err) { + throw new Error("Failed to import", err); + } else { + if(res.body.indexOf("FrameCall('undefined', 'ok');") === -1){ + throw new Error("Failed DOC import", testPadId); + }else{ + done(); + }; + } + }); + + let form = req.form(); + form.append('file', wordDoc, { + filename: '/test.doc', + contentType: 'application/msword' + }); + }); + + xit('exports DOC', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + request(host + '/p/'+testPadId+'/export/doc', function (err, res, body) { + // expect length to be > 9000 + // TODO: At some point checking that the contents is correct would be suitable + if(body.length >= 9000){ + done(); + }else{ + throw new Error("Word Document export length is not right"); + } + }) + }) + + it('Tries to import .docx that uses soffice or abiword', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + + var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { + if (err) { + throw new Error("Failed to import", err); + } else { + if(res.body.indexOf("FrameCall('undefined', 'ok');") === -1){ + throw new Error("Failed DOCX import", testPadId); + }else{ + done(); + }; + } + }); + + let form = req.form(); + form.append('file', wordXDoc, { + filename: '/test.docx', + contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + }); + }); + + it('exports DOC from imported DOCX', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + request(host + '/p/'+testPadId+'/export/doc', function (err, res, body) { + // TODO: At some point checking that the contents is correct would be suitable + if(body.length >= 9100){ + done(); + }else{ + throw new Error("Word Document export length is not right"); + } + }) + }) + + it('Tries to import .pdf that uses soffice or abiword', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + + var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { + if (err) { + throw new Error("Failed to import", err); + } else { + if(res.body.indexOf("FrameCall('undefined', 'ok');") === -1){ + throw new Error("Failed PDF import", testPadId); + }else{ + done(); + }; + } + }); + + let form = req.form(); + form.append('file', pdfDoc, { + filename: '/test.pdf', + contentType: 'application/pdf' + }); + }); + + it('exports PDF', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + request(host + '/p/'+testPadId+'/export/pdf', function (err, res, body) { + // TODO: At some point checking that the contents is correct would be suitable + if(body.length >= 1000){ + done(); + }else{ + throw new Error("PDF Document export length is not right"); + } + }) + }) + + it('Tries to import .odt that uses soffice or abiword', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + + var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { + if (err) { + throw new Error("Failed to import", err); + } else { + if(res.body.indexOf("FrameCall('undefined', 'ok');") === -1){ + throw new Error("Failed ODT import", testPadId); + }else{ + done(); + }; + } + }); + + let form = req.form(); + form.append('file', odtDoc, { + filename: '/test.odt', + contentType: 'application/odt' + }); + }); + + it('exports ODT', function(done) { + if(!settings.allowAnyoneToImport) return done(); + if((settings.abiword && settings.abiword.indexOf("/" === -1)) && (settings.office && settings.soffice.indexOf("/" === -1))) return done(); + request(host + '/p/'+testPadId+'/export/odt', function (err, res, body) { + // TODO: At some point checking that the contents is correct would be suitable + if(body.length >= 7000){ + done(); + }else{ + throw new Error("ODT Document export length is not right"); + } + }) + }) + + it('tries to import Plain Text to a pad that does not exist', function(done) { var req = request.post(host + '/p/'+testPadId+testPadId+testPadId+'/import', function (err, res, body) { if (res.statusCode === 200) { throw new Error("Was able to import to a pad that doesn't exist"); @@ -158,44 +307,6 @@ describe('Imports and Exports', function(){ }); }); - if(settings.abiword.indexOf("/" === -1) && settings.soffice.indexOf("/" === -1)){ - console.log("Did not test abiword or soffice"); - }else{ - it('Tries to import file type that uses soffice or abioffice', function(done) { - - var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) { - if (err) { - throw new Error("Failed to import", err); - } else { - if(res.body.indexOf("FrameCall('undefined', 'ok');") === -1){ - throw new Error("Failed Doc import", testPadId); - } - - request(host + '/p/'+testPadId+'/export/doc', function (errE, resE, bodyE) { - if(resE.body.indexOf("Hello World") === -1) throw new Error("Could not find Hello World in exported contents"); - - api.get(endPoint('getText')+"&padID="+testPadId) - .expect(function(res){ - if(res.body.code !== 0) throw new Error("Could not get pad"); - // Not graceflu but it works - console.warn("HERE"); - }) - .expect(200, done); - }); - } - }); - - let form = req.form(); - - form.append('file', wordDoc, { - filename: '/tmp/test.doc', - contentType: 'application/msword' - }); - - }); - } - - // end of tests }) diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js index 3d1693bd3..95138c0b8 100644 --- a/tests/backend/specs/api/pad.js +++ b/tests/backend/specs/api/pad.js @@ -647,7 +647,6 @@ describe('getHTML', function(){ api.get(endPoint('getHTML')+"&padID="+testPadId) .expect(function(res){ var receivedHtml = res.body.data.html.replace("
", "").toLowerCase(); -console.log(receivedHtml); if (receivedHtml !== expectedSpaceHtml) { throw new Error(`HTML received from export is not the one we were expecting. Received: diff --git a/tests/backend/specs/api/test.docx b/tests/backend/specs/api/test.docx new file mode 100644 index 000000000..422bb4f03 Binary files /dev/null and b/tests/backend/specs/api/test.docx differ diff --git a/tests/backend/specs/api/test.odt b/tests/backend/specs/api/test.odt new file mode 100644 index 000000000..8ab62a612 Binary files /dev/null and b/tests/backend/specs/api/test.odt differ diff --git a/tests/backend/specs/api/test.pdf b/tests/backend/specs/api/test.pdf new file mode 100644 index 000000000..79c9c2832 Binary files /dev/null and b/tests/backend/specs/api/test.pdf differ