Adding tests suites for readAll and readStream
This commit is contained in:
parent
19ef91030c
commit
77704a8786
107
lib/dist.js
107
lib/dist.js
|
@ -60,17 +60,17 @@ module.exports =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} eventId
|
* @param {string} eventId
|
||||||
* @param {object} data
|
* @param {object} event
|
||||||
* @param {object} [metadata]
|
* @param {object} [metadata]
|
||||||
* @param {string} [type]
|
* @param {string} [type]
|
||||||
* @returns {EventData}
|
* @returns {EventData}
|
||||||
*/
|
*/
|
||||||
function jsonEventDataFactory(eventId, data, metadata, type) {
|
function jsonEventDataFactory(eventId, event, metadata, type) {
|
||||||
if (!data || typeof data !== 'object') throw new TypeError("data must be an object.");
|
if (!event || typeof event !== 'object') throw new TypeError("data must be an object.");
|
||||||
|
|
||||||
var d = new Buffer(JSON.stringify(data));
|
var eventBuf = new Buffer(JSON.stringify(event));
|
||||||
var m = metadata ? new Buffer(JSON.stringify(metadata)) : null;
|
var metaBuf = metadata ? new Buffer(JSON.stringify(metadata)) : null;
|
||||||
return new EventData(eventId, type || data.constructor.name, true, d, m);
|
return new EventData(eventId, type || event.constructor.name, true, eventBuf, metaBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +100,7 @@ module.exports =
|
||||||
module.exports.positions = positions;
|
module.exports.positions = positions;
|
||||||
module.exports.systemMetadata = __webpack_require__(67);
|
module.exports.systemMetadata = __webpack_require__(67);
|
||||||
module.exports.eventReadStatus = results.EventReadStatus;
|
module.exports.eventReadStatus = results.EventReadStatus;
|
||||||
|
module.exports.sliceReadStatus = __webpack_require__(47);
|
||||||
// Helper functions
|
// Helper functions
|
||||||
module.exports.createConnection = module.exports.EventStoreConnection.create;
|
module.exports.createConnection = module.exports.EventStoreConnection.create;
|
||||||
module.exports.createEventData = eventDataFactory;
|
module.exports.createEventData = eventDataFactory;
|
||||||
|
@ -526,26 +527,41 @@ module.exports =
|
||||||
|
|
||||||
module.exports.notNullOrEmpty = function(value, name) {
|
module.exports.notNullOrEmpty = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new Error(name + " is null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
if (value === '')
|
if (value === '')
|
||||||
throw new Error(name + " is empty.");
|
throw new Error(name + " should not be empty.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.notNull = function(value, name) {
|
module.exports.notNull = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new Error(name + " is null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isInteger = function(value, name) {
|
module.exports.isInteger = function(value, name) {
|
||||||
if (typeof value !== 'number' || value % 1 !== 0)
|
if (typeof value !== 'number' || value % 1 !== 0)
|
||||||
throw new TypeError(name + " is not an integer.");
|
throw new TypeError(name + " should be an integer.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isArrayOf = function(expectedType, value, name) {
|
module.exports.isArrayOf = function(expectedType, value, name) {
|
||||||
if (!Array.isArray(value))
|
if (!Array.isArray(value))
|
||||||
throw new TypeError(name + " is not an array.");
|
throw new TypeError(name + " should be an array.");
|
||||||
if (!value.every(function(x) { return x instanceof expectedType; }))
|
if (!value.every(function(x) { return x instanceof expectedType; }))
|
||||||
throw new TypeError([name, " is not an array of ", expectedType, "."].join(""));
|
throw new TypeError([name, " should be an array of ", expectedType, "."].join(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isTypeOf = function(expectedType, value, name) {
|
||||||
|
if (!(value instanceof expectedType))
|
||||||
|
throw new TypeError([name, " should be of type '", expectedType, "'."].join(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.positive = function(value, name) {
|
||||||
|
if (value <= 0)
|
||||||
|
throw new Error(name + " should be positive.");
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.nonNegative = function(value, name) {
|
||||||
|
if (value < 0)
|
||||||
|
throw new Error(name + " should be non-negative.");
|
||||||
};
|
};
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
|
@ -644,6 +660,8 @@ module.exports =
|
||||||
var systemEventTypes = __webpack_require__(62);
|
var systemEventTypes = __webpack_require__(62);
|
||||||
var EventData = __webpack_require__(1);
|
var EventData = __webpack_require__(1);
|
||||||
|
|
||||||
|
const MaxReadSize = 4096;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param settings
|
* @param settings
|
||||||
* @param endpointDiscoverer
|
* @param endpointDiscoverer
|
||||||
|
@ -823,6 +841,12 @@ module.exports =
|
||||||
* @returns {Promise.<EventReadResult>}
|
* @returns {Promise.<EventReadResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
||||||
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
|
ensure.isInteger(eventNumber, "eventNumber");
|
||||||
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
||||||
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
||||||
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
|
@ -834,8 +858,8 @@ module.exports =
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadEventOperation(self._settings.log, cb, stream, eventNumber, resolveLinkTos || false,
|
var operation = new ReadEventOperation(self._settings.log, cb, stream, eventNumber, resolveLinkTos,
|
||||||
self._settings.requireMaster, userCredentials || null);
|
self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -852,10 +876,14 @@ module.exports =
|
||||||
EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (typeof start !== 'number' || start % 1 !== 0) throw new TypeError("start must be an integer.");
|
ensure.isInteger(start, "start");
|
||||||
if (typeof count !== 'number' || count % 1 !== 0) throw new TypeError("count must be an integer.");
|
ensure.nonNegative(start, "start");
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
ensure.isInteger(count, "count");
|
||||||
|
ensure.positive(count, "count");
|
||||||
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -864,7 +892,7 @@ module.exports =
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadStreamEventsForwardOperation(self._settings.log, cb, stream, start, count,
|
var operation = new ReadStreamEventsForwardOperation(self._settings.log, cb, stream, start, count,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -881,10 +909,13 @@ module.exports =
|
||||||
EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (typeof start !== 'number' || start % 1 !== 0) throw new TypeError("start must be an integer.");
|
ensure.isInteger(start, "start");
|
||||||
if (typeof count !== 'number' || count % 1 !== 0) throw new TypeError("count must be an integer.");
|
ensure.isInteger(count, "count");
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
ensure.positive(count, "count");
|
||||||
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -893,7 +924,7 @@ module.exports =
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadStreamEventsBackwardOperation(self._settings.log, cb, stream, start, count,
|
var operation = new ReadStreamEventsBackwardOperation(self._settings.log, cb, stream, start, count,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -909,7 +940,12 @@ module.exports =
|
||||||
EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
||||||
position, maxCount, resolveLinkTos, userCredentials
|
position, maxCount, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
//TODO validations
|
ensure.isTypeOf(results.Position, position, "position");
|
||||||
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
|
ensure.positive(maxCount, "maxCount");
|
||||||
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -918,7 +954,7 @@ module.exports =
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadAllEventsForwardOperation(self._settings.log, cb, position, maxCount,
|
var operation = new ReadAllEventsForwardOperation(self._settings.log, cb, position, maxCount,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -934,7 +970,12 @@ module.exports =
|
||||||
EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
||||||
position, maxCount, resolveLinkTos, userCredentials
|
position, maxCount, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
//TODO validations
|
ensure.isTypeOf(results.Position, position, "position");
|
||||||
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
|
ensure.positive(maxCount, "maxCount");
|
||||||
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -4478,6 +4519,7 @@ module.exports =
|
||||||
var InspectionResult = __webpack_require__(27);
|
var InspectionResult = __webpack_require__(27);
|
||||||
var InspectionDecision = __webpack_require__(26);
|
var InspectionDecision = __webpack_require__(26);
|
||||||
var results = __webpack_require__(3);
|
var results = __webpack_require__(3);
|
||||||
|
var AccessDeniedError = __webpack_require__(36);
|
||||||
|
|
||||||
var OperationBase = __webpack_require__(37);
|
var OperationBase = __webpack_require__(37);
|
||||||
|
|
||||||
|
@ -4515,7 +4557,7 @@ module.exports =
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
||||||
this.fail(new Error(util.format("Read access denied for stream '%s'.", this._stream)));
|
this.fail(new AccessDeniedError("Read", this._stream));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
@ -4604,6 +4646,7 @@ module.exports =
|
||||||
var InspectionResult = __webpack_require__(27);
|
var InspectionResult = __webpack_require__(27);
|
||||||
var InspectionDecision = __webpack_require__(26);
|
var InspectionDecision = __webpack_require__(26);
|
||||||
var results = __webpack_require__(3);
|
var results = __webpack_require__(3);
|
||||||
|
var AccessDeniedError = __webpack_require__(36);
|
||||||
|
|
||||||
var OperationBase = __webpack_require__(37);
|
var OperationBase = __webpack_require__(37);
|
||||||
|
|
||||||
|
@ -4641,7 +4684,7 @@ module.exports =
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
||||||
this.fail(new Error(util.format("Read access denied for stream '%s'.", this._stream)));
|
this.fail(new AccessDeniedError("Read", this._stream));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
@ -4682,6 +4725,7 @@ module.exports =
|
||||||
var InspectionResult = __webpack_require__(27);
|
var InspectionResult = __webpack_require__(27);
|
||||||
var InspectionDecision = __webpack_require__(26);
|
var InspectionDecision = __webpack_require__(26);
|
||||||
var results = __webpack_require__(3);
|
var results = __webpack_require__(3);
|
||||||
|
var AccessDeniedError = __webpack_require__(36);
|
||||||
|
|
||||||
var OperationBase = __webpack_require__(37);
|
var OperationBase = __webpack_require__(37);
|
||||||
|
|
||||||
|
@ -4712,7 +4756,7 @@ module.exports =
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
||||||
this.fail(new Error("Read access denied for $all."));
|
this.fail(new AccessDeniedError("Read", "$all"));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
@ -4749,6 +4793,7 @@ module.exports =
|
||||||
var InspectionResult = __webpack_require__(27);
|
var InspectionResult = __webpack_require__(27);
|
||||||
var InspectionDecision = __webpack_require__(26);
|
var InspectionDecision = __webpack_require__(26);
|
||||||
var results = __webpack_require__(3);
|
var results = __webpack_require__(3);
|
||||||
|
var AccessDeniedError = __webpack_require__(36);
|
||||||
|
|
||||||
var OperationBase = __webpack_require__(37);
|
var OperationBase = __webpack_require__(37);
|
||||||
|
|
||||||
|
@ -4779,7 +4824,7 @@ module.exports =
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
||||||
this.fail(new Error("Read access denied for $all."));
|
this.fail(new AccessDeniedError("Read", "$all"));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
|
|
@ -13,17 +13,17 @@ const positions = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} eventId
|
* @param {string} eventId
|
||||||
* @param {object} data
|
* @param {object} event
|
||||||
* @param {object} [metadata]
|
* @param {object} [metadata]
|
||||||
* @param {string} [type]
|
* @param {string} [type]
|
||||||
* @returns {EventData}
|
* @returns {EventData}
|
||||||
*/
|
*/
|
||||||
function jsonEventDataFactory(eventId, data, metadata, type) {
|
function jsonEventDataFactory(eventId, event, metadata, type) {
|
||||||
if (!data || typeof data !== 'object') throw new TypeError("data must be an object.");
|
if (!event || typeof event !== 'object') throw new TypeError("data must be an object.");
|
||||||
|
|
||||||
var d = new Buffer(JSON.stringify(data));
|
var eventBuf = new Buffer(JSON.stringify(event));
|
||||||
var m = metadata ? new Buffer(JSON.stringify(metadata)) : null;
|
var metaBuf = metadata ? new Buffer(JSON.stringify(metadata)) : null;
|
||||||
return new EventData(eventId, type || data.constructor.name, true, d, m);
|
return new EventData(eventId, type || event.constructor.name, true, eventBuf, metaBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +53,7 @@ module.exports.expectedVersion = expectedVersion;
|
||||||
module.exports.positions = positions;
|
module.exports.positions = positions;
|
||||||
module.exports.systemMetadata = require('./common/systemMetadata');
|
module.exports.systemMetadata = require('./common/systemMetadata');
|
||||||
module.exports.eventReadStatus = results.EventReadStatus;
|
module.exports.eventReadStatus = results.EventReadStatus;
|
||||||
|
module.exports.sliceReadStatus = require('./sliceReadStatus');
|
||||||
// Helper functions
|
// Helper functions
|
||||||
module.exports.createConnection = module.exports.EventStoreConnection.create;
|
module.exports.createConnection = module.exports.EventStoreConnection.create;
|
||||||
module.exports.createEventData = eventDataFactory;
|
module.exports.createEventData = eventDataFactory;
|
||||||
|
|
|
@ -7,6 +7,7 @@ var ReadDirection = require('../readDirection');
|
||||||
var InspectionResult = require('./../systemData/inspectionResult');
|
var InspectionResult = require('./../systemData/inspectionResult');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
var results = require('../results');
|
var results = require('../results');
|
||||||
|
var AccessDeniedError = require('../errors/accessDeniedError');
|
||||||
|
|
||||||
var OperationBase = require('./operationBase');
|
var OperationBase = require('./operationBase');
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ ReadAllEventsBackwardOperation.prototype._inspectResponse = function(response) {
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
||||||
this.fail(new Error("Read access denied for $all."));
|
this.fail(new AccessDeniedError("Read", "$all"));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
|
|
@ -7,6 +7,7 @@ var ReadDirection = require('../readDirection');
|
||||||
var InspectionResult = require('./../systemData/inspectionResult');
|
var InspectionResult = require('./../systemData/inspectionResult');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
var results = require('../results');
|
var results = require('../results');
|
||||||
|
var AccessDeniedError = require('../errors/accessDeniedError');
|
||||||
|
|
||||||
var OperationBase = require('./operationBase');
|
var OperationBase = require('./operationBase');
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ ReadAllEventsForwardOperation.prototype._inspectResponse = function(response) {
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied:
|
||||||
this.fail(new Error("Read access denied for $all."));
|
this.fail(new AccessDeniedError("Read", "$all"));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
|
|
@ -8,6 +8,7 @@ var StatusCode = require('../systemData/statusCode');
|
||||||
var InspectionResult = require('./../systemData/inspectionResult');
|
var InspectionResult = require('./../systemData/inspectionResult');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
var results = require('../results');
|
var results = require('../results');
|
||||||
|
var AccessDeniedError = require('../errors/accessDeniedError');
|
||||||
|
|
||||||
var OperationBase = require('./operationBase');
|
var OperationBase = require('./operationBase');
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ ReadStreamEventsBackwardOperation.prototype._inspectResponse = function(response
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
||||||
this.fail(new Error(util.format("Read access denied for stream '%s'.", this._stream)));
|
this.fail(new AccessDeniedError("Read", this._stream));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
|
|
@ -8,6 +8,7 @@ var StatusCode = require('../systemData/statusCode');
|
||||||
var InspectionResult = require('./../systemData/inspectionResult');
|
var InspectionResult = require('./../systemData/inspectionResult');
|
||||||
var InspectionDecision = require('../systemData/inspectionDecision');
|
var InspectionDecision = require('../systemData/inspectionDecision');
|
||||||
var results = require('../results');
|
var results = require('../results');
|
||||||
|
var AccessDeniedError = require('../errors/accessDeniedError');
|
||||||
|
|
||||||
var OperationBase = require('./operationBase');
|
var OperationBase = require('./operationBase');
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ ReadStreamEventsForwardOperation.prototype._inspectResponse = function(response)
|
||||||
this.fail(new Error("Server error: " + response.error));
|
this.fail(new Error("Server error: " + response.error));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
return new InspectionResult(InspectionDecision.EndOperation, "Error");
|
||||||
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied:
|
||||||
this.fail(new Error(util.format("Read access denied for stream '%s'.", this._stream)));
|
this.fail(new AccessDeniedError("Read", this._stream));
|
||||||
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result));
|
||||||
|
|
|
@ -1,23 +1,38 @@
|
||||||
module.exports.notNullOrEmpty = function(value, name) {
|
module.exports.notNullOrEmpty = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new Error(name + " is null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
if (value === '')
|
if (value === '')
|
||||||
throw new Error(name + " is empty.");
|
throw new Error(name + " should not be empty.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.notNull = function(value, name) {
|
module.exports.notNull = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new Error(name + " is null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isInteger = function(value, name) {
|
module.exports.isInteger = function(value, name) {
|
||||||
if (typeof value !== 'number' || value % 1 !== 0)
|
if (typeof value !== 'number' || value % 1 !== 0)
|
||||||
throw new TypeError(name + " is not an integer.");
|
throw new TypeError(name + " should be an integer.");
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isArrayOf = function(expectedType, value, name) {
|
module.exports.isArrayOf = function(expectedType, value, name) {
|
||||||
if (!Array.isArray(value))
|
if (!Array.isArray(value))
|
||||||
throw new TypeError(name + " is not an array.");
|
throw new TypeError(name + " should be an array.");
|
||||||
if (!value.every(function(x) { return x instanceof expectedType; }))
|
if (!value.every(function(x) { return x instanceof expectedType; }))
|
||||||
throw new TypeError([name, " is not an array of ", expectedType, "."].join(""));
|
throw new TypeError([name, " should be an array of ", expectedType, "."].join(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isTypeOf = function(expectedType, value, name) {
|
||||||
|
if (!(value instanceof expectedType))
|
||||||
|
throw new TypeError([name, " should be of type '", expectedType, "'."].join(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.positive = function(value, name) {
|
||||||
|
if (value <= 0)
|
||||||
|
throw new Error(name + " should be positive.");
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.nonNegative = function(value, name) {
|
||||||
|
if (value < 0)
|
||||||
|
throw new Error(name + " should be non-negative.");
|
||||||
};
|
};
|
|
@ -30,6 +30,8 @@ var systemStreams = require('./common/systemStreams');
|
||||||
var systemEventTypes = require('./common/systemEventTypes');
|
var systemEventTypes = require('./common/systemEventTypes');
|
||||||
var EventData = require('./eventData');
|
var EventData = require('./eventData');
|
||||||
|
|
||||||
|
const MaxReadSize = 4096;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param settings
|
* @param settings
|
||||||
* @param endpointDiscoverer
|
* @param endpointDiscoverer
|
||||||
|
@ -209,6 +211,12 @@ EventStoreNodeConnection.prototype.commitTransaction = function(transaction, use
|
||||||
* @returns {Promise.<EventReadResult>}
|
* @returns {Promise.<EventReadResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
||||||
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
|
ensure.isInteger(eventNumber, "eventNumber");
|
||||||
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
||||||
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
||||||
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
|
@ -220,8 +228,8 @@ EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, res
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadEventOperation(self._settings.log, cb, stream, eventNumber, resolveLinkTos || false,
|
var operation = new ReadEventOperation(self._settings.log, cb, stream, eventNumber, resolveLinkTos,
|
||||||
self._settings.requireMaster, userCredentials || null);
|
self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -238,10 +246,14 @@ EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, res
|
||||||
EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (typeof start !== 'number' || start % 1 !== 0) throw new TypeError("start must be an integer.");
|
ensure.isInteger(start, "start");
|
||||||
if (typeof count !== 'number' || count % 1 !== 0) throw new TypeError("count must be an integer.");
|
ensure.nonNegative(start, "start");
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
ensure.isInteger(count, "count");
|
||||||
|
ensure.positive(count, "count");
|
||||||
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -250,7 +262,7 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadStreamEventsForwardOperation(self._settings.log, cb, stream, start, count,
|
var operation = new ReadStreamEventsForwardOperation(self._settings.log, cb, stream, start, count,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -267,10 +279,13 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
||||||
EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (typeof start !== 'number' || start % 1 !== 0) throw new TypeError("start must be an integer.");
|
ensure.isInteger(start, "start");
|
||||||
if (typeof count !== 'number' || count % 1 !== 0) throw new TypeError("count must be an integer.");
|
ensure.isInteger(count, "count");
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
ensure.positive(count, "count");
|
||||||
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -279,7 +294,7 @@ EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadStreamEventsBackwardOperation(self._settings.log, cb, stream, start, count,
|
var operation = new ReadStreamEventsBackwardOperation(self._settings.log, cb, stream, start, count,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -295,7 +310,12 @@ EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
||||||
EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
||||||
position, maxCount, resolveLinkTos, userCredentials
|
position, maxCount, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
//TODO validations
|
ensure.isTypeOf(results.Position, position, "position");
|
||||||
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
|
ensure.positive(maxCount, "maxCount");
|
||||||
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -304,7 +324,7 @@ EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
var operation = new ReadAllEventsForwardOperation(self._settings.log, cb, position, maxCount,
|
var operation = new ReadAllEventsForwardOperation(self._settings.log, cb, position, maxCount,
|
||||||
resolveLinkTos || false, self._settings.requireMaster, userCredentials || null);
|
resolveLinkTos, self._settings.requireMaster, userCredentials);
|
||||||
self._enqueueOperation(operation);
|
self._enqueueOperation(operation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -320,7 +340,12 @@ EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
||||||
EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
||||||
position, maxCount, resolveLinkTos, userCredentials
|
position, maxCount, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
//TODO validations
|
ensure.isTypeOf(results.Position, position, "position");
|
||||||
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
|
ensure.positive(maxCount, "maxCount");
|
||||||
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
|
|
@ -15,13 +15,17 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'Append Multiple Events To Stream Happy Path': function(test) {
|
'Append Multiple Events To Stream Happy Path': function(test) {
|
||||||
var events = [
|
const expectedVersion = 25;
|
||||||
client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent'),
|
var events = [];
|
||||||
client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent')
|
for(var i = 0; i <= expectedVersion; i++) {
|
||||||
];
|
if (i % 2 === 0)
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent'));
|
||||||
|
else
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
||||||
|
}
|
||||||
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, 1);
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, expectedVersion);
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
|
|
|
@ -50,6 +50,7 @@ module.exports = {
|
||||||
});
|
});
|
||||||
this.conn = null;
|
this.conn = null;
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
'Test Connection': function(test) {
|
'Test Connection': function(test) {
|
||||||
test.ok(this.connError === null, "Connection error: " + this.connError);
|
test.ok(this.connError === null, "Connection error: " + this.connError);
|
||||||
test.done();
|
test.done();
|
||||||
|
@ -66,7 +67,7 @@ module.exports = {
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
},
|
},*/
|
||||||
'Test Commit Two Events Using Transaction': function(test) {
|
'Test Commit Two Events Using Transaction': function(test) {
|
||||||
this.conn.startTransaction(testStreamName, client.expectedVersion.any)
|
this.conn.startTransaction(testStreamName, client.expectedVersion.any)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
|
@ -89,6 +90,7 @@ module.exports = {
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
'Test Read One Event': function(test) {
|
'Test Read One Event': function(test) {
|
||||||
this.conn.readEvent(testStreamName, 0)
|
this.conn.readEvent(testStreamName, 0)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
|
@ -162,7 +164,7 @@ module.exports = {
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
},
|
},*/
|
||||||
'Test Subscribe to Stream': function(test) {
|
'Test Subscribe to Stream': function(test) {
|
||||||
var done = false;
|
var done = false;
|
||||||
function eventAppeared() {
|
function eventAppeared() {
|
||||||
|
@ -310,7 +312,7 @@ module.exports = {
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
},
|
}/*,
|
||||||
'Test Delete Stream': function(test) {
|
'Test Delete Stream': function(test) {
|
||||||
this.conn.deleteStream(testStreamName, client.expectedVersion.any)
|
this.conn.deleteStream(testStreamName, client.expectedVersion.any)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
|
@ -320,5 +322,5 @@ module.exports = {
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
test.done(err);
|
test.done(err);
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
};
|
};
|
|
@ -49,16 +49,26 @@ function tearDown(cb) {
|
||||||
this.conn = null;
|
this.conn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var areEqual = function(name, actual, expected) {
|
function areEqual(name, actual, expected) {
|
||||||
if (typeof expected !== 'object' || expected === null)
|
if (typeof expected !== 'object' || expected === null)
|
||||||
this.strictEqual(actual, expected, util.format("Failed %s === %s, got %s.", name, expected, actual));
|
this.strictEqual(actual, expected, util.format("Failed %s === %s, got %s.", name, expected, actual));
|
||||||
else
|
else
|
||||||
this.deepEqual(actual, expected, util.format("Failed %s deepEqual %j, got %j.", name, expected, actual));
|
this.deepEqual(actual, expected, util.format("Failed %s deepEqual %j, got %j.", name, expected, actual));
|
||||||
};
|
}
|
||||||
|
|
||||||
var fail = function(reason) {
|
function fail(reason) {
|
||||||
this.ok(false, reason);
|
this.ok(false, reason);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function eventEqualEventData(name, resolvedEvent, eventData) {
|
||||||
|
var ev = resolvedEvent.originalEvent;
|
||||||
|
this.ok(ev !== null, util.format("Failed %s !== null.", name + ".originalEvent"));
|
||||||
|
if (ev === null) return;
|
||||||
|
this.areEqual(name + ".originalEvent.eventId", ev.eventId, eventData.eventId);
|
||||||
|
this.areEqual(name + ".originalEvent.eventType", ev.eventType, eventData.type);
|
||||||
|
this.ok(Buffer.compare(ev.data, eventData.data) === 0, name + ".originalEvent.data is not equal to original data.");
|
||||||
|
this.ok(Buffer.compare(ev.metadata, eventData.metadata) === 0, name + ".originalEvent.metadata is not equal to original metadata.");
|
||||||
|
}
|
||||||
|
|
||||||
var _ = {
|
var _ = {
|
||||||
'setUp': setUp,
|
'setUp': setUp,
|
||||||
|
@ -72,6 +82,7 @@ function wrap(name, testFunc) {
|
||||||
settings.log.debug('--- %s ---', name);
|
settings.log.debug('--- %s ---', name);
|
||||||
test.areEqual = areEqual.bind(test);
|
test.areEqual = areEqual.bind(test);
|
||||||
test.fail = fail.bind(test);
|
test.fail = fail.bind(test);
|
||||||
|
test.eventEqualEventData = eventEqualEventData.bind(test);
|
||||||
return testFunc.call(this, test);
|
return testFunc.call(this, test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
73
test/readAllEventsBackward_test.js
Normal file
73
test/readAllEventsBackward_test.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
var util = require('util');
|
||||||
|
var uuid = require('uuid');
|
||||||
|
var client = require('../src/client');
|
||||||
|
|
||||||
|
const numberOfStreams = 20;
|
||||||
|
const maxBatch = 10;
|
||||||
|
const minBatch = 1;
|
||||||
|
const maxCount = 500;
|
||||||
|
const allCredentials = new client.UserCredentials("admin", "changeit");
|
||||||
|
|
||||||
|
function getRandomInt(min, max) {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
var streams = [];
|
||||||
|
for(var s = 0; s < numberOfStreams; s++) {
|
||||||
|
streams.push('test-' + uuid.v4());
|
||||||
|
}
|
||||||
|
var promises = [];
|
||||||
|
for(var total = 0; total < maxCount; ) {
|
||||||
|
var streamIndex = getRandomInt(0, numberOfStreams-1);
|
||||||
|
var batchSize = getRandomInt(minBatch, maxBatch);
|
||||||
|
var events = [];
|
||||||
|
for(var i = 0; i < batchSize; i++)
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
|
promises.push(this.conn.appendToStream(streams[streamIndex], client.expectedVersion.any, events));
|
||||||
|
total += batchSize;
|
||||||
|
}
|
||||||
|
Promise.all(promises)
|
||||||
|
.then(function() {
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
cb(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read All Events Backward Happy Path': function(test) {
|
||||||
|
var self = this;
|
||||||
|
this.conn.readAllEventsBackward(client.positions.end, maxCount, false, allCredentials)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
||||||
|
//test.areEqual('slice.fromPosition', slice.fromPosition, client.positions.end);
|
||||||
|
test.ok(slice.nextPosition.compareTo(slice.fromPosition) < 0, "slice.nextPosition is not lower than slice.fromPosition.");
|
||||||
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, false);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, maxCount);
|
||||||
|
var lastPosition = client.positions.end;
|
||||||
|
for(var i = 0; i < maxCount; i++)
|
||||||
|
test.ok(slice.events[i].originalPosition.compareTo(lastPosition) > 0,
|
||||||
|
util.format("wrong order at slice.events[%d].", i));
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read All Events Backward With No Access': function(test) {
|
||||||
|
this.conn.readAllEventsBackward(client.positions.end, maxCount)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.fail("readAllEventsBackward succeeded but should have failed.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
var isAccessDenied = err instanceof client.AccessDeniedError;
|
||||||
|
test.ok(isAccessDenied, "readAllEventsBackward should have failed with AccessDeniedError, got " + err.constructor.name);
|
||||||
|
if (isAccessDenied) return test.done();
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
require('./common/base_test').init(module.exports);
|
74
test/readAllEventsForward_test.js
Normal file
74
test/readAllEventsForward_test.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
var util = require('util');
|
||||||
|
var uuid = require('uuid');
|
||||||
|
var client = require('../src/client');
|
||||||
|
|
||||||
|
const numberOfStreams = 20;
|
||||||
|
const maxBatch = 10;
|
||||||
|
const minBatch = 1;
|
||||||
|
const maxCount = 500;
|
||||||
|
const allCredentials = new client.UserCredentials("admin", "changeit");
|
||||||
|
|
||||||
|
function getRandomInt(min, max) {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
var streams = [];
|
||||||
|
for(var s = 0; s < numberOfStreams; s++) {
|
||||||
|
streams.push('test-' + uuid.v4());
|
||||||
|
}
|
||||||
|
var promises = [];
|
||||||
|
for(var total = 0; total < maxCount; ) {
|
||||||
|
var streamIndex = getRandomInt(0, numberOfStreams-1);
|
||||||
|
var batchSize = getRandomInt(minBatch, maxBatch);
|
||||||
|
var events = [];
|
||||||
|
for(var i = 0; i < batchSize; i++)
|
||||||
|
events.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
|
promises.push(this.conn.appendToStream(streams[streamIndex], client.expectedVersion.any, events));
|
||||||
|
total += batchSize;
|
||||||
|
}
|
||||||
|
Promise.all(promises)
|
||||||
|
.then(function() {
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
cb(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read All Events Forward Happy Path': function(test) {
|
||||||
|
this.conn.readAllEventsForward(client.positions.start, maxCount, false, allCredentials)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
||||||
|
test.areEqual('slice.fromPosition', slice.fromPosition, client.positions.start);
|
||||||
|
test.ok(slice.nextPosition.compareTo(client.positions.start) > 0, "slice.nextPosition is not greater than start.");
|
||||||
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, false);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, maxCount);
|
||||||
|
var lastPosition = client.positions.start;
|
||||||
|
for(var i = 0; i < maxCount; i++) {
|
||||||
|
test.ok(slice.events[i].originalPosition.compareTo(lastPosition) > 0,
|
||||||
|
util.format("wrong order at slice.events[%d].", i));
|
||||||
|
lastPosition = slice.events[i].originalPosition;
|
||||||
|
}
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read All Events Forward With No Access': function(test) {
|
||||||
|
this.conn.readAllEventsForward(client.positions.start, maxCount)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.fail("readAllEventsForward succeeded but should have failed.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
var isAccessDenied = err instanceof client.AccessDeniedError;
|
||||||
|
test.ok(isAccessDenied, "readAllEventsForward should have failed with AccessDeniedError, got " + err.constructor.name);
|
||||||
|
if (isAccessDenied) return test.done();
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
require('./common/base_test').init(module.exports);
|
105
test/readStreamEventsBackward_test.js
Normal file
105
test/readStreamEventsBackward_test.js
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
var util = require('util');
|
||||||
|
var uuid = require('uuid');
|
||||||
|
var client = require('../src/client');
|
||||||
|
|
||||||
|
const streamSize = 100;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
this.eventsData = [];
|
||||||
|
for(var i = 0; i < streamSize; i++)
|
||||||
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
||||||
|
.then(function() {
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch(cb);
|
||||||
|
},
|
||||||
|
'Read Stream Events Backward Happy Path': function(test) {
|
||||||
|
var self = this;
|
||||||
|
this.conn.readStreamEventsBackward(this.testStreamName, streamSize-1, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
|
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
||||||
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, -1);
|
||||||
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
||||||
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
|
for(var i = 0; i < streamSize; i++) {
|
||||||
|
var reverseIndex = streamSize - i - 1;
|
||||||
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[reverseIndex]);
|
||||||
|
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, reverseIndex);
|
||||||
|
}
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read Stream Events Backward With Non-Existing Stream': function(test) {
|
||||||
|
var anotherStream = 'test' + uuid.v4();
|
||||||
|
this.conn.readStreamEventsBackward(anotherStream, streamSize-1, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Backward With Deleted Stream': function(test) {
|
||||||
|
var self = this;
|
||||||
|
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
||||||
|
.then(function() {
|
||||||
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize)
|
||||||
|
})
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Backward With Inexisting Version': function(test) {
|
||||||
|
var self = this;
|
||||||
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize * 2, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Backward With No Access': function(test) {
|
||||||
|
var self = this;
|
||||||
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
|
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
|
.then(function(){
|
||||||
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize);
|
||||||
|
})
|
||||||
|
.then(function(slice) {
|
||||||
|
test.fail("readStreamEventsBackward succeeded but should have failed.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
var isAccessDenied = err instanceof client.AccessDeniedError;
|
||||||
|
test.ok(isAccessDenied, "readStreamEventsBackward should have failed with AccessDeniedError, got " + err.constructor.name);
|
||||||
|
if (isAccessDenied) return test.done();
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
require('./common/base_test').init(module.exports);
|
104
test/readStreamEventsForward_test.js
Normal file
104
test/readStreamEventsForward_test.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
var util = require('util');
|
||||||
|
var uuid = require('uuid');
|
||||||
|
var client = require('../src/client');
|
||||||
|
|
||||||
|
const streamSize = 100;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
this.eventsData = [];
|
||||||
|
for(var i = 0; i < streamSize; i++)
|
||||||
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
||||||
|
.then(function() {
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch(cb);
|
||||||
|
},
|
||||||
|
'Read Stream Events Forward Happy Path': function(test) {
|
||||||
|
var self = this;
|
||||||
|
this.conn.readStreamEventsForward(this.testStreamName, 0, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
|
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
||||||
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, streamSize);
|
||||||
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
||||||
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
|
for(var i = 0; i < streamSize; i++) {
|
||||||
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[i]);
|
||||||
|
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, i);
|
||||||
|
}
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'Read Stream Events Forward With Non-Existing Stream': function(test) {
|
||||||
|
var anotherStream = 'test' + uuid.v4();
|
||||||
|
this.conn.readStreamEventsForward(anotherStream, 0, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Forward With Deleted Stream': function(test) {
|
||||||
|
var self = this;
|
||||||
|
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
||||||
|
.then(function() {
|
||||||
|
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize)
|
||||||
|
})
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Forward With Inexisting Version': function(test) {
|
||||||
|
var self = this;
|
||||||
|
return self.conn.readStreamEventsForward(self.testStreamName, streamSize * 2, streamSize)
|
||||||
|
.then(function(slice) {
|
||||||
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
||||||
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'Read Stream Events Forward With No Access': function(test) {
|
||||||
|
var self = this;
|
||||||
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
|
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
|
.then(function(){
|
||||||
|
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize);
|
||||||
|
})
|
||||||
|
.then(function(slice) {
|
||||||
|
test.fail("readStreamEventsForward succeeded but should have failed.");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
var isAccessDenied = err instanceof client.AccessDeniedError;
|
||||||
|
test.ok(isAccessDenied, "readStreamEventsForward should have failed with AccessDeniedError, got " + err.constructor.name);
|
||||||
|
if (isAccessDenied) return test.done();
|
||||||
|
test.done(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
require('./common/base_test').init(module.exports);
|
Loading…
Reference in New Issue
Block a user