UNPKG

smc-hub

Version:

CoCalc: Backend webserver component

1,801 lines (1,782 loc) 54.9 kB
// Generated by CoffeeScript 2.5.1 (function() { //######################################################################## // This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. // License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details //######################################################################## /* TESTING of user queries specifically involving changefeeds - part 2 -- projects, ....? COPYRIGHT : (c) 2017 SageMath, Inc. LICENSE : AGPLv3 */ var async, changefeed_series, create_accounts, create_projects, db, expect, misc, pgtest, setup, teardown; async = require('async'); expect = require('expect'); pgtest = require('./pgtest'); db = void 0; setup = function(cb) { return pgtest.setup(function(err) { db = pgtest.db; return cb(err); }); }; teardown = pgtest.teardown; ({create_accounts, create_projects, changefeed_series} = pgtest); misc = require('smc-util/misc'); describe('very basic test of projects table', function() { this.timeout(10000); before(setup); after(teardown); return it('creates account, project feed, a project, and see it appear', function(done) { var accounts, changefeed_id, projects; changefeed_id = misc.uuid(); accounts = void 0; projects = []; return async.series([ function(cb) { return create_accounts(1, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return db.user_query({ account_id: accounts[0], query: { projects: [ { project_id: null, title: null, users: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { expect(x.projects.length).toEqual(0); return create_projects(1, accounts[0], function(err, v) { projects.push(v[0]); return cb(err); }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[0], title: 'Project 0', users: { [`${accounts[0]}`]: { group: "owner" } } } }); // Test removing user from the project return db.remove_user_from_project({ account_id: accounts[0], project_id: projects[0], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[0], title: 'Project 0', users: {} } }); return cb(); }, function(x, cb) { expect(x).toEqual({ action: 'delete', old_val: { project_id: projects[0] } }); // Test adding user back to the project return db.add_user_to_project({ account_id: accounts[0], project_id: projects[0], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[0], title: 'Project 0', users: { [`${accounts[0]}`]: { group: "collaborator" } } } }); // create another project return create_projects(1, accounts[0], function(err, v) { projects.push(v[0]); return cb(err); }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[1], title: 'Project 0', users: { [`${accounts[0]}`]: { group: "owner" } } } }); cb(); // Test actually deleting project completely from database return db._query({ query: "DELETE FROM projects", where: { "project_id = $::UUID": projects[1] }, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'delete', old_val: { project_id: projects[1] } }); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); } ], done); }); }); describe('create multiple projects with multiple collaborators', function() { var log; before(setup); after(teardown); //log = console.log log = function() {}; return it('create 3 accounts and several projects, and see them appear in one projects feed properly', function(done) { var accounts, changefeed_id, projects; accounts = void 0; projects = []; changefeed_id = misc.uuid(); return async.series([ function(cb) { return create_accounts(3, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return db.user_query({ account_id: accounts[0], query: { projects: [ { project_id: null, users: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { expect(x.projects.length).toEqual(0); log('create first project'); return create_projects(1, accounts[0], function(err, v) { projects.push(v[0]); return cb(err); }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[0], users: { [`${accounts[0]}`]: { group: "owner" } } } }); log('create another project'); return create_projects(1, accounts[0], function(err, v) { projects.push(v[0]); return cb(err); }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[1], users: { [`${accounts[0]}`]: { group: "owner" } } } }); log('create a project that will get ignored by the feed...'); return create_projects(1, accounts[1], function(err, v) { if (err) { cb(err); return; } projects.push(v[0]); log('... until we add the first user to it, in which case....'); return db.add_user_to_project({ project_id: v[0], account_id: accounts[0], cb: cb }); }); }, function(x, cb) { log('... it appears!'); expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[2], users: { [`${accounts[0]}`]: { group: "collaborator" }, [`${accounts[1]}`]: { group: "owner" } } } }); log('Now add another collaborator'); return db.add_user_to_project({ project_id: projects[2], account_id: accounts[2], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[2], users: { [`${accounts[0]}`]: { group: "collaborator" }, [`${accounts[1]}`]: { group: "owner" }, [`${accounts[2]}`]: { group: "collaborator" } } } }); log('Now take first user back off'); return db.remove_user_from_project({ project_id: projects[2], account_id: accounts[0], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'update', new_val: { project_id: projects[2], users: { [`${accounts[1]}`]: { group: "owner" }, [`${accounts[2]}`]: { group: "collaborator" } } } }); return cb(); }, function(x, cb) { expect(x).toEqual({ action: 'delete', old_val: { project_id: projects[2] } }); log('cancel feed'); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); } ], done); }); }); describe('changefeed on a single project', function() { before(setup); after(teardown); return it('make 2 projects, feed on single, remove and add user', function(done) { var accounts, changefeed_id, projects; changefeed_id = misc.uuid(); accounts = projects = void 0; return async.series([ function(cb) { return create_accounts(1, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { // make 2 projects; one will be comletely ignored return create_projects(2, accounts[0], function(err, v) { projects = v; return cb(err); }); }, function(cb) { return db.user_query({ account_id: accounts[0], query: { projects: [ { project_id: projects[0], description: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { expect(x.projects.length).toEqual(1); return db.remove_user_from_project({ project_id: projects[0], account_id: accounts[0], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'delete', old_val: { project_id: projects[0] } }); return db.add_user_to_project({ project_id: projects[0], account_id: accounts[0], cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: projects[0], description: "Description 0" } }); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); } ], done); }); }); describe('changefeed testing all projects fields', function() { before(setup); after(teardown); return it('make 2 projects, feed, and edit all fields', function(done) { var accounts, changefeed_id, last_edited, obj0, projects, user_query; changefeed_id = misc.uuid(); accounts = projects = void 0; obj0 = void 0; last_edited = void 0; user_query = function(opts) { opts.account_id = accounts[0]; return db.user_query(opts); }; return async.series([ function(cb) { return create_accounts(1, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { // make 2 projects return create_projects(2, accounts[0], function(err, v) { projects = v; return cb(err); }); }, function(cb) { return user_query({ query: { projects: [ { project_id: null, title: null, description: null, users: null, invite: null, invite_requests: null, deleted: null, host: null, settings: null, status: null, state: null, last_edited: null, last_active: null, action_request: null, course: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { var i, len, p, ref; expect(x.projects.length).toEqual(2); ref = x.projects; for (i = 0, len = ref.length; i < len; i++) { p = ref[i]; if (p.project_id === projects[0]) { obj0 = p; } } return user_query({ query: { projects: { project_id: projects[0], title: "Foo", description: "bar" } }, cb: cb }); }, function(x, cb) { obj0.title = 'Foo'; obj0.description = 'bar'; expect(x).toEqual({ action: 'insert', new_val: obj0 }); return user_query({ query: { projects: { project_id: projects[0], deleted: true } }, cb: cb }); }, function(x, cb) { obj0.deleted = true; expect(x.action).toEqual('update'); expect(x.new_val.deleted).toEqual(obj0.deleted); obj0.action_request = { action: 'test', started: new Date() }; return user_query({ query: { projects: { project_id: projects[0], action_request: obj0.action_request } }, cb: cb }); }, function(x, cb) { expect(x.action).toEqual('update'); expect(x.new_val.action_request).toEqual(obj0.action_request); obj0.last_edited = new Date(); return db._query({ query: "UPDATE projects", set: { last_edited: obj0.last_edited }, where: { project_id: projects[0] }, cb: cb }); }, function(x, cb) { var set; expect(x.action).toEqual('update'); expect(x.new_val.last_edited).toEqual(obj0.last_edited); set = { invite: { a: 'map' }, invite_requests: { b: 'map2' }, host: { host: 'compute0-us' }, status: { c: 'map3' }, state: { d: 'map4' }, last_active: { [`${accounts[0]}`]: new Date() }, course: { project_id: obj0.project_id } }; misc.merge(obj0, set); return db._query({ query: "UPDATE projects", set: set, where: { project_id: projects[0] }, cb: cb }); }, function(x, cb) { var field, i, len, ref; expect(x.action).toEqual('update'); ref = ['invite', 'invite_requests', 'host', 'status', 'state', 'last_active', 'course']; for (i = 0, len = ref.length; i < len; i++) { field = ref[i]; expect(x.new_val[field]).toEqual(obj0[field]); } return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); } ], done); }); }); describe('testing a changefeed from a project (instead of account)', function() { before(setup); after(teardown); return it('makes a projects, has project get a feed and see changes', function(done) { var accounts, changefeed_id, obj, projects; changefeed_id = misc.uuid(); accounts = projects = obj = void 0; return async.series([ function(cb) { return create_accounts(1, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return create_projects(1, accounts[0], (function(err, v) { projects = v; return cb(err); })); }, function(cb) { return db.user_query({ project_id: projects[0], query: { projects: [ { project_id: projects[0], title: null, description: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { obj = { description: 'Description 0', project_id: projects[0], title: 'Project 0' }; expect(x.projects).toEqual([obj]); obj.title = 'Title'; obj.description = 'Description'; return db.user_query({ project_id: projects[0], query: { projects: obj }, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: obj }); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); } ], done); }); }); describe('test changefeed admin-only access to project', function() { var accounts, project_id; before(setup); after(teardown); accounts = project_id = void 0; it('set things up', function(done) { return async.series([ function(cb) { return create_accounts(3, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return db.make_user_admin({ account_id: accounts[0], cb: cb }); }, function(cb) { return create_projects(1, accounts[2], (function(err, v) { project_id = v[0]; return cb(err); })); } ], done); }); it('tests writing to project as admin user', function(done) { return db.user_query({ account_id: accounts[0], query: { projects: { project_id: project_id, title: "Better Title" } }, cb: done }); }); it('tests writing to project_admin as admin user', function(done) { return db.user_query({ account_id: accounts[0], query: { projects_admin: { project_id: project_id, title: "Better Title" } }, cb: function(err) { expect(err).toEqual("FATAL: user set queries not allowed for table 'projects_admin'"); return done(); } }); }); it('tests project title changed properly (so reading as admin)', function(done) { return db.user_query({ account_id: accounts[0], query: { projects: { project_id: project_id, title: null } }, cb: function(err, x) { expect(x).toEqual({ projects: { project_id: project_id, title: "Better Title" } }); return done(err); } }); }); it('tests writing to project as non-collab', function(done) { return db.user_query({ account_id: accounts[1], query: { projects: { project_id: project_id, title: "Even Better Title" } }, cb: function(err) { expect(err).toEqual('FATAL: user must be an admin'); return done(); } }); }); it('tests reading from project as non-collab', function(done) { return db.user_query({ account_id: accounts[1], query: { projects: { project_id: project_id, title: null } }, cb: function(err) { expect(err).toEqual('FATAL: you do not have read access to this project'); return done(); } }); }); it('tests writing to project as anonymous', function(done) { return db.user_query({ query: { projects: { project_id: project_id, title: null } }, cb: function(err) { expect(err).toEqual("FATAL: anonymous get queries not allowed for table 'projects'"); return done(); } }); }); it('tests admin changefeed on projects_admin table', function(done) { var changefeed_id; changefeed_id = misc.uuid(); return db.user_query({ account_id: accounts[0], query: { projects_admin: [ { project_id: project_id, title: null } ] }, changes: changefeed_id, cb: changefeed_series([ function(x, cb) { expect(x.projects_admin).toEqual([ { project_id: project_id, title: 'Better Title' } ]); return db.user_query({ account_id: accounts[0], query: { projects: { project_id: project_id, title: "WAY Better Title" } }, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: project_id, title: "WAY Better Title" } }); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], done) }); }); return it('tests that FATAL: user must be an admin to read from (or get changefeed on) projects_admin table', function(done) { var changefeed_id; changefeed_id = misc.uuid(); return db.user_query({ account_id: accounts[1], query: { projects_admin: [ { project_id: project_id, title: null } ] }, changes: changefeed_id, cb: function(err) { expect(err).toEqual('FATAL: user must be an admin'); return done(); } }); }); }); describe('test public_projects table -- ', function() { var accounts, project_id, tests; before(setup); after(teardown); accounts = project_id = void 0; it('set things up', function(done) { return async.series([ function(cb) { return create_accounts(2, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return create_projects(1, accounts[0], (function(err, v) { project_id = v[0]; return cb(err); })); } ], done); }); it('get error if project is not public, i.e., has no public paths', function(done) { return db.user_query({ account_id: accounts[1], query: { public_projects: { project_id: project_id, title: null, description: null } }, cb: function(err, x) { expect(err).toEqual("project does not have any public paths"); return done(); } }); }); it('adds a public paths', function(done) { return db.user_query({ account_id: accounts[0], query: { public_paths: { project_id: project_id, path: "foo.txt" } }, cb: done }); }); it('tests owner can now get title and description of project', function(done) { return db.user_query({ account_id: accounts[0], query: { public_projects: { project_id: project_id, title: null, description: null } }, cb: function(err, x) { expect(x).toEqual({ public_projects: { project_id: project_id, title: 'Project 0', description: 'Description 0' } }); return done(err); } }); }); it('tests other user can get title and description of project', function(done) { return db.user_query({ account_id: accounts[1], query: { public_projects: { project_id: project_id, title: null, description: null } }, cb: function(err, x) { expect(x).toEqual({ public_projects: { project_id: project_id, title: 'Project 0', description: 'Description 0' } }); return done(err); } }); }); it('tests anonymous user can get title and description of project', function(done) { return db.user_query({ account_id: accounts[1], query: { public_projects: { project_id: project_id, title: null, description: null } }, cb: function(err, x) { expect(x).toEqual({ public_projects: { project_id: project_id, title: 'Project 0', description: 'Description 0' } }); return done(err); } }); }); it('tests that project_id must be specified', function(done) { return db.user_query({ account_id: accounts[0], query: { public_projects: { project_id: null, title: null, description: null } }, cb: function(err, x) { expect(err).toEqual('FATAL: must specify project_id'); return done(); } }); }); tests = function(account_id, done) { var id; id = misc.uuid(); return db.user_query({ account_id: account_id, query: { public_projects: [ { project_id: project_id, title: null, description: null } ] }, changes: id, cb: changefeed_series([ function(x, cb) { expect(x).toEqual({ public_projects: [ { project_id: project_id, title: 'Project 0', description: 'Description 0' } ] }); return db.user_query({ account_id: accounts[0], query: { projects: { project_id: project_id, title: 'TITLE', description: 'DESC' } }, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { project_id: project_id, description: 'DESC', title: 'TITLE' } }); return db.user_query({ account_id: accounts[0], query: { projects: { project_id: project_id, title: 'Project 0', description: 'Description 0' } }, cb: cb }); }, function(x, cb) { return db.user_query_cancel_changefeed({ id: id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], done) }); }; it('tests non-anonymous user on project can get a changefeed on public project', function(done) { return tests(accounts[0], done); }); it('tests non-anonymous NON-user on project can get a changefeed on public project', function(done) { return tests(accounts[1], done); }); return it('tests anonymous can get a changefeed on public project', function(done) { return tests(void 0, done); }); }); describe('test public_paths table -- ', function() { var accounts, changefeed_pub_paths, projects, read_public_paths; before(setup); after(teardown); accounts = projects = void 0; it('set things up', function(done) { return async.series([ function(cb) { return create_accounts(3, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return db.make_user_admin({ account_id: accounts[2], cb: cb }); }, function(cb) { return create_projects(2, accounts[0], (function(err, v) { projects = v; return cb(err); })); } ], done); }); it('adds a public path to a project', function(done) { return db.user_query({ account_id: accounts[0], query: { public_paths: { project_id: projects[0], path: "foo.txt", description: "foo" } }, cb: done }); }); it('adds a public path to a project not on as admin', function(done) { return db.user_query({ account_id: accounts[2], query: { public_paths: { project_id: projects[0], path: "bar.txt", description: 'bar', disabled: true } }, cb: done }); }); it('fail to add a public path to a project user is not on', function(done) { return db.user_query({ account_id: accounts[1], query: { public_paths: { project_id: projects[0], path: "bar2.txt" } }, cb: function(err) { expect(err).toEqual('FATAL: user must be an admin'); return done(); } }); }); it('fail to add a public path when not logged in', function(done) { return db.user_query({ query: { public_paths: { project_id: projects[0], path: 'foo2.txt' } }, cb: function(err) { expect(err).toEqual('FATAL: no anonymous set queries'); return done(); } }); }); read_public_paths = function(done) { var f; f = function(account_id, cb) { return db.user_query({ account_id: account_id, query: { public_paths: [ { project_id: projects[0], path: null, description: null, disabled: null } ] }, options: [ { order_by: 'path' } ], cb: function(err, x) { expect(x).toEqual({ public_paths: [ { description: 'bar', disabled: true, path: 'bar.txt', project_id: projects[0] }, { description: 'foo', path: 'foo.txt', project_id: projects[0] } ] }); return cb(err); } }); }; return async.map([accounts[0], accounts[1], void 0], f, done); }; it('reads public paths as owner, non-collab, and anon', function(done) { return read_public_paths(done); }); it('verifies that changefeed required id field (the primary key)', function(done) { return db.user_query({ query: { public_paths: [ { project_id: projects[0], path: null } ] }, changes: misc.uuid(), cb: (err) => { expect(err).toEqual("FATAL: changefeed MUST include primary key (='id') in query"); return done(); } }); }); changefeed_pub_paths = function(done) { var f; f = function(account_id, cb) { var changefeed_id, v; changefeed_id = misc.uuid(); v = void 0; return db.user_query({ account_id: account_id, query: { public_paths: [ { id: null, project_id: projects[0], path: null, description: null, disabled: null } ] }, options: [ { order_by: 'path' } ], changes: changefeed_id, cb: changefeed_series([ function(x, cb) { v = x.public_paths; expect(v.length).toEqual(2); return db.user_query({ account_id: accounts[0], query: { public_paths: { project_id: projects[0], path: "foo.txt", description: "foo2", disabled: true } }, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { id: v[1].id, project_id: projects[0], path: "foo.txt", description: "foo2", disabled: true } }); return db.user_query({ account_id: accounts[0], query: { public_paths: { project_id: projects[0], path: "foo.txt", description: "foo", disabled: false } }, cb: cb }); }, function(x, cb) { expect(x.action).toEqual('update'); expect(x.new_val.description).toEqual("foo"); expect(x.new_val.disabled).toEqual(false); return db.user_query_cancel_changefeed({ id: changefeed_id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], cb) }); }; return async.mapSeries([accounts[0], accounts[1], void 0], f, done); }; return it('makes a changefeed and verifies modifying existing entry works', function(done) { return changefeed_pub_paths(done); }); }); describe('test site_settings table -- ', function() { var accounts; before(setup); after(teardown); accounts = void 0; it('make an admin and non-admin account', function(done) { return async.series([ function(cb) { return create_accounts(2, function(err, x) { accounts = x; return cb(err); }); }, function(cb) { return db.make_user_admin({ account_id: accounts[0], cb: cb }); } ], done); }); it("check writing to wrong field gives an error", function(done) { return db.user_query({ account_id: accounts[0], query: { site_settings: { site_name: 'Hacker Site!' } }, cb: function(err) { expect(err).toEqual("FATAL: error setting 'name' -- Error: setting name='undefined' not allowed"); return done(); } }); }); it("check writing to not allowed row", function(done) { return db.user_query({ account_id: accounts[0], query: { site_settings: { name: 'foobar', value: 'stuff' } }, cb: function(err) { expect(err).toEqual("FATAL: error setting 'name' -- Error: setting name='foobar' not allowed"); return done(); } }); }); it("check anon can't write", function(done) { return db.user_query({ query: { site_settings: { name: 'site_name', value: 'Hacker Site!' } }, cb: function(err) { expect(err).toEqual("FATAL: no anonymous set queries"); return done(); } }); }); it("check anon can't read", function(done) { return db.user_query({ query: { site_settings: { name: 'site_name', value: null } }, cb: function(err) { expect(err).toEqual("FATAL: anonymous get queries not allowed for table 'site_settings'"); return done(); } }); }); it("check non-admin can't write", function(done) { return db.user_query({ account_id: accounts[1], query: { site_settings: { name: 'site_name', value: 'Hacker Site!' } }, cb: function(err) { expect(err).toEqual("FATAL: user must be an admin"); return done(); } }); }); it("check non-admin can't read", function(done) { return db.user_query({ account_id: accounts[1], query: { site_settings: { name: 'site_name', value: null } }, cb: function(err) { expect(err).toEqual("FATAL: user must be an admin"); return done(); } }); }); it("check admin can write", function(done) { return db.user_query({ account_id: accounts[0], query: { site_settings: { name: 'site_name', value: 'Hacker Site!' } }, cb: done }); }); it("check admin can read", function(done) { return db.user_query({ account_id: accounts[0], query: { site_settings: { name: 'site_name', value: null } }, cb: function(err, x) { expect(x).toEqual({ site_settings: { name: 'site_name', value: 'Hacker Site!' } }); return done(); } }); }); return it('create admin changefeed and write some things to it', function(done) { var id, user_query; id = misc.uuid(); user_query = function(query, cb) { return db.user_query({ account_id: accounts[0], query: { site_settings: query }, cb: cb }); }; return db.user_query({ account_id: accounts[0], query: { site_settings: [ { name: null, value: null } ] }, changes: id, cb: changefeed_series([ function(x, cb) { expect(x).toEqual({ site_settings: [ { name: 'site_name', value: 'Hacker Site!' } ] }); return user_query({ name: 'site_name', value: 'CoCalc' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'site_name', value: 'CoCalc' } }); return user_query({ name: 'site_description', value: 'The collaborative site' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'site_description', value: 'The collaborative site' } }); return user_query({ name: 'terms_of_service', value: 'Do nice things' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'terms_of_service', value: 'Do nice things' } }); return user_query({ name: 'account_creation_email_instructions', value: 'Create account' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'account_creation_email_instructions', value: 'Create account' } }); return user_query({ name: 'help_email', value: 'h@a.b.c' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'help_email', value: 'h@a.b.c' } }); return user_query({ name: 'commercial', value: 'yes' }, cb); }, function(x, cb) { expect(x).toEqual({ action: 'insert', new_val: { name: 'commercial', value: 'yes' } }); return db.user_query_cancel_changefeed({ id: id, cb: cb }); }, function(x, cb) { expect(x).toEqual({ action: 'close' }); return cb(); } ], done) }); }); }); describe('test stats changefeed: ', function() { var account_id, obj; before(setup); after(teardown); obj = { id: null, time: null, accounts: null, accounts_created: null, projects: null, projects_created: null, projects_edited: null, hub_servers: null }; account_id = void 0; it('make an account', function(done) { return async.series([ function(cb) { return create_accounts(1, function(err, x) { account_id = x[0]; return cb(err); }); } ], done); }); it('query the stats table anonymously (get nothing, no error)', function(done) { return db.user_query({ query: { stats: [obj] }, cb: function(err, x) { expect(err).toEqual("FATAL: get queries not allowed for table 'stats'"); return done(); } }); }); it('query the stats table as user (get nothing, no error)', function(done) { return db.user_query({ account_id: account_id, query: { stats: [obj] }, cb: function(err, x) { expect(err).toEqual("FATAL: get queries not allowed for table 'stats'"); return done(); } }); }); it('insert some entries in the stats table', function(done) { return db.get_stats({ cb: done }); }); it('query the stats table as user and gets the one entry', function(done) { return db.user_query({ account_id: account_id, query: { stats: [obj] }, cb: function(err, x) { expect(err).toEqual("FATAL: get queries not allowed for table 'stats'"); return done(); } }); }); return it('query the stats table as anon and gets the one entry', function(done) { re