-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
phpunit tests converted to mocha/chai #140
base: master
Are you sure you want to change the base?
Changes from 13 commits
cfc8228
d58206e
0244f16
f4dfc10
b30737f
aae33b1
878afef
e8449db
8b7804b
bf083e1
6af7367
9e746e0
339d923
2f5ccd0
755e133
319ce22
1ee44b1
41d5981
4d7632c
e150cd1
ae270e5
0d653ed
5e21351
8e0936b
1976445
d8f3427
2e7a853
d4465f2
e7518c2
c5b1a93
640caf4
8253f4d
b2b562a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const fs = require('fs'); | ||
|
||
var config = {}; | ||
|
||
const data = fs.readFileSync('config.json'); | ||
config = JSON.parse(data); | ||
config.timeout = 60000; | ||
config.numOwnedGroups = 3; | ||
config.numPublicGroups = 2; | ||
module.exports = config; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"verbose": 1, | ||
"syncURLPrefix": "http://dataserver/", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need this |
||
"apiURLPrefix": "http://localhost/", | ||
"rootUsername": "YtTnrHcWUC0FqP27xuaa", | ||
"rootPassword": "esFEIngwxnyp1kuTrUpKpH72gEftHbkiWneoeimV", | ||
"awsRegion": "us-east-1", | ||
"s3Bucket": "zotero", | ||
"awsAccessKey": "", | ||
"awsSecretKey": "", | ||
"filesystemStorage": 1, | ||
"syncVersion": 9, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need this |
||
|
||
|
||
"userID": 1, | ||
"libraryID": 1, | ||
"username": "testuser", | ||
"password": "letmein", | ||
"displayName": "testuser", | ||
"emailPrimary": "test@test.com", | ||
"emailSecondary": "test@test.com", | ||
"ownedPrivateGroupID": 1, | ||
"ownedPrivateGroupLibraryID": 1, | ||
"ownedPrivateGroupName": "Test Group", | ||
|
||
|
||
"userID2": 2, | ||
"username2": "testuser2", | ||
"password2": "letmein2", | ||
"displayName2": "testuser2", | ||
"ownedPrivateGroupID2": 0, | ||
"ownedPrivateGroupLibraryID2": 0 | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<p>&nbsp;</p> | ||
<p style="margin-top: 0.18cm; margin-bottom: 0.18cm; line-height: 100%;" lang="es-ES"><br /><br /></p> | ||
<p style="margin-top: 0.18cm; margin-bottom: 0.18cm; line-height: 100%;" lang="es-ES"><br /><br /></p> | ||
<table border="1" cellspacing="0" cellpadding="7" width="614"> | ||
<colgroup><col width="598"></col> </colgroup> | ||
<p style="margin-top: 0.18cm; margin-bottom: 0.18cm;" lang="en-US"><span style="font-family: Times New Roman,serif;"><span style="font-size: x-large;"><strong>test</strong></span></span></p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
|
||
const config = require('./config'); | ||
const API3 = require('./api3.js'); | ||
|
||
const resetGroups = async () => { | ||
let resetGroups = true; | ||
|
||
let response = await API3.superGet( | ||
`users/${config.userID}/groups` | ||
); | ||
let groups = await API3.getJSONFromResponse(response); | ||
config.ownedPublicGroupID = null; | ||
config.ownedPublicNoAnonymousGroupID = null; | ||
config.ownedPrivateGroupID = null; | ||
config.ownedPrivateGroupName = 'Private Test Group'; | ||
config.ownedPrivateGroupID2 = null; | ||
let toDelete = []; | ||
for (let group of groups) { | ||
let data = group.data; | ||
let id = data.id; | ||
let type = data.type; | ||
let owner = data.owner; | ||
let libraryReading = data.libraryReading; | ||
|
||
if (resetGroups) { | ||
toDelete.push(id); | ||
continue; | ||
} | ||
|
||
if (!config.ownedPublicGroupID | ||
&& type == 'PublicOpen' | ||
&& owner == config.userID | ||
&& libraryReading == 'all') { | ||
config.ownedPublicGroupID = id; | ||
} | ||
else if (!config.ownedPublicNoAnonymousGroupID | ||
&& type == 'PublicClosed' | ||
&& owner == config.userID | ||
&& libraryReading == 'members') { | ||
config.ownedPublicNoAnonymousGroupID = id; | ||
} | ||
else if (type == 'Private' && owner == config.userID && data.name == config.ownedPrivateGroupName) { | ||
config.ownedPrivateGroupID = id; | ||
} | ||
else if (type == 'Private' && owner == config.userID2) { | ||
config.ownedPrivateGroupID2 = id; | ||
} | ||
else { | ||
toDelete.push(id); | ||
} | ||
} | ||
|
||
if (!config.ownedPublicGroupID) { | ||
config.ownedPublicGroupID = await API3.createGroup({ | ||
owner: config.userID, | ||
type: 'PublicOpen', | ||
libraryReading: 'all' | ||
}); | ||
} | ||
if (!config.ownedPublicNoAnonymousGroupID) { | ||
config.ownedPublicNoAnonymousGroupID = await API3.createGroup({ | ||
owner: config.userID, | ||
type: 'PublicClosed', | ||
libraryReading: 'members' | ||
}); | ||
} | ||
if (!config.ownedPrivateGroupID) { | ||
config.ownedPrivateGroupID = await API3.createGroup({ | ||
owner: config.userID, | ||
name: "Private Test Group", | ||
type: 'Private', | ||
libraryReading: 'members', | ||
fileEditing: 'members', | ||
members: [ | ||
config.userID2 | ||
] | ||
}); | ||
} | ||
if (!config.ownedPrivateGroupID2) { | ||
config.ownedPrivateGroupID2 = await API3.createGroup({ | ||
owner: config.userID2, | ||
type: 'Private', | ||
libraryReading: 'members', | ||
fileEditing: 'members' | ||
}); | ||
} | ||
for (let groupID of toDelete) { | ||
await API3.deleteGroup(groupID); | ||
} | ||
|
||
config.numOwnedGroups = 3; | ||
config.numPublicGroups = 2; | ||
|
||
for (let group of groups) { | ||
if (!toDelete.includes(group.id)) { | ||
await API3.groupClear(group.id); | ||
} | ||
} | ||
}; | ||
|
||
module.exports = { | ||
resetGroups | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
const { JSDOM } = require("jsdom"); | ||
const chai = require('chai'); | ||
const assert = chai.assert; | ||
const crypto = require('crypto'); | ||
|
||
class Helpers { | ||
static isV3 = false; | ||
|
||
static useV3 = () => { | ||
this.isV3 = true; | ||
}; | ||
|
||
static uniqueToken = () => { | ||
const id = crypto.randomBytes(16).toString("hex"); | ||
const hash = crypto.createHash('md5').update(id).digest('hex'); | ||
return hash; | ||
}; | ||
|
||
static uniqueID = (count = 8) => { | ||
const chars = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Z']; | ||
let result = ""; | ||
for (let i = 0; i < count; i++) { | ||
result += chars[crypto.randomInt(chars.length)]; | ||
} | ||
return result; | ||
}; | ||
|
||
static namespaceResolver = (prefix) => { | ||
let ns = { | ||
atom: 'http://www.w3.org/2005/Atom', | ||
zapi: 'http://zotero.org/ns/api', | ||
zxfer: 'http://zotero.org/ns/transfer', | ||
html: 'http://www.w3.org/1999/xhtml' | ||
}; | ||
return ns[prefix] || null; | ||
}; | ||
|
||
static xpathEval = (document, xpath, returnHtml = false, multiple = false, element = null) => { | ||
const xpathData = document.evaluate(xpath, (element || document), this.namespaceResolver, 5, null); | ||
if (!multiple && xpathData.snapshotLength != 1) { | ||
throw new Error("No single xpath value fetched"); | ||
} | ||
var node; | ||
var result = []; | ||
do { | ||
node = xpathData.iterateNext(); | ||
if (node) { | ||
result.push(node); | ||
} | ||
} while (node); | ||
|
||
if (returnHtml) { | ||
return multiple ? result : result[0]; | ||
} | ||
|
||
return multiple ? result.map(el => el.innerHTML) : result[0].innerHTML; | ||
}; | ||
|
||
static assertRegExp(exp, val) { | ||
if (typeof exp == "string") { | ||
exp = new RegExp(exp); | ||
} | ||
if (!exp.test(val)) { | ||
throw new Error(`${val} does not match regular expression`); | ||
} | ||
} | ||
|
||
static assertXMLEqual = (one, two) => { | ||
const contentDom = new JSDOM(one); | ||
const expectedDom = new JSDOM(two); | ||
assert.equal(contentDom.window.document.innerHTML, expectedDom.window.document.innerHTML); | ||
}; | ||
|
||
static assertStatusCode = (response, expectedCode, message) => { | ||
try { | ||
assert.equal(response.status, expectedCode); | ||
if (message) { | ||
assert.equal(response.data, message); | ||
} | ||
} | ||
catch (e) { | ||
console.log(response.data); | ||
throw e; | ||
} | ||
}; | ||
|
||
static assertStatusForObject = (response, status, recordId, httpCode, message) => { | ||
let body = response; | ||
if (response.data) { | ||
body = response.data; | ||
} | ||
try { | ||
body = JSON.parse(body); | ||
} | ||
catch (e) { } | ||
assert.include(['unchanged', 'failed', 'success'], status); | ||
|
||
try { | ||
//Make sure the recordId is in the right category - unchanged, failed, success | ||
assert.property(body[status], recordId); | ||
if (httpCode) { | ||
assert.equal(body[status][recordId].code, httpCode); | ||
} | ||
if (message) { | ||
assert.equal(body[status][recordId].message, message); | ||
} | ||
} | ||
catch (e) { | ||
console.log(response.data); | ||
throw e; | ||
} | ||
}; | ||
|
||
static assertNumResults = (response, expectedResults) => { | ||
const doc = new JSDOM(response.data, { url: "http://localhost/" }); | ||
const entries = this.xpathEval(doc.window.document, "//entry", false, true); | ||
assert.equal(entries.length, expectedResults); | ||
}; | ||
|
||
static assertTotalResults = (response, expectedResults) => { | ||
const doc = new JSDOM(response.data, { url: "http://localhost/" }); | ||
const totalResults = this.xpathEval(doc.window.document, "//zapi:totalResults", false, true); | ||
assert.equal(parseInt(totalResults[0]), expectedResults); | ||
}; | ||
|
||
static assertContentType = (response, contentType) => { | ||
assert.include(response?.headers['content-type'], contentType.toLowerCase()); | ||
}; | ||
|
||
|
||
//Assert codes | ||
static assert200 = (response) => { | ||
this.assertStatusCode(response, 200); | ||
}; | ||
|
||
static assert201 = (response) => { | ||
this.assertStatusCode(response, 201); | ||
}; | ||
|
||
static assert204 = (response) => { | ||
this.assertStatusCode(response, 204); | ||
}; | ||
|
||
static assert300 = (response) => { | ||
this.assertStatusCode(response, 300); | ||
}; | ||
|
||
static assert302 = (response) => { | ||
this.assertStatusCode(response, 302); | ||
}; | ||
|
||
static assert400 = (response, message) => { | ||
this.assertStatusCode(response, 400, message); | ||
}; | ||
|
||
static assert401 = (response) => { | ||
this.assertStatusCode(response, 401); | ||
}; | ||
|
||
static assert403 = (response) => { | ||
this.assertStatusCode(response, 403); | ||
}; | ||
|
||
static assert412 = (response) => { | ||
this.assertStatusCode(response, 412); | ||
}; | ||
|
||
static assert428 = (response) => { | ||
this.assertStatusCode(response, 428); | ||
}; | ||
|
||
static assert404 = (response) => { | ||
this.assertStatusCode(response, 404); | ||
}; | ||
|
||
static assert405 = (response) => { | ||
this.assertStatusCode(response, 405); | ||
}; | ||
|
||
static assert500 = (response) => { | ||
this.assertStatusCode(response, 500); | ||
}; | ||
|
||
static assert400ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 400, message); | ||
}; | ||
|
||
static assert200ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'success', index, message); | ||
}; | ||
|
||
static assert404ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 404, message); | ||
}; | ||
|
||
static assert409ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 409, message); | ||
}; | ||
|
||
static assert412ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 412, message); | ||
}; | ||
|
||
static assert413ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 413, message); | ||
}; | ||
|
||
static assert428ForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'failed', index, 428, message); | ||
}; | ||
|
||
static assertUnchangedForObject = (response, { index = 0, message = null } = {}) => { | ||
this.assertStatusForObject(response, 'unchanged', index, null, message); | ||
}; | ||
|
||
// Methods to help during conversion | ||
static assertEquals = (one, two) => { | ||
assert.equal(two, one); | ||
}; | ||
|
||
static assertCount = (count, object) => { | ||
assert.lengthOf(Object.keys(object), count); | ||
}; | ||
} | ||
|
||
module.exports = Helpers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the logic for why these are in here and not in config.json?
In any case, we should use the npm
config
package and move everything into a default.json5 file inconfig
(like translation-server).And then we could either do a find-and-replace to switch to the recommended access method or we could just stick to direct property access.
get()
would let us set values (e.g.,rootUsername
/rootPassword
) toundefined
in default.json to force them to be populated in a local.json, but since these are tests anyway, they'll just fail if something isn't configured properly, so maybe it's not worth the extra noise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing specific here. I think the config.ini used in phpunit did not have those fields, and they were set in some of the other php files. I was converting files one by one, so it just turned out that way.
Anyways, after my cleanup, I removed it all and setup the node-config with default.json5