extracting base class for tests, adding readEvent tests, fixing typed error in related operations, adding a file logger

This commit is contained in:
Nicolas Dextraze 2016-03-13 18:38:42 -07:00
parent 0b63df85e7
commit d1b9d6958b
11 changed files with 540 additions and 259 deletions

View File

@ -85,14 +85,21 @@ module.exports =
return new EventData(eventId, type, isJson, data, metadata);
}
// Exporting classes
module.exports.EventStoreConnection = __webpack_require__(6);
module.exports.UserCredentials = __webpack_require__(62);
module.exports.UserCredentials = __webpack_require__(65);
module.exports.EventData = EventData;
module.exports.PersistentSubscriptionSettings = __webpack_require__(63);
module.exports.SystemConsumerStrategies = __webpack_require__(49);
module.exports.PersistentSubscriptionSettings = __webpack_require__(66);
module.exports.SystemConsumerStrategies = __webpack_require__(52);
// Exporting errors
module.exports.WrongExpectedVersionError = __webpack_require__(34);
module.exports.StreamDeletedError = __webpack_require__(35);
module.exports.AccessDeniedError = __webpack_require__(36);
// Exporting enums/constants
module.exports.expectedVersion = expectedVersion;
module.exports.positions = positions;
module.exports.systemMetadata = __webpack_require__(67);
module.exports.eventReadStatus = results.EventReadStatus;
// Helper functions
module.exports.createConnection = module.exports.EventStoreConnection.create;
module.exports.createEventData = eventDataFactory;
@ -529,13 +536,25 @@ module.exports =
throw new Error(name + " is null.");
};
module.exports.isInteger = function(value, name) {
if (typeof value !== 'number' || value % 1 !== 0)
throw new TypeError(name + " is not an integer.");
};
module.exports.isArrayOf = function(expectedType, value, name) {
if (!Array.isArray(value))
throw new TypeError(name + " is not an array.");
if (!value.every(function(x) { return x instanceof expectedType; }))
throw new TypeError([name, " is not an array of ", expectedType, "."].join(""));
};
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
var EventStoreNodeConnection = __webpack_require__(7);
var StaticEndpointDiscoverer = __webpack_require__(60);
var NoopLogger = __webpack_require__(61);
var StaticEndpointDiscoverer = __webpack_require__(63);
var NoopLogger = __webpack_require__(64);
var defaultConnectionSettings = {
log: new NoopLogger(),
@ -602,27 +621,27 @@ module.exports =
var EventStoreConnectionLogicHandler = __webpack_require__(10);
var DeleteStreamOperation = __webpack_require__(33);
var AppendToStreamOperation = __webpack_require__(35);
var StartTransactionOperation = __webpack_require__(36);
var TransactionalWriteOperation = __webpack_require__(38);
var CommitTransactionOperation = __webpack_require__(39);
var ReadEventOperation = __webpack_require__(40);
var ReadStreamEventsForwardOperation = __webpack_require__(41);
var ReadStreamEventsBackwardOperation = __webpack_require__(45);
var ReadAllEventsForwardOperation = __webpack_require__(46);
var ReadAllEventsBackwardOperation = __webpack_require__(47);
var CreatePersistentSubscriptionOperation = __webpack_require__(48);
var UpdatePersistentSubscriptionOperation = __webpack_require__(50);
var DeletePersistentSubscriptionOperation = __webpack_require__(51);
var AppendToStreamOperation = __webpack_require__(38);
var StartTransactionOperation = __webpack_require__(39);
var TransactionalWriteOperation = __webpack_require__(41);
var CommitTransactionOperation = __webpack_require__(42);
var ReadEventOperation = __webpack_require__(43);
var ReadStreamEventsForwardOperation = __webpack_require__(44);
var ReadStreamEventsBackwardOperation = __webpack_require__(48);
var ReadAllEventsForwardOperation = __webpack_require__(49);
var ReadAllEventsBackwardOperation = __webpack_require__(50);
var CreatePersistentSubscriptionOperation = __webpack_require__(51);
var UpdatePersistentSubscriptionOperation = __webpack_require__(53);
var DeletePersistentSubscriptionOperation = __webpack_require__(54);
var EventStoreTransaction = __webpack_require__(37);
var EventStoreStreamCatchUpSubscription = __webpack_require__(52);
var EventStoreAllCatchUpSubscription = __webpack_require__(54);
var EventStorePersistentSubscription = __webpack_require__(55);
var EventStoreTransaction = __webpack_require__(40);
var EventStoreStreamCatchUpSubscription = __webpack_require__(55);
var EventStoreAllCatchUpSubscription = __webpack_require__(57);
var EventStorePersistentSubscription = __webpack_require__(58);
var results = __webpack_require__(3);
var systemStreams = __webpack_require__(58);
var systemEventTypes = __webpack_require__(59);
var systemStreams = __webpack_require__(61);
var systemEventTypes = __webpack_require__(62);
var EventData = __webpack_require__(1);
/**
@ -691,8 +710,10 @@ module.exports =
* @returns {Promise.<DeleteResult>}
*/
EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) {
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
if (typeof expectedVersion !== 'number' || expectedVersion % 1 !== 0) throw new TypeError("expectedVersion must be an integer.");
ensure.notNullOrEmpty(stream, "stream");
ensure.isInteger(expectedVersion, "expectedVersion");
hardDelete = !!hardDelete;
userCredentials = userCredentials || null;
var self = this;
return new Promise(function(resolve, reject) {
@ -702,8 +723,7 @@ module.exports =
}
var deleteStreamOperation = new DeleteStreamOperation(
self._settings.log, cb, self._settings.requireMaster, stream, expectedVersion,
!!hardDelete, userCredentials || null);
self._settings.log, cb, self._settings.requireMaster, stream, expectedVersion, hardDelete, userCredentials);
self._enqueueOperation(deleteStreamOperation);
});
};
@ -712,14 +732,17 @@ module.exports =
* Append events to a stream (async)
* @param {string} stream The name of the stream to which to append.
* @param {number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed.
* @param {Array.<EventData>} events The events to append.
* @param {EventData[]|EventData} events The event(s) to append.
* @param {UserCredentials} [userCredentials] User credentials
* @returns {Promise.<WriteResult>}
*/
EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) {
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
if (typeof expectedVersion !== 'number' || expectedVersion % 1 !== 0) throw new TypeError("expectedVersion must be an integer.");
if (!Array.isArray(events)) throw new TypeError("events must be an array.");
ensure.notNullOrEmpty(stream, "stream");
ensure.isInteger(expectedVersion, "expectedVersion");
if (!Array.isArray(events))
events = [events];
ensure.isArrayOf(EventData, events, "events");
userCredentials = userCredentials || null;
var self = this;
return new Promise(function(resolve, reject) {
@ -728,7 +751,7 @@ module.exports =
resolve(result);
}
var operation = new AppendToStreamOperation(self._settings.log, cb, self._settings.requireMaster, stream,
expectedVersion, events, userCredentials || null);
expectedVersion, events, userCredentials);
self._enqueueOperation(operation);
});
};
@ -1185,7 +1208,7 @@ module.exports =
case results.EventReadStatus.NoStream:
return new results.RawStreamMetadataResult(stream, false, -1, null);
case results.EventReadStatus.StreamDeleted:
return new results.RawStreamMetadataResult(stream, true, Number.MAX_VALUE, null);
return new results.RawStreamMetadataResult(stream, true, 0x7fffffff, null);
default:
throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status));
}
@ -1454,15 +1477,15 @@ module.exports =
EventStoreConnectionLogicHandler.prototype._discoverEndpoint = function(cb) {
this._logDebug('DiscoverEndpoint');
if (this._state != ConnectionState.Connecting) return;
if (this._connectingPhase != ConnectingPhase.Reconnecting) return;
if (this._state !== ConnectionState.Connecting) return;
if (this._connectingPhase !== ConnectingPhase.Reconnecting) return;
this._connectingPhase = ConnectingPhase.EndPointDiscovery;
cb = cb || function() {};
var self = this;
this._endpointDiscoverer.discover(this._connection != null ? this._connection.remoteEndPoint : null)
this._endpointDiscoverer.discover(this._connection !== null ? this._connection.remoteEndPoint : null)
.then(function(nodeEndpoints){
self.enqueueMessage(new messages.EstablishTcpConnectionMessage(nodeEndpoints));
cb();
@ -1920,7 +1943,6 @@ module.exports =
{
case ConnectionState.Init: break;
case ConnectionState.Connecting:
{
if (this._connectingPhase == ConnectingPhase.Reconnecting && Date.now() - this._reconnInfo.timeStamp >= this._settings.reconnectionDelay)
{
this._logDebug("TimerTick checking reconnection...");
@ -1934,17 +1956,15 @@ module.exports =
this._discoverEndpoint(null);
}
}
if (this._connectingPhase == ConnectingPhase.Authentication && Date.now() - this._authInfo.timeStamp >= this._settings.operationTimeout)
else if (this._connectingPhase == ConnectingPhase.Authentication && Date.now() - this._authInfo.timeStamp >= this._settings.operationTimeout)
{
this.emit('authenticationFailed', "Authentication timed out.");
this._goToConnectedState();
}
if (this._connectingPhase > ConnectingPhase.ConnectionEstablishing)
else if (this._connectingPhase > ConnectingPhase.ConnectionEstablishing)
this._manageHeartbeats();
break;
}
case ConnectionState.Connected:
{
// operations timeouts are checked only if connection is established and check period time passed
if (Date.now() - this._lastTimeoutsTimeStamp >= this._settings.operationTimeoutCheckPeriod)
{
@ -1958,7 +1978,6 @@ module.exports =
}
this._manageHeartbeats();
break;
}
case ConnectionState.Closed:
break;
default:
@ -2137,21 +2156,25 @@ module.exports =
});
}
Object.defineProperty(TcpPackageConnection.prototype, 'connectionId', {
enumerable: true,
get: function() {
return this._connectionId;
}
});
Object.defineProperty(TcpPackageConnection.prototype, 'isClosed', {
enumerable: true,
get: function() {
return this._connection.isClosed;
}
});
Object.defineProperty(TcpPackageConnection.prototype, 'remoteEndPoint', {
enumerable: true,
get: function() {
return this._connection.remoteEndPoint;
}
});
Object.defineProperty(TcpPackageConnection.prototype, 'localEndPoint', {
enumerable: true,
get: function() {
return this._connection.localEndPoint;
}
@ -2355,11 +2378,13 @@ module.exports =
this._receiveQueue = [];
Object.defineProperty(this, 'remoteEndPoint', {
enumerable: true,
get: function() {
return this._remoteEndPoint;
}
});
Object.defineProperty(this, 'localEndPoint', {
enumerable: true,
get: function() {
return this._localEndPoint;
}
@ -3731,8 +3756,11 @@ module.exports =
var InspectionResult = __webpack_require__(27);
var ClientMessage = __webpack_require__(28);
var results = __webpack_require__(3);
var WrongExpectedVersionError = __webpack_require__(34);
var StreamDeletedError = __webpack_require__(35);
var AccessDeniedError = __webpack_require__(36);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function DeleteStreamOperation(log, cb, requireMaster, stream, expectedVersion, hardDelete, userCredentials) {
@ -3763,17 +3791,16 @@ module.exports =
case ClientMessage.OperationResult.ForwardTimeout:
return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout");
case ClientMessage.OperationResult.WrongExpectedVersion:
var err = util.format("Delete stream failed due to WrongExpectedVersion. Stream: %s, Expected version: %d.", this._stream, this._expectedVersion);
this.fail(new Error("Wrong expected version: " + err));
this.fail(new WrongExpectedVersionError("Delete", this._stream, this._expectedVersion));
return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion");
case ClientMessage.OperationResult.StreamDeleted:
this.fail(new Error("Stream deleted: " + this._stream));
this.fail(new StreamDeletedError(this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted");
case ClientMessage.OperationResult.InvalidTransaction:
this.fail(new Error("Invalid transaction."));
return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction");
case ClientMessage.OperationResult.AccessDenied:
this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream)));
this.fail(new AccessDeniedError("Delete", this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
default:
throw new Error(util.format("Unexpected OperationResult: %d.", response.result));
@ -3796,12 +3823,63 @@ module.exports =
var util = __webpack_require__(4);
function WrongExpectedVersionError(action, stream, expectedVersion) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, stream, expectedVersion);
this.action = action;
this.stream = stream;
this.expectedVersion = expectedVersion;
}
util.inherits(WrongExpectedVersionError, Error);
module.exports = WrongExpectedVersionError;
/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
function StreamDeletedError(stream) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = util.format("Event stream '%s' is deleted.", stream);
this.stream = stream;
}
util.inherits(StreamDeletedError, Error);
module.exports = StreamDeletedError;
/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
function AccessDeniedError(action, stream) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = util.format("%s access denied for stream '%s'.", action, stream);
this.action = action;
this.stream = stream;
}
util.inherits(AccessDeniedError, Error);
module.exports = AccessDeniedError;
/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var TcpPackage = __webpack_require__(17);
var TcpCommand = __webpack_require__(19);
var TcpFlags = __webpack_require__(18);
var InspectionDecision = __webpack_require__(26);
var ClientMessage = __webpack_require__(28);
var createInspectionResult = __webpack_require__(27);
var InspectionResult = __webpack_require__(27);
var createBufferSegment = __webpack_require__(14);
function OperationBase(log, cb, requestCommand, responseCommand, userCredentials) {
@ -3875,7 +3953,7 @@ module.exports =
}
} catch(e) {
this.fail(e);
return createInspectionResult(InspectionDecision.EndOperation, "Error - " + e.message);
return new InspectionResult(InspectionDecision.EndOperation, "Error - " + e.message);
}
};
@ -3887,7 +3965,7 @@ module.exports =
} catch(e) {}
//TODO typed error
this.fail(new Error("Authentication error: " + message));
return createInspectionResult(InspectionDecision.EndOperation, "NotAuthenticated");
return new InspectionResult(InspectionDecision.EndOperation, "NotAuthenticated");
};
OperationBase.prototype._inspectBadRequest = function(pkg)
@ -3898,7 +3976,7 @@ module.exports =
} catch(e) {}
//TODO typed error
this.fail(new Error("Bad request: " + message));
return createInspectionResult(InspectionDecision.EndOperation, "BadRequest - " + message);
return new InspectionResult(InspectionDecision.EndOperation, "BadRequest - " + message);
};
OperationBase.prototype._inspectNotHandled = function(pkg)
@ -3907,20 +3985,20 @@ module.exports =
switch (message.reason)
{
case ClientMessage.NotHandled.NotHandledReason.NotReady:
return createInspectionResult(InspectionDecision.Retry, "NotHandled - NotReady");
return new InspectionResult(InspectionDecision.Retry, "NotHandled - NotReady");
case ClientMessage.NotHandled.NotHandledReason.TooBusy:
return createInspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy");
case ClientMessage.NotHandled.NotHandledReason.NotMaster:
var masterInfo = ClientMessage.NotHandled.MasterInfo.decode(message.additional_info);
return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster",
return new new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster",
{host: masterInfo.external_tcp_address, port: masterInfo.external_tcp_port},
{host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port});
default:
this.log.error("Unknown NotHandledReason: %s.", message.reason);
return createInspectionResult(InspectionDecision.Retry, "NotHandled - <unknown>");
return new InspectionResult(InspectionDecision.Retry, "NotHandled - <unknown>");
}
};
@ -3937,7 +4015,7 @@ module.exports =
this.constructor.name, this, pkg.data);
this.fail(new Error(util.format("Unexpected command. Expecting %s got %s.", TcpCommand.getName(expectedCommand), TcpCommand.getName(pkg.command))));
return createInspectionResult(InspectionDecision.EndOperation, "Unexpected command - " + TcpCommand.getName(pkg.command));
return new InspectionResult(InspectionDecision.EndOperation, "Unexpected command - " + TcpCommand.getName(pkg.command));
};
@ -3945,7 +4023,7 @@ module.exports =
/***/ },
/* 35 */
/* 38 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -3957,8 +4035,11 @@ module.exports =
var ClientMessage = __webpack_require__(28);
var WriteResult = __webpack_require__(3).WriteResult;
var Position = __webpack_require__(3).Position;
var WrongExpectedVersionError = __webpack_require__(34);
var StreamDeletedError = __webpack_require__(35);
var AccessDeniedError = __webpack_require__(36);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function AppendToStreamOperation(log, cb, requireMaster, stream, expectedVersion, events, userCredentials) {
OperationBase.call(this, log, cb, TcpCommand.WriteEvents, TcpCommand.WriteEventsCompleted, userCredentials);
@ -4002,17 +4083,16 @@ module.exports =
this._wasCommitTimeout = true;
return new InspectionResult(InspectionDecision.Retry, "CommitTimeout");
case ClientMessage.OperationResult.WrongExpectedVersion:
var err = ["Append failed due to WrongExpectedVersion. Stream: ", this._stream,", Expected version: ", this._expectedVersion].join('');
this.fail(new Error(err));
this.fail(new WrongExpectedVersionError("Append", this._stream, this._expectedVersion));
return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion");
case ClientMessage.OperationResult.StreamDeleted:
this.fail(new Error("Stream deleted. Stream: " + this._stream));
this.fail(new StreamDeletedError(this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted");
case ClientMessage.OperationResult.InvalidTransaction:
this.fail(new Error("Invalid transaction."));
return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction");
case ClientMessage.OperationResult.AccessDenied:
this.fail(new Error(["Write access denied for stream '", this._stream, "'."].join('')));
this.fail(new AccessDeniedError("Write", this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
default:
throw new Error("Unexpected OperationResult: " + response.result);
@ -4031,7 +4111,7 @@ module.exports =
/***/ },
/* 36 */
/* 39 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4041,10 +4121,10 @@ module.exports =
var InspectionDecision = __webpack_require__(26);
var InspectionResult = __webpack_require__(27);
var ClientMessage = __webpack_require__(28);
var EventStoreTransaction = __webpack_require__(37);
var EventStoreTransaction = __webpack_require__(40);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function StartTransactionOperation(log, cb, requireMaster, stream, expectedVersion, parentConnection, userCredentials) {
OperationBase.call(this, log, cb, TcpCommand.TransactionStart, TcpCommand.TransactionStartCompleted, userCredentials);
@ -4103,7 +4183,7 @@ module.exports =
/***/ },
/* 37 */
/* 40 */
/***/ function(module, exports) {
/**
@ -4161,7 +4241,7 @@ module.exports =
module.exports = EventStoreTransaction;
/***/ },
/* 38 */
/* 41 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4172,7 +4252,7 @@ module.exports =
var InspectionResult = __webpack_require__(27);
var ClientMessage = __webpack_require__(28);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function TransactionalWriteOperation(log, cb, requireMaster, transactionId, events, userCredentials) {
@ -4229,7 +4309,7 @@ module.exports =
/***/ },
/* 39 */
/* 42 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4241,7 +4321,7 @@ module.exports =
var ClientMessage = __webpack_require__(28);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function CommitTransactionOperation(log, cb, requireMaster, transactionId, userCredentials) {
@ -4299,7 +4379,7 @@ module.exports =
module.exports = CommitTransactionOperation;
/***/ },
/* 40 */
/* 43 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4309,8 +4389,9 @@ module.exports =
var InspectionResult = __webpack_require__(27);
var InspectionDecision = __webpack_require__(26);
var results = __webpack_require__(3);
var AccessDeniedError = __webpack_require__(36);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function ReadEventOperation(log, cb, stream, eventNumber, resolveLinkTos, requireMaster, userCredentials) {
OperationBase.call(this, log, cb, TcpCommand.ReadEvent, TcpCommand.ReadEventCompleted, userCredentials);
@ -4346,7 +4427,7 @@ module.exports =
this.fail(new Error("Server error: " + response.error));
return new InspectionResult(InspectionDecision.EndOperation, "Error");
case ClientMessage.ReadEventCompleted.ReadEventResult.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");
default:
throw new Error(util.format("Unexpected ReadEventResult: %s.", response.result));
@ -4384,7 +4465,7 @@ module.exports =
/***/ },
/* 41 */
/* 44 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4392,13 +4473,13 @@ module.exports =
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var ReadDirection = __webpack_require__(42);
var StatusCode = __webpack_require__(43);
var ReadDirection = __webpack_require__(45);
var StatusCode = __webpack_require__(46);
var InspectionResult = __webpack_require__(27);
var InspectionDecision = __webpack_require__(26);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function ReadStreamEventsForwardOperation(
log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials
@ -4463,7 +4544,7 @@ module.exports =
/***/ },
/* 42 */
/* 45 */
/***/ function(module, exports) {
const ReadDirection = {
@ -4475,11 +4556,11 @@ module.exports =
/***/ },
/* 43 */
/* 46 */
/***/ function(module, exports, __webpack_require__) {
var ClientMessage = __webpack_require__(28);
var SliceReadStatus = __webpack_require__(44);
var SliceReadStatus = __webpack_require__(47);
module.exports = {};
@ -4497,7 +4578,7 @@ module.exports =
};
/***/ },
/* 44 */
/* 47 */
/***/ function(module, exports) {
const SliceReadStatus = {
@ -4510,7 +4591,7 @@ module.exports =
/***/ },
/* 45 */
/* 48 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4518,13 +4599,13 @@ module.exports =
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var ReadDirection = __webpack_require__(42);
var StatusCode = __webpack_require__(43);
var ReadDirection = __webpack_require__(45);
var StatusCode = __webpack_require__(46);
var InspectionResult = __webpack_require__(27);
var InspectionDecision = __webpack_require__(26);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function ReadStreamEventsBackwardOperation(
log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials
@ -4589,7 +4670,7 @@ module.exports =
/***/ },
/* 46 */
/* 49 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4597,12 +4678,12 @@ module.exports =
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var ReadDirection = __webpack_require__(42);
var ReadDirection = __webpack_require__(45);
var InspectionResult = __webpack_require__(27);
var InspectionDecision = __webpack_require__(26);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function ReadAllEventsForwardOperation(
log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials
@ -4656,7 +4737,7 @@ module.exports =
/***/ },
/* 47 */
/* 50 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -4664,12 +4745,12 @@ module.exports =
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var ReadDirection = __webpack_require__(42);
var ReadDirection = __webpack_require__(45);
var InspectionResult = __webpack_require__(27);
var InspectionDecision = __webpack_require__(26);
var results = __webpack_require__(3);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
function ReadAllEventsBackwardOperation(
log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials
@ -4723,17 +4804,17 @@ module.exports =
/***/ },
/* 48 */
/* 51 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var uuid = __webpack_require__(2);
var ensure = __webpack_require__(5);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var SystemConsumerStrategies = __webpack_require__(49);
var SystemConsumerStrategies = __webpack_require__(52);
var InspectionDecision = __webpack_require__(26);
var InspectionResult = __webpack_require__(27);
var results = __webpack_require__(3);
@ -4803,7 +4884,7 @@ module.exports =
/***/ },
/* 49 */
/* 52 */
/***/ function(module, exports) {
const SystemConsumerStrategies = {
@ -4816,17 +4897,17 @@ module.exports =
/***/ },
/* 50 */
/* 53 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var uuid = __webpack_require__(2);
var ensure = __webpack_require__(5);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var SystemConsumerStrategies = __webpack_require__(49);
var SystemConsumerStrategies = __webpack_require__(52);
var InspectionDecision = __webpack_require__(26);
var InspectionResult = __webpack_require__(27);
var results = __webpack_require__(3);
@ -4896,14 +4977,14 @@ module.exports =
/***/ },
/* 51 */
/* 54 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var uuid = __webpack_require__(2);
var ensure = __webpack_require__(5);
var OperationBase = __webpack_require__(34);
var OperationBase = __webpack_require__(37);
var TcpCommand = __webpack_require__(19);
var ClientMessage = __webpack_require__(28);
var InspectionDecision = __webpack_require__(26);
@ -4957,13 +5038,13 @@ module.exports =
/***/ },
/* 52 */
/* 55 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var EventStoreCatchUpSubscription = __webpack_require__(53);
var SliceReadStatus = __webpack_require__(44);
var EventStoreCatchUpSubscription = __webpack_require__(56);
var SliceReadStatus = __webpack_require__(47);
function EventStoreStreamCatchUpSubscription(
connection, log, streamId, fromEventNumberExclusive, resolveLinkTos, userCredentials,
@ -5055,7 +5136,7 @@ module.exports =
/***/ },
/* 53 */
/* 56 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
@ -5313,12 +5394,12 @@ module.exports =
module.exports = EventStoreCatchUpSubscription;
/***/ },
/* 54 */
/* 57 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var EventStoreCatchUpSubscription = __webpack_require__(53);
var EventStoreCatchUpSubscription = __webpack_require__(56);
var results = __webpack_require__(3);
@ -5403,12 +5484,12 @@ module.exports =
/***/ },
/* 55 */
/* 58 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var EventStorePersistentSubscriptionBase = __webpack_require__(56);
var EventStorePersistentSubscriptionBase = __webpack_require__(59);
var messages = __webpack_require__(9);
function EventStorePersistentSubscription(
@ -5443,12 +5524,12 @@ module.exports =
module.exports = EventStorePersistentSubscription;
/***/ },
/* 56 */
/* 59 */
/***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(4);
var ensure = __webpack_require__(5);
var PersistentSubscriptionNakEventAction = __webpack_require__(57);
var PersistentSubscriptionNakEventAction = __webpack_require__(60);
var SubscriptionDropReason = __webpack_require__(23);
function DropSubscriptionEvent() {}
@ -5616,7 +5697,7 @@ module.exports =
/***/ },
/* 57 */
/* 60 */
/***/ function(module, exports) {
const PersistentSubscriptionNakEventAction = {
@ -5636,7 +5717,7 @@ module.exports =
/***/ },
/* 58 */
/* 61 */
/***/ function(module, exports) {
module.exports.metastreamOf = function(stream) {
@ -5647,7 +5728,7 @@ module.exports =
};
/***/ },
/* 59 */
/* 62 */
/***/ function(module, exports) {
const SystemEventTypes = {
@ -5658,7 +5739,7 @@ module.exports =
/***/ },
/* 60 */
/* 63 */
/***/ function(module, exports) {
function StaticEndpointDiscoverer(tcpEndPoint, useSsl) {
@ -5675,7 +5756,7 @@ module.exports =
module.exports = StaticEndpointDiscoverer;
/***/ },
/* 61 */
/* 64 */
/***/ function(module, exports) {
function NoopLogger() {
@ -5687,7 +5768,7 @@ module.exports =
module.exports = NoopLogger;
/***/ },
/* 62 */
/* 65 */
/***/ function(module, exports, __webpack_require__) {
var ensure = __webpack_require__(5);
@ -5712,10 +5793,10 @@ module.exports =
module.exports = UserCredentials;
/***/ },
/* 63 */
/* 66 */
/***/ function(module, exports, __webpack_require__) {
var SystemConsumerStrategies = __webpack_require__(49);
var SystemConsumerStrategies = __webpack_require__(52);
function PersistentSubscriptionSettings(
resolveLinkTos, startFrom, extraStatistics, messageTimeout,
@ -5742,5 +5823,26 @@ module.exports =
return new PersistentSubscriptionSettings(false, -1, false, 30000, 500, 500, 10, 20, 2000, 10, 1000, 0, SystemConsumerStrategies.RoundRobin);
};
/***/ },
/* 67 */
/***/ function(module, exports) {
const SystemMetadata = {
maxAge: '$maxAge',
maxCount: '$maxCount',
truncateBefore: '$tb',
cacheControl: '$cacheControl',
acl: '$acl',
aclRead: '$r',
aclWrite: '$w',
aclDelete: '$d',
aclMetaRead: '$mr',
aclMetaWrite: '$mw',
userStreamAcl: '$userStreamAcl',
systemStreamAcl: '$systemStreamAcl'
};
module.exports = SystemMetadata;
/***/ }
/******/ ]);

View File

@ -38,18 +38,21 @@ function eventDataFactory(eventId, type, isJson, data, metadata) {
return new EventData(eventId, type, isJson, data, metadata);
}
// Exporting classes
module.exports.EventStoreConnection = require('./eventStoreConnection');
module.exports.UserCredentials = require('./systemData/userCredentials');
module.exports.EventData = EventData;
module.exports.PersistentSubscriptionSettings = require('./persistentSubscriptionSettings');
module.exports.SystemConsumerStrategies = require('./systemConsumerStrategies');
// Exporting errors
module.exports.WrongExpectedVersionError = require('./errors/wrongExpectedVersionError');
module.exports.StreamDeletedError = require('./errors/streamDeletedError');
module.exports.AccessDeniedError = require('./errors/accessDeniedError');
// Exporting enums/constants
module.exports.expectedVersion = expectedVersion;
module.exports.positions = positions;
module.exports.systemMetadata = require('./common/systemMetadata');
module.exports.eventReadStatus = results.EventReadStatus;
// Helper functions
module.exports.createConnection = module.exports.EventStoreConnection.create;
module.exports.createEventData = eventDataFactory;

View File

@ -6,6 +6,9 @@ var InspectionDecision = require('../systemData/inspectionDecision');
var InspectionResult = require('./../systemData/inspectionResult');
var ClientMessage = require('../messages/clientMessage');
var results = require('../results');
var WrongExpectedVersionError = require('../errors/wrongExpectedVersionError');
var StreamDeletedError = require('../errors/streamDeletedError');
var AccessDeniedError = require('../errors/accessDeniedError');
var OperationBase = require('../clientOperations/operationBase');
@ -38,17 +41,16 @@ DeleteStreamOperation.prototype._inspectResponse = function(response) {
case ClientMessage.OperationResult.ForwardTimeout:
return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout");
case ClientMessage.OperationResult.WrongExpectedVersion:
var err = util.format("Delete stream failed due to WrongExpectedVersion. Stream: %s, Expected version: %d.", this._stream, this._expectedVersion);
this.fail(new Error("Wrong expected version: " + err));
this.fail(new WrongExpectedVersionError("Delete", this._stream, this._expectedVersion));
return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion");
case ClientMessage.OperationResult.StreamDeleted:
this.fail(new Error("Stream deleted: " + this._stream));
this.fail(new StreamDeletedError(this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted");
case ClientMessage.OperationResult.InvalidTransaction:
this.fail(new Error("Invalid transaction."));
return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction");
case ClientMessage.OperationResult.AccessDenied:
this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream)));
this.fail(new AccessDeniedError("Delete", this._stream));
return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied");
default:
throw new Error(util.format("Unexpected OperationResult: %d.", response.result));

View File

@ -5,6 +5,7 @@ var ClientMessage = require('../messages/clientMessage');
var InspectionResult = require('./../systemData/inspectionResult');
var InspectionDecision = require('../systemData/inspectionDecision');
var results = require('../results');
var AccessDeniedError = require('../errors/accessDeniedError');
var OperationBase = require('./operationBase');
@ -42,7 +43,7 @@ ReadEventOperation.prototype._inspectResponse = function(response) {
this.fail(new Error("Server error: " + response.error));
return new InspectionResult(InspectionDecision.EndOperation, "Error");
case ClientMessage.ReadEventCompleted.ReadEventResult.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");
default:
throw new Error(util.format("Unexpected ReadEventResult: %s.", response.result));

View File

@ -13,7 +13,7 @@ function FileLogger(filePath, append) {
function createLine(level, args, argsStartIndex) {
var msg = util.format.apply(util, Array.prototype.slice.call(args, argsStartIndex));
return util.format('%s %s - %s%s', new Date().toISOString(), level, msg, os.EOL);
return util.format('%s %s - %s%s', new Date().toISOString().substr(11,12), level, msg, os.EOL);
}
FileLogger.prototype.debug = function() {

View File

@ -111,7 +111,12 @@ module.exports = require("protobufjs").newBuilder({})['import']({
"name": "ResolvedIndexedEvent",
"fields": [
{
"rule": "required",
/*
rule changed from required to optional
because protobufjs doesn't allow null value for required object
and in the case of a non-success result, event will be null
*/
"rule": "optional",
"type": "EventRecord",
"name": "event",
"id": 1

View File

@ -1,46 +1,12 @@
var uuid = require('uuid');
var client = require('../src/client');
var settings = {};
if (process.env.TESTS_VERBOSE_LOGGING === '1') {
settings.verboseLogging = true;
var FileLogger = require('../src/common/log/fileLogger');
settings.log = new FileLogger('appendToStream_test.log');
}
module.exports = {
setUp: function(cb) {
this.testStreamName = 'test-' + uuid.v4();
var connected = false;
this.conn = client.EventStoreConnection.create(settings, {host: 'localhost', port: 1113});
this.conn.connect()
.then(function() {
//Doesn't mean anything, connection is just initiated
})
.catch(function(err) {
cb(err);
});
this.conn.on('closed', function(reason){
if (connected) return;
cb(new Error("Connection failed: " + reason));
});
this.conn.on('connected', function() {
connected = true;
cb();
});
},
tearDown: function(cb) {
this.conn.close();
this.conn.on('closed', function() {
cb();
});
this.conn = null;
},
'Append One Event To Stream Happy Path': function(test) {
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, event)
.then(function(result) {
test.ok(result.nextExpectedVersion === 0, "Expected nextExpectedVersion === 0, but was " + result.nextExpectedVersion);
test.areEqual("nextExpectedVersion", result.nextExpectedVersion, 0);
test.ok(result.logPosition, "No log position in result.");
test.done();
})
@ -55,7 +21,7 @@ module.exports = {
];
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
.then(function(result) {
test.ok(result.nextExpectedVersion === 1, "Expected nextExpectedVersion === 1, but was " + result.nextExpectedVersion);
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, 1);
test.ok(result.logPosition, "No log position in result.");
test.done();
})
@ -67,17 +33,14 @@ module.exports = {
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
this.conn.appendToStream(this.testStreamName, 10, event)
.then(function(result) {
test.ok(false, "Append succeeded but should have failed.");
test.fail("Append succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isWrongExpectedVersion = err instanceof client.WrongExpectedVersionError;
test.ok(isWrongExpectedVersion, "Expected WrongExpectedVersionError, got " + err.constructor.name);
if (!isWrongExpectedVersion) {
test.done(err);
return;
}
test.done();
if (isWrongExpectedVersion) return test.done();
test.done(err);
});
},
'Append To Stream Deleted': function(test) {
@ -88,17 +51,14 @@ module.exports = {
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
})
.then(function(result) {
test.ok(false, "Append succeeded but should have failed.");
test.fail("Append succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isStreamDeleted = err instanceof client.StreamDeletedError;
test.ok(isStreamDeleted, "Expected StreamDeletedError, got " + err.constructor.name);
if (!isStreamDeleted) {
test.done(err);
return;
}
test.done();
if (isStreamDeleted) return test.done();
test.done(err);
});
},
'Append To Stream Access Denied': function(test) {
@ -110,17 +70,16 @@ module.exports = {
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
})
.then(function(result) {
test.ok(false, "Append succeeded but should have failed.");
test.fail("Append succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isStreamDeleted = err instanceof client.AccessDeniedError;
test.ok(isStreamDeleted, "Expected AccessDeniedError, got " + err.constructor.name);
if (!isStreamDeleted) {
test.done(err);
return;
}
test.done();
if (isStreamDeleted) return test.done();
test.done(err);
});
}
};
require('./common/base_test').init(module.exports);

109
test/common/base_test.js Normal file
View File

@ -0,0 +1,109 @@
var util = require('util');
var uuid = require('uuid');
var client = require('../../src/client');
var FileLogger = require('../../src/common/log/fileLogger');
var NoopLogger = require('../../src/common/log/noopLogger');
var settings = {
log: new NoopLogger()
};
if (process.env.TESTS_VERBOSE_LOGGING === '1') {
settings.verboseLogging = true;
settings.log = new FileLogger('test-verbose.log');
}
var tcpEndPoint = {host: 'localhost', port: 1113};
function setUp(cb) {
this.log = settings.log;
this.testStreamName = 'test-' + uuid.v4();
var connected = false;
this.conn = client.EventStoreConnection.create(settings, tcpEndPoint);
this.conn.connect()
.then(function () {
//Doesn't mean anything, connection is just initiated
settings.log.debug("Connection to %j initialized.", tcpEndPoint);
})
.catch(function (err) {
settings.log.error(err, "Initializing connection to %j failed.", tcpEndPoint);
cb(err);
});
this.conn.on('closed', function (reason) {
if (connected) return;
var error = new Error("Connection failed: " + reason);
settings.log.error(error, "Connection to %j failed.", tcpEndPoint);
cb(error);
});
this.conn.on('connected', function () {
settings.log.debug("Connected to %j.", tcpEndPoint);
connected = true;
cb();
});
}
function tearDown(cb) {
this.conn.close();
this.conn.on('closed', function() {
cb();
});
this.conn = null;
}
var areEqual = function(name, actual, expected) {
if (typeof expected !== 'object' || expected === null)
this.strictEqual(actual, expected, util.format("Failed %s === %s, got %s.", name, expected, actual));
else
this.deepEqual(actual, expected, util.format("Failed %s deepEqual %j, got %j.", name, expected, actual));
};
var fail = function(reason) {
this.ok(false, reason);
};
var _ = {
'setUp': setUp,
'tearDown': tearDown
};
function wrap(name, testFunc) {
var base = _[name];
if (base === undefined) {
return function(test) {
settings.log.debug('--- %s ---', name);
test.areEqual = areEqual.bind(test);
test.fail = fail.bind(test);
return testFunc.call(this, test);
}
}
return function(cb) {
var self = this;
base.call(this, function(err) {
if (err) return cb(err);
return testFunc.call(self, cb);
});
}
}
module.exports.init = function(testSuite, addSetUpTearDownIfNotPresent) {
var thisObj = {};
if (addSetUpTearDownIfNotPresent === undefined) addSetUpTearDownIfNotPresent = true;
for(var k in testSuite) {
if (testSuite.hasOwnProperty(k)) {
testSuite[k] = wrap(k, testSuite[k]).bind(thisObj);
}
}
if (!addSetUpTearDownIfNotPresent) return;
if (!testSuite.hasOwnProperty('setUp')) testSuite['setUp'] = setUp.bind(thisObj);
if (!testSuite.hasOwnProperty('tearDown')) testSuite['tearDown'] = tearDown.bind(thisObj);
};
module.exports.settings = function(settingsOverride) {
var obj = {};
for(var prop in settings) {
obj[prop] = settings[prop];
}
if (!settingsOverride) return obj;
for(var prop in settingsOverride) {
obj[prop] = settingsOverride[prop];
}
return obj;
};

View File

@ -1,53 +1,40 @@
var util = require('util');
var client = require('../src/client.js');
var consoleLogger = {
debug: function() {
var msg = util.format.apply(util, Array.prototype.slice.call(arguments));
util.log(msg);
},
info: function() {},
error: function() {}
};
var settings = {};//verboseLogging: true, log: consoleLogger};
var testBase = require('./common/base_test');
module.exports = {
'Connect To Endpoint Happy Path': function(test) {
var tcpEndpoint = {hostname: 'localhost', port: 1113};
var conn = client.EventStoreConnection.create({}, tcpEndpoint);
var conn = client.EventStoreConnection.create(testBase.settings(), tcpEndpoint);
conn.connect()
.catch(function(e) {
test.done(e);
.catch(function(err) {
test.done(err);
});
conn.on('connected', function(endPoint){
test.deepEqual(endPoint, tcpEndpoint);
test.areEqual("connected endPoint", endPoint, tcpEndpoint);
done();
});
conn.on('error', done);
function done(e) {
function done(err) {
conn.close();
if (e) {
test.done(e);
return;
}
if (err) return test.done(err);
test.done();
}
},
'Connect To Endpoint That Don\'t Exist': function(test) {
var tcpEndpoint = {hostname: 'localhost', port: 1114};
var conn = client.EventStoreConnection.create({maxReconnections: 1}, tcpEndpoint);
var conn = client.EventStoreConnection.create(testBase.settings({maxReconnections:1}), tcpEndpoint);
conn.connect()
.catch(function (e) {
test.done(e);
.catch(function (err) {
test.done(err);
});
conn.on('connected', function () {
test.ok(false, "Should not be able to connect.");
test.fail("Should not be able to connect.");
test.done();
});
conn.on('error', function (e) {
test.done(e);
conn.on('error', function (err) {
test.done(err);
});
conn.on('closed', function(reason) {
test.ok(reason.indexOf("Reconnection limit reached") === 0, "Wrong expected reason.");
@ -55,3 +42,5 @@ module.exports = {
});
}
};
testBase.init(module.exports, false);

View File

@ -1,49 +1,17 @@
var uuid = require('uuid');
var client = require('../src/client');
var settings = {};
if (process.env.TESTS_VERBOSE_LOGGING === '1') {
settings.verboseLogging = true;
var FileLogger = require('../src/common/log/fileLogger');
settings.log = new FileLogger('deleteStream_test.log');
}
module.exports = {
setUp: function(cb) {
this.testStreamName = 'test-' + uuid.v4();
var connected = false;
this.conn = client.EventStoreConnection.create(settings, {host: 'localhost', port: 1113});
this.conn.connect()
var events = [
client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent'),
client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent')
];
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, events)
.then(function() {
//Doesn't mean anything, connection is just initiated
cb();
})
.catch(function(err) {
cb(err);
});
this.conn.on('closed', function(reason){
if (connected) return;
cb(new Error("Connection failed: " + reason));
});
var self = this;
this.conn.on('connected', function() {
connected = true;
var events = [
client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent'),
client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent')
];
self.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
.then(function() {
cb();
})
.catch(cb);
});
},
tearDown: function(cb) {
this.conn.close();
this.conn.on('closed', function() {
cb();
});
this.conn = null;
.catch(cb);
},
'Test Delete Stream Soft Happy Path': function(test) {
var self = this;
@ -53,8 +21,8 @@ module.exports = {
return self.conn.getStreamMetadataRaw(self.testStreamName);
})
.then(function(metadata) {
test.ok(metadata.stream === self.testStreamName, "Metadata stream doesn't match.");
test.ok(metadata.isStreamDeleted === false, "Metadata says stream is deleted.");
test.areEqual("metadata.stream", metadata.stream, self.testStreamName);
test.areEqual("metadata.isStreamDeleted", metadata.isStreamDeleted, false);
test.ok(metadata.streamMetadata.$tb, "Expected Truncate Before to be set");
test.done();
})
@ -62,12 +30,6 @@ module.exports = {
test.done(err);
});
},
/*
This test fails because of a protobufjs error.
Client.ReadEventCompleted fails to decode because ResolvedIndexedEvent.event is null and it's marked as required.
Test will pass if messages.proto is modified so that ResolvedIndexedEvent.event is optional.
Unsure if it's a protobufjs issue or a GES issue. Need to duplicate this test with .Net Client.
'Test Delete Stream Hard Happy Path': function(test) {
var self = this;
this.conn.deleteStream(this.testStreamName, 1, true)
@ -76,15 +38,62 @@ module.exports = {
return self.conn.getStreamMetadataRaw(self.testStreamName);
})
.then(function(metadata) {
test.ok(metadata.stream === self.testStreamName, "Metadata stream doesn't match.");
test.ok(metadata.isStreamDeleted === true, "Metadata says stream is deleted.");
test.ok(metadata.streamMetadata === null, "Expected streamMetadata to be null.");
test.areEqual("metadata.stream", metadata.stream, self.testStreamName);
test.areEqual("metadata.isStreamDeleted", metadata.isStreamDeleted, true);
test.areEqual("metadata.streamMetadata", metadata.streamMetadata, null);
test.done();
})
.catch(function(err) {
test.done(err);
});
},
'Test Delete Stream With Wrong Expected Version': function(test) {
this.conn.deleteStream(this.testStreamName, 10)
.then(function(result) {
test.fail("Delete succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isWrongExpectedVersion = err instanceof client.WrongExpectedVersionError;
test.ok(isWrongExpectedVersion, "Expected WrongExpectedVersionError, but got " + err.constructor.name);
if (isWrongExpectedVersion) return test.done();
test.done(err);
});
},
'Test Delete Stream With No Access': function(test) {
var self = this;
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.any, {$acl: {$d: "$admins"}})
.then(function() {
return self.conn.deleteStream(self.testStreamName, 10);
})
.then(function(result) {
test.fail("Delete succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isAccessDenied = err instanceof client.AccessDeniedError;
test.ok(isAccessDenied, "Expected AccessDeniedError, but got " + err.constructor.name);
if (isAccessDenied) return test.done();
test.done(err);
});
},
'Test Delete Stream Hard When Already Deleted': function(test) {
var self = this;
this.conn.deleteStream(this.testStreamName, 1, true)
.then(function() {
return self.conn.deleteStream(self.testStreamName, 1, true);
})
.then(function(result) {
test.fail("Delete succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isStreamDeleted = err instanceof client.StreamDeletedError;
test.ok(isStreamDeleted, "Expected StreamDeletedError, but got " + err.constructor.name);
if (isStreamDeleted) return test.done();
test.done(err);
});
}
*/
};
require('./common/base_test').init(module.exports);

102
test/readEvent_test.js Normal file
View File

@ -0,0 +1,102 @@
var util = require('util');
var uuid = require('uuid');
var client = require('../src/client');
module.exports = {
setUp: function(cb) {
this.expectedEvent = {a: uuid.v4(), b: Math.random()};
this.expectedEventType = 'anEvent';
this.expectedEventId = uuid.v4();
var event = client.createJsonEventData(this.expectedEventId, this.expectedEvent, null, this.expectedEventType);
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, event)
.then(function() {
cb();
})
.catch(cb);
},
'Read Event Happy Path': function(test) {
var self = this;
this.conn.readEvent(this.testStreamName, 0)
.then(function(result) {
test.areEqual('status', result.status, client.eventReadStatus.Success);
test.areEqual('stream', result.stream, self.testStreamName);
test.areEqual('eventNumber', result.eventNumber, 0);
test.ok(result.event !== null, "event is null.");
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
var event = JSON.parse(result.event.originalEvent.data.toString());
test.areEqual('event.eventId', result.event.originalEvent.eventId, self.expectedEventId);
test.areEqual('event.eventType', result.event.originalEvent.eventType, self.expectedEventType);
test.areEqual('decoded event.data', event, self.expectedEvent);
test.done();
})
.catch(function(err) {
test.done(err);
})
},
'Read Event From Non-Existing Stream': function(test) {
var anotherStream = 'test' + uuid.v4();
this.conn.readEvent(anotherStream, 0)
.then(function(result) {
test.areEqual('status', result.status, client.eventReadStatus.NoStream);
test.areEqual('stream', result.stream, anotherStream);
test.areEqual('eventNumber', result.eventNumber, 0);
test.areEqual('event', result.event, null);
test.done();
})
.catch(function(err) {
test.done(err);
});
},
'Read Event From Deleted Stream': function(test) {
var self = this;
this.conn.deleteStream(this.testStreamName, 0, true)
.then(function() {
return self.conn.readEvent(self.testStreamName, 0)
})
.then(function(result) {
test.areEqual('status', result.status, client.eventReadStatus.StreamDeleted);
test.areEqual('stream', result.stream, self.testStreamName);
test.areEqual('eventNumber', result.eventNumber, 0);
test.areEqual('event', result.event, null);
test.done();
})
.catch(function(err) {
test.done(err);
});
},
'Read Event With Inexisting Version': function(test) {
var self = this;
return self.conn.readEvent(self.testStreamName, 1)
.then(function(result) {
test.areEqual('status', result.status, client.eventReadStatus.NotFound);
test.areEqual('stream', result.stream, self.testStreamName);
test.areEqual('eventNumber', result.eventNumber, 1);
test.areEqual('event', result.event, null);
test.done();
})
.catch(function(err) {
test.done(err);
});
},
'Read Event 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.readEvent(self.testStreamName, 0);
})
.then(function(result) {
test.fail("readEvent succeeded but should have failed.");
test.done();
})
.catch(function(err) {
var isAccessDenied = err instanceof client.AccessDeniedError;
test.ok(isAccessDenied, "readEvent should have failed with AccessDeniedError, got " + err.constructor.name);
if (isAccessDenied) return test.done();
test.done(err);
});
}
};
require('./common/base_test').init(module.exports);