Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tenant change related integration tests - allow tenant change and retain tenant in shortlink #736

Merged
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
46dd03a
Test to ensure when a shortlink is copied, tenant is changed and shor…
leanneeliatra Jul 7, 2023
f68f455
After link copy, allow tenant change
leanneeliatra Jul 7, 2023
631a03f
Addressing comments, removing function to it's own file and removing …
leanneeliatra Jul 11, 2023
836089a
Spelling error rectified
leanneeliatra Jul 11, 2023
5b0df4a
Linting errors resolved
leanneeliatra Jul 12, 2023
d5f3520
Update cypress/utils/commands.js
leanneeliatra Jul 14, 2023
dee3b57
Changed data-test-subj to getElementByTestId for consitency
leanneeliatra Jul 17, 2023
9f1ac57
Switch tenant updated to use interceps and should() for improved test…
leanneeliatra Jul 18, 2023
dff22e8
switch tenant changed to use intercepts and should() for increaced te…
leanneeliatra Jul 18, 2023
2074437
Adding commen to explain how the addtion of the should() helps
leanneeliatra Jul 18, 2023
14a870b
Global declaration of the tenant removed. The clearing of session sto…
leanneeliatra Jul 18, 2023
b0cf9bd
Additition of 'createDashboard' method to allow programatic dashboard…
leanneeliatra Jul 18, 2023
c4c418a
When testing we are looking for the private tenant.
leanneeliatra Jul 18, 2023
a9db5e5
check changed to allow for both 'private' and __user__
leanneeliatra Jul 19, 2023
51d5d42
linting errors resolved Signed-off-by: leanneeliatra <leanne.laceybyr…
leanneeliatra Jul 20, 2023
e91238b
merging in changes on remote
leanneeliatra Jul 24, 2023
ec83509
Adding back --headless parameter.
leanneeliatra Jul 27, 2023
3303e23
undoing package-lock changes.
leanneeliatra Jul 27, 2023
02ad4e4
Use library from release tag instead of git reference (#706)
kavilla Jul 10, 2023
1d46c05
update testSplitTables test (#731)
curq Jul 10, 2023
00811cc
[Vis Augmenter / Feature Anywhere] Add tests in core OSD and AD plugi…
ohltyler Jul 11, 2023
9a74842
Revert "[Vis Augmenter / Feature Anywhere] Add tests in core OSD and …
manasvinibs Jul 12, 2023
f15d9ba
Test sample data with multiple data source enabled on local cluster (…
kristenTian Jul 13, 2023
2a8fd3a
[Vis Augmenter] Add tests in OSD & AD plugin (#752)
ohltyler Jul 13, 2023
6ebfd9c
fix: CVE of tough-cookie and word-wrap (#763)
SuZhou-Joe Jul 18, 2023
2432032
feat: use "overrides" to install desired version of tough-cookie and …
SuZhou-Joe Jul 20, 2023
07a6613
Improve date selection across versions of OUI (#778)
AMoo-Miki Jul 20, 2023
9507738
feat: sync cypress test from notifications-dashboards (#776) (#784)
SuZhou-Joe Jul 21, 2023
bda3d9e
[Table Visualizations] Tests cleanup (#785)
curq Jul 21, 2023
5917744
Bump dependency on opensearch-dashboards-test-library (#790)
AMoo-Miki Jul 25, 2023
e9ac430
[Table Visualizations] Test Update (#787)
curq Jul 25, 2023
e3379ff
fix discover (#803)
abbyhu2000 Aug 30, 2023
b37c0b1
Change to toast message in Reports (#578)
kavithacm Aug 30, 2023
c9990e7
fix discover (#807)
abbyhu2000 Aug 31, 2023
99a4a59
feat: add test cases for remote models (#813)
wanglam Sep 4, 2023
8528312
fix workbench download text and csv schema (#814) (#817)
opensearch-trigger-bot[bot] Sep 5, 2023
80eb972
update trace analytics cypress tests according to observability chang…
derek-ho Sep 6, 2023
f6081d9
Bump semver from 7.3.7 to 7.5.4 (#822)
dependabot[bot] Sep 7, 2023
ac153a5
[Dashboard] Retry visbuilder dashboard test (#823)
kavilla Sep 7, 2023
d6201f9
Add new tests for alerting dashboards (#832)
lezzago Sep 8, 2023
1489306
Update source element in import_vector_map_tab.spec.js (#844)
junqiu-lei Sep 13, 2023
3a3063a
Use index pattern id to find page in import_vector_map_tab.spec.js (#…
junqiu-lei Sep 14, 2023
b3e2b74
Buffer `waitForLoader` before checking for icon (#857) (#859)
opensearch-trigger-bot[bot] Sep 18, 2023
df07263
Overwrite removed and moved to after in unit test
leanneeliatra Sep 29, 2023
758300b
Merge branch 'main' into shortlink-tenancy-retained-test
leanneeliatra Oct 9, 2023
53b38e3
Update dashboard.spec.js
leanneeliatra Oct 9, 2023
2731dbf
Update dashboard_sample_data_spec.js
leanneeliatra Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cypress/integration/common/dashboard_sample_data_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export function dashboardSanityTests() {

describe('checking discover', () => {
before(() => {
cy.setAdvancedSetting({ 'discover:v2': false });
leanneeliatra marked this conversation as resolved.
Show resolved Hide resolved
// Go to the Discover page
miscUtils.visitPage('app/data-explorer/discover#/');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { CURRENT_TENANT } from '../../../utils/commands';
import { switchTenantTo } from './switch_tenant';

if (Cypress.env('SECURITY_ENABLED')) {
describe('Switch tenants when visiting copied links: ', () => {
const tenantName = 'private';

before(() => {
cy.server();
});
it('Checks that the tenant switcher can switch tenants despite a different tenant being present in the tenant query parameter.', function () {
CURRENT_TENANT.newTenant = tenantName;
leanneeliatra marked this conversation as resolved.
Show resolved Hide resolved

cy.visit('/app/home').then(() => {
cy.waitForLoader();
switchTenantTo('global');
cy.waitForLoader();
cy.getElementByTestId('account-popover').click();
cy.get('#tenantName').should('contain.text', 'Global');
leanneeliatra marked this conversation as resolved.
Show resolved Hide resolved
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export function switchTenantTo(newTenant) {
cy.getElementByTestId('account-popover').click();
cy.intercept({
method: 'GET',
url: '/api/v1/auth/dashboardsinfo',
leanneeliatra marked this conversation as resolved.
Show resolved Hide resolved
}).as('waitForDashboardsInfo');

cy.intercept({
method: 'GET',
url: '/api/v1/configuration/account',
}).as('waitForAccountInfo');

cy.getElementByTestId('switch-tenants').click();
//should ensures the dialog window is fully loaded and the radios can be selected.
cy.get('[id="' + newTenant + '"][name="tenantSwitchRadios"]').should(
'be.enabled'
);
cy.get('.euiRadio__label[for="' + newTenant + '"]').click();

cy.intercept({
method: 'POST',
url: '/api/v1/multitenancy/tenant',
}).as('waitForUpdatingTenants');
cy.getElementByTestId('tenant-switch-modal')
.find('[data-test-subj="confirm"]')
.click();

cy.wait('@waitForUpdatingTenants');

// Make sure dashboards has really reloaded.
// @waitForReloadAfterTenantSwitch should be triggered twice
cy.wait('@waitForDashboardsInfo');
cy.wait('@waitForDashboardsInfo');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { CURRENT_TENANT } from '../../../utils/commands';
import { switchTenantTo } from './switch_tenant';
import indexPatternGlobalTenantHeaderSetUp from '../../../fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternGlobalTenantHeader.json';
import indexPatternPrivateTenantHeaderSetUp from '../../../fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternPrivateTenantHeader.json';

if (Cypress.env('SECURITY_ENABLED')) {
describe('Multi Tenancy Tests: ', () => {
before(() => {
cy.server();

cy.createIndexPattern(
'index-pattern1',
{
title: 's*',
timeFieldName: 'timestamp',
},
indexPatternGlobalTenantHeaderSetUp
);

cy.createIndexPattern(
'index-pattern2',
{
title: 'se*',
timeFieldName: 'timestamp',
},
indexPatternPrivateTenantHeaderSetUp
);
});

it('Tests that when the short URL is copied and pasted, it will route correctly with the right tenant', function () {
const randomNumber = Cypress._.random(0, 1e6);
const dashboardName = 'Cypress dashboard - ' + randomNumber;
// We are programmatically creating a dashboard so that the test
// always have the same view. An empty list would show the empty prompt.
// Also, this saves us some typing, clicking and waiting in the test.
cy.createDashboard(
{
title: dashboardName,
},
{
security_tenant: 'private',
}
);

// When creating the shortUrl, we don't want to have the security_tenant
// parameter in the url - otherwise it will be stored in the shortUrl
// itself, which would make this test obsolete.
// But it is also hard to get the tests running reliably when opening
// Dashboards without the parameter (tenant selector popup etc.).
// Hence, we do some navigation to "lose" the query parameter.
CURRENT_TENANT.newTenant = 'private';
cy.visit('/app/home', {
waitForGetTenant: true,
onBeforeLoad(window) {
// set up session storage as we would expect to emulate browser
window.sessionStorage.setItem(
'opendistro::security::tenant::show_popup',
false
);

window.localStorage.setItem(
'opendistro::security::tenant::saved',
'__user__'
);
},
});
// Navigate to the Dashboards app
cy.getElementByTestId('toggleNavButton').should('be.visible').click();
// After clicking the navigation, the security_tenant parameter should be gone
cy.get('[href$="/app/dashboards#/list"]').should('be.visible').click();

// The test subj seems to replace spaces with a dash, so we convert the dashboard name here too.
// Go to the dashboard we have created
const selectorDashboardName = dashboardName.split(' ').join('-');
cy.getElementByTestId(
'dashboardListingTitleLink-' + selectorDashboardName
)
.should('be.visible')
.click();

cy.getElementByTestId('savedObjectTitle').type(dashboardName);

cy.intercept({
method: 'POST',
url: '/api/saved_objects/_bulk_get',
}).as('waitForReloadingDashboard');
cy.getElementByTestId('confirmSaveSavedObjectButton').click();
cy.wait('@waitForReloadingDashboard');
cy.wait(2000);
leanneeliatra marked this conversation as resolved.
Show resolved Hide resolved

// 2. Open top share navigation to access copy short url
cy.getElementByTestId('shareTopNavButton').click();
cy.getElementByTestId('sharePanel-Permalinks').click();

// 3. Create the short url, wait for response
cy.intercept('POST', '/api/shorten_url').as('getShortUrl');
// If the url already contains the tenant parameter, it will be stored in the short url. That will work in the app
// but would render this test useless. We're testing that resolved short urls without the tenant parameter work as well.
cy.url().should('not.contain', 'security_tenant');
cy.getElementByTestId('createShortUrl').click();
cy.wait('@getShortUrl');

//4. Switch tenant & visit shortURL link to ensure tenant from short URL is retained
cy.getElementByTestId('copyShareUrlButton')
.invoke('attr', 'data-share-url')
.should('contain', '/goto/')
.then((shortUrl) => {
cy.log('Short url is ' + shortUrl);
// Navigate away to avoid the non existing dashboard in the next tenant.
switchTenantTo('global');

// Since we can't reliably read the clipboard data, we have to append the tenant parameter manually
cy.visit(shortUrl + '?security_tenant=private', {
excludeTenant: true, // We are passing the tenant as a query parameter. Mainly because of readability.
onBeforeLoad(window) {
// Here we are simulating the new tab scenario which isn't supported by Cypress
window.sessionStorage.clear();
},
});

cy.url({ timeout: 10000 }).should('contain', 'security_tenant=');
cy.getElementByTestId('breadcrumb last').should(
'contain.text',
dashboardName
);
});
});
after(() => {
cy.deleteIndexPattern('index-pattern1', {
headers: {
securitytenant: ['global'],
'osd-xsrf': true,
},
});
cy.deleteIndexPattern('index-pattern2', {
headers: {
securitytenant: ['private'],
'osd-xsrf': true,
},
});
});
});
}
25 changes: 24 additions & 1 deletion cypress/utils/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ Cypress.Commands.overwrite('visit', (orig, url, options) => {
auth: ADMIN_AUTH,
};
}
newOptions.qs = { security_tenant: CURRENT_TENANT.defaultTenant };
if (!newOptions.excludeTenant) {
newOptions.qs = {
...newOptions.qs,
security_tenant: CURRENT_TENANT.defaultTenant,
};
}

if (waitForGetTenant) {
cy.intercept('GET', '/api/v1/multitenancy/tenant').as('getTenant');
orig(url, newOptions);
Expand Down Expand Up @@ -367,6 +373,23 @@ Cypress.Commands.add('createIndexPattern', (id, attributes, header = {}) => {
});
});

Cypress.Commands.add('createDashboard', (attributes = {}, headers = {}) => {
const url = `${Cypress.config().baseUrl}/api/saved_objects/dashboard`;

cy.request({
method: 'POST',
url,
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
...headers,
},
body: JSON.stringify({
attributes,
}),
});
});

Cypress.Commands.add('changeDefaultTenant', (attributes, header = {}) => {
const url =
Cypress.env('openSearchUrl') + '/_plugins/_security/api/tenancy/config';
Expand Down
14 changes: 14 additions & 0 deletions cypress/utils/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ declare namespace Cypress {
header: string,
): Chainable<S>;

/**
* Adds a dashboard
* @example
* cy.createDashboard({ title: 'My dashboard'})
*/
createDashboard<S = any>(
attributes: {
title: string;
[key: string]: any;
},
headers?: {
[key: string]: any;
}
): Chainable<S>;

/**
* Changes the Default tenant for the domain.
Expand Down
Loading