Skip to content
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

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cfc8228
phpunit test v1 and v2 converted to mocha/chai
abaevbog May 19, 2023
d58206e
helper functions for api v3, annotation, atom and creator tests for v3
abaevbog May 22, 2023
0244f16
v3 collection, group, fullText and note test
abaevbog May 22, 2023
f4dfc10
v3 object test
abaevbog May 22, 2023
b30737f
leftover object tests, mappings, params tests
abaevbog May 23, 2023
aae33b1
previously skipped tests requiring citation or translation server
abaevbog May 23, 2023
878afef
file tests v2 and half of v3
abaevbog May 24, 2023
e8449db
the rest of file tests
abaevbog May 25, 2023
8b7804b
publication tests
abaevbog May 25, 2023
bf083e1
minor adjustments to prevent random 500 errors
abaevbog May 26, 2023
6af7367
more v3 tests
abaevbog May 26, 2023
9e746e0
removing work dir, removed unneeded data/ files
abaevbog May 26, 2023
339d923
notification, tag and version tests
abaevbog May 29, 2023
2f5ccd0
v3 itemTest
abaevbog May 30, 2023
755e133
some cleanup, proper retry logic when socket hangs
abaevbog May 30, 2023
319ce22
using node-config
abaevbog May 30, 2023
1ee44b1
removed inheritance from between api files and helpers
abaevbog May 30, 2023
41d5981
package.json
abaevbog May 30, 2023
4d7632c
changed 'Setup' for 'Before' and 'Wrapup' for 'After' in shared.js, g…
abaevbog May 30, 2023
e150cd1
removing retries, using 0-second delay instead
abaevbog May 31, 2023
ae270e5
minor cleanup, added missing comments, some tweaking with socker hanging
abaevbog Jun 1, 2023
0d653ed
using helper functions for statusForObject + removed unnecessary part…
abaevbog Jun 2, 2023
5e21351
initial pdf text extraction setup
abaevbog Jun 9, 2023
8e0936b
pdf text extraction test
abaevbog Jun 9, 2023
1976445
full-text tests with indexing function invoked locally
abaevbog Jun 12, 2023
d8f3427
items/unfiled and items/unfiled/tags tests
abaevbog Jun 23, 2023
2e7a853
?sort=editBy for group libraries
abaevbog Jun 23, 2023
d4465f2
test to rename tag for PR #150
abaevbog Jun 23, 2023
e7518c2
test for literal || escaping for tags PR #143
abaevbog Jun 23, 2023
c5b1a93
new annotation types test
abaevbog Jun 28, 2023
640caf4
minor cleanup, skip tests for PRs, missing tests
abaevbog Aug 21, 2023
8253f4d
skip annotation tags test for collections
abaevbog Aug 21, 2023
b2b562a
should_add_zero_integer_value_for_lastPageIndex
abaevbog Sep 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
758 changes: 758 additions & 0 deletions tests/remote_js/api2.js

Large diffs are not rendered by default.

1,080 changes: 1,080 additions & 0 deletions tests/remote_js/api3.js

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions tests/remote_js/config/default.json5
@@ -0,0 +1,32 @@
{
"verbose": 0,
"apiURLPrefix": "http://localhost/",
"rootUsername": "",
"rootPassword": "",
"awsRegion": "",
"s3Bucket": "",
"awsAccessKey": "",
"awsSecretKey": "",
"timeout": 30000,
"numOwnedGroups": 3,
"numPublicGroups": 2,

"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

}
6 changes: 6 additions & 0 deletions tests/remote_js/data/bad_string.xml
@@ -0,0 +1,6 @@
<p> </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>
Binary file added tests/remote_js/data/test.html.zip
Binary file not shown.
Binary file added tests/remote_js/data/test.pdf
Binary file not shown.
100 changes: 100 additions & 0 deletions tests/remote_js/groupsSetup.js
@@ -0,0 +1,100 @@

var 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);
}

for (let group of groups) {
if (!toDelete.includes(group.id)) {
await API3.groupClear(group.id);
}
}
};

module.exports = {
resetGroups
};
240 changes: 240 additions & 0 deletions tests/remote_js/helpers2.js
@@ -0,0 +1,240 @@
const { JSDOM } = require("jsdom");
const chai = require('chai');
const assert = chai.assert;
const crypto = require('crypto');
const fs = require('fs');

class Helpers2 {
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 md5 = (str) => {
return crypto.createHash('md5').update(str).digest('hex');
};

static md5File = (fileName) => {
const data = fs.readFileSync(fileName);
return crypto.createHash('md5').update(data).digest('hex');
};

static implodeParams = (params, exclude = []) => {
let parts = [];
for (const [key, value] of Object.entries(params)) {
if (!exclude.includes(key)) {
parts.push(key + "=" + encodeURIComponent(value));
}
}
return parts.join("&");
};

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 = Helpers2;