blob: 7242f074d3da38700c5eda5dfcfe0bc32192755e [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
module.exports = {
setupApp: setupApp,
setupDatabase: setupDatabase,
setupService: setupService,
setupSyncGroup: setupSyncGroup,
setupTable: setupTable,
assertScanRows: assertScanRows,
testGetSetPermissions: testGetSetPermissions,
uniqueName: uniqueName
};
var deepEqual = require('deep-equal');
var extend = require('xtend');
var streamToArray = require('stream-to-array');
var vanadium = require('vanadium');
var syncbase = require('../..');
var syncbaseSuffix = syncbase.syncbaseSuffix;
var SERVICE_NAME = require('./service-name');
// Helper function to generate unique names.
var nameCounter = Date.now();
function uniqueName(prefix) {
prefix = prefix || 'name';
return prefix + '_' + nameCounter++;
}
// Initializes Vanadium runtime.
function setupService(t, cb) {
vanadium.init(function(err, rt) {
if (err) {
return cb(err);
}
function teardown(cb) {
rt.close(function(err) {
t.error(err, 'rt.close should not error.');
cb(null);
});
}
var service = syncbase.newService(SERVICE_NAME);
return cb(null, {
ctx: rt.getContext(),
rt: rt,
service: service,
teardown: teardown
});
});
}
// Initializes Vanadium runtime and creates an App.
function setupApp(t, cb) {
setupService(t, function(err, o) {
if (err) {
return cb(err);
}
var app = o.service.app(uniqueName('app'));
app.create(o.ctx, {}, function(err) {
if (err) {
o.rt.close(t.error);
return cb(err);
}
return cb(null, extend(o, {
app: app
}));
});
});
}
// Initializes Vanadium runtime and creates an App and a Database.
function setupDatabase(t, cb) {
setupApp(t, function(err, o) {
if (err) {
return cb(err);
}
var db = o.app.noSqlDatabase(uniqueName('db'));
db.create(o.ctx, {}, function(err) {
if (err) {
o.rt.close(t.error);
return cb(err);
}
return cb(null, extend(o, {
database: db
}));
});
});
}
// Initializes Vanadium runtime and creats an App, Database and SyncGroup.
function setupSyncGroup(t, perms, prefixes, cb) {
setupDatabase(t, function(err, o) {
if (err) {
return cb(err);
}
var sgName = uniqueName('syncgroup');
var fullSgName = vanadium.naming.join(o.service.fullName,
syncbaseSuffix,
sgName);
// TODO(nlacasse): Where does this magic number 8 come from? It's in
// syncgroup_test.go.
var myInfo = new syncbase.nosql.SyncGroupMemberInfo({
syncPriority: 8
});
var spec = new syncbase.nosql.SyncGroupSpec({
description: 'test syncgroup ' + fullSgName,
perms: perms,
prefixes: prefixes
});
var sg = o.database.syncGroup(fullSgName);
sg.create(o.ctx, spec, myInfo, function(err) {
if (err) {
o.rt.close(t.error);
return cb(err);
}
return cb(null, extend(o, {
syncgroup: sg
}));
});
});
}
// Initializes Vanadium runtime and creates an App, a Database and a Table.
function setupTable(t, cb) {
setupDatabase(t, function(err, o) {
if (err) {
return cb(err);
}
var db = o.database;
var tableName = uniqueName('table');
db.createTable(o.ctx, tableName, {}, function(err) {
if (err) {
o.rt.close(t.error);
return cb(err);
}
return cb(null, extend(o, {
table: db.table(tableName)
}));
});
});
}
// Assert that two permissions objects are equal.
function assertPermissionsEqual(t, got, want) {
t.equal(got.size, want.size, 'Permissions size matches');
want.forEach(function(value, key) {
t.deepEqual(got.get(key), value, 'Permission value matches');
});
}
// For any object that implements get/setPermissions, test that getting and
// setting permissions behaves as it should.
function testGetSetPermissions(t, ctx, obj, cb) {
obj.getPermissions(ctx, function(err, perms, version) {
if (err) {
t.error('error getting permissions ' + err);
return cb(err);
}
t.ok(perms, 'Has permissions');
t.ok(version, 'Has a version');
var newPerms = new Map([
['Read', {
'in': ['...', 'canRead'],
'notIn': ['cantRead']
}],
['Write', {
'in': ['...', 'canWrite'],
'notIn': ['cantWrite']
}],
['Admin', {
'in': ['...', 'canAdmin'],
'notIn': ['cantAdmin']
}]
]);
obj.setPermissions(ctx, newPerms, version, function(err) {
if (err) {
t.error('error setting permissions ' + err);
return cb(err);
}
obj.getPermissions(ctx, function(err, gotPerms, gotVersion) {
if (err) {
t.error('error getting permissions ' + err);
return cb(err);
}
t.ok(perms, 'Has permissions');
t.ok(version, 'Has a version');
t.notEqual(version, gotVersion, 'should have a new version');
assertPermissionsEqual(t, gotPerms, newPerms);
return cb(null);
});
});
});
}
function compareRows(r1, r2) {
if (r1.key > r2.key) {
return 1;
}
if (r1.key < r2.key) {
return -1;
}
if (r1.value > r2.value) {
return 1;
}
if (r1.value < r2.value) {
return -1;
}
return 0;
}
function assertScanRows(ctx, table, range, wantRows, cb) {
var stream = table.scan(ctx, range, function(err) {
if (err) {
return cb(err);
}
});
streamToArray(stream, function(err, rows) {
if (err) {
return cb(err);
}
rows = rows || [];
rows.sort(compareRows);
wantRows.sort(compareRows);
if (!deepEqual(rows, wantRows)) {
var error = new Error('Expected rows to be ' + JSON.stringify(wantRows) +
' but got ' + JSON.stringify(rows));
return cb(error);
}
cb(null);
});
}