mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
WIP - Test Coverage: Import & Export include LibreOffice Test Coverage (#4163)
Runs on Travis Will only run locally is ``allowAnyoneToImport`` and ``soffice`` or ``abiword`` is set.
This commit is contained in:
parent
9d69caa8dc
commit
ab8320d15b
7 changed files with 190 additions and 76 deletions
|
@ -38,6 +38,10 @@ jobs:
|
||||||
- name: "Run the Backend tests"
|
- name: "Run the Backend tests"
|
||||||
install:
|
install:
|
||||||
- "bin/installDeps.sh"
|
- "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 -"
|
- "cd src && npm install && cd -"
|
||||||
script:
|
script:
|
||||||
- "tests/frontend/travis/runnerBackend.sh"
|
- "tests/frontend/travis/runnerBackend.sh"
|
||||||
|
|
|
@ -71,12 +71,12 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
*
|
*
|
||||||
* See: https://github.com/ether/etherpad-lite/pull/3833#discussion_r407490205
|
* 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`);
|
console.warn(`Unable to import file into "${req.params.pad}". No cookies included in request`);
|
||||||
return next();
|
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`);
|
console.warn(`Unable to import file into "${req.params.pad}". No token in the cookies`);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
* Executed using request. Designed to find flaws and bugs
|
* 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 assert = require('assert');
|
||||||
const supertest = require(__dirname+'/../../../../src/node_modules/supertest');
|
const supertest = require(__dirname+'/../../../../src/node_modules/supertest');
|
||||||
const fs = require('fs');
|
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 host = 'http://127.0.0.1:'+settings.port;
|
||||||
const api = supertest('http://'+settings.ip+":"+settings.port);
|
const api = supertest('http://'+settings.ip+":"+settings.port);
|
||||||
const path = require('path');
|
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 request = require(__dirname+'/../../../../src/node_modules/request');
|
||||||
const padText = fs.readFileSync("../tests/backend/specs/api/test.txt");
|
const padText = fs.readFileSync("../tests/backend/specs/api/test.txt");
|
||||||
const wordDoc = fs.readFileSync("../tests/backend/specs/api/test.doc");
|
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 filePath = path.join(__dirname, '../../../../APIKEY.txt');
|
||||||
|
|
||||||
var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
|
var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
|
||||||
|
@ -59,13 +66,6 @@ Test.
|
||||||
Test.
|
Test.
|
||||||
/ Try to import an unsupported file to a pad that exists
|
/ 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.
|
-- TODO: Test.
|
||||||
Try to import to a file and abort it half way through
|
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(){
|
describe('Imports and Exports', function(){
|
||||||
|
|
||||||
it('creates a new Pad, imports content to it, checks that content', function(done) {
|
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)
|
var req = request.post(host + '/p/'+testPadId+'/import', function (err, res, body) {
|
||||||
.expect(function(res){
|
if (err) {
|
||||||
if(res.body.code !== 0) throw new Error("Unable to create new Pad");
|
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) {
|
let form = req.form();
|
||||||
if (err) {
|
|
||||||
throw new Error("Failed to import", err);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
api.get(endPoint('getText')+"&padID="+testPadId)
|
form.append('file', padText, {
|
||||||
.expect(function(res){
|
filename: '/test.txt',
|
||||||
if(res.body.data.text === padText.toString()){
|
contentType: 'text/plain'
|
||||||
console.log("yay it matches");
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
.expect(200)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let form = req.form();
|
})
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
form.append('file', padText, {
|
.expect(200, done)
|
||||||
filename: '/test.txt',
|
}
|
||||||
contentType: 'text/plain'
|
|
||||||
});
|
|
||||||
|
|
||||||
})
|
|
||||||
.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) {
|
var req = request.post(host + '/p/'+testPadId+testPadId+testPadId+'/import', function (err, res, body) {
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
throw new Error("Was able to import to a pad that doesn't exist");
|
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
|
// end of tests
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -647,7 +647,6 @@ describe('getHTML', function(){
|
||||||
api.get(endPoint('getHTML')+"&padID="+testPadId)
|
api.get(endPoint('getHTML')+"&padID="+testPadId)
|
||||||
.expect(function(res){
|
.expect(function(res){
|
||||||
var receivedHtml = res.body.data.html.replace("<br></body>", "</body>").toLowerCase();
|
var receivedHtml = res.body.data.html.replace("<br></body>", "</body>").toLowerCase();
|
||||||
console.log(receivedHtml);
|
|
||||||
if (receivedHtml !== expectedSpaceHtml) {
|
if (receivedHtml !== expectedSpaceHtml) {
|
||||||
throw new Error(`HTML received from export is not the one we were expecting.
|
throw new Error(`HTML received from export is not the one we were expecting.
|
||||||
Received:
|
Received:
|
||||||
|
|
BIN
tests/backend/specs/api/test.docx
Normal file
BIN
tests/backend/specs/api/test.docx
Normal file
Binary file not shown.
BIN
tests/backend/specs/api/test.odt
Normal file
BIN
tests/backend/specs/api/test.odt
Normal file
Binary file not shown.
BIN
tests/backend/specs/api/test.pdf
Normal file
BIN
tests/backend/specs/api/test.pdf
Normal file
Binary file not shown.
Loading…
Reference in a new issue