UNPKG

smc-hub

Version:

CoCalc: Backend webserver component

1,385 lines (1,360 loc) 39.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 //######################################################################## var DOMAIN_URL, SITE_NAME, all_results, async, count_result, db, expect, misc, one_result, pgtest, setup, teardown, indexOf = [].indexOf; /* Test suite for PostgreSQL interface and functionality. COPYRIGHT : (c) 2017 SageMath, Inc. LICENSE : AGPLv3 */ // to run just this test, goto src/smc-hub/ and // SMC_DB_RESET=true SMC_TEST=true time node_modules/.bin/mocha --reporter ${REPORTER:-progress} test/postgres/postgres-test.coffee pgtest = require('./pgtest'); db = void 0; setup = function(cb) { return pgtest.setup(function(err) { db = pgtest.db; return cb(err); }); }; teardown = pgtest.teardown; ({one_result, all_results, count_result} = require('../../postgres')); async = require('async'); expect = require('expect'); misc = require('smc-util/misc'); ({DOMAIN_URL, SITE_NAME} = require('smc-util/theme')); describe('email verification: ', function() { var locals; this.timeout(5000); before(setup); after(teardown); locals = { token: null, email_address: "test@test.com", email_address2: "test2@test.com", data: null, account_id: null }; it("creates a random token", function(done) { return async.waterfall([ function(cb) { return db.create_account({ first_name: "A", last_name: "B", created_by: "1.2.3.4", email_address: locals.email_address, password_hash: "test", cb: cb }); }, function(account_id, cb) { locals.account_id = account_id; return db.verify_email_create_token({ account_id: account_id, cb: cb }); } ], function(err, verify_info) { var char, i, len, token; ({token} = verify_info); expect(token.length > 5).toBe(true); // only lowercase, because upper/lower case in links in emails can get mangled for (i = 0, len = token.length; i < len; i++) { char = token[i]; expect(indexOf.call('0123456789abcdefghijklmnopqrstuvwxyz', char) >= 0).toBe(true); } locals.token = token; return done(err); }); }); it("correctly checks the token", function(done) { return async.series([ function(cb) { return db.verify_email_check_token({ email_address: locals.email_address, token: locals.token, cb: cb }); }, function(cb) { return db._query({ query: "SELECT email_address_verified FROM accounts", where: { "email_address = $::TEXT": locals.email_address }, cb: one_result('email_address_verified', function(err, data) { locals.data = data; return cb(err); }) }); }, function(cb) { // and that the token is deleted return db._query({ query: 'SELECT email_address_challenge FROM accounts', where: { "account_id = $::UUID": locals.account_id }, cb: one_result(function(err, data) { expect(Object.keys(data).length === 0).toBe(true); return cb(err); }) }); } ], function(err) { var ref; expect((ref = locals.email_address, indexOf.call(misc.keys(locals.data), ref) >= 0)).toBe(true); return done(err); }); }); it("has no idea about unkown accounts", function(done) { return db.verify_email_check_token({ email_address: "other-one@test.com", token: locals.token, cb: function(err) { expect(!!err).toBe(true); expect(err.indexOf('no such account') !== -1).toBe(true); return done(void 0); // suppress error } }); }); it("detects a wrong token", function(done) { return async.waterfall([ function(cb) { return db.create_account({ first_name: "C", last_name: "D", created_by: "1.2.3.4", email_address: locals.email_address2, password_hash: "test", cb: cb }); }, function(account_id, cb) { return db.verify_email_create_token({ account_id: account_id, cb: cb }); }, function(verify_info, cb) { var email_address, token; ({token, email_address} = verify_info); expect(email_address).toBe(locals.email_address2); return db.verify_email_check_token({ email_address: locals.email_address2, token: "X", // a wrong one cb: function(err) { expect(err.indexOf('token does not match') !== -1).toBe(true); return cb(void 0); // suppress error } }); } ], done); }); it("returns the verified email address", function(done) { return db.verify_email_get({ account_id: locals.account_id, cb: function(err, x) { var ref, verified; verified = (ref = x.email_address, indexOf.call(misc.keys(x.email_address_verified), ref) >= 0); expect(verified).toBe(true); return done(err); } }); }); return it("and also answers is_verified_email correctly", function(done) { return async.series([ function(cb) { return db.is_verified_email({ email_address: locals.email_address, cb: function(err, verified) { expect(verified).toBe(true); return cb(err); } }); }, function(cb) { return db.is_verified_email({ email_address: locals.email_address2, cb: function(err, verified) { expect(verified).toBe(false); return cb(err); } }); } ], done); }); }); describe('working with accounts: ', function() { this.timeout(5000); before(setup); after(teardown); it("checks that the account we haven't made yet doesn't already exist", function(done) { return db.account_exists({ email_address: 'sage@example.com', cb: function(err, exists) { expect(!!exists).toBe(false); return done(err); } }); }); it("tries to get an account that doesn't exist", function(done) { return db.get_account({ email_address: 'sage@example.com', cb: function(err, account) { expect(err != null).toBe(true); return done(); } }); }); it("creates a new account", function(done) { return db.create_account({ first_name: "Sage", last_name: "Salvus", created_by: "1.2.3.4", email_address: "sage@example.com", password_hash: "blah", cb: done }); }); it("checks the newly created account does exist", function(done) { return db.account_exists({ email_address: 'sage@example.com', cb: function(err, exists) { expect(!!exists).toBe(true); return done(err); } }); }); it("verifies that there is 1 account in the database via a count", function(done) { return db.count({ table: 'accounts', cb: function(err, n) { expect(n).toBe(1); return done(err); } }); }); it("creates a second account", function(done) { return db.create_account({ first_name: "Mr", last_name: "Smith", created_by: "10.10.1.1", email_address: "sage-2@example.com", password_hash: "foo", cb: done }); }); it("verifies that there are a total of 2 accounts in the database via the stats table", function(done) { return db.get_stats({ cb: function(err, stats) { expect(stats.accounts).toBe(2); return done(err); } }); }); it("grabs our second new account by email and checks a name and property", function(done) { return db.get_account({ email_address: 'sage-2@example.com', cb: function(err, account) { expect(account.first_name).toBe("Mr"); expect(account.password_is_set).toBe(true); return done(err); } }); }); it("computes number of accounts created from 1.2.3.4", function(done) { return db.count_accounts_created_by({ ip_address: '1.2.3.4', age_s: 1000000, cb: function(err, n) { expect(n).toBe(1); return done(err); } }); }); it("deletes an account", function(done) { return db.get_account({ email_address: 'sage-2@example.com', cb: function(err, account) { return db.delete_account({ account_id: account.account_id, cb: done }); } }); }); it("checks that account is gone", function(done) { return db.account_exists({ email_address: 'sage-2@example.com', cb: function(err, exists) { expect(!!exists).toBe(false); return done(err); } }); }); it("creates an account with no password set", function(done) { return db.create_account({ first_name: "Simple", last_name: "Sage", created_by: "1.2.3.4", email_address: "simple@example.com", cb: done }); }); return it("verifies that the password_is_set field is false", function(done) { return db.get_account({ email_address: 'simple@example.com', cb: function(err, account) { expect(account.password_is_set).toBe(false); return done(err); } }); }); }); describe('working with logs: ', function() { var account_id, error, event; before(setup); after(teardown); it('creates a log message', function(done) { return db.log({ event: "test", value: "a message", cb: done }); }); it('gets contents of the log and checks that the message we made is there', function(done) { return db.get_log({ start: new Date(new Date() - 10000000), end: new Date(), event: 'test', cb: function(err, log) { expect(log.length).toBe(1); expect(log[0]).toEqual({ event: 'test', value: 'a message', id: log[0].id, time: log[0].time, expire: log[0].expire }); return done(err); } }); }); it('checks that there is nothing "old" in the log', function(done) { // no old stuff return db.get_log({ start: new Date(new Date() - 10000000), end: new Date(new Date() - 1000000), cb: function(err, log) { expect(log.length).toBe(0); return done(err); } }); }); account_id = '4d29eec4-c126-4f06-b679-9a661fd7bcdf'; error = `Your internet connection is unstable/down or ${SITE_NAME} is temporarily not available. Therefore ${SITE_NAME} is not working.`; event = 'test'; it('logs a client error', function(done) { return db.log_client_error({ event: event, error: error, account_id: account_id, cb: done }); }); it('logs another client error with a different event', function(done) { return db.log_client_error({ event: event + "-other", error: error, account_id: account_id, cb: done }); }); it('gets the recent error log for only one event and checks that it has only one log entry in it', function(done) { return db.get_client_error_log({ start: new Date(new Date() - 10000000), end: new Date(), event: event, cb: function(err, log) { expect(log.length).toBe(1); expect(log[0]).toEqual({ event: event, error: error, account_id: account_id, id: log[0].id, time: log[0].time, expire: log[0].expire }); return done(err); } }); }); return it('gets old log entries and makes sure there are none', function(done) { return db.get_client_error_log({ start: new Date(new Date() - 10000000), end: new Date(new Date() - 1000000), event: event, cb: function(err, log) { expect(log.length).toBe(0); return done(err); } }); }); }); describe('testing working with blobs: ', function() { var project_id, uuidsha1; this.timeout(10000); beforeEach(setup); afterEach(teardown); ({uuidsha1} = require('smc-util-node/misc_node')); project_id = misc.uuid(); it('creating a blob and reading it', function(done) { var blob; blob = Buffer.from("This is a test blob"); return async.series([ function(cb) { return db.save_blob({ uuid: uuidsha1(blob), blob: blob, project_id: project_id, cb: cb }); }, function(cb) { return db.count({ table: 'blobs', cb: function(err, n) { expect(n).toBe(1); return cb(err); } }); }, function(cb) { return db.get_blob({ uuid: uuidsha1(blob), cb: function(err, blob2) { expect(blob2.equals(blob)).toBe(true); return cb(err); } }); } ], done); }); it('tries to save a blob with an invalid uuid and gets an error', function(done) { return db.save_blob({ uuid: 'not a uuid', blob: Buffer.from("This is a test blob"), project_id: project_id, cb: function(err) { expect(err).toEqual('uuid is invalid'); return done(); } }); }); it('save a string blob (with a null byte!), and confirms it works (properly converted to Buffer)', function(done) { return async.series([ function(cb) { return db.save_blob({ blob: 'my blob', project_id: project_id, cb: cb }); }, function(cb) { return db.get_blob({ uuid: uuidsha1('my blob'), cb: function(err, blob2) { expect(blob2 != null ? blob2.toString() : void 0).toEqual('my blob'); return cb(err); } }); } ], done); }); it('creating 50 blobs and verifying that 50 are in the table', function(done) { return async.series([ function(cb) { var f; f = function(n, cb) { var blob; blob = Buffer.from(`x${n}`); return db.save_blob({ uuid: uuidsha1(blob), blob: blob, project_id: project_id, cb: cb }); }; return async.map((function() { var results = []; for (var i = 0; i < 50; i++){ results.push(i); } return results; }).apply(this), f, cb); }, function(cb) { return db.count({ table: 'blobs', cb: function(err, n) { expect(n).toBe(50); return cb(err); } }); } ], done); }); it('creating 5 blobs that expire in 0.01 second and 5 that do not, then wait 0.15s, delete_expired, then verify that the expired ones are gone from the table', function(done) { return async.series([ function(cb) { var f; f = function(n, cb) { var blob; blob = Buffer.from(`x${n}`); return db.save_blob({ uuid: uuidsha1(blob), blob: blob, project_id: project_id, cb: cb, ttl: n < 5 ? 0.01 : 0 }); }; return async.map([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], f, cb); }, function(cb) { return setTimeout(cb, 150); }, function(cb) { return db.delete_expired({ cb: cb }); }, function(cb) { return db.count({ table: 'blobs', cb: function(err, n) { expect(n).toBe(5); return cb(err); } }); } ], done); }); return it('creating a blob that expires in 0.01 seconds, then extending it to never expire; wait, delete, and ensure it is still there', function(done) { var blob, uuid; blob = "a blob"; uuid = uuidsha1(blob); return async.series([ function(cb) { return db.save_blob({ uuid: uuid, blob: blob, project_id: project_id, cb: cb, ttl: 0.01 }); }, function(cb) { return db.remove_blob_ttls({ uuids: [uuid], cb: cb }); }, function(cb) { return setTimeout(cb, 100); }, function(cb) { return db.count({ table: 'blobs', cb: function(err, n) { expect(n).toBe(1); return cb(err); } }); } ], done); }); }); describe('testing the hub servers registration table: ', function() { beforeEach(setup); afterEach(teardown); return it('test registering a hub that expires in 0.05 seconds, test is right, then wait 0.1s, delete_expired, then verify done', function(done) { return async.series([ function(cb) { return db.register_hub({ host: "smc0", port: 5000, clients: 17, ttl: 0.05, cb: cb }); }, function(cb) { return db.get_hub_servers({ cb: function(err, v) { expect(v.length).toBe(1); expect(v[0]).toEqual({ host: "smc0-5000", port: 5000, clients: 17, expire: v[0].expire }); return cb(err); } }); }, function(cb) { return setTimeout(cb, 150); }, function(cb) { return db.delete_expired({ cb: cb }); }, function(cb) { return db.get_hub_servers({ cb: function(err, v) { expect(v.length).toBe(0); return cb(err); } }); } ], done); }); }); describe('testing the server settings table: ', function() { before(setup); after(teardown); it('sets a server setting', function(done) { return db.set_server_setting({ name: 'name', value: "some stuff", cb: done }); }); return it('reads that setting back', function(done) { return db.get_server_setting({ name: 'name', cb: function(err, value) { expect(value).toEqual("some stuff"); return done(err); } }); }); }); describe('testing the passport settings table: ', function() { before(setup); after(teardown); it('creates a fake passport auth', function(done) { return db.set_passport_settings({ strategy: 'fake', conf: { token: 'foo' }, cb: done }); }); it('verifies that the fake passport was created', function(done) { return db.get_passport_settings({ strategy: 'fake', cb: function(err, value) { expect(value).toEqual({ token: 'foo' }); return done(err); } }); }); return it('checks that it is also in the list of all passport entries', function(done) { return db.get_all_passport_settings({ cb: function(err, settings) { var i, len, ref, s; if (err) { return done(err); } else { for (i = 0, len = settings.length; i < len; i++) { s = settings[i]; if (s.strategy === 'fake' && ((ref = s.conf) != null ? ref.token : void 0) === 'foo') { done(); return; } expect(false); // not found! } } } }); }); }); describe('user enumeration functionality: ', function() { var account_id, num; before(setup); after(teardown); num = 20; it(`creates ${num} accounts`, function(done) { var f; f = function(n, cb) { return db.create_account({ first_name: `Sage${n}`, last_name: `Math${n}`, created_by: "1.2.3.4", email_address: `sage${n}@sagemath.com`, password_hash: `sage${n}`, cb: cb }); }; return async.map((function() { var results = []; for (var i = 0; 0 <= num ? i < num : i > num; 0 <= num ? i++ : i--){ results.push(i); } return results; }).apply(this), f, done); }); it("searches for users using the 'sage' query", function(done) { return db.user_search({ query: "sage", limit: num - 2, cb: function(err, v) { expect(v.length).toBe(num - 2); return done(err); } }); }); it("searches for the user with email sage0@sagemath.com", function(done) { return db.user_search({ query: "sage0@sagemath.com", cb: function(err, users) { var data, n; expect(users.length).toBe(1); n = 0; data = users[0]; delete data.created; expect(data).toEqual({ email_address: "sage0@sagemath.com", account_id: users[n].account_id, first_name: `Sage${n}`, last_name: `Math${n}`, email_address_verified: null, last_active: null }); return done(err); } }); }); it("searches for the non-existent user with email sageBLAH@sagemath.com", function(done) { return db.user_search({ query: "sageBLAH@sagemath.com", cb: function(err, users) { expect(users.length).toBe(0); return done(err); } }); }); account_id = void 0; it("adds another user", function(done) { return db.create_account({ first_name: "FOO", last_name: "BAR", created_by: "1.2.3.4", email_address: "foo@sagemath.com", password_hash: "sage", cb: function(err, x) { account_id = x; return done(err); } }); }); it("then checks that the new user is found by first name", function(done) { return db.user_search({ query: "FOO", cb: function(err, users) { expect(users.length).toBe(1); return done(err); } }); }); it("then checks that the new user is found by last name", function(done) { return db.user_search({ query: "BAR", cb: function(err, users) { expect(users.length).toBe(1); return done(err); } }); }); it("change that user in place", function(done) { return db._query({ query: "UPDATE accounts", set: { first_name: 'VERT', last_name: 'RAMP' }, where: { "account_id = $": account_id }, cb: done }); }); it("then checks that the modified user is found", function(done) { return db.user_search({ query: "VERT", cb: function(err, users) { expect(users.length).toBe(1); return done(err); } }); }); return it("but the previous name is not found", function(done) { return db.user_search({ query: "BAR", cb: function(err, users) { expect(users.length).toBe(0); return done(err); } }); }); }); describe('banning of users: ', function() { var account_id; before(setup); after(teardown); account_id = void 0; it('creates an account', function(done) { return db.create_account({ first_name: "Sage", last_name: "Math", created_by: "1.2.3.4", email_address: "sage@example.com", password_hash: "blah", cb: (err, x) => { account_id = x; return done(err); } }); }); it('checks by account_id that the user we just created is not banned', function(done) { return db.is_banned_user({ account_id: account_id, cb: (err, x) => { expect(x).toBe(false); return done(err); } }); }); it('checks by email that user is not banned', function(done) { return db.is_banned_user({ email_address: "sage@example.com", cb: (err, x) => { expect(x).toBe(false); return done(err); } }); }); it('verifies that a user that does not exist is not banned', function(done) { return db.is_banned_user({ email_address: "sageXXX@example.com", cb: (err, x) => { expect(x).toBe(false); return done(err); } }); }); it('bans the user we created', function(done) { return db.ban_user({ account_id: account_id, cb: done }); }); it('checks they are banned by account_id', function(done) { return db.is_banned_user({ account_id: account_id, cb: (err, x) => { expect(x).toBe(true); return done(err); } }); }); it('checks they are banned by email address', function(done) { return db.is_banned_user({ email_address: "sage@example.com", cb: (err, x) => { expect(x).toBe(true); return done(err); } }); }); it('unbans our banned user', function(done) { return db.unban_user({ account_id: account_id, cb: done }); }); it('checks that the user we just unbanned is unbanned', function(done) { return db.is_banned_user({ account_id: account_id, cb: (err, x) => { expect(x).toBe(false); return done(err); } }); }); it('bans our user by email address instead', function(done) { return db.ban_user({ email_address: "sage@example.com", cb: done }); }); return it('then checks that banning by email address worked', function(done) { return db.is_banned_user({ account_id: account_id, cb: (err, x) => { expect(x).toBe(true); return done(err); } }); }); }); describe('testing the passport table: ', function() { var account_id; before(setup); after(teardown); account_id = void 0; it('creates an account', function(done) { return db.create_account({ first_name: "Sage", last_name: "Math", created_by: "1.2.3.4", email_address: "sage@example.com", password_hash: "blah", cb: (err, x) => { account_id = x; return done(err); } }); }); it('creates a passport', function(done) { return db.create_passport({ account_id: account_id, strategy: 'google', id: '929304823048', profile: { email_address: "sage@example.com", avatar: 'James Cameron' }, cb: done }); }); it('checks the passport we just created exists', function(done) { return db.passport_exists({ strategy: 'google', id: '929304823048', cb: function(err, x) { expect(x).toBe(account_id); return done(err); } }); }); it('check that a non-existent passport does not exist', function(done) { return db.passport_exists({ strategy: 'google', id: 'FAKE', cb: function(err, x) { expect(x).toBe(void 0); return done(err); } }); }); it('check that a passport we created above exists directly via checking the accounts entry', function(done) { return db.get_account({ account_id: account_id, columns: ['passports'], cb: function(err, x) { expect(x.passports).toEqual({ 'google-929304823048': { avatar: 'James Cameron', email_address: 'sage@example.com' } }); return done(err); } }); }); it('deletes the passport we made above', function(done) { return db.delete_passport({ account_id: account_id, strategy: 'google', id: '929304823048', cb: done }); }); it('verifies the passport is really gone', function(done) { return db.passport_exists({ strategy: 'google', id: '929304823048', cb: function(err, x) { expect(x).toBe(void 0); return done(err); } }); }); it('check the passport is also gone from the accounts table', function(done) { return db.get_account({ account_id: account_id, columns: ['passports'], cb: function(err, x) { expect(misc.keys(x.passports).length).toEqual(0); return done(err); } }); }); return it('create two passports and verifies that both exist', function(done) { return async.series([ function(cb) { return db.create_passport({ account_id: account_id, strategy: 'google', id: '929304823048', profile: { email_address: "sage@example.com", avatar: 'James Cameron' }, cb: cb }); }, function(cb) { return db.create_passport({ account_id: account_id, strategy: 'facebook', id: '12346', profile: { email_address: "sage@facebook.com", avatar: 'Zuck' }, cb: cb }); }, function(cb) { return db.get_account({ account_id: account_id, columns: ['passports'], cb: function(err, x) { expect(misc.keys(x.passports).length).toEqual(2); return cb(err); } }); } ], done); }); }); describe('testing file use notifications table: ', function() { var account_id, account_id1, path0, path1, path2, project_id, project_id1; before(setup); after(teardown); account_id = void 0; project_id = void 0; path0 = "test_file"; it('creates an account', function(done) { return db.create_account({ first_name: "Sage", last_name: "Math", created_by: "1.2.3.4", email_address: "sage@example.com", password_hash: "blah", cb: (err, x) => { account_id = x; return done(err); } }); }); it('creates a project', function(done) { return db.create_project({ account_id: account_id, title: "Test project", description: "The description", cb: (err, x) => { project_id = x; return done(err); } }); }); it(`record editing of file '${path0}'`, function(done) { return db.record_file_use({ project_id: project_id, path: path0, account_id: account_id, action: "edit", cb: done }); }); it(`get activity for project and '${path0}'`, function(done) { return db.get_file_use({ project_id: project_id, path: path0, max_age_s: 1000, cb: function(err, x) { expect(x.project_id).toBe(project_id); expect(x.path).toBe(path0); expect(misc.keys(x.users)).toEqual([account_id]); expect(misc.keys(x.users[account_id])).toEqual(['edit']); return done(err); } }); }); it("get activity for the project and ensure there was is instance of activity", function(done) { return db.get_file_use({ project_id: project_id, max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(1); return done(err); } }); }); path1 = "another_file"; project_id1 = void 0; it('creates another project', function(done) { return db.create_project({ account_id: account_id, title: "Test project 2", description: "The description 2", cb: (err, x) => { project_id1 = x; return done(err); } }); }); it(`tests recording activity on another file '${path1}'`, function(done) { return db.record_file_use({ project_id: project_id1, path: path1, account_id: account_id, action: "edit", cb: done }); }); it("gets activity only for the second project and checks there is only one entry", function(done) { return db.get_file_use({ project_id: project_id1, max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(1); return done(err); } }); }); it("gets activity for both projects and checks there are two entries", function(done) { return db.get_file_use({ project_ids: [project_id, project_id1], max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(2); return done(err); } }); }); it("gets all info about a project", function(done) { return db.get_project({ project_id: project_id, cb: function(err, info) { expect(info != null ? info.title : void 0).toEqual('Test project'); expect(info != null ? info.project_id : void 0).toEqual(project_id); return done(err); } }); }); account_id1 = void 0; path2 = "a_third_file"; it('creates another account', function(done) { return db.create_account({ first_name: "Sage1", last_name: "Math1", created_by: "1.2.3.4", email_address: "sage1@example.com", password_hash: "blah1", cb: (err, x) => { account_id1 = x; return done(err); } }); }); it(`records activity by new user on '${path0}`, function(done) { return db.record_file_use({ project_id: project_id, path: path0, account_id: account_id1, action: "edit", cb: done }); }); it("checks that there is still one activity entry for first project", function(done) { return db.get_file_use({ project_id: project_id, max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(1); return done(err); } }); }); it(`checks two users are listed as editors on '${path0}'`, function(done) { return db.get_file_use({ project_id: project_id, path: path0, max_age_s: 1000, cb: function(err, x) { expect(misc.keys(x.users).length).toBe(2); return done(err); } }); }); it(`records activity by new user on '${path2}`, function(done) { return db.record_file_use({ project_id: project_id, path: path2, account_id: account_id1, action: "edit", cb: done }); }); it("checks that there are two activity entries now for first project", function(done) { return db.get_file_use({ project_id: project_id, max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(2); return done(err); } }); }); it("gets activity for both projects and checks there are now three entries", function(done) { return db.get_file_use({ project_ids: [project_id, project_id1], max_age_s: 1000, cb: function(err, x) { expect(x.length).toBe(3); return done(err); } }); }); it("verifies that max_age_s filter works", function(done) { var f; f = function() { return db.get_file_use({ project_ids: [project_id, project_id1], max_age_s: 0.05, cb: function(err, x) { expect(x.length).toBe(0); return done(err); } }); }; return setTimeout(f, 100); }); it("records edit action again on a file by a user and verifies that this changes the last_edited field", function(done) { var last_edited; last_edited = void 0; return async.series([ function(cb) { return db.get_file_use({ project_id: project_id, path: path0, max_age_s: 1000, cb: function(err, x) { last_edited = x.last_edited; return cb(err); } }); }, function(cb) { return db.record_file_use({ project_id: project_id, path: path0, account_id: account_id, action: "edit", cb: cb }); }, function(cb) { return db.get_file_use({ project_id: project_id, path: path0, max_age_s: 1000, cb: function(err, x) { expect(last_edited).toNotBe(x.last_edited); return cb(err); } }); } ], done); }); return it("records seen action on a file by a user and verifies that this does not change the last_edited field and adds seen info", function(done) { return async.series([ function(cb) { return db.record_file_use({ project_id: project_id, path: path0, account_id: account_id, action: "seen", cb: cb }); }, function(cb) { return db.get_file_use({ project_id: project_id, path: path0, max_age_s: 1000, cb: function(err, x) { expect(x.users[account_id].seen != null).toBe(true); expect(x.users[account_id].read != null).toBe(false); return cb(err); } }); } ], done); }); }); describe('doing a "naked update"', function() { return it('is an error', function(done) { return db._query({ query: "UPDATE accounts SET first_name='William'", cb: function(err) { expect(err).toEqual("ERROR -- Dangerous UPDATE or DELETE without a WHERE, TRIGGER, or INSERT: query='UPDATE accounts SET first_name='William''"); return done(); } }); }); }); }).call(this); //# sourceMappingURL=postgres-test.js.map