// Copyright 2021 Alexandre DÃaz <[email protected]>
// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
odoo.define("terminal.tests.common", function (require) {
"use strict";
const TerminalTestSuite = require("terminal.tests");
const Utils = require("terminal.core.Utils");
const rpc = require("terminal.core.rpc");
TerminalTestSuite.include({
// Can't test 'lang'
// Can't test 'reload'
// Can't test 'debug'
// Can't test 'post': No endpoint to test
// Can't test 'jstest'
// Can't test 'logout'
onStartTests: function () {
// Get the last res.partner.industry id
const def = this._super.apply(this, arguments);
return def.then(() => {
return rpc
.query({
method: "search_read",
domain: [],
fields: ["id"],
model: "res.partner.industry",
limit: 1,
orderBy: "id DESC",
kwargs: {context: this.terminal._getContext()},
})
.then((result) => {
this._last_res_id = result[0].id;
return result;
});
});
},
onEndTests: function () {
// Delete all records used in tests
const def = this._super.apply(this, arguments);
return def.then(() => {
return rpc
.query({
method: "search_read",
domain: [["id", ">", this._last_res_id]],
fields: ["id"],
model: "res.partner.industry",
orderBy: "id DESC",
kwargs: {context: this.terminal._getContext()},
})
.then((result) => {
const ids = _.map(result, "id");
if (_.isEmpty(result)) {
return result;
}
return rpc.query({
method: "unlink",
model: "res.partner.industry",
args: [ids],
kwargs: {context: this.terminal._getContext()},
});
});
});
},
onBeforeTest: function (test_name) {
const def = this._super.apply(this, arguments);
return def.then(() => {
if (
test_name === "test_context" ||
test_name === "test_context_no_arg"
) {
return this.terminal
.executeCommand("context", false, true)
.then((context) => {
this._orig_context = context;
});
} else if (
test_name === "test_upgrade" ||
test_name === "test_upgrade__no_arg"
) {
return this.terminal.executeCommand(
"install -m sms",
false,
true
);
} else if (
test_name === "test_uninstall" ||
test_name === "test_uninstall__no_arg"
) {
return this.terminal.executeCommand(
"install -m sms",
false,
true
);
}
});
},
onAfterTest: function (test_name) {
const def = this._super.apply(this, arguments);
return def.then(() => {
if (
test_name === "test_context" ||
test_name === "test_context_no_arg"
) {
return this.terminal.executeCommand(
`context -o set -v '${JSON.stringify(
this._orig_context
)}'`,
false,
true
);
} else if (
test_name === "test_upgrade" ||
test_name === "test_upgrade__no_arg"
) {
return this.terminal.executeCommand(
"uninstall -m sms",
false,
true
);
}
});
},
test_create: async function () {
await this.terminal.executeCommand(
"create -m res.partner.industry",
false,
true
);
await new Promise((resolve) => setTimeout(resolve, 800));
this.assertTrue(this.isFormOpen());
const record_id = await this.terminal.executeCommand(
`create -m res.partner.industry -v "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
this.assertTrue(record_id > 0);
},
test_create__no_arg: async function () {
await this.terminal.executeCommand(
"create res.partner.industry",
false,
true
);
await new Promise((resolve) => setTimeout(resolve, 800));
this.assertTrue(this.isFormOpen());
const record_id = await this.terminal.executeCommand(
`create res.partner.industry "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
this.assertTrue(record_id > 0);
},
test_unlink: async function () {
const record_id = await this.terminal.executeCommand(
`create -m res.partner.industry -v "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
const res = await this.terminal.executeCommand(
`unlink -m res.partner.industry -i ${record_id}`,
false,
true
);
this.assertTrue(res);
},
test_unlink__no_arg: async function () {
const record_id = await this.terminal.executeCommand(
`create res.partner.industry "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
const res = await this.terminal.executeCommand(
`unlink res.partner.industry ${record_id}`,
false,
true
);
this.assertTrue(res);
},
test_write: async function () {
const record_a_id = await this.terminal.executeCommand(
`create -m res.partner.industry -v "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
const record_b_id = await this.terminal.executeCommand(
`create -m res.partner.industry -v "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
let res = await this.terminal.executeCommand(
`write -m res.partner.industry -i ${record_b_id} -v "{'name': '${_.uniqueId(
"Other name Test #"
)}'}"`,
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
`write -m res.partner.industry -i "${record_a_id}, ${record_b_id}" -v "{'name': '${_.uniqueId(
"Other name Test #"
)}'}"`,
false,
true
);
this.assertTrue(res);
},
test_write__no_arg: async function () {
const record_a_id = await this.terminal.executeCommand(
`create -m res.partner.industry -v "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
const record_b_id = await this.terminal.executeCommand(
`create res.partner.industry "{'name': '${_.uniqueId(
"This is a Test #"
)}'}"`,
false,
true
);
let res = await this.terminal.executeCommand(
`write res.partner.industry ${record_b_id} "{'name': '${_.uniqueId(
"Other name Test #"
)}'}"`,
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
`write res.partner.industry "${record_a_id}, ${record_b_id}" "{'name': '${_.uniqueId(
"Other name Test #"
)}'}"`,
false,
true
);
this.assertTrue(res);
},
test_search: async function () {
const res = await this.terminal.executeCommand(
"search -m res.partner.industry -f name -d \"[['id', '>', 1]]\" -l 3 -of 2 -o \"id desc\"",
false,
true
);
this.assertEqual(res.length, 3);
},
test_search__no_arg: async function () {
const res = await this.terminal.executeCommand(
"search res.partner.industry name \"[['id', '>', 1]]\" 4 2 \"id desc\"",
false,
true
);
this.assertEqual(res.length, 4);
},
test_call: async function () {
const res = await this.terminal.executeCommand(
"call -m res.partner -c can_edit_vat -a [1]",
false,
true
);
this.assertTrue(res);
},
test_call__no_arg: async function () {
const res = await this.terminal.executeCommand(
"call res.partner can_edit_vat [1]",
false,
true
);
this.assertTrue(res);
},
test_upgrade: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"upgrade -m sms",
false,
true
);
this.assertEqual(res[0]?.name, "sms");
await Utils.asyncSleep(6000);
},
test_upgrade__no_arg: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"upgrade sms",
false,
true
);
await Utils.asyncSleep(6000);
this.assertEqual(res[0]?.name, "sms");
},
test_install: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"install -m sms",
false,
true
);
await Utils.asyncSleep(6000);
this.assertEqual(res[0]?.name, "sms");
},
test_install__no_arg: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"install sms",
false,
true
);
await Utils.asyncSleep(6000);
this.assertEqual(res[0]?.name, "sms");
},
test_uninstall: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"uninstall -m sms",
false,
true
);
await Utils.asyncSleep(6000);
this.assertEqual(res[0]?.name, "sms");
},
test_uninstall__no_arg: async function () {
await Utils.asyncSleep(6000);
const res = await this.terminal.executeCommand(
"uninstall sms",
false,
true
);
await Utils.asyncSleep(6000);
this.assertEqual(res[0]?.name, "sms");
},
test_action: async function () {
let res = await this.terminal.executeCommand(
"action -a 5",
false,
true
);
this.assertEqual(res.id, 5);
if (this.terminal._mode === this.terminal.MODES.BACKEND_NEW) {
res = await this.terminal.executeCommand(
"action -a base.action_res_company_form",
false,
true
);
this.assertEqual(res.id, "base.action_res_company_form");
res = await this.terminal.executeCommand(
"action -a \"{'type': 'ir.actions.act_window', 'res_model': 'res.currency', 'view_type': 'form', 'view_mode': 'form', 'views': [[false, 'form']], 'target': 'current', 'res_id': 1}\"",
false,
true
);
this.assertNotEmpty(res);
} else {
res = await this.terminal.executeCommand(
"action -a base.action_res_company_form",
false,
true
);
this.assertEqual(res.xml_id, "base.action_res_company_form");
res = await this.terminal.executeCommand(
"action -a \"{'type': 'ir.actions.act_window', 'res_model': 'res.currency', 'view_type': 'form', 'view_mode': 'form', 'views': [[false, 'form']], 'target': 'current', 'res_id': 1}\"",
false,
true
);
this.assertEqual(res.res_model, "res.currency");
this.assertEqual(res.res_id, 1);
}
},
test_action__no_arg: async function () {
let res = await this.terminal.executeCommand(
"action 5",
false,
true
);
this.assertEqual(res.id, 5);
if (this.terminal._mode === this.terminal.MODES.BACKEND_NEW) {
res = await this.terminal.executeCommand(
"action base.action_res_company_form",
false,
true
);
this.assertEqual(res.id, "base.action_res_company_form");
res = await this.terminal.executeCommand(
"action \"{'type': 'ir.actions.act_window', 'res_model': 'res.currency', 'view_type': 'form', 'view_mode': 'form', 'views': [[false, 'form']], 'target': 'current', 'res_id': 1}\"",
false,
true
);
this.assertNotEmpty(res);
} else {
res = await this.terminal.executeCommand(
"action base.action_res_company_form",
false,
true
);
this.assertEqual(res.xml_id, "base.action_res_company_form");
res = await this.terminal.executeCommand(
"action \"{'type': 'ir.actions.act_window', 'res_model': 'res.currency', 'view_type': 'form', 'view_mode': 'form', 'views': [[false, 'form']], 'target': 'current', 'res_id': 1}\"",
false,
true
);
this.assertEqual(res.res_model, "res.currency");
this.assertEqual(res.res_id, 1);
}
},
test_whoami: async function () {
const res = await this.terminal.executeCommand(
"whoami",
false,
true
);
this.assertEqual(res[0]?.login, "admin");
},
test_caf: async function () {
const res = await this.terminal.executeCommand(
"caf -m res.currency -f symbol -fi \"{'required': true}\"",
false,
true
);
this.assertNotEmpty(res.symbol);
this.assertEmpty(res.id);
},
test_caf__no_arg: async function () {
const res = await this.terminal.executeCommand(
"caf res.currency symbol \"{'required': true}\"",
false,
true
);
this.assertNotEmpty(res.symbol);
this.assertEmpty(res.id);
},
test_cam: async function () {
let res = await this.terminal.executeCommand(
"cam -m res.currency -o create",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"cam -m res.currency -o unlink",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"cam -m res.currency -o write",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"cam -m res.currency -o read",
false,
true
);
this.assertTrue(res);
},
test_cam__no_arg: async function () {
const res = await this.terminal.executeCommand(
"cam res.currency create",
false,
true
);
this.assertTrue(res);
},
test_lastseen: async function () {
// Only test that can be called
await this.terminal.executeCommand("lastseen", false, true);
},
test_read: async function () {
const res = await this.terminal.executeCommand(
"read -m res.currency -i 1 -f symbol",
false,
true
);
this.assertEqual(res[0]?.id, 1);
this.assertNotEmpty(res[0]?.symbol);
this.assertEmpty(res[0]?.display_name);
},
test_read__no_arg: async function () {
const res = await this.terminal.executeCommand(
"read res.currency 1 symbol",
false,
true
);
this.assertEqual(res[0]?.id, 1);
this.assertNotEmpty(res[0]?.symbol);
this.assertEmpty(res[0]?.display_name);
},
test_context: async function () {
let res = await this.terminal.executeCommand(
"context",
false,
true
);
this.assertIn(res, "uid");
res = await this.terminal.executeCommand(
"context -o read",
false,
true
);
this.assertIn(res, "uid");
// At the moment operations with the context are not possible in legacy mode
if (this.terminal._mode !== this.terminal.MODES.BACKEND_NEW) {
res = await this.terminal.executeCommand(
"context -o write -v \"{'test_key': 'test_value'}\"",
false,
true
);
this.assertIn(res, "test_key");
res = await this.terminal.executeCommand(
"context -o set -v \"{'test_key': 'test_value_change'}\"",
false,
true
);
this.assertEqual(res.test_key, "test_value_change");
res = await this.terminal.executeCommand(
"context -o delete -v test_key",
false,
true
);
this.assertNotIn(res, "test_key");
}
},
test_context__no_arg: async function () {
let res = await this.terminal.executeCommand(
"context read",
false,
true
);
this.assertIn(res, "uid");
// At the moment operations with the context are not possible in legacy mode
if (this.terminal._mode !== this.terminal.MODES.BACKEND_NEW) {
res = await this.terminal.executeCommand(
"context write \"{'test_key': 'test_value'}\"",
false,
true
);
this.assertIn(res, "test_key");
res = await this.terminal.executeCommand(
"context set \"{'test_key': 'test_value_change'}\"",
false,
true
);
this.assertEqual(res.test_key, "test_value_change");
res = await this.terminal.executeCommand(
"context delete test_key",
false,
true
);
this.assertNotIn(res, "test_key");
}
},
test_version: async function () {
const res = await this.terminal.executeCommand(
"version",
false,
true
);
this.assertTrue(res);
},
test_longpolling: async function () {
let res = await this.terminal.executeCommand(
"longpolling -o verbose",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling -o off",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling -o add_channel -p test_channel",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling -o del_channel -p test_channel",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling -o stop",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling -o start",
false,
true
);
this.assertTrue(res);
},
test_longpolling__no_arg: async function () {
let res = await this.terminal.executeCommand(
"longpolling verbose",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling off",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling add_channel test_channel",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling del_channel test_channel",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling stop",
false,
true
);
this.assertTrue(res);
res = await this.terminal.executeCommand(
"longpolling start",
false,
true
);
this.assertTrue(res);
},
_isLogin: async function (login) {
const res = await this.terminal.executeCommand(
"whoami",
false,
true
);
return res[0]?.login === login;
},
test_login: async function () {
// Get active database
// FIXME: This type of calls are ugly, maybe some day
// can scan the dependencies.
let res = await this.terminal.executeCommand(
"dblist --only-active",
false,
true
);
const dbname = res;
res = await this.terminal.executeCommand(
`login -d ${dbname} -u demo -p demo`,
false,
true
);
this.assertTrue(res);
this.assertTrue(this._isLogin("demo"));
res = await this.terminal.executeCommand(
`login -d ${dbname} -u #admin`,
false,
true
);
this.assertTrue(res);
this.assertTrue(this._isLogin("admin"));
},
test_login__no_arg: async function () {
// Get active database
// FIXME: This type of calls are ugly, maybe some day
// can scan the dependencies.
let res = await this.terminal.executeCommand(
"dblist --only-active",
false,
true
);
const dbname = res;
res = await this.terminal.executeCommand(
`login ${dbname} demo demo`,
false,
true
);
this.assertTrue(res);
this.assertTrue(this._isLogin("demo"));
res = await this.terminal.executeCommand(
`login ${dbname} #admin`,
false,
true
);
this.assertTrue(res);
this.assertTrue(this._isLogin("admin"));
},
test_uhg: async function () {
const res = await this.terminal.executeCommand(
"uhg -g base.group_user",
false,
true
);
this.assertTrue(res);
},
test_uhg__no_arg: async function () {
const res = await this.terminal.executeCommand(
"uhg base.group_user",
false,
true
);
this.assertTrue(res);
},
test_dblist: async function () {
let res = await this.terminal.executeCommand("dblist", false, true);
this.assertNotEmpty(res);
res = await this.terminal.executeCommand(
"dblist --only-active",
false,
true
);
this.assertTrue(typeof res === "string");
},
test_tour: async function () {
// This test is incomplete to avoid page reloads
const res = await this.terminal.executeCommand("tour", false, true);
this.assertNotEmpty(res);
},
test_json: async function () {
const res = await this.terminal.executeCommand(
"json -e /web_editor/get_assets_editor_resources -d \"{'key':'web.assets_backend'}\"",
false,
true
);
this.assertIn(res, "views");
},
test_json__no_arg: async function () {
const res = await this.terminal.executeCommand(
"json /web_editor/get_assets_editor_resources \"{'key':'web.assets_backend'}\"",
false,
true
);
this.assertIn(res, "views");
},
test_depends: async function () {
const res = await this.terminal.executeCommand(
"depends -m mail",
false,
true
);
this.assertNotEmpty(res);
},
test_depends__no_arg: async function () {
const res = await this.terminal.executeCommand(
"depends mail",
false,
true
);
this.assertNotEmpty(res);
},
test_ual: async function () {
const res = await this.terminal.executeCommand("ual", false, true);
this.assertTrue(res);
},
test_count: async function () {
const res = await this.terminal.executeCommand(
"count -m res.currency",
false,
true
);
this.assertTrue(res > 0);
const resb = await this.terminal.executeCommand(
"count -m res.currency -d \"[['symbol', '=', '$']]\"",
false,
true
);
this.assertTrue(resb < res);
},
test_count__no_arg: async function () {
const res = await this.terminal.executeCommand(
"count res.currency",
false,
true
);
this.assertTrue(res > 0);
const resb = await this.terminal.executeCommand(
"count res.currency \"[['symbol', '=', '$']]\"",
false,
true
);
this.assertTrue(resb < res);
},
test_ref: async function () {
const res = await this.terminal.executeCommand(
"ref -x base.main_company,base.model_res_partner",
false,
true
);
this.assertNotEmpty(res);
this.assertEqual(res.length, 2);
},
test_ref__no_arg: async function () {
const res = await this.terminal.executeCommand(
"ref base.main_company,base.model_res_partner",
false,
true
);
this.assertNotEmpty(res);
this.assertEqual(res.length, 2);
},
test_rpc: async function () {
const res = await this.terminal.executeCommand(
"rpc -o \"{'route': '/jsonrpc', 'method': 'server_version', 'params': {'service': 'db'}}\"",
false,
true
);
this.assertNotEmpty(res);
},
test_rpc__no_arg: async function () {
const res = await this.terminal.executeCommand(
"rpc \"{'route': '/jsonrpc', 'method': 'server_version', 'params': {'service': 'db'}}\"",
false,
true
);
this.assertNotEmpty(res);
},
test_metadata: async function () {
const res = await this.terminal.executeCommand(
"metadata -m res.partner -i 1",
false,
true
);
this.assertNotEmpty(res);
this.assertEqual(res.xmlid, "base.main_partner");
},
test_metadata__no_arg: async function () {
const res = await this.terminal.executeCommand(
"metadata res.partner 1",
false,
true
);
this.assertNotEmpty(res);
this.assertEqual(res.xmlid, "base.main_partner");
},
});
});
import fs from "fs";
import path from "path";
import vscode from "vscode";
import yaml from "js-yaml";
import lockFile from "lockfile";
import untildify from "untildify";
import {activate, deactivate} from "../src/extension";
import {
COMMAND,
NOTIFICATION,
SYNCIGNORE,
getRepoInSyncMsg,
getDirectoryIsSyncedMsg,
getDirectorySyncIgnoredMsg
} from "../src/constants";
import {
SignUpHandler,
SyncHandler,
trackFileHandler,
trackRepoHandler,
unSyncHandler,
openSyncIgnoreHandler
} from "../src/handlers/commands_handler";
import {createSystemDirectories} from "../src/utils/setup_utils";
import {
addUser,
Config,
getConfigFilePath,
randomBaseRepoPath,
randomRepoPath,
setWorkspaceFolders
} from "./helpers/helpers";
import {logout} from "../src/utils/auth_utils";
import { generateSettings } from "../src/settings";
import { CodeSyncState, CODESYNC_STATES } from "../src/utils/state_utils";
describe("Extension: activate",() => {
const baseRepoPath = randomBaseRepoPath();
const repoPath = randomRepoPath();
const configPath = getConfigFilePath(baseRepoPath);
const configData = {repos: {}};
configData.repos[repoPath] = {branches: {}};
beforeEach(() => {
jest.clearAllMocks();
setWorkspaceFolders(repoPath);
untildify.mockReturnValue(baseRepoPath);
createSystemDirectories();
fs.mkdirSync(repoPath, {recursive: true});
global.IS_CODESYNC_DEV = true;
});
afterEach(() => {
fs.rmSync(repoPath, { recursive: true, force: true });
fs.rmSync(baseRepoPath, { recursive: true, force: true });
});
test("Fresh Setup, no user, no repo opened", async () => {
setWorkspaceFolders("");
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(5);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(true);
// showConnectRepoView should be false
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(false);
// isSubDir should be false
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(false);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
// CodeSyncActivated should be true
expect(vscode.commands.executeCommand.mock.calls[4][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[4][1]).toStrictEqual("CodeSyncActivated");
expect(vscode.commands.executeCommand.mock.calls[4][2]).toStrictEqual(true);
// Register commands
expect(vscode.commands.registerCommand).toHaveBeenCalledTimes(7);
expect(vscode.commands.registerCommand.mock.calls[0][0]).toStrictEqual(COMMAND.triggerSignUp);
expect(vscode.commands.registerCommand.mock.calls[0][1]).toStrictEqual(SignUpHandler);
expect(vscode.commands.registerCommand.mock.calls[1][0]).toStrictEqual(COMMAND.triggerLogout);
expect(vscode.commands.registerCommand.mock.calls[1][1]).toStrictEqual(logout);
expect(vscode.commands.registerCommand.mock.calls[2][0]).toStrictEqual(COMMAND.triggerSync);
expect(vscode.commands.registerCommand.mock.calls[2][1]).toStrictEqual(SyncHandler);
expect(vscode.commands.registerCommand.mock.calls[3][0]).toStrictEqual(COMMAND.triggerUnsync);
expect(vscode.commands.registerCommand.mock.calls[3][1]).toStrictEqual(unSyncHandler);
expect(vscode.commands.registerCommand.mock.calls[4][0]).toStrictEqual(COMMAND.trackRepo);
expect(vscode.commands.registerCommand.mock.calls[4][1]).toStrictEqual(trackRepoHandler);
expect(vscode.commands.registerCommand.mock.calls[5][0]).toStrictEqual(COMMAND.trackFile);
expect(vscode.commands.registerCommand.mock.calls[5][1]).toStrictEqual(trackFileHandler);
expect(vscode.commands.registerCommand.mock.calls[6][0]).toStrictEqual(COMMAND.openSyncIgnore);
expect(vscode.commands.registerCommand.mock.calls[6][1]).toStrictEqual(openSyncIgnoreHandler);
// createStatusBarItem
expect(vscode.window.createStatusBarItem).toHaveBeenCalledTimes(1);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(NOTIFICATION.WELCOME_MSG);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.JOIN);
expect(vscode.window.showInformationMessage.mock.calls[0][2]).toBe(NOTIFICATION.IGNORE);
// Verify events listeners are registered just fine
// onDidChangeTextDocument
expect(vscode.workspace.onDidChangeTextDocument).toHaveBeenCalledTimes(1);
// onDidCreateFiles
expect(vscode.workspace.onDidCreateFiles).toHaveBeenCalledTimes(1);
// onDidRenameFiles
expect(vscode.workspace.onDidRenameFiles).toHaveBeenCalledTimes(1);
});
test("Fresh Setup, no active user, repo not synced", async () => {
addUser(baseRepoPath, false);
setWorkspaceFolders(repoPath);
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(5);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(true);
// showConnectRepoView should be true
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(true);
// isSubDir should be false
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(false);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(NOTIFICATION.WELCOME_MSG);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.JOIN);
expect(vscode.window.showInformationMessage.mock.calls[0][2]).toBe(NOTIFICATION.IGNORE);
});
test("With user, repo not synced", async () => {
addUser(baseRepoPath);
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(7);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(false);
// showConnectRepoView should be true
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(true);
// isSubDir should be false
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(false);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(NOTIFICATION.CONNECT_REPO);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.CONNECT);
});
test("With user, repo is disconnected", async () => {
addUser(baseRepoPath);
const _configData = JSON.parse(JSON.stringify(configData));
_configData.repos[repoPath].is_disconnected = true;
fs.writeFileSync(configPath, yaml.safeDump(_configData));
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(7);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(false);
// showConnectRepoView should be true
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(true);
// isSubDir should be false
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(false);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(NOTIFICATION.CONNECT_REPO);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.CONNECT);
});
test("With user, repo is in sync", async () => {
const configUtil = new Config(repoPath, configPath);
configUtil.addRepo();
addUser(baseRepoPath);
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(7);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(false);
// showConnectRepoView should be true
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(false);
// isSubDir should be false
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(false);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
const msg = getRepoInSyncMsg(repoPath);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(msg);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.TRACK_IT);
});
test("With user, repo is sub directory and synced", async () => {
const configUtil = new Config(repoPath, configPath);
configUtil.addRepo();
addUser(baseRepoPath);
const subDir = path.join(repoPath, "directory");
setWorkspaceFolders(subDir);
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(7);
// showLogin should be false
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(false);
// showConnectRepoView should be false
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(false);
// isSubDir should be true
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(true);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(false);
const msg = getDirectoryIsSyncedMsg(subDir, repoPath);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(msg);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.TRACK_PARENT_REPO);
});
test("With user, repo is sub directory and syncignored", async () => {
const subDirName = "directory";
const configUtil = new Config(repoPath, configPath);
configUtil.addRepo();
addUser(baseRepoPath);
// Add subDir to .syncignore
const syncignorePath = path.join(repoPath, SYNCIGNORE);
fs.writeFileSync(syncignorePath, subDirName);
const subDir = path.join(repoPath, subDirName);
setWorkspaceFolders(subDir);
await activate(vscode.ExtensionContext);
expect(vscode.commands.executeCommand).toHaveBeenCalledTimes(7);
// showLogin should be true
expect(vscode.commands.executeCommand.mock.calls[0][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[0][1]).toStrictEqual("showLogIn");
expect(vscode.commands.executeCommand.mock.calls[0][2]).toStrictEqual(false);
// showConnectRepoView should be true
expect(vscode.commands.executeCommand.mock.calls[1][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[1][1]).toStrictEqual("showConnectRepoView");
expect(vscode.commands.executeCommand.mock.calls[1][2]).toStrictEqual(true);
// isSubDir should be true
expect(vscode.commands.executeCommand.mock.calls[2][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[2][1]).toStrictEqual("isSubDir");
expect(vscode.commands.executeCommand.mock.calls[2][2]).toStrictEqual(true);
// isSyncIgnored should be false
expect(vscode.commands.executeCommand.mock.calls[3][0]).toStrictEqual("setContext");
expect(vscode.commands.executeCommand.mock.calls[3][1]).toStrictEqual("isSyncIgnored");
expect(vscode.commands.executeCommand.mock.calls[3][2]).toStrictEqual(true);
const msg = getDirectorySyncIgnoredMsg(subDir, repoPath);
// Should show Welcome msg
expect(vscode.window.showInformationMessage).toHaveBeenCalledTimes(1);
expect(vscode.window.showInformationMessage.mock.calls[0][0]).toBe(msg);
expect(vscode.window.showInformationMessage.mock.calls[0][1]).toBe(NOTIFICATION.OPEN_SYNCIGNORE);
expect(vscode.window.showInformationMessage.mock.calls[0][2]).toBe(NOTIFICATION.TRACK_PARENT_REPO);
expect(vscode.window.showInformationMessage.mock.calls[0][3]).toBe(NOTIFICATION.UNSYNC_PARENT_REPO);
});
});
describe("Extension: deactivate",() => {
const baseRepoPath = randomBaseRepoPath();
untildify.mockReturnValue(baseRepoPath);
const settings = generateSettings();
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(global.console, 'log');
untildify.mockReturnValue(baseRepoPath);
createSystemDirectories();
const settings = generateSettings();
lockFile.lockSync(settings.POPULATE_BUFFER_LOCK_FILE);
lockFile.lockSync(settings.DIFFS_SEND_LOCK_FILE);
});
afterEach(() => {
lockFile.unlockSync(settings.POPULATE_BUFFER_LOCK_FILE);
lockFile.unlockSync(settings.DIFFS_SEND_LOCK_FILE);
fs.rmSync(baseRepoPath, { recursive: true, force: true });
});
test("Acquried no lock", () => {
CodeSyncState.set(CODESYNC_STATES.POPULATE_BUFFER_LOCK_ACQUIRED, false);
CodeSyncState.set(CODESYNC_STATES.DIFFS_SEND_LOCK_ACQUIRED, false);
deactivate(vscode.ExtensionContext);
expect(console.log).toHaveBeenCalledTimes(0);
expect(lockFile.checkSync(settings.POPULATE_BUFFER_LOCK_FILE)).toBe(true);
expect(lockFile.checkSync(settings.DIFFS_SEND_LOCK_FILE)).toBe(true);
});
test("Acquried populateBuffer lock", () => {
CodeSyncState.set(CODESYNC_STATES.POPULATE_BUFFER_LOCK_ACQUIRED, true);
CodeSyncState.set(CODESYNC_STATES.DIFFS_SEND_LOCK_ACQUIRED, false);
deactivate(vscode.ExtensionContext);
expect(console.log).toHaveBeenCalledTimes(0);
expect(lockFile.checkSync(settings.POPULATE_BUFFER_LOCK_FILE)).toBe(false);
expect(lockFile.checkSync(settings.DIFFS_SEND_LOCK_FILE)).toBe(true);
});
test("Acquried diffsSend lock", () => {
CodeSyncState.set(CODESYNC_STATES.POPULATE_BUFFER_LOCK_ACQUIRED, false);
CodeSyncState.set(CODESYNC_STATES.DIFFS_SEND_LOCK_ACQUIRED, true);
deactivate(vscode.ExtensionContext);
expect(console.log).toHaveBeenCalledTimes(0);
expect(lockFile.checkSync(settings.POPULATE_BUFFER_LOCK_FILE)).toBe(true);
expect(lockFile.checkSync(settings.DIFFS_SEND_LOCK_FILE)).toBe(false);
});
test("Acquried both locks", () => {
CodeSyncState.set(CODESYNC_STATES.POPULATE_BUFFER_LOCK_ACQUIRED, true);
CodeSyncState.set(CODESYNC_STATES.DIFFS_SEND_LOCK_ACQUIRED, true);
deactivate(vscode.ExtensionContext);
expect(console.log).toHaveBeenCalledTimes(0);
expect(lockFile.checkSync(settings.POPULATE_BUFFER_LOCK_FILE)).toBe(false);
expect(lockFile.checkSync(settings.DIFFS_SEND_LOCK_FILE)).toBe(false);
});
});