Fix search saving, and add some unit tests
Also: - Return an object from `Zotero.Search.prototype.getConditions()` instead of an array. - Add support function `getPromiseError(promise)` to return the error thrown from a chain of promises, or false if none. (We could make an `assert.throwsAsync()`, but this allows testing of various properties such as `.name`, which even the built-in `assert.throws()` can't test.) - Clarify some search save errors
This commit is contained in:
parent
59773f3f6d
commit
d9c32a8e90
|
@ -569,9 +569,15 @@ Zotero.DataObject.prototype._recoverFromSaveError = Zotero.Promise.coroutine(fun
|
||||||
});
|
});
|
||||||
|
|
||||||
Zotero.DataObject.prototype._initSave = Zotero.Promise.coroutine(function* (env) {
|
Zotero.DataObject.prototype._initSave = Zotero.Promise.coroutine(function* (env) {
|
||||||
|
if (!this.libraryID) {
|
||||||
|
throw new Error("libraryID must be set before saving " + this._objectType);
|
||||||
|
}
|
||||||
|
|
||||||
env.isNew = !this.id;
|
env.isNew = !this.id;
|
||||||
|
|
||||||
if (!env.options.skipEditCheck) this.editCheck();
|
if (!env.options.skipEditCheck) {
|
||||||
|
this.editCheck();
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.hasChanged()) {
|
if (!this.hasChanged()) {
|
||||||
Zotero.debug(this._ObjectType + ' ' + this.id + ' has not changed', 4);
|
Zotero.debug(this._ObjectType + ' ' + this.id + ' has not changed', 4);
|
||||||
|
|
|
@ -172,7 +172,7 @@ Zotero.Search.prototype.loadFromRow = function (row) {
|
||||||
|
|
||||||
Zotero.Search.prototype._initSave = Zotero.Promise.coroutine(function* (env) {
|
Zotero.Search.prototype._initSave = Zotero.Promise.coroutine(function* (env) {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
throw('Name not provided for saved search');
|
throw new Error('Name not provided for saved search');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Zotero.Search._super.prototype._initSave.apply(this, arguments);
|
return Zotero.Search._super.prototype._initSave.apply(this, arguments);
|
||||||
|
@ -199,7 +199,6 @@ Zotero.Search.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
|
||||||
var sqlValues = [
|
var sqlValues = [
|
||||||
searchID ? { int: searchID } : null,
|
searchID ? { int: searchID } : null,
|
||||||
{ string: this.name },
|
{ string: this.name },
|
||||||
Zotero.DB.transactionDateTime,
|
|
||||||
this.libraryID,
|
this.libraryID,
|
||||||
key,
|
key,
|
||||||
this.version ? this.version : 0,
|
this.version ? this.version : 0,
|
||||||
|
@ -478,14 +477,14 @@ Zotero.Search.prototype.getCondition = function(searchConditionID){
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a multidimensional array of conditions/operator/value sets
|
* Returns an object of conditions/operator/value sets used in the search,
|
||||||
* used in the search, indexed by searchConditionID
|
* indexed by searchConditionID
|
||||||
*/
|
*/
|
||||||
Zotero.Search.prototype.getConditions = function(){
|
Zotero.Search.prototype.getConditions = function(){
|
||||||
this._requireData('conditions');
|
this._requireData('conditions');
|
||||||
var conditions = [];
|
var conditions = {};
|
||||||
for (var id in this._conditions) {
|
for (let id in this._conditions) {
|
||||||
var condition = this._conditions[id];
|
let condition = this._conditions[id];
|
||||||
conditions[id] = {
|
conditions[id] = {
|
||||||
id: id,
|
id: id,
|
||||||
condition: condition.condition,
|
condition: condition.condition,
|
||||||
|
@ -2340,7 +2339,7 @@ Zotero.SearchConditions = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_conditions[condition]){
|
if (!_conditions[condition]){
|
||||||
throw ("Invalid condition '" + condition + "' in hasOperator()");
|
throw new Error("Invalid condition '" + condition + "' in hasOperator()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!operator && typeof _conditions[condition]['operators'] == 'undefined'){
|
if (!operator && typeof _conditions[condition]['operators'] == 'undefined'){
|
||||||
|
|
|
@ -114,6 +114,13 @@ function waitForCallback(cb, interval, timeout) {
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a promise for the error thrown by a promise, or false if none
|
||||||
|
*/
|
||||||
|
function getPromiseError(promise) {
|
||||||
|
return promise.thenReturn(false).catch(e => e);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the PDF tools are installed, or installs them if not.
|
* Ensures that the PDF tools are installed, or installs them if not.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
|
|
47
test/tests/searchTests.js
Normal file
47
test/tests/searchTests.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
describe("Zotero.Search", function() {
|
||||||
|
describe("#save()", function () {
|
||||||
|
it("should fail without a libraryID", function* () {
|
||||||
|
var s = new Zotero.Search;
|
||||||
|
s.name = "Test";
|
||||||
|
s.addCondition('title', 'is', 'test');
|
||||||
|
var e = yield getPromiseError(s.save());
|
||||||
|
assert.ok(e);
|
||||||
|
assert.equal(e.constructor.name, Error.prototype.constructor.name); // TEMP: Error mismatch
|
||||||
|
assert.equal(e.message, "libraryID must be set before saving search");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail without a name", function* () {
|
||||||
|
var s = new Zotero.Search;
|
||||||
|
s.libraryID = Zotero.Libraries.userLibraryID;
|
||||||
|
s.addCondition('title', 'is', 'test');
|
||||||
|
var e = yield getPromiseError(s.save());
|
||||||
|
assert.ok(e);
|
||||||
|
assert.equal(e.constructor.name, Error.prototype.constructor.name); // TEMP: Error mismatch
|
||||||
|
assert.equal(e.message, "Name not provided for saved search");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should save a new search", function* () {
|
||||||
|
// Save search
|
||||||
|
var s = new Zotero.Search;
|
||||||
|
s.libraryID = Zotero.Libraries.userLibraryID;
|
||||||
|
s.name = "Test";
|
||||||
|
s.addCondition('title', 'is', 'test');
|
||||||
|
var id = yield s.save();
|
||||||
|
assert.typeOf(id, 'number');
|
||||||
|
|
||||||
|
// Check saved search
|
||||||
|
s = yield Zotero.Searches.getAsync(id);
|
||||||
|
assert.ok(s);
|
||||||
|
assert.instanceOf(s, Zotero.Search);
|
||||||
|
assert.equal(s.name, "Test");
|
||||||
|
yield s.loadConditions();
|
||||||
|
var conditions = s.getConditions();
|
||||||
|
assert.lengthOf(Object.keys(conditions), 1);
|
||||||
|
assert.property(conditions, "1"); // searchConditionIDs start at 1
|
||||||
|
var condition = conditions[1];
|
||||||
|
assert.propertyVal(condition, 'condition', 'title')
|
||||||
|
assert.propertyVal(condition, 'operator', 'is')
|
||||||
|
assert.propertyVal(condition, 'value', 'test')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user