mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
d1803dddb7
Summary: Moving some tests in preparation for some new development work. Test Plan: moving tests Reviewers: jordigh Reviewed By: jordigh Differential Revision: https://phab.getgrist.com/D4374
506 lines
23 KiB
TypeScript
506 lines
23 KiB
TypeScript
/**
|
|
* Test of the UI for Granular Access Control, part 1.
|
|
*/
|
|
import { assert, driver, Key, stackWrapFunc } from 'mocha-webdriver';
|
|
import { enterRulePart, findDefaultRuleSet, findRuleSet,
|
|
findTable, triggerAutoComplete } from 'test/nbrowser/aclTestUtils';
|
|
import * as gu from 'test/nbrowser/gristUtils';
|
|
import { server } from 'test/nbrowser/testServer';
|
|
import { setupTestSuite } from 'test/nbrowser/testUtils';
|
|
|
|
describe('AccessRules1', function() {
|
|
this.timeout(20000);
|
|
const cleanup = setupTestSuite();
|
|
let docId: string;
|
|
|
|
before(async function() {
|
|
// Import a test document we've set up for this.
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
docId = (await mainSession.tempDoc(cleanup, 'ACL-Test.grist', {load: false})).id;
|
|
|
|
// Share it with a few users.
|
|
const api = mainSession.createHomeApi();
|
|
await api.updateDocPermissions(docId, { users: {
|
|
[gu.translateUser("user2").email]: 'owners',
|
|
[gu.translateUser("user3").email]: 'editors',
|
|
} });
|
|
return docId;
|
|
});
|
|
|
|
afterEach(() => gu.checkForErrors());
|
|
|
|
const getTableNamesToAddWidget = stackWrapFunc(async function(): Promise<string[]> {
|
|
await gu.openAddWidgetToPage();
|
|
const options = await driver.findAll('.test-wselect-table', e => e.getText());
|
|
// Close add widget popup
|
|
await driver.sendKeys(Key.ESCAPE);
|
|
|
|
assert.equal(options[0], "New Table");
|
|
return options.slice(1);
|
|
});
|
|
|
|
const checkFullView = stackWrapFunc(async function(user: gu.TestUser) {
|
|
const session = await gu.session().teamSite.user(user).login();
|
|
await session.loadDoc(`/doc/${docId}`);
|
|
|
|
// Check that we can see and add widgets for FinancialsTable.
|
|
assert.deepEqual(await gu.getPageNames(), ['ClientsTable', 'FinancialsTable']);
|
|
assert.deepEqual(await getTableNamesToAddWidget(), ['ClientsTable', 'FinancialsTable']);
|
|
await gu.openPage('FinancialsTable');
|
|
await gu.waitForServer();
|
|
assert.deepEqual(await gu.getVisibleGridCells({cols: ['Year', 'Income', 'Expenses'], rowNums: [1, 2, 3]}), [
|
|
'2010', '$123.40', '$540,000.00',
|
|
'2011', '$1,234.50', '$640,000.00',
|
|
'2022', '$1,234,567.00', '$0.55',
|
|
]);
|
|
|
|
// Check that we can see RumorsColumn of ClientsTable.
|
|
await gu.openPage('ClientsTable');
|
|
await gu.waitForServer();
|
|
assert.equal(await driver.findContent('.column_name', /RumorsColumn/).isPresent(), true);
|
|
assert.deepEqual(await gu.getVisibleGridCells({cols: ['RumorsColumn'], rowNums: [1, 3, 9, 13]}), [
|
|
'Secrets', '', 'Dark rumors', 'Buzz'
|
|
]);
|
|
|
|
// Check that we can all rows of ClientsTable
|
|
assert.deepEqual(await gu.getVisibleGridCells({cols: ['First Name', 'Shared'], rowNums: [1, 3, 9, 13]}), [
|
|
'Deina', 'false',
|
|
'Terrence', 'true',
|
|
'Rachele', 'true',
|
|
'Erny', 'false',
|
|
]);
|
|
});
|
|
|
|
const checkLimitedView = stackWrapFunc(async function(user: gu.TestUser) {
|
|
const session = await gu.session().teamSite.user(user).login();
|
|
await session.loadDoc(`/doc/${docId}`);
|
|
|
|
assert.deepEqual(await gu.getPageNames(), ['ClientsTable']);
|
|
assert.deepEqual(await getTableNamesToAddWidget(), ['ClientsTable']);
|
|
await gu.openPage('ClientsTable');
|
|
await gu.waitForServer();
|
|
assert.equal(await driver.findContent('.column_name', /RumorsColumn/).isPresent(), false);
|
|
});
|
|
|
|
const checkLimitedUpdateMemo = stackWrapFunc(async function(user: gu.TestUser, memo: string = '') {
|
|
const session = await gu.session().teamSite.user(user).login();
|
|
await session.loadDoc(`/doc/${docId}`);
|
|
await gu.openPage('ClientsTable');
|
|
await gu.waitForServer();
|
|
await gu.getCell(0, 1).click();
|
|
await gu.sendKeys('Will it work?', Key.ENTER);
|
|
await gu.waitForServer();
|
|
if (memo === '') {
|
|
assert.isFalse(await driver.find('.test-notifier-toast-memo').isPresent());
|
|
} else {
|
|
await driver.findContent('.test-notifier-toast-memo', memo);
|
|
}
|
|
});
|
|
|
|
it('should support rules for tables and columns', async function() {
|
|
this.timeout(40000);
|
|
// Check that users 1 and 3 can see everything initially.
|
|
await checkFullView('user1');
|
|
await checkFullView('user3');
|
|
|
|
// Load Access Rules UI.
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000); // Wait for initialization fetch to complete.
|
|
|
|
// Make FinancialsTable private to user1.
|
|
await driver.findContentWait('button', /Add Table Rules/, 2000).click();
|
|
await driver.findContentWait('.grist-floating-menu li', /FinancialsTable/, 3000).click();
|
|
let ruleSet = findDefaultRuleSet(/FinancialsTable/);
|
|
await enterRulePart(ruleSet, 1, null, 'Deny All');
|
|
await ruleSet.find('.test-rule-part .test-rule-add').click();
|
|
await enterRulePart(ruleSet, 1, `user.Email == '${gu.translateUser('user1').email}'`, 'Allow All');
|
|
|
|
// Make RumorsColumn of ClientsTable private to user1.
|
|
await driver.findContentWait('button', /Add Table Rules/, 2000).click();
|
|
await driver.findContent('.grist-floating-menu li', /ClientsTable/).click();
|
|
await findTable(/ClientsTable/).find('.test-rule-table-menu-btn').click();
|
|
await driver.findContent('.grist-floating-menu li', /Add Column Rule/).click();
|
|
ruleSet = findRuleSet(/ClientsTable/, 1);
|
|
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
assert.deepEqual(
|
|
await driver.findAll('.test-select-menu li', el => el.getText()),
|
|
[
|
|
'Agent_Email',
|
|
'Email',
|
|
'First_Name',
|
|
'Last_Name',
|
|
'Phone',
|
|
'RumorsColumn',
|
|
'Shared',
|
|
]
|
|
);
|
|
await driver.findContent('.test-select-menu li', 'RumorsColumn').click();
|
|
await enterRulePart(ruleSet, 1, null, 'Deny All');
|
|
await ruleSet.find('.test-rule-part .test-rule-add').click();
|
|
await enterRulePart(ruleSet, 1, `user.Email == '${gu.translateUser('user1').email}'`, 'Allow All');
|
|
|
|
// Make rows of ClientsTable only visible to the team if assigned to them, or marked as shared.
|
|
ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await ruleSet.find('.test-rule-part .test-rule-add').click();
|
|
await ruleSet.find('.test-rule-part .test-rule-add').click();
|
|
await ruleSet.find('.test-rule-part .test-rule-add').click();
|
|
await enterRulePart(ruleSet, 1, `user.Email == '${gu.translateUser('user1').email}'`, 'Allow All');
|
|
await enterRulePart(ruleSet, 2, `rec.Shared`, {R: 'allow'});
|
|
await enterRulePart(ruleSet, 3, `user.Email == rec.Agent_Email`, {R: 'allow'});
|
|
await enterRulePart(ruleSet, 4, null, 'Deny All');
|
|
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
|
|
// Check that user1 can see FinancialsTable, RumorsColumn, and all rows of ClientsTable.
|
|
await checkFullView('user1');
|
|
|
|
// Check that user2 cannot see FinancialsTable or RumorsColumn.
|
|
await checkLimitedView('user2');
|
|
|
|
// Check that user2 only sees certain rows of ClientsTable.
|
|
assert.deepEqual(await gu.getVisibleGridCells(
|
|
{cols: ['First Name', 'Agent Email', 'Shared'], rowNums: [1, 3, 6, 7, 8, 9, 10]}
|
|
), [
|
|
// Everyone assigned to charon is visible.
|
|
'Deina', 'gristoid+charon@gmail.com', 'false',
|
|
'Terrence', 'gristoid+charon@gmail.com', 'true',
|
|
'Wyndham', 'gristoid+charon@gmail.com', 'false',
|
|
// And everyone with Shared = true is visible.
|
|
'Rachele', 'gristoid+chimpy@gmail.com', 'true',
|
|
'Elianore', 'gristoid+kiwi@gmail.com', 'true',
|
|
'Ellsworth', 'gristoid+kiwi@gmail.com', 'true',
|
|
'', '', ''
|
|
]);
|
|
|
|
// Check that user3 cannot see FinancialsTable or RumorsColumn.
|
|
await checkLimitedView('user3');
|
|
|
|
// Check that user3 only sees certain rows of ClientsTable.
|
|
assert.deepEqual(await gu.getVisibleGridCells(
|
|
{cols: ['First Name', 'Agent Email', 'Shared'], rowNums: [1, 2, 3, 4, 9, 11, 12]}
|
|
), [
|
|
// And everyone with Shared = true is visible.
|
|
'Siobhan', 'gristoid+charon@gmail.com', 'true',
|
|
'Terrence', 'gristoid+charon@gmail.com', 'true',
|
|
'Rachele', 'gristoid+chimpy@gmail.com', 'true',
|
|
// Everyone assigned to kiwi is visible.
|
|
'Kettie', 'gristoid+kiwi@gmail.com', 'false',
|
|
'Neely', 'gristoid+kiwi@gmail.com', 'false',
|
|
'Ellsworth', 'gristoid+kiwi@gmail.com', 'true',
|
|
'', '', '',
|
|
]);
|
|
});
|
|
|
|
it('should support rules with rec.id in formula', async function() {
|
|
// This tests behavior that broke after a bug was introduced.
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
const ruleSet = findDefaultRuleSet(/FinancialsTable/);
|
|
await enterRulePart(ruleSet, 1, `rec.id == 1`, 'Allow All');
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
await gu.openPage('FinancialsTable');
|
|
await gu.waitForServer();
|
|
assert.deepEqual(
|
|
await gu.getVisibleGridCells({cols: ['Expenses', 'Income', 'Year'], rowNums: [1, 2]}),
|
|
[
|
|
'$540,000.00', '$123.40', '2010',
|
|
'', '', ''
|
|
]
|
|
);
|
|
await gu.undo();
|
|
});
|
|
|
|
it('should support adding memos', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000); // Wait for initialization fetch to complete.
|
|
|
|
// Change the catch-all rule on ClientsTable to read-only permission, and give it a memo.
|
|
const ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await enterRulePart(ruleSet, 4, null, 'Read Only', 'Sorry, this table is read-only.');
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
|
|
// Check that user2 sees the memo when trying to update ClientsTable.
|
|
await checkLimitedUpdateMemo('user2', 'Sorry, this table is read-only');
|
|
});
|
|
|
|
it('should support removing memos', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000); // Wait for initialization fetch to complete.
|
|
|
|
// Delete the memo for the ClientsTable catch-all rule.
|
|
await gu.session().teamSite.user('user1').login();
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
const ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await ruleSet.find('.test-rule-part-and-memo:nth-child(4) .test-rule-memo-remove').click();
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
|
|
// Check that user2 no longer sees the memo.
|
|
await checkLimitedUpdateMemo('user2');
|
|
});
|
|
|
|
it('should not produce unnecessary user actions when changing rules', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000); // Wait for initialization fetch to complete.
|
|
|
|
// Revert a rule that was modified in an earlier test.
|
|
let ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await enterRulePart(ruleSet, 4, null, 'Deny All');
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
|
|
// Add/remove a rule; unchanged AccessRules should still show as Saved.
|
|
ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-add').click();
|
|
await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-remove').click();
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
|
|
// Add a rule part, remove another rule part, and save.
|
|
ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-add').click();
|
|
// Add a rule giving user2 (charon) access.
|
|
await enterRulePart(ruleSet, 1, `user.Email == '${gu.translateUser('user2').email}'`, {R: 'allow'});
|
|
// Remove the rule giving everyone access to Shared rows.
|
|
await ruleSet.find('.test-rule-part-and-memo:nth-child(3) .test-rule-remove').click();
|
|
|
|
// Check that the Save button is enabled, and save.
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), true);
|
|
await gu.userActionsCollect();
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
|
|
await gu.userActionsVerify([
|
|
["BulkRemoveRecord", "_grist_ACLRules", [6]],
|
|
["BulkAddRecord", "_grist_ACLRules", [-1], {
|
|
aclFormula: ["user.Email == 'gristoid+charon@gmail.com'"],
|
|
permissionsText: ["+R"],
|
|
resource: [5],
|
|
rulePos: [4.5],
|
|
memo: [""],
|
|
}],
|
|
]);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
|
|
// Check that the rule has an effect: user3 has limited access, and cannot see Shared rows except their own.
|
|
await checkLimitedView('user3');
|
|
assert.deepEqual(await gu.getVisibleGridCells(
|
|
{cols: ['First Name', 'Agent Email', 'Shared'], rowNums: [1, 6, 8, 9]}
|
|
), [
|
|
'Kettie', 'gristoid+kiwi@gmail.com', 'false',
|
|
'Neely', 'gristoid+kiwi@gmail.com', 'false',
|
|
'Ellsworth', 'gristoid+kiwi@gmail.com', 'true',
|
|
'', '', '',
|
|
]);
|
|
});
|
|
|
|
it('should report errors when typed-in rule is invalid', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
const ruleSet = findDefaultRuleSet(/ClientsTable/);
|
|
await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-add').click();
|
|
await enterRulePart(ruleSet, 1, `user.Access === 'owners'`, {R: 'allow'});
|
|
await gu.waitForServer();
|
|
|
|
// Check that an error is shown, and save button is disabled.
|
|
assert.match(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').getText(),
|
|
/^SyntaxError/);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').getText(), 'Invalid');
|
|
|
|
// Check that invalid names are also detected.
|
|
await enterRulePart(ruleSet, 1, `fuser.Access == 'owners'`, {R: 'allow'});
|
|
await gu.waitForServer();
|
|
assert.match(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').getText(),
|
|
/Unknown variable 'fuser'/);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').getText(), 'Invalid');
|
|
|
|
// Check that invalid colIds are detected.
|
|
await enterRulePart(ruleSet, 1, `rec.Shared == True or rec.Sharedd == True`, {R: 'allow'});
|
|
await gu.waitForServer();
|
|
assert.match(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').getText(),
|
|
/Invalid columns: Sharedd/);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').getText(), 'Invalid');
|
|
|
|
// Check that saving is also disabled while checking rules.
|
|
await server.pauseUntil(async () => {
|
|
await enterRulePart(ruleSet, 1, `user.Access == 'owners'`, {R: 'allow'});
|
|
assert.equal(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').isPresent(), false);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').getText(), 'Checking…');
|
|
});
|
|
|
|
// Once rules are checked to be valid, the Save button is shown.
|
|
await gu.waitForServer();
|
|
assert.equal(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').isPresent(), false);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), false);
|
|
|
|
// Revert the changes in this test case.
|
|
await driver.find('.test-rules-revert').click();
|
|
await gu.waitForServer();
|
|
});
|
|
|
|
it('should allow read control for columns with rec in formula', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}`);
|
|
await driver.find('.test-tools-access-rules').click();
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
|
|
// Add a column rule that uses rec but doesn't set read permission.
|
|
await findTable(/FinancialsTable/).find('.test-rule-table-menu-btn').click();
|
|
await driver.findContent('.grist-floating-menu li', /Add Column Rule/).click();
|
|
let ruleSet = findRuleSet(/FinancialsTable/, 1);
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
assert.deepEqual(
|
|
await driver.findAll('.test-select-menu li', el => el.getText()),
|
|
['Expenses', 'Income', 'Year']
|
|
);
|
|
await driver.findContent('.test-select-menu li', 'Year').click();
|
|
await enterRulePart(ruleSet, 1, 'rec.Year == "yore"', {U: 'deny'});
|
|
await gu.waitForServer();
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
|
|
// Attempting to set read bit should no longer result in a notification.
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
ruleSet = findRuleSet(/FinancialsTable/, 1);
|
|
await assert.isFulfilled(enterRulePart(ruleSet, 1, null, {R: 'deny'}));
|
|
await gu.checkForErrors();
|
|
|
|
// Remove rule.
|
|
await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-remove').click();
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
});
|
|
|
|
it('should report possible order-dependencies', async function() {
|
|
// Make a rule for FinancialsTable.Year and FinancialsTable.Income that denies something.
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}/p/acl`, {wait: false});
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
await findTable(/FinancialsTable/).find('.test-rule-table-menu-btn').click();
|
|
await driver.findContent('.grist-floating-menu li', /Add Column Rule/).click();
|
|
let ruleSet = findRuleSet(/FinancialsTable/, 1);
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
assert.deepEqual(
|
|
await driver.findAll('.test-select-menu li', el => el.getText()),
|
|
['Expenses', 'Income', 'Year']
|
|
);
|
|
await driver.findContent('.test-select-menu li', 'Year').click();
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
await driver.findContent('.test-select-menu li', 'Income').click();
|
|
await enterRulePart(ruleSet, 1, 'user.Email == "noone1"', {R: 'deny'});
|
|
|
|
// Make a rule for FinancialsTable.Year and FinancialsTable.Expenses that allows something.
|
|
await findTable(/FinancialsTable/).find('.test-rule-table-menu-btn').click();
|
|
await driver.findContent('.grist-floating-menu li', /Add Column Rule/).click();
|
|
ruleSet = findRuleSet(/FinancialsTable/, 2);
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
assert.deepEqual(
|
|
await driver.findAll('.test-select-menu li', el => el.getText()),
|
|
['Expenses', 'Income', 'Year']
|
|
);
|
|
await driver.findContent('.test-select-menu li', 'Year').click();
|
|
await ruleSet.find('.test-rule-resource .test-select-open').click();
|
|
await driver.findContent('.test-select-menu li', 'Expenses').click();
|
|
await enterRulePart(ruleSet, 1, 'user.Email == "noone2"', {R: 'allow'});
|
|
|
|
// Check that trying to save throws an error.
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
await driver.findContent('.test-notifier-toast-wrapper',
|
|
/Column Year appears .* table FinancialsTable .* might be order-dependent/);
|
|
await gu.wipeToasts();
|
|
|
|
// Tweak one rule to be compatible (no order dependency) with the other, and recheck.
|
|
await enterRulePart(ruleSet, 1, 'user.Email == "noone2"', {R: 'deny'});
|
|
await gu.waitForServer();
|
|
assert.lengthOf(await gu.getToasts(), 0);
|
|
});
|
|
|
|
it("'Add Widget to Page' should be disabled", async() => {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}/p/acl`, {wait: false});
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
await driver.find('.test-dp-add-new').doClick();
|
|
assert.includeMembers(await driver.findAll('.test-dp-add-new-menu > li.disabled', (imp) => imp.getText()), [
|
|
"Add Widget to Page",
|
|
]);
|
|
await driver.sendKeys(Key.ESCAPE);
|
|
await gu.waitAppFocus();
|
|
});
|
|
|
|
it('should support dollar syntax in the editor', async function() {
|
|
const mainSession = await gu.session().teamSite.user('user1').login();
|
|
await mainSession.loadDoc(`/doc/${docId}/p/acl`, {wait: false});
|
|
// Wait for ACL page to load.
|
|
await driver.findWait('.test-rule-set', 2000);
|
|
// Add rules for FinancialsTable.
|
|
const ruleSet = findRuleSet(/FinancialsTable/, 1);
|
|
// Use new syntax to hide Year 2010.
|
|
|
|
// First make sure we have autocomplete working.
|
|
await triggerAutoComplete(ruleSet, 1, '$');
|
|
await gu.waitToPass(async () => {
|
|
const completions = await driver.findAll('.ace_autocomplete .ace_line', el => el.getText());
|
|
assert.deepEqual(completions, [
|
|
'$\nExpenses\n ',
|
|
'$\nid\n ',
|
|
'$\nIncome\n ',
|
|
'$\nYear\n ',
|
|
]);
|
|
});
|
|
await driver.sendKeys(Key.ESCAPE);
|
|
|
|
// Next test that column is understood.
|
|
await enterRulePart(ruleSet, 1, '1 == 1 and (rec.Year != "2" and $Year2 == "2010")', {R: 'deny'});
|
|
await gu.waitForServer();
|
|
assert.match(await ruleSet.find('.test-rule-part:nth-child(1) .test-rule-error').getText(),
|
|
/Invalid columns: Year2/);
|
|
assert.equal(await driver.find('.test-rules-save').isDisplayed(), false);
|
|
assert.equal(await driver.find('.test-rules-non-save').isDisplayed(), true);
|
|
assert.equal(await driver.find('.test-rules-non-save').getText(), 'Invalid');
|
|
|
|
// Now apply the rule.
|
|
await enterRulePart(ruleSet, 1, '($Year == "2010" or rec.Year == "2011")', {R: 'deny'});
|
|
await gu.waitForServer();
|
|
// Remove second rule that hides table for everyone.
|
|
await ruleSet.find('.test-rule-part-and-memo:nth-child(2) .test-rule-remove').click();
|
|
|
|
await driver.find('.test-rules-save').click();
|
|
await gu.waitForServer();
|
|
// Test that this rule works.
|
|
await gu.openPage("FinancialsTable");
|
|
assert.deepEqual(await gu.getVisibleGridCells(
|
|
{cols: ['Year'], rowNums: [1, 2]}
|
|
), [
|
|
'2022',
|
|
'',
|
|
]);
|
|
});
|
|
});
|