mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
reworking the code and adding tests
This commit is contained in:
parent
ee4481c8e9
commit
88e248ad52
20 changed files with 602 additions and 233 deletions
|
|
@ -19,15 +19,17 @@ path = require 'path'
|
|||
###
|
||||
##Module call
|
||||
|
||||
Calling the module as a function will make it look for the `relPath` property in the
|
||||
Calling the module as a function will make it look for the `configPath` property in the
|
||||
args object and then try to load a config file from that relative path.
|
||||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) ->
|
||||
args = args ? {}
|
||||
log args
|
||||
if typeof args.relPath is 'string'
|
||||
loadConfigFile args.relPath
|
||||
if typeof args.configPath is 'string'
|
||||
loadConfigFile args.configPath
|
||||
else
|
||||
loadConfigFile path.join('config', 'config.json')
|
||||
module.exports
|
||||
|
||||
###
|
||||
|
|
@ -35,12 +37,12 @@ Tries to load a configuration file from the path relative to this module's paren
|
|||
Reads the config file synchronously from the file system and try to parse it.
|
||||
|
||||
@private loadConfigFile
|
||||
@param {String} relPath
|
||||
@param {String} configPath
|
||||
###
|
||||
loadConfigFile = ( relPath ) =>
|
||||
loadConfigFile = ( configPath ) =>
|
||||
@config = null
|
||||
try
|
||||
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', relPath
|
||||
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', configPath
|
||||
if @config and @config.http_port and @config.db_port and
|
||||
@config.crypto_key and @config.session_secret
|
||||
log.print 'CF', 'config file loaded successfully'
|
||||
|
|
@ -54,7 +56,6 @@ loadConfigFile = ( relPath ) =>
|
|||
e.addInfo = 'no config ready'
|
||||
log.error 'CF', e
|
||||
|
||||
loadConfigFile path.join('config', 'config.json')
|
||||
|
||||
###
|
||||
Fetch a property from the configuration
|
||||
|
|
|
|||
|
|
@ -42,12 +42,16 @@ exports = module.exports = ( args ) =>
|
|||
log args
|
||||
config = require './config'
|
||||
config args
|
||||
@crypto_key = config.getCryptoKey()
|
||||
@db = redis.createClient config.getDBPort(),
|
||||
'localhost', { connect_timeout: 2000 }
|
||||
@db.on "error", ( err ) ->
|
||||
err.addInfo = 'message from DB'
|
||||
log.error 'DB', err
|
||||
@db?.quit()
|
||||
if config.isReady()
|
||||
@crypto_key = config.getCryptoKey()
|
||||
@db = redis.createClient config.getDBPort(),
|
||||
'localhost', { connect_timeout: 2000 }
|
||||
@db.on 'error', ( err ) ->
|
||||
err.addInfo = 'message from DB'
|
||||
log.error 'DB', err
|
||||
else
|
||||
log.error 'DB', 'Initialization failed because of missing config file!'
|
||||
|
||||
###
|
||||
Checks whether the db is connected and passes either an error on failure after
|
||||
|
|
@ -56,7 +60,6 @@ ten attempts within five seconds, or nothing on success to the callback(err).
|
|||
@public isConnected( *cb* )
|
||||
@param {function} cb
|
||||
###
|
||||
#TODO check if timeout works with func in func
|
||||
exports.isConnected = ( cb ) =>
|
||||
if @db.connected then cb()
|
||||
else
|
||||
|
|
@ -66,13 +69,24 @@ exports.isConnected = ( cb ) =>
|
|||
log.print 'DB', 'Successfully connected to DB!'
|
||||
cb()
|
||||
else if numAttempts++ < 10
|
||||
setTimeout fCheckConnection, 500
|
||||
setTimeout fCheckConnection, 100
|
||||
else
|
||||
e = new Error 'Connection to DB failed!'
|
||||
log.error 'DB', e
|
||||
cb e
|
||||
setTimeout fCheckConnection, 500
|
||||
cb new Error 'Connection to DB failed!'
|
||||
setTimeout fCheckConnection, 100
|
||||
|
||||
###
|
||||
Abstracts logging for simple action replies from the DB.
|
||||
|
||||
@private replyHandler( *action* )
|
||||
@param {String} action
|
||||
###
|
||||
replyHandler = ( action ) ->
|
||||
( err, reply ) ->
|
||||
if err
|
||||
err.addInfo = 'during "' + action + '"'
|
||||
log.error 'DB', err
|
||||
else
|
||||
log.print 'DB', action + ': ' + reply
|
||||
|
||||
###
|
||||
Push an event into the event queue.
|
||||
|
|
@ -81,8 +95,11 @@ Push an event into the event queue.
|
|||
@param {Object} event
|
||||
###
|
||||
exports.pushEvent = ( event ) =>
|
||||
log.print 'DB', 'Event pushed into the queue: ' + event.eventid
|
||||
@db.rpush 'event_queue', JSON.stringify(event)
|
||||
if event
|
||||
log.print 'DB', 'Event pushed into the queue: ' + event.eventid
|
||||
@db.rpush 'event_queue', JSON.stringify( event )
|
||||
else
|
||||
log.error 'DB', 'Why would you give me an empty event...'
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -91,9 +108,19 @@ Pop an event from the event queue and pass it to the callback(err, obj) function
|
|||
@public popEvent( *cb* )
|
||||
@param {function} cb
|
||||
###
|
||||
exports.popEvent = ( cb )=>
|
||||
@db.lpop 'event_queue', cb
|
||||
exports.popEvent = ( cb ) =>
|
||||
makeObj = ( pcb ) ->
|
||||
( err, obj ) ->
|
||||
pcb err, JSON.parse( obj )
|
||||
@db.lpop 'event_queue', makeObj( cb )
|
||||
|
||||
###
|
||||
Purge the event queue.
|
||||
|
||||
@public purgeEventQueue()
|
||||
###
|
||||
exports.purgeEventQueue = () =>
|
||||
@db.del 'event_queue', replyHandler 'purging event queue'
|
||||
|
||||
###
|
||||
Hashes a string based on SHA-3-512.
|
||||
|
|
@ -104,7 +131,7 @@ Hashes a string based on SHA-3-512.
|
|||
hash = ( plainText ) =>
|
||||
if !plainText? then return null
|
||||
try
|
||||
(crypto.SHA3 plainText, { outputLength: 512 }).toString()
|
||||
( crypto.SHA3 plainText, { outputLength: 512 } ).toString()
|
||||
catch err
|
||||
err.addInfo = 'during hashing'
|
||||
log.error 'DB', err
|
||||
|
|
@ -145,20 +172,6 @@ decrypt = ( crypticText ) =>
|
|||
log.error 'DB', err
|
||||
null
|
||||
|
||||
###
|
||||
Abstracts logging for simple action replies from the DB.
|
||||
|
||||
@private replyHandler( *action* )
|
||||
@param {String} action
|
||||
###
|
||||
replyHandler = ( action ) ->
|
||||
( err, reply ) ->
|
||||
if err
|
||||
err.addInfo = 'during "' + action + '"'
|
||||
log.error 'DB', err
|
||||
else
|
||||
log.print 'DB', action + ': ' + reply
|
||||
|
||||
###
|
||||
Fetches all linked data set keys from a linking set, fetches the single data objects
|
||||
via the provided function and returns the results to the callback(err, obj) function.
|
||||
|
|
@ -179,7 +192,6 @@ getSetRecords = ( set, fSingle, cb ) =>
|
|||
else
|
||||
semaphore = arrReply.length
|
||||
objReplies = {}
|
||||
#TODO What if the DB needs longer than two seconds to respond?...
|
||||
setTimeout ->
|
||||
if semaphore > 0
|
||||
cb new Error('Timeout fetching ' + set)
|
||||
|
|
@ -193,10 +205,10 @@ getSetRecords = ( set, fSingle, cb ) =>
|
|||
else if not data
|
||||
log.error 'DB', new Error 'Empty key in DB: ' + prop
|
||||
else
|
||||
objReplies[prop] = data
|
||||
objReplies[ prop ] = data
|
||||
if semaphore == 0
|
||||
cb null, objReplies
|
||||
fSingle reply, fCallback(reply) for reply in arrReply
|
||||
fSingle reply, fCallback( reply ) for reply in arrReply
|
||||
|
||||
###
|
||||
## Action Modules
|
||||
|
|
@ -236,30 +248,30 @@ exports.getActionModules = ( cb ) ->
|
|||
getSetRecords 'action-modules', exports.getActionModule, cb
|
||||
|
||||
###
|
||||
Store a string representation of the authentication parameters for an action module.
|
||||
Store user-specific action module parameters .
|
||||
|
||||
@public storeActionAuth( *userId, moduleId, data* )
|
||||
@public storeActionParams( *userId, moduleId, data* )
|
||||
@param {String} userId
|
||||
@param {String} moduleId
|
||||
@param {String} data
|
||||
###
|
||||
exports.storeActionAuth = ( userId, moduleId, data ) =>
|
||||
log.print 'DB', 'storeActionAuth: ' + userId + ':' + moduleId
|
||||
@db.set 'action-auth:' + userId + ':' + moduleId, hash(data),
|
||||
replyHandler 'storing action auth ' + userId + ':' + moduleId
|
||||
exports.storeActionParams = ( userId, moduleId, data ) =>
|
||||
log.print 'DB', 'storeActionParams: ' + moduleId + ':' + userId
|
||||
@db.set 'action-params:' + moduleId + ':' + userId, hash(data),
|
||||
replyHandler 'storing action params ' + moduleId + ':' + userId
|
||||
|
||||
###
|
||||
Query the DB for an action module authentication token associated to a user
|
||||
Query the DB for user-specific action module parameters,
|
||||
and pass it to the callback(err, obj) function.
|
||||
|
||||
@public getActionAuth( *userId, moduleId, cb* )
|
||||
@public getActionParams( *userId, moduleId, cb* )
|
||||
@param {String} userId
|
||||
@param {String} moduleId
|
||||
@param {function} cb
|
||||
###
|
||||
exports.getActionAuth = ( userId, moduleId, cb ) =>
|
||||
log.print 'DB', 'getActionAuth: ' + userId + ':' + moduleId
|
||||
@db.get 'action-auth:' + userId + ':' + moduleId, ( err, data ) ->
|
||||
exports.getActionParams = ( userId, moduleId, cb ) =>
|
||||
log.print 'DB', 'getActionParams: ' + moduleId + ':' + userId
|
||||
@db.get 'action-params:' + moduleId + ':' + userId, ( err, data ) ->
|
||||
cb err, decrypt data
|
||||
|
||||
|
||||
|
|
@ -309,10 +321,10 @@ Store a string representation of user-specific parameters for an event module.
|
|||
###
|
||||
# TODO is used, remove unused ones
|
||||
exports.storeEventParams = ( userId, moduleId, data ) =>
|
||||
log.print 'DB', 'storeEventParams: ' + userId + ':' + moduleId
|
||||
log.print 'DB', 'storeEventParams: ' + moduleId + ':' + userId
|
||||
# TODO encryption based on user specific key?
|
||||
@db.set 'event-params:' + moduleId + ':' + userId, encrypt(data),
|
||||
replyHandler 'storing event auth ' + userId + ':' + moduleId
|
||||
replyHandler 'storing event auth ' + moduleId + ':' + userId
|
||||
|
||||
###
|
||||
Query the DB for an action module authentication token, associated with a user.
|
||||
|
|
@ -323,8 +335,8 @@ Query the DB for an action module authentication token, associated with a user.
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getEventAuth = ( userId, moduleId, cb ) =>
|
||||
log.print 'DB', 'getEventAuth: ' + userId + ':' + moduleId
|
||||
@db.get 'event-auth:' + userId + ':' + moduleId, ( err, data ) ->
|
||||
log.print 'DB', 'getEventAuth: ' + moduleId + ':' + userId
|
||||
@db.get 'event-auth:' + moduleId + ':' + userId, ( err, data ) ->
|
||||
cb err, decrypt data
|
||||
|
||||
|
||||
|
|
@ -335,16 +347,17 @@ exports.getEventAuth = ( userId, moduleId, cb ) =>
|
|||
###
|
||||
Store a string representation of a rule in the DB.
|
||||
|
||||
@public storeRule( *id, data* )
|
||||
@param {String} id
|
||||
@public storeRule( *ruleId, userId, data* )
|
||||
@param {String} ruleId
|
||||
@param {String} userId
|
||||
@param {String} data
|
||||
###
|
||||
exports.storeRule = ( id, user, data ) =>
|
||||
log.print 'DB', 'storeRule: ' + id
|
||||
@db.sadd 'rules', id + ':' + user, replyHandler 'storing rule key "' + id + ':' + user + '"'
|
||||
@db.sadd 'user:' + user + ':rules', id, replyHandler 'storing rule key to "user:' + user + ':rules"'
|
||||
@db.sadd 'rule:' + id + ':users', user, replyHandler 'storing user key to "rule:' + id + ':users"'
|
||||
@db.set 'rule:' + id + ':' + user, data, replyHandler 'storing rule "' + id + ':' + user + '"'
|
||||
exports.storeRule = ( ruleId, userId, data ) =>
|
||||
log.print 'DB', 'storeRule: ' + ruleId
|
||||
@db.sadd 'rules', ruleId + ':' + user, replyHandler 'storing rule key "' + ruleId + ':' + user + '"'
|
||||
@db.sadd 'user-set:' + user + ':rules', ruleId, replyHandler 'storing rule key to "user:' + user + ':rules"'
|
||||
@db.sadd 'rule-set:' + ruleId + ':users', user, replyHandler 'storing user key to "rule:' + ruleId + ':users"'
|
||||
@db.set 'rule:' + ruleId + ':' + user, data, replyHandler 'storing rule "' + ruleId + ':' + user + '"'
|
||||
|
||||
###
|
||||
Query the DB for a rule and pass it to the callback(err, obj) function.
|
||||
|
|
@ -391,10 +404,11 @@ Associate a role with a user.
|
|||
@param {String} username
|
||||
@param {String} role
|
||||
###
|
||||
exports.storeUserRole = ( username, role ) =>
|
||||
exports.storeUserRole = ( userId, roleId ) =>
|
||||
log.print 'DB', 'storeUserRole: ' + username + ':' + role
|
||||
@db.sadd 'user-roles:' + username, role, replyHandler 'adding role ' + role + ' to user ' + username
|
||||
@db.sadd 'role-users:' + role, username, replyHandler 'adding user ' + username + ' to role ' + role
|
||||
@db.sadd 'roles', role, replyHandler 'adding role ' + role + ' to role index set'
|
||||
@db.sadd 'user:' + userId + ':roles', role, replyHandler 'adding role ' + role + ' to user ' + username
|
||||
@db.sadd 'role:' + roleId + ':users', username, replyHandler 'adding user ' + username + ' to role ' + role
|
||||
|
||||
###
|
||||
Fetch all roles of a user and pass them to the callback(err, obj)
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@ app = express()
|
|||
|
||||
#RedisStore = require('connect-redis')(express), # TODO use RedisStore for persistent sessions
|
||||
|
||||
# Just to have at least something. I know all of you know it now ;-P
|
||||
sess_sec = '#C[>;j`@".TXm2TA;A2Tg)'
|
||||
|
||||
|
||||
###
|
||||
Module call
|
||||
-----------
|
||||
|
|
@ -48,16 +44,20 @@ exports = module.exports = ( args ) ->
|
|||
log args
|
||||
config args
|
||||
requestHandler args
|
||||
#TODO check whether this really does what it's supposed to do (fetch wrong sess property)
|
||||
sess_sec = config.getSessionSecret() || sess_sec
|
||||
module.exports
|
||||
|
||||
###
|
||||
Adds the shutdown handler to the admin commands.
|
||||
|
||||
@param {function} fshutDown
|
||||
@public addHandlers( *fShutDown* )
|
||||
###
|
||||
exports.addHandlers = ( fShutDown ) ->
|
||||
requestHandler.addHandlers fShutDown
|
||||
# Add cookie support for session handling.
|
||||
app.use express.cookieParser()
|
||||
app.use express.session { secret: sess_sec }
|
||||
# At the moment there's no redis session backbone (didn't work straight away)
|
||||
app.use express.session { secret: config.getSessionSecret() }
|
||||
#At the moment there's no redis session backbone (didn't work straight away)
|
||||
log.print 'HL', 'no session backbone'
|
||||
|
||||
# **Accepted requests to paths:**
|
||||
|
|
@ -95,6 +95,11 @@ exports.addHandlers = ( fShutDown ) ->
|
|||
e.addInfo = 'opening port'
|
||||
log.error e
|
||||
|
||||
###
|
||||
Shuts down the http listener.
|
||||
|
||||
@public shutDown()
|
||||
###
|
||||
exports.shutDown = () ->
|
||||
log.print 'HL', 'Shutting down HTTP listener'
|
||||
process.exit() # This is a bit brute force...
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ This function is invoked right after the module is loaded and starts the server.
|
|||
###
|
||||
init = ->
|
||||
log.print 'RS', 'STARTING SERVER'
|
||||
|
||||
conf args
|
||||
# > Check whether the config file is ready, which is required to start the server.
|
||||
if !conf.isReady()
|
||||
log.error 'RS', 'Config file not ready!'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Configuration
|
|||
/*
|
||||
##Module call
|
||||
|
||||
Calling the module as a function will make it look for the `relPath` property in the
|
||||
Calling the module as a function will make it look for the `configPath` property in the
|
||||
args object and then try to load a config file from that relative path.
|
||||
@param {Object} args
|
||||
*/
|
||||
|
|
@ -29,8 +29,10 @@ Configuration
|
|||
exports = module.exports = function(args) {
|
||||
args = args != null ? args : {};
|
||||
log(args);
|
||||
if (typeof args.relPath === 'string') {
|
||||
loadConfigFile(args.relPath);
|
||||
if (typeof args.configPath === 'string') {
|
||||
loadConfigFile(args.configPath);
|
||||
} else {
|
||||
loadConfigFile(path.join('config', 'config.json'));
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
|
|
@ -40,15 +42,15 @@ Configuration
|
|||
Reads the config file synchronously from the file system and try to parse it.
|
||||
|
||||
@private loadConfigFile
|
||||
@param {String} relPath
|
||||
@param {String} configPath
|
||||
*/
|
||||
|
||||
|
||||
loadConfigFile = function(relPath) {
|
||||
loadConfigFile = function(configPath) {
|
||||
var e;
|
||||
_this.config = null;
|
||||
try {
|
||||
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', relPath)));
|
||||
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
|
||||
if (_this.config && _this.config.http_port && _this.config.db_port && _this.config.crypto_key && _this.config.session_secret) {
|
||||
return log.print('CF', 'config file loaded successfully');
|
||||
} else {
|
||||
|
|
@ -61,8 +63,6 @@ Configuration
|
|||
}
|
||||
};
|
||||
|
||||
loadConfigFile(path.join('config', 'config.json'));
|
||||
|
||||
/*
|
||||
Fetch a property from the configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -41,19 +41,26 @@ DB Interface
|
|||
|
||||
|
||||
exports = module.exports = function(args) {
|
||||
var config;
|
||||
var config, _ref;
|
||||
args = args != null ? args : {};
|
||||
log(args);
|
||||
config = require('./config');
|
||||
config(args);
|
||||
_this.crypto_key = config.getCryptoKey();
|
||||
_this.db = redis.createClient(config.getDBPort(), 'localhost', {
|
||||
connect_timeout: 2000
|
||||
});
|
||||
return _this.db.on("error", function(err) {
|
||||
err.addInfo = 'message from DB';
|
||||
return log.error('DB', err);
|
||||
});
|
||||
if ((_ref = _this.db) != null) {
|
||||
_ref.quit();
|
||||
}
|
||||
if (config.isReady()) {
|
||||
_this.crypto_key = config.getCryptoKey();
|
||||
_this.db = redis.createClient(config.getDBPort(), 'localhost', {
|
||||
connect_timeout: 2000
|
||||
});
|
||||
return _this.db.on('error', function(err) {
|
||||
err.addInfo = 'message from DB';
|
||||
return log.error('DB', err);
|
||||
});
|
||||
} else {
|
||||
return log.error('DB', 'Initialization failed because of missing config file!');
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -72,22 +79,38 @@ DB Interface
|
|||
} else {
|
||||
numAttempts = 0;
|
||||
fCheckConnection = function() {
|
||||
var e;
|
||||
if (_this.db.connected) {
|
||||
log.print('DB', 'Successfully connected to DB!');
|
||||
return cb();
|
||||
} else if (numAttempts++ < 10) {
|
||||
return setTimeout(fCheckConnection, 500);
|
||||
return setTimeout(fCheckConnection, 100);
|
||||
} else {
|
||||
e = new Error('Connection to DB failed!');
|
||||
log.error('DB', e);
|
||||
return cb(e);
|
||||
return cb(new Error('Connection to DB failed!'));
|
||||
}
|
||||
};
|
||||
return setTimeout(fCheckConnection, 500);
|
||||
return setTimeout(fCheckConnection, 100);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Abstracts logging for simple action replies from the DB.
|
||||
|
||||
@private replyHandler( *action* )
|
||||
@param {String} action
|
||||
*/
|
||||
|
||||
|
||||
replyHandler = function(action) {
|
||||
return function(err, reply) {
|
||||
if (err) {
|
||||
err.addInfo = 'during "' + action + '"';
|
||||
return log.error('DB', err);
|
||||
} else {
|
||||
return log.print('DB', action + ': ' + reply);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Push an event into the event queue.
|
||||
|
||||
|
|
@ -97,8 +120,12 @@ DB Interface
|
|||
|
||||
|
||||
exports.pushEvent = function(event) {
|
||||
log.print('DB', 'Event pushed into the queue: ' + event.eventid);
|
||||
return _this.db.rpush('event_queue', JSON.stringify(event));
|
||||
if (event) {
|
||||
log.print('DB', 'Event pushed into the queue: ' + event.eventid);
|
||||
return _this.db.rpush('event_queue', JSON.stringify(event));
|
||||
} else {
|
||||
return log.error('DB', 'Why would you give me an empty event...');
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -110,7 +137,24 @@ DB Interface
|
|||
|
||||
|
||||
exports.popEvent = function(cb) {
|
||||
return _this.db.lpop('event_queue', cb);
|
||||
var makeObj;
|
||||
makeObj = function(pcb) {
|
||||
return function(err, obj) {
|
||||
return pcb(err, JSON.parse(obj));
|
||||
};
|
||||
};
|
||||
return _this.db.lpop('event_queue', makeObj(cb));
|
||||
};
|
||||
|
||||
/*
|
||||
Purge the event queue.
|
||||
|
||||
@public purgeEventQueue()
|
||||
*/
|
||||
|
||||
|
||||
exports.purgeEventQueue = function() {
|
||||
return _this.db.del('event_queue', replyHandler('purging event queue'));
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -188,25 +232,6 @@ DB Interface
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Abstracts logging for simple action replies from the DB.
|
||||
|
||||
@private replyHandler( *action* )
|
||||
@param {String} action
|
||||
*/
|
||||
|
||||
|
||||
replyHandler = function(action) {
|
||||
return function(err, reply) {
|
||||
if (err) {
|
||||
err.addInfo = 'during "' + action + '"';
|
||||
return log.error('DB', err);
|
||||
} else {
|
||||
return log.print('DB', action + ': ' + reply);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Fetches all linked data set keys from a linking set, fetches the single data objects
|
||||
via the provided function and returns the results to the callback(err, obj) function.
|
||||
|
|
@ -308,34 +333,34 @@ DB Interface
|
|||
};
|
||||
|
||||
/*
|
||||
Store a string representation of the authentication parameters for an action module.
|
||||
Store user-specific action module parameters .
|
||||
|
||||
@public storeActionAuth( *userId, moduleId, data* )
|
||||
@public storeActionParams( *userId, moduleId, data* )
|
||||
@param {String} userId
|
||||
@param {String} moduleId
|
||||
@param {String} data
|
||||
*/
|
||||
|
||||
|
||||
exports.storeActionAuth = function(userId, moduleId, data) {
|
||||
log.print('DB', 'storeActionAuth: ' + userId + ':' + moduleId);
|
||||
return _this.db.set('action-auth:' + userId + ':' + moduleId, hash(data), replyHandler('storing action auth ' + userId + ':' + moduleId));
|
||||
exports.storeActionParams = function(userId, moduleId, data) {
|
||||
log.print('DB', 'storeActionParams: ' + moduleId + ':' + userId);
|
||||
return _this.db.set('action-params:' + moduleId + ':' + userId, hash(data), replyHandler('storing action params ' + moduleId + ':' + userId));
|
||||
};
|
||||
|
||||
/*
|
||||
Query the DB for an action module authentication token associated to a user
|
||||
Query the DB for user-specific action module parameters,
|
||||
and pass it to the callback(err, obj) function.
|
||||
|
||||
@public getActionAuth( *userId, moduleId, cb* )
|
||||
@public getActionParams( *userId, moduleId, cb* )
|
||||
@param {String} userId
|
||||
@param {String} moduleId
|
||||
@param {function} cb
|
||||
*/
|
||||
|
||||
|
||||
exports.getActionAuth = function(userId, moduleId, cb) {
|
||||
log.print('DB', 'getActionAuth: ' + userId + ':' + moduleId);
|
||||
return _this.db.get('action-auth:' + userId + ':' + moduleId, function(err, data) {
|
||||
exports.getActionParams = function(userId, moduleId, cb) {
|
||||
log.print('DB', 'getActionParams: ' + moduleId + ':' + userId);
|
||||
return _this.db.get('action-params:' + moduleId + ':' + userId, function(err, data) {
|
||||
return cb(err, decrypt(data));
|
||||
});
|
||||
};
|
||||
|
|
@ -397,8 +422,8 @@ DB Interface
|
|||
|
||||
|
||||
exports.storeEventParams = function(userId, moduleId, data) {
|
||||
log.print('DB', 'storeEventParams: ' + userId + ':' + moduleId);
|
||||
return _this.db.set('event-params:' + moduleId + ':' + userId, encrypt(data), replyHandler('storing event auth ' + userId + ':' + moduleId));
|
||||
log.print('DB', 'storeEventParams: ' + moduleId + ':' + userId);
|
||||
return _this.db.set('event-params:' + moduleId + ':' + userId, encrypt(data), replyHandler('storing event auth ' + moduleId + ':' + userId));
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -412,8 +437,8 @@ DB Interface
|
|||
|
||||
|
||||
exports.getEventAuth = function(userId, moduleId, cb) {
|
||||
log.print('DB', 'getEventAuth: ' + userId + ':' + moduleId);
|
||||
return _this.db.get('event-auth:' + userId + ':' + moduleId, function(err, data) {
|
||||
log.print('DB', 'getEventAuth: ' + moduleId + ':' + userId);
|
||||
return _this.db.get('event-auth:' + moduleId + ':' + userId, function(err, data) {
|
||||
return cb(err, decrypt(data));
|
||||
});
|
||||
};
|
||||
|
|
@ -426,18 +451,19 @@ DB Interface
|
|||
/*
|
||||
Store a string representation of a rule in the DB.
|
||||
|
||||
@public storeRule( *id, data* )
|
||||
@param {String} id
|
||||
@public storeRule( *ruleId, userId, data* )
|
||||
@param {String} ruleId
|
||||
@param {String} userId
|
||||
@param {String} data
|
||||
*/
|
||||
|
||||
|
||||
exports.storeRule = function(id, user, data) {
|
||||
log.print('DB', 'storeRule: ' + id);
|
||||
_this.db.sadd('rules', id + ':' + user, replyHandler('storing rule key "' + id + ':' + user + '"'));
|
||||
_this.db.sadd('user:' + user + ':rules', id, replyHandler('storing rule key to "user:' + user + ':rules"'));
|
||||
_this.db.sadd('rule:' + id + ':users', user, replyHandler('storing user key to "rule:' + id + ':users"'));
|
||||
return _this.db.set('rule:' + id + ':' + user, data, replyHandler('storing rule "' + id + ':' + user + '"'));
|
||||
exports.storeRule = function(ruleId, userId, data) {
|
||||
log.print('DB', 'storeRule: ' + ruleId);
|
||||
_this.db.sadd('rules', ruleId + ':' + user, replyHandler('storing rule key "' + ruleId + ':' + user + '"'));
|
||||
_this.db.sadd('user-set:' + user + ':rules', ruleId, replyHandler('storing rule key to "user:' + user + ':rules"'));
|
||||
_this.db.sadd('rule-set:' + ruleId + ':users', user, replyHandler('storing user key to "rule:' + ruleId + ':users"'));
|
||||
return _this.db.set('rule:' + ruleId + ':' + user, data, replyHandler('storing rule "' + ruleId + ':' + user + '"'));
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -495,10 +521,11 @@ DB Interface
|
|||
*/
|
||||
|
||||
|
||||
exports.storeUserRole = function(username, role) {
|
||||
exports.storeUserRole = function(userId, roleId) {
|
||||
log.print('DB', 'storeUserRole: ' + username + ':' + role);
|
||||
_this.db.sadd('user-roles:' + username, role, replyHandler('adding role ' + role + ' to user ' + username));
|
||||
return _this.db.sadd('role-users:' + role, username, replyHandler('adding user ' + username + ' to role ' + role));
|
||||
_this.db.sadd('roles', role, replyHandler('adding role ' + role + ' to role index set'));
|
||||
_this.db.sadd('user:' + userId + ':roles', role, replyHandler('adding role ' + role + ' to user ' + username));
|
||||
return _this.db.sadd('role:' + roleId + ':users', username, replyHandler('adding user ' + username + ' to role ' + role));
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ exports.addRule = function(objRule) {
|
|||
|
||||
function pollQueue() {
|
||||
if(isRunning) {
|
||||
db.popEvent(function (err, text) {
|
||||
if(!err && text) {
|
||||
processEvent(JSON.parse(text));
|
||||
db.popEvent(function (err, obj) {
|
||||
if(!err && obj) {
|
||||
processEvent(obj);
|
||||
}
|
||||
setTimeout(pollQueue, 50); //TODO adapt to load
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ HTTP Listener
|
|||
|
||||
|
||||
(function() {
|
||||
var app, config, exports, express, log, path, qs, requestHandler, sess_sec;
|
||||
var app, config, exports, express, log, path, qs, requestHandler;
|
||||
|
||||
log = require('./logging');
|
||||
|
||||
|
|
@ -26,8 +26,6 @@ HTTP Listener
|
|||
|
||||
app = express();
|
||||
|
||||
sess_sec = '#C[>;j`@".TXm2TA;A2Tg)';
|
||||
|
||||
/*
|
||||
Module call
|
||||
-----------
|
||||
|
|
@ -44,16 +42,23 @@ HTTP Listener
|
|||
log(args);
|
||||
config(args);
|
||||
requestHandler(args);
|
||||
sess_sec = config.getSessionSecret() || sess_sec;
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/*
|
||||
Adds the shutdown handler to the admin commands.
|
||||
|
||||
@param {function} fshutDown
|
||||
@public addHandlers( *fShutDown* )
|
||||
*/
|
||||
|
||||
|
||||
exports.addHandlers = function(fShutDown) {
|
||||
var e, http_port;
|
||||
requestHandler.addHandlers(fShutDown);
|
||||
app.use(express.cookieParser());
|
||||
app.use(express.session({
|
||||
secret: sess_sec
|
||||
secret: config.getSessionSecret()
|
||||
}));
|
||||
log.print('HL', 'no session backbone');
|
||||
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
|
||||
|
|
@ -79,6 +84,13 @@ HTTP Listener
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Shuts down the http listener.
|
||||
|
||||
@public shutDown()
|
||||
*/
|
||||
|
||||
|
||||
exports.shutDown = function() {
|
||||
log.print('HL', 'Shutting down HTTP listener');
|
||||
return process.exit();
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ TODO how about we allow spawning child processes with servers based on address?
|
|||
|
||||
init = function() {
|
||||
log.print('RS', 'STARTING SERVER');
|
||||
conf(args);
|
||||
if (!conf.isReady()) {
|
||||
log.error('RS', 'Config file not ready!');
|
||||
process.exit();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
var cs = require('coffee-script');
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
log = require('./logging');
|
||||
|
|
@ -12,6 +13,10 @@ exports = module.exports = function(args) {
|
|||
|
||||
exports.requireFromString = function(src, name, dir) {
|
||||
if(!dir) dir = __dirname;
|
||||
|
||||
// Allow coffee scripts!
|
||||
console.log(cs.compile(src));
|
||||
|
||||
var id = path.resolve(dir, name, name + '.vm');
|
||||
var vm = require('vm'),
|
||||
sandbox = {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@
|
|||
var urlService = 'https://probinder.com/service/',
|
||||
credentials = null;
|
||||
|
||||
exports.validUserParams = function() {
|
||||
|
||||
}
|
||||
|
||||
function loadCredentials(cred) {
|
||||
if(!cred || !cred.username || !cred.password) {
|
||||
console.error('ERROR: ProBinder AM credentials file corrupt');
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
"needle": "0.6.1",
|
||||
"nodeunit": "0.8.2",
|
||||
"redis": "0.9.0",
|
||||
"request": "2.27.0"
|
||||
"request": "2.27.0",
|
||||
"coffee-script": "1.6.3"
|
||||
},
|
||||
"__comment": {
|
||||
"dependencies": {
|
||||
|
|
|
|||
5
sandbox.js
Normal file
5
sandbox.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
var cs = require('coffee-script');
|
||||
var fs = require('fs');
|
||||
var csSrc = fs.readFileSync('coffee/config.coffee', { encoding: "utf-8" });
|
||||
// csSrc = "log = require './logging'";
|
||||
console.log(cs.compile(csSrc));
|
||||
6
testing/jsonWrongConfig.json
Normal file
6
testing/jsonWrongConfig.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"http_port": 2,
|
||||
"db_port": 9,
|
||||
"crypto_key": "",
|
||||
"session_secret": ""
|
||||
}
|
||||
|
|
@ -1,20 +1,32 @@
|
|||
exports.testRequire = (test) ->
|
||||
conf = require '../js-coffee/config'
|
||||
conf { logType: 2 }
|
||||
test.ok conf.isReady(), 'File exists'
|
||||
conf { relPath: 'wrongpath' }
|
||||
test.strictEqual conf.isReady(), false
|
||||
|
||||
exports.setUp = ( cb ) =>
|
||||
@conf = require '../js-coffee/config'
|
||||
@conf
|
||||
logType: 2
|
||||
cb()
|
||||
|
||||
exports.testRequire = ( test ) =>
|
||||
test.expect 1
|
||||
test.ok @conf.isReady(), 'File does not exist!'
|
||||
test.done()
|
||||
|
||||
exports.testParametersReady = (test) ->
|
||||
exports.testParameters = ( test ) =>
|
||||
test.expect 4
|
||||
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'
|
||||
test.ok @conf.getDBPort(), 'DB port does not exist!'
|
||||
test.ok @conf.getCryptoKey(), 'Crypto key does not exist!'
|
||||
test.ok @conf.getSessionSecret(), 'Session Secret does not exist!'
|
||||
test.done()
|
||||
|
||||
conf = require '../js-coffee/config'
|
||||
conf { logType: 2 }
|
||||
console.log conf
|
||||
test.ok conf.getHttpPort(), 'HTTP port exists'
|
||||
test.ok conf.getDBPort(), 'DB port exists'
|
||||
test.ok conf.getCryptoKey(), 'Crypto key exists'
|
||||
test.ok conf.getSessionSecret(), 'Session Secret exists'
|
||||
exports.testDifferentConfigFile = ( test ) =>
|
||||
test.expect 1
|
||||
@conf
|
||||
configPath: 'testing/jsonWrongConfig.json'
|
||||
test.ok @conf.isReady(), 'Different path not loaded!'
|
||||
test.done()
|
||||
|
||||
test.done()
|
||||
exports.testNoConfigFile = ( test ) =>
|
||||
test.expect 1
|
||||
@conf
|
||||
configPath: 'wrongpath.file'
|
||||
test.strictEqual @conf.isReady(), false, 'Wrong path still loaded!'
|
||||
test.done()
|
||||
|
|
|
|||
|
|
@ -1,30 +1,45 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
exports.testRequire = function(test) {
|
||||
var conf;
|
||||
conf = require('../js-coffee/config');
|
||||
conf({
|
||||
var _this = this;
|
||||
|
||||
exports.setUp = function(cb) {
|
||||
_this.conf = require('../js-coffee/config');
|
||||
_this.conf({
|
||||
logType: 2
|
||||
});
|
||||
test.ok(conf.isReady(), 'File exists');
|
||||
conf({
|
||||
relPath: 'wrongpath'
|
||||
});
|
||||
test.strictEqual(conf.isReady(), false);
|
||||
return cb();
|
||||
};
|
||||
|
||||
exports.testRequire = function(test) {
|
||||
test.expect(1);
|
||||
test.ok(_this.conf.isReady(), 'File does not exist!');
|
||||
return test.done();
|
||||
};
|
||||
|
||||
exports.testParametersReady = function(test) {
|
||||
var conf;
|
||||
conf = require('../js-coffee/config');
|
||||
conf({
|
||||
logType: 2
|
||||
exports.testParameters = function(test) {
|
||||
test.expect(4);
|
||||
test.ok(_this.conf.getHttpPort(), 'HTTP port does not exist!');
|
||||
test.ok(_this.conf.getDBPort(), 'DB port does not exist!');
|
||||
test.ok(_this.conf.getCryptoKey(), 'Crypto key does not exist!');
|
||||
test.ok(_this.conf.getSessionSecret(), 'Session Secret does not exist!');
|
||||
return test.done();
|
||||
};
|
||||
|
||||
exports.testDifferentConfigFile = function(test) {
|
||||
test.expect(1);
|
||||
_this.conf({
|
||||
configPath: 'testing/jsonWrongConfig.json'
|
||||
});
|
||||
console.log(conf);
|
||||
test.ok(conf.getHttpPort(), 'HTTP port exists');
|
||||
test.ok(conf.getDBPort(), 'DB port exists');
|
||||
test.ok(conf.getCryptoKey(), 'Crypto key exists');
|
||||
test.ok(conf.getSessionSecret(), 'Session Secret exists');
|
||||
test.ok(_this.conf.isReady(), 'Different path not loaded!');
|
||||
return test.done();
|
||||
};
|
||||
|
||||
exports.testNoConfigFile = function(test) {
|
||||
test.expect(1);
|
||||
_this.conf({
|
||||
configPath: 'wrongpath.file'
|
||||
});
|
||||
test.strictEqual(_this.conf.isReady(), false, 'Wrong path still loaded!');
|
||||
return test.done();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,128 @@
|
|||
exports.testRequire = (test) ->
|
||||
db = require '../js-coffee/db_interface'
|
||||
test.ok db, 'DB interface loaded'
|
||||
db { logType: 2 }
|
||||
test.ok conf.isReady(), 'File exists'
|
||||
|
||||
test.ok conf.getHttpPort(), 'HTTP port exists'
|
||||
test.ok conf.getDBPort(), 'DB port exists'
|
||||
test.ok conf.getCryptoKey(), 'Crypto key exists'
|
||||
test.ok conf.getSessionSecret(), 'Session Secret exists'
|
||||
exports.setUp = ( cb ) =>
|
||||
@db = require '../js-coffee/db_interface'
|
||||
@db logType: 2
|
||||
cb()
|
||||
|
||||
conf { relPath: 'wrongpath' }
|
||||
test.strictEqual conf.isReady(), false
|
||||
|
||||
test.done()
|
||||
exports.availability =
|
||||
testRequire: ( test ) =>
|
||||
test.expect 1
|
||||
test.ok @db, 'DB interface loaded'
|
||||
test.done()
|
||||
|
||||
testConnect: ( test ) =>
|
||||
test.expect 1
|
||||
@db.isConnected ( err ) ->
|
||||
test.ifError err, 'Connection failed!'
|
||||
test.done()
|
||||
|
||||
testNoConfig: ( test ) =>
|
||||
test.expect 1
|
||||
@db
|
||||
configPath: 'nonexistingconf.file'
|
||||
@db.isConnected ( err ) ->
|
||||
test.ok err, 'Still connected!?'
|
||||
test.done()
|
||||
|
||||
testWrongConfig: ( test ) =>
|
||||
test.expect 1
|
||||
@db { configPath: 'testing/jsonWrongConfig.json' }
|
||||
@db.isConnected ( err ) ->
|
||||
test.ok err, 'Still connected!?'
|
||||
test.done()
|
||||
|
||||
testPurgeQueue: ( test ) =>
|
||||
test.expect 2
|
||||
@db.pushEvent @evt1
|
||||
@db.purgeEventQueue()
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during pop after purging!'
|
||||
test.strictEqual obj, null, 'There was an event in the queue!?'
|
||||
test.done()
|
||||
|
||||
exports.events =
|
||||
setUp: ( cb ) =>
|
||||
@evt1 =
|
||||
eventid: '1'
|
||||
event: 'mail'
|
||||
@evt2 =
|
||||
eventid: '2'
|
||||
event: 'mail'
|
||||
@db.purgeEventQueue()
|
||||
cb()
|
||||
|
||||
testEmptyPopping: ( test ) =>
|
||||
test.expect 2
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during pop after purging!'
|
||||
test.strictEqual obj, null, 'There was an event in the queue!?'
|
||||
test.done()
|
||||
|
||||
testEmptyPushing: ( test ) =>
|
||||
test.expect 2
|
||||
@db.pushEvent null
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during non-empty pushing!'
|
||||
test.strictEqual obj, null, 'There was an event in the queue!?'
|
||||
test.done()
|
||||
|
||||
testPushing: ( test ) =>
|
||||
test.expect 1
|
||||
fPush = ->
|
||||
@db.pushEvent null
|
||||
@db.pushEvent @evt1
|
||||
test.throws fPush, Error, 'This should not throw an error'
|
||||
test.done()
|
||||
|
||||
testNonEmptyPopping: ( test ) =>
|
||||
test.expect 3
|
||||
@db.pushEvent @evt1
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during non-empty popping!'
|
||||
test.notStrictEqual obj, null, 'There was no event in the queue!'
|
||||
test.deepEqual @evt1, obj, 'Wrong event in queue!'
|
||||
test.done()
|
||||
|
||||
testMultiplePushAndPops: ( test ) =>
|
||||
test.expect 6
|
||||
numForks = 2
|
||||
isFinished = () ->
|
||||
test.done() if --numForks is 0
|
||||
|
||||
@db.pushEvent @evt1
|
||||
@db.pushEvent @evt2
|
||||
# eventually it would be wise to not care about the order of events
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during multiple push and pop!'
|
||||
test.notStrictEqual obj, null, 'There was no event in the queue!'
|
||||
test.deepEqual @evt1, obj, 'Wrong event in queue!'
|
||||
isFinished()
|
||||
@db.popEvent ( err, obj ) =>
|
||||
test.ifError err, 'Error during multiple push and pop!'
|
||||
test.notStrictEqual obj, null, 'There was no event in the queue!'
|
||||
test.deepEqual @evt2, obj, 'Wrong event in queue!'
|
||||
isFinished()
|
||||
|
||||
exports.action_modules =
|
||||
test: (test) =>
|
||||
test.ok false, 'implement testing!'
|
||||
test.done()
|
||||
|
||||
exports.event_modules =
|
||||
test: (test) =>
|
||||
test.done()
|
||||
|
||||
|
||||
exports.rules =
|
||||
test: (test) =>
|
||||
test.done()
|
||||
|
||||
exports.users =
|
||||
test: (test) =>
|
||||
test.done()
|
||||
|
||||
|
||||
|
||||
exports.tearDown = ( cb ) =>
|
||||
@db.shutDown()
|
||||
cb()
|
||||
|
|
@ -1,22 +1,164 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
exports.testRequire = function(test) {
|
||||
var db;
|
||||
db = require('../js-coffee/db_interface');
|
||||
test.ok(db, 'DB interface loaded');
|
||||
db({
|
||||
var _this = this;
|
||||
|
||||
exports.setUp = function(cb) {
|
||||
_this.db = require('../js-coffee/db_interface');
|
||||
_this.db({
|
||||
logType: 2
|
||||
});
|
||||
test.ok(conf.isReady(), 'File exists');
|
||||
test.ok(conf.getHttpPort(), 'HTTP port exists');
|
||||
test.ok(conf.getDBPort(), 'DB port exists');
|
||||
test.ok(conf.getCryptoKey(), 'Crypto key exists');
|
||||
test.ok(conf.getSessionSecret(), 'Session Secret exists');
|
||||
conf({
|
||||
relPath: 'wrongpath'
|
||||
});
|
||||
test.strictEqual(conf.isReady(), false);
|
||||
return test.done();
|
||||
return cb();
|
||||
};
|
||||
|
||||
exports.availability = {
|
||||
testRequire: function(test) {
|
||||
test.expect(1);
|
||||
test.ok(_this.db, 'DB interface loaded');
|
||||
return test.done();
|
||||
},
|
||||
testConnect: function(test) {
|
||||
test.expect(1);
|
||||
return _this.db.isConnected(function(err) {
|
||||
test.ifError(err, 'Connection failed!');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testNoConfig: function(test) {
|
||||
test.expect(1);
|
||||
_this.db({
|
||||
configPath: 'nonexistingconf.file'
|
||||
});
|
||||
return _this.db.isConnected(function(err) {
|
||||
test.ok(err, 'Still connected!?');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testWrongConfig: function(test) {
|
||||
test.expect(1);
|
||||
_this.db({
|
||||
configPath: 'testing/jsonWrongConfig.json'
|
||||
});
|
||||
return _this.db.isConnected(function(err) {
|
||||
test.ok(err, 'Still connected!?');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testPurgeQueue: function(test) {
|
||||
test.expect(2);
|
||||
_this.db.pushEvent(_this.evt1);
|
||||
_this.db.purgeEventQueue();
|
||||
return _this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during pop after purging!');
|
||||
test.strictEqual(obj, null, 'There was an event in the queue!?');
|
||||
return test.done();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.events = {
|
||||
setUp: function(cb) {
|
||||
_this.evt1 = {
|
||||
eventid: '1',
|
||||
event: 'mail'
|
||||
};
|
||||
_this.evt2 = {
|
||||
eventid: '2',
|
||||
event: 'mail'
|
||||
};
|
||||
_this.db.purgeEventQueue();
|
||||
return cb();
|
||||
},
|
||||
testEmptyPopping: function(test) {
|
||||
test.expect(2);
|
||||
return _this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during pop after purging!');
|
||||
test.strictEqual(obj, null, 'There was an event in the queue!?');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testEmptyPushing: function(test) {
|
||||
test.expect(2);
|
||||
_this.db.pushEvent(null);
|
||||
return _this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during non-empty pushing!');
|
||||
test.strictEqual(obj, null, 'There was an event in the queue!?');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testPushing: function(test) {
|
||||
var fPush;
|
||||
test.expect(1);
|
||||
fPush = function() {
|
||||
this.db.pushEvent(null);
|
||||
return this.db.pushEvent(this.evt1);
|
||||
};
|
||||
test.throws(fPush, Error, 'This should not throw an error');
|
||||
return test.done();
|
||||
},
|
||||
testNonEmptyPopping: function(test) {
|
||||
test.expect(3);
|
||||
_this.db.pushEvent(_this.evt1);
|
||||
return _this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during non-empty popping!');
|
||||
test.notStrictEqual(obj, null, 'There was no event in the queue!');
|
||||
test.deepEqual(_this.evt1, obj, 'Wrong event in queue!');
|
||||
return test.done();
|
||||
});
|
||||
},
|
||||
testMultiplePushAndPops: function(test) {
|
||||
var isFinished, numForks;
|
||||
test.expect(6);
|
||||
numForks = 2;
|
||||
isFinished = function() {
|
||||
if (--numForks === 0) {
|
||||
return test.done();
|
||||
}
|
||||
};
|
||||
_this.db.pushEvent(_this.evt1);
|
||||
_this.db.pushEvent(_this.evt2);
|
||||
_this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during multiple push and pop!');
|
||||
test.notStrictEqual(obj, null, 'There was no event in the queue!');
|
||||
test.deepEqual(_this.evt1, obj, 'Wrong event in queue!');
|
||||
return isFinished();
|
||||
});
|
||||
return _this.db.popEvent(function(err, obj) {
|
||||
test.ifError(err, 'Error during multiple push and pop!');
|
||||
test.notStrictEqual(obj, null, 'There was no event in the queue!');
|
||||
test.deepEqual(_this.evt2, obj, 'Wrong event in queue!');
|
||||
return isFinished();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.action_modules = {
|
||||
test: function(test) {
|
||||
test.ok(false, 'implement testing!');
|
||||
return test.done();
|
||||
}
|
||||
};
|
||||
|
||||
exports.event_modules = {
|
||||
test: function(test) {
|
||||
return test.done();
|
||||
}
|
||||
};
|
||||
|
||||
exports.rules = {
|
||||
test: function(test) {
|
||||
return test.done();
|
||||
}
|
||||
};
|
||||
|
||||
exports.users = {
|
||||
test: function(test) {
|
||||
return test.done();
|
||||
}
|
||||
};
|
||||
|
||||
exports.tearDown = function(cb) {
|
||||
_this.db.shutDown();
|
||||
return cb();
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
<div id="menubar">
|
||||
<div id="menubar_menu">menu</div>
|
||||
<div id="menubar_logout">logout</div>
|
||||
<div id="menubar_modules">forge modules</div>
|
||||
<div id="menubar_rules">forge rules</div>
|
||||
<div id="menubar_event">invoke events</div>
|
||||
<div id="menubar_logout">logout</div>
|
||||
<script>
|
||||
$('#menubar_logout').click(function() {
|
||||
$('#menubar_modules').click(function() {
|
||||
window.location.href = 'forge_modules';
|
||||
});
|
||||
$('#menubar_rules').click(function() {
|
||||
window.location.href = 'forge_rules';
|
||||
});
|
||||
$('#menubar_event').click(function() {
|
||||
window.location.href = 'invoke_event';
|
||||
});
|
||||
$('#menubar_logout').click(function() {
|
||||
$.post('/logout').done(function() {
|
||||
window.location.href = document.URL;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,20 +21,15 @@ textarea {
|
|||
background-color: #DDD;
|
||||
}
|
||||
|
||||
#menubar_menu {
|
||||
float: left;
|
||||
margin:0 auto;
|
||||
#menubar div {
|
||||
height: 100%;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#menubar_logout {
|
||||
height: 100%;
|
||||
float: right;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#menubar_logout:hover {
|
||||
#menubar div:hover {
|
||||
background-color: #AAA;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue