From ad7de8277d75d6029d81d0039e40f80c9fb796e2 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 25 Nov 2014 22:12:25 +0000 Subject: [PATCH 01/19] mocha --- src/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 4b0ae82b4..4a472be07 100644 --- a/src/package.json +++ b/src/package.json @@ -40,7 +40,8 @@ "swagger-node-express" : ">=2.1.0", "channels" : "0.0.x", "jsonminify" : "0.2.2", - "measured" : "0.1.3" + "measured" : "0.1.3", + "mocha" : "*" }, "bin": { "etherpad-lite": "./node/server.js" }, "devDependencies": { From 3ac833d455dcf280e69c04a54cf7acd2e35dd91a Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 25 Nov 2014 22:47:22 +0000 Subject: [PATCH 02/19] basic test runner --- bin/backendTests.sh | 1 + tests/backend/specs/api.js | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100755 bin/backendTests.sh create mode 100644 tests/backend/specs/api.js diff --git a/bin/backendTests.sh b/bin/backendTests.sh new file mode 100755 index 000000000..ab07e012b --- /dev/null +++ b/bin/backendTests.sh @@ -0,0 +1 @@ +src/node_modules/mocha/bin/mocha --timeout 5000 --reporter nyan tests/backend/specs diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api.js new file mode 100644 index 000000000..5cd567c65 --- /dev/null +++ b/tests/backend/specs/api.js @@ -0,0 +1,41 @@ +var assert = require("assert") + supertest = require('supertest'), + api = supertest('http://localhost:9001'); + +describe('Array', function(){ + describe('#indexOf()', function(){ + it('should return -1 when the value is not present', function(){ + assert.equal(-1, [1,2,3].indexOf(5)); + assert.equal(-1, [1,2,3].indexOf(0)); + }) + }) +}) + +describe('Connectivity', function(){ + it('errors if can not connect', function(done) { + api.get('/api/') + .expect(200, done) + }); +}) + + + +/* +describe('Authentication', function() { + + it('errors if wrong basic auth', function(done) { + api.get('/blog') + .set('x-api-key', '123myapikey') + .auth('incorrect', 'credentials') + .expect(401, done) + }); + + it('errors if bad x-api-key header', function(done) { + api.get('/blog') + .auth('correct', 'credentials') + .expect(401) + .expect({error:"Bad or missing app identification header"}, done); + }); + +}); +*/ From a4be5b4fd7bef7d1e5d48ae715aae7dc8e359221 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 01:03:57 +0000 Subject: [PATCH 03/19] mocha version --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 4a472be07..5f684d0ee 100644 --- a/src/package.json +++ b/src/package.json @@ -41,7 +41,7 @@ "channels" : "0.0.x", "jsonminify" : "0.2.2", "measured" : "0.1.3", - "mocha" : "*" + "mocha" : ">=2.0.1" }, "bin": { "etherpad-lite": "./node/server.js" }, "devDependencies": { From 7a4a3b5ef312327d8f16503a74911c60df3f2f09 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 01:11:42 +0000 Subject: [PATCH 04/19] make internal note of which endpoints need testing --- tests/backend/specs/api.js | 122 +++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 25 deletions(-) diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api.js index 5cd567c65..685714c16 100644 --- a/tests/backend/specs/api.js +++ b/tests/backend/specs/api.js @@ -1,41 +1,113 @@ -var assert = require("assert") +var assert = require('assert') supertest = require('supertest'), + fs = require('fs'), api = supertest('http://localhost:9001'); + path = require('path'); -describe('Array', function(){ - describe('#indexOf()', function(){ - it('should return -1 when the value is not present', function(){ - assert.equal(-1, [1,2,3].indexOf(5)); - assert.equal(-1, [1,2,3].indexOf(0)); - }) - }) -}) +var filePath = path.join(__dirname, '../../../APIKEY.txt'); + +var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'}); +var apiVersion = 1; +var testPadId = makeid(); 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 + throw new Error("Erroring anyway just because the API seems broken here"); + api.get('/api/'+apiVersion+'/createPad&apikey=password&padID=test') + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('createPad', function(){ + it('creates a new pad', function(done) { + api.get(endPoint('createPad')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +/* Endpoints to interact with.. +createPad(padID [, text]) +getRevisions(padID) +padUsersCount(padID) +deletePad(padID) +getReadOnlyID(padID) +setPublicStatus(padID, publicStatus) +getPublicStatus(padID) +setPassword(padID, password) +isPasswordProtected(padID) +listAuthorsOfPad(padID) +getLastEdited(padID) +getHTML(padID, [rev]) +setText(padID, text) +getText(padID, [rev]) + +listSessionsOfGroup(groupID) +getSessionInfo(sessionID) +deleteSession(sessionID) +createSession(groupID, authorID, validUntil) + +listPadsOfAuthor(authorID) +createAuthorIfNotExistsFor(authorMapper [, name]) +createAuthor([name]) + +createGroupPad(groupID, padName [, text]) +listPads(groupID) +deleteGroup(groupID) +createGroupIfNotExistsFor(groupMapper) +createGroup() +*/ /* -describe('Authentication', function() { - - it('errors if wrong basic auth', function(done) { - api.get('/blog') - .set('x-api-key', '123myapikey') - .auth('incorrect', 'credentials') - .expect(401, done) +describe('getRevisionsCount', function(){ + it('gets the revision counts of a new pad', function(done) { + // This is broken because Etherpad doesn't handle HTTP codes properly see #2$ + // If your APIKey is password you deserve to fail all tests anyway + api.get(endPoint('getRevisionsCount')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(function(res){ + console.log(res.body); + }) + .expect(200, done) }); - - it('errors if bad x-api-key header', function(done) { - api.get('/blog') - .auth('correct', 'credentials') - .expect(401) - .expect({error:"Bad or missing app identification header"}, 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; +} From 16f3ebb3ba4066ffb2856e378010e5ea6d843b8d Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 17:34:44 +0000 Subject: [PATCH 05/19] handle auth fails --- src/node/handler/APIHandler.js | 1 + tests/backend/specs/api.js | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js index 9adc24180..a26dd2cfb 100644 --- a/src/node/handler/APIHandler.js +++ b/src/node/handler/APIHandler.js @@ -450,6 +450,7 @@ exports.handle = function(apiVersion, functionName, fields, req, res) if(fields["apikey"] != apikey.trim()) { + res.statusCode = 401; res.send({code: 4, message: "no or wrong API Key", data: null}); return; } diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api.js index 685714c16..40aa2183f 100644 --- a/tests/backend/specs/api.js +++ b/tests/backend/specs/api.js @@ -34,10 +34,9 @@ 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 - throw new Error("Erroring anyway just because the API seems broken here"); - api.get('/api/'+apiVersion+'/createPad&apikey=password&padID=test') - .expect('Content-Type', /json/) - .expect(200, done) + var permErrorURL = '/api/'+apiVersion+'/createPad?apikey=password&padID=test'; + api.get(permErrorURL) + .expect(401, done) }); }) From 1347a814f04d611499d7ee0c3c41f222d46f4ff9 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 17:53:31 +0000 Subject: [PATCH 06/19] basic pad tests without test logic yet --- tests/backend/specs/api.js | 136 +++++++++++++++++++++++++++++++++---- 1 file changed, 124 insertions(+), 12 deletions(-) diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api.js index 40aa2183f..d485c900f 100644 --- a/tests/backend/specs/api.js +++ b/tests/backend/specs/api.js @@ -40,39 +40,151 @@ describe('Permission', function(){ }); }) +/* Pad Tests Order of execution +-> deletePad -- This gives us a guaranteed clear environment + -> createPad + -> getRevisions(0) -- 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 +*/ + +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) { + it('creates a new Pad', function(done) { api.get(endPoint('createPad')+"&padID="+testPadId) .expect('Content-Type', /json/) .expect(200, done) }); }) -/* Endpoints to interact with.. -createPad(padID [, text]) -getRevisions(padID) +describe('getRevisions', function(){ + it('gets revision count of Pad', function(done) { + api.get(endPoint('getRevisions')+"&padID="+testPadId) + .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('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('deletePad', function(){ + it('deletes a Pad', function(done) { + api.get(endPoint('deletePad')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('getHTML', function(){ + it('get the HTML of a Pad', function(done) { + api.get(endPoint('getHTML')+"&padID="+testPadId) + .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+"&test=testText") + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('getText', function(){ + it('gets the Pad text', function(done) { + api.get(endPoint('getText')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('setText', function(){ + it('creates a new Pad with text', function(done) { + api.get(endPoint('createPad')+"&padID="+testPadId+"&test=testText") + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('getText', function(){ + it('gets the Pad text', function(done) { + api.get(endPoint('getText')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('getRevisions', function(){ + it('gets Revision Coutn of a Pad', function(done) { + api.get(endPoint('getRevisions')+"&padID="+testPadId) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('padUsersCount', function(){ + it('gets Revision Coutn of a Pad', function(done) { + api.get(endPoint('padUsersCount')+"&padID="+testPadId) + .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('Content-Type', /json/) + .expect(200, done) + }); +}) + + + +/* Endpoints Still to interact with.. +/ createPad(padID [, text]) +/ getRevisions(padID) +/ deletePad(padID) +/ getReadOnlyID(padID) +/ getHTML(padID, [rev]) +/ setText(padID, text) +/ getText(padID, [rev]) + padUsersCount(padID) -deletePad(padID) -getReadOnlyID(padID) setPublicStatus(padID, publicStatus) getPublicStatus(padID) setPassword(padID, password) isPasswordProtected(padID) listAuthorsOfPad(padID) getLastEdited(padID) -getHTML(padID, [rev]) -setText(padID, text) -getText(padID, [rev]) - listSessionsOfGroup(groupID) getSessionInfo(sessionID) deleteSession(sessionID) createSession(groupID, authorID, validUntil) - listPadsOfAuthor(authorID) createAuthorIfNotExistsFor(authorMapper [, name]) createAuthor([name]) - createGroupPad(groupID, padName [, text]) listPads(groupID) deleteGroup(groupID) From c0679980bf383ce452431feb7020c91d6c4ee43b Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 19:25:09 +0000 Subject: [PATCH 07/19] all pad tests with content --- tests/backend/specs/api.js | 65 +++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api.js index d485c900f..279f3088a 100644 --- a/tests/backend/specs/api.js +++ b/tests/backend/specs/api.js @@ -67,14 +67,21 @@ describe('deletePad', function(){ 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('getRevisions', function(){ +describe('getRevisionsCount', function(){ it('gets revision count of Pad', function(done) { - api.get(endPoint('getRevisions')+"&padID="+testPadId) + 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) }); @@ -83,6 +90,9 @@ describe('getRevisions', function(){ 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) }); @@ -91,14 +101,20 @@ describe('getHTML', function(){ 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', function(done) { + 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) }); @@ -106,15 +122,21 @@ describe('getHTML', function(){ describe('createPad', function(){ it('creates a new Pad with text', function(done) { - api.get(endPoint('createPad')+"&padID="+testPadId+"&test=testText") + 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', function(done) { + 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) }); @@ -122,7 +144,10 @@ describe('getText', function(){ describe('setText', function(){ it('creates a new Pad with text', function(done) { - api.get(endPoint('createPad')+"&padID="+testPadId+"&test=testText") + 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) }); @@ -131,14 +156,20 @@ describe('setText', function(){ 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('getRevisions', function(){ +describe('getRevisionsCount', function(){ it('gets Revision Coutn of a Pad', function(done) { - api.get(endPoint('getRevisions')+"&padID="+testPadId) + 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) }); @@ -147,14 +178,20 @@ describe('getRevisions', function(){ describe('padUsersCount', function(){ it('gets Revision Coutn 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(){ +describe('getReadOnlyID', function(){ it('Gets the Read Only ID of a Pad', function(done) { - api.get(endPoint('getReadOnlyId')+"&padID="+testPadId) + 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) }); @@ -163,14 +200,6 @@ describe('getReadOnlyId', function(){ /* Endpoints Still to interact with.. -/ createPad(padID [, text]) -/ getRevisions(padID) -/ deletePad(padID) -/ getReadOnlyID(padID) -/ getHTML(padID, [rev]) -/ setText(padID, text) -/ getText(padID, [rev]) - padUsersCount(padID) setPublicStatus(padID, publicStatus) getPublicStatus(padID) From 5434d2118d9b6828f3c679f88618ee8403fd6e8b Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 19:28:49 +0000 Subject: [PATCH 08/19] tidy up and re-organize --- bin/backendTests.sh | 2 +- tests/backend/specs/{api.js => api/pad.js} | 42 +------------------- tests/backend/specs/api/sessionsAndGroups.js | 38 ++++++++++++++++++ 3 files changed, 40 insertions(+), 42 deletions(-) rename tests/backend/specs/{api.js => api/pad.js} (85%) create mode 100644 tests/backend/specs/api/sessionsAndGroups.js diff --git a/bin/backendTests.sh b/bin/backendTests.sh index ab07e012b..ec12775ba 100755 --- a/bin/backendTests.sh +++ b/bin/backendTests.sh @@ -1 +1 @@ -src/node_modules/mocha/bin/mocha --timeout 5000 --reporter nyan tests/backend/specs +src/node_modules/mocha/bin/mocha --timeout 5000 --reporter nyan tests/backend/specs/api diff --git a/tests/backend/specs/api.js b/tests/backend/specs/api/pad.js similarity index 85% rename from tests/backend/specs/api.js rename to tests/backend/specs/api/pad.js index 279f3088a..efb3f6dee 100644 --- a/tests/backend/specs/api.js +++ b/tests/backend/specs/api/pad.js @@ -4,7 +4,7 @@ var assert = require('assert') api = supertest('http://localhost:9001'); path = require('path'); -var filePath = path.join(__dirname, '../../../APIKEY.txt'); +var filePath = path.join(__dirname, '../../../../APIKEY.txt'); var apiKey = fs.readFileSync(filePath, {encoding: 'utf-8'}); var apiVersion = 1; @@ -197,46 +197,6 @@ describe('getReadOnlyID', function(){ }); }) - - -/* Endpoints Still to interact with.. -padUsersCount(padID) -setPublicStatus(padID, publicStatus) -getPublicStatus(padID) -setPassword(padID, password) -isPasswordProtected(padID) -listAuthorsOfPad(padID) -getLastEdited(padID) -listSessionsOfGroup(groupID) -getSessionInfo(sessionID) -deleteSession(sessionID) -createSession(groupID, authorID, validUntil) -listPadsOfAuthor(authorID) -createAuthorIfNotExistsFor(authorMapper [, name]) -createAuthor([name]) -createGroupPad(groupID, padName [, text]) -listPads(groupID) -deleteGroup(groupID) -createGroupIfNotExistsFor(groupMapper) -createGroup() -*/ - - -/* -describe('getRevisionsCount', function(){ - it('gets the revision counts of a new pad', function(done) { - // This is broken because Etherpad doesn't handle HTTP codes properly see #2$ - // If your APIKey is password you deserve to fail all tests anyway - api.get(endPoint('getRevisionsCount')+"&padID="+testPadId) - .expect('Content-Type', /json/) - .expect(function(res){ - console.log(res.body); - }) - .expect(200, done) - }); -}) -*/ - var endPoint = function(point){ return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey; } diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js new file mode 100644 index 000000000..921724c7d --- /dev/null +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -0,0 +1,38 @@ +/* Endpoints Still to interact with.. +padUsersCount(padID) +setPublicStatus(padID, publicStatus) +getPublicStatus(padID) +setPassword(padID, password) +isPasswordProtected(padID) +listAuthorsOfPad(padID) +getLastEdited(padID) +listSessionsOfGroup(groupID) +getSessionInfo(sessionID) +deleteSession(sessionID) +createSession(groupID, authorID, validUntil) +listPadsOfAuthor(authorID) +createAuthorIfNotExistsFor(authorMapper [, name]) +createAuthor([name]) +createGroupPad(groupID, padName [, text]) +listPads(groupID) +deleteGroup(groupID) +createGroupIfNotExistsFor(groupMapper) +createGroup() +*/ + + +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; +} + From f3c2ac6d94737de2f26c33fe9458fb1da39a25f4 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 19:44:38 +0000 Subject: [PATCH 09/19] mowah pad tests, tea time --- tests/backend/specs/api/pad.js | 60 ++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js index efb3f6dee..fa9863fb8 100644 --- a/tests/backend/specs/api/pad.js +++ b/tests/backend/specs/api/pad.js @@ -9,6 +9,7 @@ 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) { @@ -43,7 +44,7 @@ describe('Permission', function(){ /* Pad Tests Order of execution -> deletePad -- This gives us a guaranteed clear environment -> createPad - -> getRevisions(0) -- Should be 0 + -> 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 @@ -54,6 +55,10 @@ describe('Permission', function(){ -> 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(){ @@ -176,7 +181,7 @@ describe('getRevisionsCount', function(){ }) describe('padUsersCount', function(){ - it('gets Revision Coutn of a Pad', function(done) { + 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") @@ -197,6 +202,57 @@ describe('getReadOnlyID', function(){ }); }) +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; } From 98cc725300de21c1cb80a26f9ec65fed829af144 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 21:06:35 +0000 Subject: [PATCH 10/19] 30% of session and group tests done --- tests/backend/specs/api/sessionsAndGroups.js | 215 +++++++++++++++++-- 1 file changed, 194 insertions(+), 21 deletions(-) diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js index 921724c7d..41c16b4e1 100644 --- a/tests/backend/specs/api/sessionsAndGroups.js +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -1,24 +1,198 @@ -/* Endpoints Still to interact with.. -padUsersCount(padID) -setPublicStatus(padID, publicStatus) -getPublicStatus(padID) -setPassword(padID, password) -isPasswordProtected(padID) -listAuthorsOfPad(padID) -getLastEdited(padID) -listSessionsOfGroup(groupID) -getSessionInfo(sessionID) -deleteSession(sessionID) -createSession(groupID, authorID, validUntil) -listPadsOfAuthor(authorID) -createAuthorIfNotExistsFor(authorMapper [, name]) -createAuthor([name]) -createGroupPad(groupID, padName [, text]) -listPads(groupID) -deleteGroup(groupID) -createGroupIfNotExistsFor(groupMapper) -createGroup() +var assert = require('assert') + supertest = require('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 = ""; + +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) + }); +}) + +/* 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" + -> listPadsOfAuthor(authorID) + +-> 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) + -> isPasswordProtected(padID) -- should be false + -> setPassword(padID, password) + -> isPasswordProtected(padID) -- should be true */ + +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"); + 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("Sessions show as existing for this group"); + }) + .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) + }); +}) + + +/* Endpoints Still to interact with.. + -> getAuthorName(authorID) -- should return a name IE "john" + -> listPadsOfAuthor(authorID) + +-> 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) + -> isPasswordProtected(padID) -- should be false + -> setPassword(padID, password) + -> isPasswordProtected(padID) -- should be true +*/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + var endPoint = function(point){ @@ -35,4 +209,3 @@ function makeid() } return text; } - From 253d6da2ac4b534d717caf2013aa265d9c1e1711 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 21:19:55 +0000 Subject: [PATCH 11/19] 60% of backend api tests written --- tests/backend/specs/api/sessionsAndGroups.js | 75 +++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js index 41c16b4e1..77e8b25d2 100644 --- a/tests/backend/specs/api/sessionsAndGroups.js +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -11,6 +11,7 @@ var apiVersion = 1; var testPadId = makeid(); var groupID = ""; var authorID = ""; +var sessionID = ""; describe('API Versioning', function(){ it('errors if can not connect', function(done) { @@ -24,6 +25,10 @@ describe('API Versioning', function(){ }); }) +// BEGIN GROUP AND AUTHOR TESTS +///////////////////////////////////// +///////////////////////////////////// + /* Tests performed -> createGroup() -- should return a groupID -> listSessionsOfGroup(groupID) -- should be 0 @@ -142,17 +147,67 @@ describe('getAuthorName', function(){ }); }) +// 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) + }); +}) /* Endpoints Still to interact with.. - -> getAuthorName(authorID) -- should return a name IE "john" - -> listPadsOfAuthor(authorID) - --> 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 @@ -161,6 +216,8 @@ describe('getAuthorName', function(){ -> isPasswordProtected(padID) -- should be false -> setPassword(padID, password) -> isPasswordProtected(padID) -- should be true + + -> listPadsOfAuthor(authorID) */ From 198e21167197becf8a7e907ebaaa6140914bfd33 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 21:36:57 +0000 Subject: [PATCH 12/19] 4 more to go --- tests/backend/specs/api/sessionsAndGroups.js | 104 ++++++++++++++++--- 1 file changed, 90 insertions(+), 14 deletions(-) diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js index 77e8b25d2..583e2c36c 100644 --- a/tests/backend/specs/api/sessionsAndGroups.js +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -12,6 +12,7 @@ var testPadId = makeid(); var groupID = ""; var authorID = ""; var sessionID = ""; +var padID = makeid(); describe('API Versioning', function(){ it('errors if can not connect', function(done) { @@ -51,9 +52,10 @@ describe('API Versioning', function(){ -> listPads(groupID) -- should be empty array -> getPublicStatus(padId) -> setPublicStatus(padId, status) - -> isPasswordProtected(padID) -- should be false - -> setPassword(padID, password) - -> isPasswordProtected(padID) -- should be true + -> getPublicStatus(padId) + -> isPasswordProtected(padID) -- should be false + -> setPassword(padID, password) + -> isPasswordProtected(padID) -- should be true */ describe('createGroup', function(){ @@ -95,7 +97,18 @@ describe('createGroupIfNotExistsFor', function(){ 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"); - groupID = res.body.data.groupID + }) + .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) @@ -207,17 +220,80 @@ describe('getSessionInfo', function(){ }); }) -/* Endpoints Still to interact with.. --> listPads(groupID) -- should be empty array - -> createGroupPad(groupID, padName [, text]) - -> listPads(groupID) -- should be empty array - -> getPublicStatus(padId) - -> setPublicStatus(padId, status) - -> isPasswordProtected(padID) -- should be false - -> setPassword(padID, password) - -> isPasswordProtected(padID) -- should be true +describe('listPads', function(){ + it('Lists Pads of a Group', function(done) { + api.get(endPoint('listPads')+"&groupID="+groupID) + .expect(function(res){ +console.log(res.body.data.padIDs); + 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) + }); +}) - -> listPadsOfAuthor(authorID) +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) + }); +}) + +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) + }); +}) + + +/* Endpoints Still to interact with.. +-> isPasswordProtected(padID) -- should be false + -> setPassword(padID, password) + -> isPasswordProtected(padID) -- should be true + -> listPadsOfAuthor(authorID) */ From e9115880b3792106fc072f0b63e549dc79f0d4bf Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 21:44:50 +0000 Subject: [PATCH 13/19] final api test written for now --- tests/backend/specs/api/sessionsAndGroups.js | 91 ++++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js index 583e2c36c..fc9137489 100644 --- a/tests/backend/specs/api/sessionsAndGroups.js +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -39,7 +39,6 @@ describe('API Versioning', function(){ -> createAuthor([name]) -- should return an authorID -> createAuthorIfNotExistsFor(authorMapper [, name]) -- should return an authorID -> getAuthorName(authorID) -- should return a name IE "john" - -> listPadsOfAuthor(authorID) -> createSession(groupID, authorID, validUntil) -> getSessionInfo(sessionID) @@ -56,6 +55,8 @@ describe('API Versioning', function(){ -> isPasswordProtected(padID) -- should be false -> setPassword(padID, password) -> isPasswordProtected(padID) -- should be true + +-> listPadsOfAuthor(authorID) */ describe('createGroup', function(){ @@ -119,7 +120,7 @@ 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("Sessions show as existing for this group"); + if(res.body.code !== 0 || !res.body.data.authorID) throw new Error("Unable to create author"); }) .expect('Content-Type', /json/) .expect(200, done) @@ -220,11 +221,14 @@ describe('getSessionInfo', function(){ }); }) +// GROUP PAD MANAGEMENT +/////////////////////////////////////// +/////////////////////////////////////// + describe('listPads', function(){ it('Lists Pads of a Group', function(done) { api.get(endPoint('listPads')+"&groupID="+groupID) .expect(function(res){ -console.log(res.body.data.padIDs); 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/) @@ -255,6 +259,10 @@ describe('listPads', function(){ }); }) +// PAD SECURITY /-_-\ +/////////////////////////////////////// +/////////////////////////////////////// + describe('getPublicStatus', function(){ it('Gets the public status of a pad', function(done) { api.get(endPoint('getPublicStatus')+"&padID="+padID) @@ -288,43 +296,54 @@ describe('getPublicStatus', function(){ }); }) +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) + }); +}) -/* Endpoints Still to interact with.. --> isPasswordProtected(padID) -- should be false - -> setPassword(padID, password) - -> isPasswordProtected(padID) -- should be true - -> listPadsOfAuthor(authorID) -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - +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) + }); +}) From cff8f4a61ebe48fe47cb2d9c54f41b9cff05781e Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 21:58:27 +0000 Subject: [PATCH 14/19] remember to add supertest --- src/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 1408d9fe5..f173b94ec 100644 --- a/src/package.json +++ b/src/package.json @@ -41,7 +41,8 @@ "channels" : "0.0.x", "jsonminify" : "0.2.2", "measured" : "0.1.3", - "mocha" : ">=2.0.1" + "mocha" : ">=2.0.1", + "supertest" : ">=0.15.0" }, "bin": { "etherpad-lite": "./node/server.js" }, "devDependencies": { From fa5130978c3b47defbdb45b266e3c45c897d074d Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 26 Nov 2014 22:10:56 +0000 Subject: [PATCH 15/19] path issues for supertitties --- tests/backend/specs/api/pad.js | 2 +- tests/backend/specs/api/sessionsAndGroups.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js index fa9863fb8..80f77220f 100644 --- a/tests/backend/specs/api/pad.js +++ b/tests/backend/specs/api/pad.js @@ -1,5 +1,5 @@ var assert = require('assert') - supertest = require('supertest'), + supertest = require(__dirname+'/../../../../src/node_modules/supertest'), fs = require('fs'), api = supertest('http://localhost:9001'); path = require('path'); diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js index fc9137489..86ba454a2 100644 --- a/tests/backend/specs/api/sessionsAndGroups.js +++ b/tests/backend/specs/api/sessionsAndGroups.js @@ -1,5 +1,5 @@ var assert = require('assert') - supertest = require('supertest'), + supertest = require(__dirname+'/../../../../src/node_modules/supertest'), fs = require('fs'), api = supertest('http://localhost:9001'); path = require('path'); From e6d85bbe69de34089039e28ae984807c0b37883f Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 28 Nov 2014 00:26:34 +0000 Subject: [PATCH 16/19] fix issue with top of chatbox not being aligned properly --- src/static/js/pad_editbar.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index bdf2d5569..73a968eee 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -184,6 +184,9 @@ var padeditbar = (function() var containerTop = $('.menu_left').height() + 7 + "px"; $('#editbar').css("height", editbarHeight); $('#editorcontainer').css("top", containerTop); + if($('#options-stickychat').is(":checked")){ + $('#chatbox').css("top", containerTop); + }; }, registerDropdownCommand: function (cmd, dropdown) { dropdown = dropdown || cmd; From 68979e12123f010c3fbcd5c460af09b7ccdc13b5 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 28 Nov 2014 00:35:46 +0000 Subject: [PATCH 17/19] better fix --- src/static/js/pad_editbar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index 73a968eee..76a79a629 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -183,9 +183,10 @@ var padeditbar = (function() var editbarHeight = $('.menu_left').height() + 2 + "px"; var containerTop = $('.menu_left').height() + 7 + "px"; $('#editbar').css("height", editbarHeight); + $('#editorcontainer').css("top", containerTop); if($('#options-stickychat').is(":checked")){ - $('#chatbox').css("top", containerTop); + $('#chatbox').css("top", $('#editorcontainer').offset().top + "px"); }; }, registerDropdownCommand: function (cmd, dropdown) { From a642deaa72eef3e6e457271de93156ccac010696 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 28 Nov 2014 02:25:21 +0000 Subject: [PATCH 18/19] gritter css fix --- src/static/css/pad.css | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 5045f2995..8b7e82581 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -1057,6 +1057,7 @@ input[type=checkbox] { right:20px; width:301px; z-index:9999; + background-color:#666; } #gritter-notice-wrapper.bottom-right { top: auto; @@ -1070,14 +1071,12 @@ input[type=checkbox] { } .gritter-top { - background:url(../../static/img/gritter.png) no-repeat left -30px; height:10px; } .hover .gritter-top { background-position:right -30px; } .gritter-bottom { - background:url(../../static/img/gritter.png) no-repeat left bottom; height:8px; margin:0; } @@ -1086,7 +1085,6 @@ input[type=checkbox] { } .gritter-item { display:block; - background:url(../../static/img/gritter.png) no-repeat left -40px; color:#eee; padding:2px 11px 8px 11px; font-size: 11px; @@ -1104,7 +1102,6 @@ input[type=checkbox] { position:absolute; top:5px; left:3px; - background:url('../../static/img/gritter.png') no-repeat left top; cursor:pointer; width:30px; height:30px; From c6d7ed114ea3bbb8fc700f316fcaa145d290c4af Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 28 Nov 2014 16:27:12 +0000 Subject: [PATCH 19/19] script to update all plugins with one command on CLI --- bin/updatePlugins.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 bin/updatePlugins.sh diff --git a/bin/updatePlugins.sh b/bin/updatePlugins.sh new file mode 100755 index 000000000..d696eca79 --- /dev/null +++ b/bin/updatePlugins.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +#Move to the folder where ep-lite is installed +cd `dirname $0` + +#Was this script started in the bin folder? if yes move out +if [ -d "../bin" ]; then + cd "../" +fi + +npm outdated --depth=0 | grep -v "^Package" | awk '{print $1}' | xargs npm install $1 --save-dev +