summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJohn McLear <john@mclear.co.uk>2014-11-28 00:04:12 +0000
committerJohn McLear <john@mclear.co.uk>2014-11-28 00:04:12 +0000
commitedc5669fa6cdf96bd7dbd531656ac2f53aa74e71 (patch)
treefdc62d47e9bc745772b426d5473d5537b8540b39 /tests
parent8b787b8d23fa65ad82566ee4f3bacc9c9d71b650 (diff)
parentfa5130978c3b47defbdb45b266e3c45c897d074d (diff)
downloadetherpad-lite-edc5669fa6cdf96bd7dbd531656ac2f53aa74e71.zip
Merge pull request #2344 from ether/backend-tests
Backend tests
Diffstat (limited to 'tests')
-rw-r--r--tests/backend/specs/api/pad.js269
-rw-r--r--tests/backend/specs/api/sessionsAndGroups.js363
2 files changed, 632 insertions, 0 deletions
diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js
new file mode 100644
index 00000000..80f77220
--- /dev/null
+++ b/tests/backend/specs/api/pad.js
@@ -0,0 +1,269 @@
+var assert = require('assert')
+ supertest = require(__dirname+'/../../../../src/node_modules/supertest'),
+ fs = require('fs'),
+ api = supertest('http://localhost:9001');
+ path = require('path');
+
+var filePath = path.join(__dirname, '../../../../APIKEY.txt');
+
+var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
+var apiVersion = 1;
+var testPadId = makeid();
+var lastEdited = "";
+
+describe('Connectivity', function(){
+ it('errors if can not connect', function(done) {
+ api.get('/api/')
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('API Versioning', function(){
+ it('errors if can not connect', function(done) {
+ api.get('/api/')
+ .expect(function(res){
+ apiVersion = res.body.currentVersion;
+ if (!res.body.currentVersion) throw new Error("No version set in API");
+ return;
+ })
+ .expect(200, done)
+ });
+})
+
+describe('Permission', function(){
+ it('errors if can connect without correct APIKey', function(done) {
+ // This is broken because Etherpad doesn't handle HTTP codes properly see #2343
+ // If your APIKey is password you deserve to fail all tests anyway
+ var permErrorURL = '/api/'+apiVersion+'/createPad?apikey=password&padID=test';
+ api.get(permErrorURL)
+ .expect(401, done)
+ });
+})
+
+/* Pad Tests Order of execution
+-> deletePad -- This gives us a guaranteed clear environment
+ -> createPad
+ -> getRevisions -- Should be 0
+ -> getHTML -- Should be the default pad text in HTML format
+ -> deletePad -- Should just delete a pad
+ -> getHTML -- Should return an error
+ -> createPad(withText)
+ -> getText -- Should have the text specified above as the pad text
+ -> setText
+ -> getText -- Should be the text set before
+ -> getRevisions -- Should be 0 still?
+ -> padUsersCount -- Should be 0
+ -> getReadOnlyId -- Should be a value
+ -> listAuthorsOfPad(padID) -- should be empty array?
+ -> getLastEdited(padID) -- Should be when pad was made
+ -> setText(padId)
+ -> getLastEdited(padID) -- Should be when setText was performed
+*/
+
+describe('deletePad', function(){
+ it('deletes a Pad', function(done) {
+ api.get(endPoint('deletePad')+"&padID="+testPadId)
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createPad', function(){
+ it('creates a new Pad', function(done) {
+ api.get(endPoint('createPad')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Unable to create new Pad");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getRevisionsCount', function(){
+ it('gets revision count of Pad', function(done) {
+ api.get(endPoint('getRevisionsCount')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Unable to get Revision Count");
+ if(res.body.data.revisions !== 0) throw new Error("Incorrect Revision Count");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getHTML', function(){
+ it('get the HTML of Pad', function(done) {
+ api.get(endPoint('getHTML')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.html.length <= 1) throw new Error("Unable to get Revision Count");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('deletePad', function(){
+ it('deletes a Pad', function(done) {
+ api.get(endPoint('deletePad')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Pad Deletion failed")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getHTML', function(){
+ it('get the HTML of a Pad -- Should return a failure', function(done) {
+ api.get(endPoint('getHTML')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.code !== 1) throw new Error("Pad deletion failed")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createPad', function(){
+ it('creates a new Pad with text', function(done) {
+ api.get(endPoint('createPad')+"&padID="+testPadId+"&text=testText")
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Pad Creation failed")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getText', function(){
+ it('gets the Pad text and expect it to be testText with \n which is a line break', function(done) {
+ api.get(endPoint('getText')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.text !== "testText\n") throw new Error("Pad Creation with text")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('setText', function(){
+ it('creates a new Pad with text', function(done) {
+ api.get(endPoint('setText')+"&padID="+testPadId+"&text=testTextTwo")
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Pad setting text failed");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getText', function(){
+ it('gets the Pad text', function(done) {
+ api.get(endPoint('getText')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.text !== "testTextTwo\n") throw new Error("Setting Text")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getRevisionsCount', function(){
+ it('gets Revision Coutn of a Pad', function(done) {
+ api.get(endPoint('getRevisionsCount')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.revisions !== 1) throw new Error("Unable to set text revision count")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('padUsersCount', function(){
+ it('gets User Count of a Pad', function(done) {
+ api.get(endPoint('padUsersCount')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.padUsersCount !== 0) throw new Error("Incorrect Pad User count")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getReadOnlyID', function(){
+ it('Gets the Read Only ID of a Pad', function(done) {
+ api.get(endPoint('getReadOnlyID')+"&padID="+testPadId)
+ .expect(function(res){
+ if(!res.body.data.readOnlyID) throw new Error("No Read Only ID for Pad")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('listAuthorsOfPad', function(){
+ it('Get Authors of the Pad', function(done) {
+ api.get(endPoint('listAuthorsOfPad')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.authorIDs.length !== 0) throw new Error("# of Authors of pad is not 0")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getLastEdited', function(){
+ it('Get When Pad was left Edited', function(done) {
+ api.get(endPoint('getLastEdited')+"&padID="+testPadId)
+ .expect(function(res){
+ if(!res.body.data.lastEdited){
+ throw new Error("# of Authors of pad is not 0")
+ }else{
+ lastEdited = res.body.data.lastEdited;
+ }
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('setText', function(){
+ it('creates a new Pad with text', function(done) {
+ api.get(endPoint('setText')+"&padID="+testPadId+"&text=testTextTwo")
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Pad setting text failed");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getLastEdited', function(){
+ it('Get When Pad was left Edited', function(done) {
+ api.get(endPoint('getLastEdited')+"&padID="+testPadId)
+ .expect(function(res){
+ if(res.body.data.lastEdited <= lastEdited){
+ throw new Error("Editing A Pad is not updating when it was last edited")
+ }
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+
+var endPoint = function(point){
+ return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
+}
+
+function makeid()
+{
+ var text = "";
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+ for( var i=0; i < 5; i++ ){
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+}
diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js
new file mode 100644
index 00000000..86ba454a
--- /dev/null
+++ b/tests/backend/specs/api/sessionsAndGroups.js
@@ -0,0 +1,363 @@
+var assert = require('assert')
+ supertest = require(__dirname+'/../../../../src/node_modules/supertest'),
+ fs = require('fs'),
+ api = supertest('http://localhost:9001');
+ path = require('path');
+
+var filePath = path.join(__dirname, '../../../../APIKEY.txt');
+
+var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'});
+var apiVersion = 1;
+var testPadId = makeid();
+var groupID = "";
+var authorID = "";
+var sessionID = "";
+var padID = makeid();
+
+describe('API Versioning', function(){
+ it('errors if can not connect', function(done) {
+ api.get('/api/')
+ .expect(function(res){
+ apiVersion = res.body.currentVersion;
+ if (!res.body.currentVersion) throw new Error("No version set in API");
+ return;
+ })
+ .expect(200, done)
+ });
+})
+
+// BEGIN GROUP AND AUTHOR TESTS
+/////////////////////////////////////
+/////////////////////////////////////
+
+/* Tests performed
+-> createGroup() -- should return a groupID
+ -> listSessionsOfGroup(groupID) -- should be 0
+ -> deleteGroup(groupID)
+ -> createGroupIfNotExistsFor(groupMapper) -- should return a groupID
+
+ -> createAuthor([name]) -- should return an authorID
+ -> createAuthorIfNotExistsFor(authorMapper [, name]) -- should return an authorID
+ -> getAuthorName(authorID) -- should return a name IE "john"
+
+-> createSession(groupID, authorID, validUntil)
+ -> getSessionInfo(sessionID)
+ -> listSessionsOfGroup(groupID) -- should be 1
+ -> deleteSession(sessionID)
+ -> getSessionInfo(sessionID) -- should have author id etc in
+
+-> listPads(groupID) -- should be empty array
+ -> createGroupPad(groupID, padName [, text])
+ -> listPads(groupID) -- should be empty array
+ -> getPublicStatus(padId)
+ -> setPublicStatus(padId, status)
+ -> getPublicStatus(padId)
+ -> isPasswordProtected(padID) -- should be false
+ -> setPassword(padID, password)
+ -> isPasswordProtected(padID) -- should be true
+
+-> listPadsOfAuthor(authorID)
+*/
+
+describe('createGroup', function(){
+ it('creates a new group', function(done) {
+ api.get(endPoint('createGroup'))
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Unable to create new Pad");
+ groupID = res.body.data.groupID;
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('listSessionsOfGroup', function(){
+ it('Lists the session of a group', function(done) {
+ api.get(endPoint('listSessionsOfGroup')+"&groupID="+groupID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data !== null) throw new Error("Sessions show as existing for this group");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('deleteGroup', function(){
+ it('Deletes a group', function(done) {
+ api.get(endPoint('deleteGroup')+"&groupID="+groupID)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Group failed to be deleted");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createGroupIfNotExistsFor', function(){
+ it('Creates a group if one doesnt exist for mapper 0', function(done) {
+ api.get(endPoint('createGroupIfNotExistsFor')+"&groupMapper=management")
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Sessions show as existing for this group");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createGroup', function(){
+ it('creates a new group', function(done) {
+ api.get(endPoint('createGroup'))
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.groupID) throw new Error("Unable to create new Pad");
+ groupID = res.body.data.groupID;
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createAuthor', function(){
+ it('Creates an author with a name set', function(done) {
+ api.get(endPoint('createAuthor'))
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create author");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createAuthor', function(){
+ it('Creates an author with a name set', function(done) {
+ api.get(endPoint('createAuthor')+"&name=john")
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create user with name set");
+ authorID = res.body.data.authorID; // we will be this author for the rest of the tests
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createAuthorIfNotExistsFor', function(){
+ it('Creates an author if it doesnt exist already and provides mapping', function(done) {
+ api.get(endPoint('createAuthorIfNotExistsFor')+"&authorMapper=chris")
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create author with mapper");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getAuthorName', function(){
+ it('Gets the author name', function(done) {
+ api.get(endPoint('getAuthorName')+"&authorID="+authorID)
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data === "john") throw new Error("Unable to get Author Name from Author ID");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+// BEGIN SESSION TESTS
+///////////////////////////////////////
+///////////////////////////////////////
+
+describe('createSession', function(){
+ it('Creates a session for an Author', function(done) {
+ api.get(endPoint('createSession')+"&authorID="+authorID+"&groupID="+groupID+"&validUntil=999999999999")
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.sessionID) throw new Error("Unable to create Session");
+ sessionID = res.body.data.sessionID;
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getSessionInfo', function(){
+ it('Gets session inf', function(done) {
+ api.get(endPoint('getSessionInfo')+"&sessionID="+sessionID)
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.groupID || !res.body.data.authorID || !res.body.data.validUntil) throw new Error("Unable to get Session info");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('listSessionsOfGroup', function(){
+ it('Gets sessions of a group', function(done) {
+ api.get(endPoint('listSessionsOfGroup')+"&groupID="+groupID)
+ .expect(function(res){
+ if(res.body.code !== 0 || typeof res.body.data !== "object") throw new Error("Unable to get sessions of a group");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('deleteSession', function(){
+ it('Deletes a session', function(done) {
+ api.get(endPoint('deleteSession')+"&sessionID="+sessionID)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Unable to delete a session");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getSessionInfo', function(){
+ it('Gets session info', function(done) {
+ api.get(endPoint('getSessionInfo')+"&sessionID="+sessionID)
+ .expect(function(res){
+ if(res.body.code !== 1) throw new Error("Session was not properly deleted");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+// GROUP PAD MANAGEMENT
+///////////////////////////////////////
+///////////////////////////////////////
+
+describe('listPads', function(){
+ it('Lists Pads of a Group', function(done) {
+ api.get(endPoint('listPads')+"&groupID="+groupID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data.padIDs.length !== 0) throw new Error("Group already had pads for some reason"+res.body.data.padIDs);
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('createGroupPad', function(){
+ it('Creates a Group Pad', function(done) {
+ api.get(endPoint('createGroupPad')+"&groupID="+groupID+"&padName="+padID)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Unable to create group pad");
+ padID = res.body.data.padID;
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('listPads', function(){
+ it('Lists Pads of a Group', function(done) {
+ api.get(endPoint('listPads')+"&groupID="+groupID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data.padIDs.length !== 1) throw new Error("Group isnt listing this pad");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+// PAD SECURITY /-_-\
+///////////////////////////////////////
+///////////////////////////////////////
+
+describe('getPublicStatus', function(){
+ it('Gets the public status of a pad', function(done) {
+ api.get(endPoint('getPublicStatus')+"&padID="+padID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data.publicstatus) throw new Error("Unable to get public status of this pad");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('setPublicStatus', function(){
+ it('Sets the public status of a pad', function(done) {
+ api.get(endPoint('setPublicStatus')+"&padID="+padID+"&publicStatus=true")
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Setting status did not work");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getPublicStatus', function(){
+ it('Gets the public status of a pad', function(done) {
+ api.get(endPoint('getPublicStatus')+"&padID="+padID)
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.publicStatus) throw new Error("Setting public status of this pad did not work");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('isPasswordProtected', function(){
+ it('Gets the public status of a pad', function(done) {
+ api.get(endPoint('isPasswordProtected')+"&padID="+padID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data.isPasswordProtected) throw new Error("Pad is password protected by default");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('setPassword', function(){
+ it('Gets the public status of a pad', function(done) {
+ api.get(endPoint('setPassword')+"&padID="+padID+"&password=test")
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("Unabe to set password");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('isPasswordProtected', function(){
+ it('Gets the public status of a pad', function(done) {
+ api.get(endPoint('isPasswordProtected')+"&padID="+padID)
+ .expect(function(res){
+ if(res.body.code !== 0 || !res.body.data.isPasswordProtected) throw new Error("Pad password protection has not applied");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+
+// NOT SURE HOW TO POPULAT THIS /-_-\
+///////////////////////////////////////
+///////////////////////////////////////
+
+describe('listPadsOfAuthor', function(){
+ it('Gets the Pads of an Author', function(done) {
+ api.get(endPoint('listPadsOfAuthor')+"&authorID="+authorID)
+ .expect(function(res){
+ if(res.body.code !== 0 || res.body.data.padIDs.length !== 0) throw new Error("Pad password protection has not applied");
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+
+
+var endPoint = function(point){
+ return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
+}
+
+function makeid()
+{
+ var text = "";
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+ for( var i=0; i < 5; i++ ){
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+}