From 1970290ad5a5f00bb915c9302fe03e136091df63 Mon Sep 17 00:00:00 2001
From: "opensearch-trigger-bot[bot]"
 <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 11:12:10 +0800
Subject: [PATCH] Add workspace initial page functional tests (#1636) (#1641)

* Add workspace initial page funtional tests

Signed-off-by: yubonluo <yubonluo@amazon.com>

* Fix error

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

* fix test error

Signed-off-by: yubonluo <yubonluo@amazon.com>

* fix test error

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

---------

Signed-off-by: yubonluo <yubonluo@amazon.com>
(cherry picked from commit 268a50c28dbd8cdc18c53e70f6d5b099904488cf)

Co-authored-by: yuboluo <yubonluo@amazon.com>
---
 .../workspace/workspaceTestRole.json          |  17 ++
 .../workspace/workspaceTestRoleMapping.json   |   3 +
 .../workspace/workspaceTestUser.json          |   3 +
 .../mds_workspace_initial.spec.js             | 265 ++++++++++++++++++
 .../security-dashboards-plugin/commands.js    |  24 ++
 5 files changed, 312 insertions(+)
 create mode 100644 cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRole.json
 create mode 100644 cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRoleMapping.json
 create mode 100644 cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestUser.json
 create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_initial.spec.js

diff --git a/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRole.json b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRole.json
new file mode 100644
index 000000000..167afbb74
--- /dev/null
+++ b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRole.json
@@ -0,0 +1,17 @@
+{
+    "cluster_permissions": ["*"],
+    "index_permissions": [
+      {
+        "index_patterns": ["*"],
+        "fls": [],
+        "masked_fields": [],
+        "allowed_actions": ["*"]
+      }
+    ],
+    "tenant_permissions": [
+      {
+        "tenant_patterns": ["*"],
+        "allowed_actions": ["kibana_all_write"]
+      }
+    ]
+  }
\ No newline at end of file
diff --git a/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRoleMapping.json b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRoleMapping.json
new file mode 100644
index 000000000..95ddce0da
--- /dev/null
+++ b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRoleMapping.json
@@ -0,0 +1,3 @@
+{
+    "users": ["workspace-test"]
+  }
\ No newline at end of file
diff --git a/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestUser.json b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestUser.json
new file mode 100644
index 000000000..6e9ccf873
--- /dev/null
+++ b/cypress/fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestUser.json
@@ -0,0 +1,3 @@
+{
+    "password": "testUserPassword123"
+  }
\ No newline at end of file
diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_initial.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_initial.spec.js
new file mode 100644
index 000000000..48d7a95ba
--- /dev/null
+++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_initial.spec.js
@@ -0,0 +1,265 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { MiscUtils } from '@opensearch-dashboards-test/opensearch-dashboards-test-library';
+import { ADMIN_AUTH } from '../../../../utils/commands';
+import workspaceTestUser from '../../../../fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestUser.json';
+import workspaceTestRole from '../../../../fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRole.json';
+import workspaceTestRoleMapping from '../../../../fixtures/dashboard/opensearch_dashboards/workspace/workspaceTestRoleMapping.json';
+
+const miscUtils = new MiscUtils(cy);
+const workspaceName = 'test_workspace';
+let workspaceId;
+let workspaceFeatures = ['use-case-observability'];
+const NONE_DASHBOARDS_ADMIN_USERNAME = 'workspace-test';
+const WORKSPACE_TEST_ROLE_NAME = 'workspace-test-role';
+
+if (Cypress.env('WORKSPACE_ENABLED')) {
+  describe('Workspace initial', () => {
+    describe('OSD admin user visits workspace initial page', () => {
+      before(() => {
+        cy.deleteWorkspaceByName(workspaceName);
+        cy.createWorkspace({
+          name: workspaceName,
+          features: workspaceFeatures,
+          settings: {
+            permissions: {
+              library_write: { users: ['%me%'] },
+              write: { users: ['%me%'] },
+            },
+          },
+        }).then((value) => (workspaceId = value));
+      });
+
+      beforeEach(() => {
+        // Visit workspace initial page
+        miscUtils.visitPage(`/app/home`);
+      });
+
+      after(() => {
+        cy.deleteWorkspaceById(workspaceId);
+      });
+
+      it('should contain correct content', () => {
+        // Contain initial page title and description
+        cy.contains('Welcome to OpenSearch').should('exist');
+        cy.contains('My workspaces').should('exist');
+        cy.contains(
+          'Collaborate on use-case based projects with workspaces. Select a workspace to get started.'
+        ).should('exist');
+
+        // Contain five use case title
+        cy.contains('Observability').should('exist');
+        cy.contains('Security Analytics').should('exist');
+        cy.contains('Search').should('exist');
+        cy.contains('Essentials').should('exist');
+        cy.contains('Analytics').should('exist');
+
+        // Contain no workspace message
+        cy.contains('No workspaces').should('exist');
+        cy.contains(
+          'Create a workspace or request a workspace owner to add you as a collaborator.'
+        ).should('exist');
+
+        // Contain created workspaces
+        cy.contains(workspaceName).should('exist');
+        cy.contains(
+          'Gain visibility into system health, performance, and reliability through monitoring of logs, metrics and traces.'
+        ).should('not.exist');
+
+        // Contain correct link
+        cy.contains('a', 'Learn more from documentation').should('exist');
+        cy.get(
+          'a[href="https://opensearch.org/docs/latest/opensearch/index/"]'
+        ).should('have.attr', 'target', '_blank');
+        cy.contains(
+          'a',
+          'Explore live demo environment at playground.opensearch.org'
+        ).should('exist');
+        cy.get('a[href="https://playground.opensearch.org/"]').should(
+          'have.attr',
+          'target',
+          '_blank'
+        );
+
+        // Contain left bottom button
+        cy.get('[id$="popoverForSettingsIcon"]').should('exist');
+        cy.getElementByTestId('openDevToolsModal').should('exist');
+        if (Cypress.env('SECURITY_ENABLED')) {
+          cy.getElementByTestId('account-popover').should('exist');
+        }
+      });
+
+      it('should show correct use case information', () => {
+        cy.getElementByTestId(
+          'workspace-initial-useCaseCard-observability-button-information'
+        ).click();
+        cy.contains('Use cases').should('exist');
+        cy.contains(
+          'Gain visibility into system health, performance, and reliability through monitoring of logs, metrics and traces.'
+        ).should('exist');
+      });
+
+      it('should navigate to the workspace', () => {
+        cy.contains(workspaceName).click();
+
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/w/${workspaceId}/app/`
+        );
+      });
+
+      it('should return user to homepage when clicking home icon and show correct recent access message', () => {
+        cy.contains(workspaceName).click();
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/w/${workspaceId}/app/`
+        );
+        cy.get('button[aria-label="go-to-home"]').click();
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/home`
+        );
+
+        cy.contains('Viewed a few seconds ago');
+      });
+
+      it('should click create button and navigate to workspace create page', () => {
+        // Click the create button at the upper right corner
+        cy.getElementByTestId(
+          'workspace-initial-card-createWorkspace-button'
+        ).click();
+
+        cy.getElementByTestId(
+          'workspace-initial-button-create-essentials-workspace'
+        ).click();
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/workspace_create`
+        );
+        cy.location('hash').should('include', 'useCase=Essentials');
+
+        cy.getElementByTestId('workspaceUseCase-essentials')
+          .get(`input[type="radio"]`)
+          .should('be.checked');
+
+        miscUtils.visitPage(`/app/home`);
+        // Click the use case create icon button
+        cy.getElementByTestId(
+          'workspace-initial-useCaseCard-observability-button-createWorkspace'
+        ).click();
+
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/workspace_create`
+        );
+        cy.location('hash').should('include', 'useCase=Observability');
+
+        cy.getElementByTestId('workspaceUseCase-observability')
+          .get(`input[type="radio"]`)
+          .should('be.checked');
+
+        miscUtils.visitPage(`/app/home`);
+        // Click the create button in no workspace message
+        cy.getElementByTestId(
+          'workspace-initial-useCaseCard-search-button-createWorkspace'
+        ).click();
+
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/workspace_create`
+        );
+        cy.location('hash').should('include', 'useCase=Search');
+
+        cy.getElementByTestId('workspaceUseCase-search')
+          .get(`input[type="radio"]`)
+          .should('be.checked');
+      });
+
+      it('should navigate to workspace list page with use case filter', () => {
+        // Click will all button in the use case card
+        cy.getElementByTestId(
+          'workspace-initial-useCaseCard-observability-button-view'
+        ).click();
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/workspace_list`
+        );
+        cy.location('hash').should('include', 'useCase=Observability');
+        cy.contains(workspaceName).should('exist');
+
+        // Default filtering based on use cases
+        cy.get('input[type="search"]').should(
+          'have.value',
+          'useCase:"Observability"'
+        );
+
+        miscUtils.visitPage(`/app/home`);
+        // Click will all workspace button
+        cy.contains('View all workspaces').click();
+        cy.location('pathname', { timeout: 6000 }).should(
+          'include',
+          `/app/workspace_list`
+        );
+
+        cy.contains(workspaceName).should('exist');
+        cy.get('input[type="search"]').should('have.value', '');
+      });
+    });
+
+    if (Cypress.env('SECURITY_ENABLED')) {
+      describe('Non OSD admin user visits workspace initial page', () => {
+        const originalUser = ADMIN_AUTH.username;
+        const originalPassword = ADMIN_AUTH.password;
+        before(() => {
+          cy.createInternalUser(
+            NONE_DASHBOARDS_ADMIN_USERNAME,
+            workspaceTestUser
+          );
+          cy.createRole(WORKSPACE_TEST_ROLE_NAME, workspaceTestRole);
+          cy.createRoleMapping(
+            WORKSPACE_TEST_ROLE_NAME,
+            workspaceTestRoleMapping
+          );
+        });
+        beforeEach(() => {
+          // Login as non OSD admin user
+          ADMIN_AUTH.newUser = NONE_DASHBOARDS_ADMIN_USERNAME;
+          ADMIN_AUTH.newPassword = workspaceTestUser.password;
+          // Visit workspace initial page
+          miscUtils.visitPage(`/app/home`);
+        });
+        after(() => {
+          ADMIN_AUTH.newUser = originalUser;
+          ADMIN_AUTH.newPassword = originalPassword;
+          cy.deleteRoleMapping(WORKSPACE_TEST_ROLE_NAME);
+          cy.deleteInternalUser(NONE_DASHBOARDS_ADMIN_USERNAME);
+          cy.deleteRole(WORKSPACE_TEST_ROLE_NAME);
+        });
+
+        it('should show correct no workspaces content', () => {
+          cy.contains('Welcome to OpenSearch').should('exist');
+
+          // Contain correct no workspaces message
+          cy.contains('No workspaces').should('exist');
+          cy.contains(
+            'Request a workspace owner to add you as a collaborator.'
+          ).should('exist');
+
+          // Not contain the create buttons
+          cy.getElementByTestId(
+            'workspace-initial-card-createWorkspace-button'
+          ).should('not.exist');
+          cy.getElementByTestId(
+            'workspace-initial-useCaseCard-observability-button-createWorkspace'
+          ).should('not.exist');
+          cy.getElementByTestId(
+            'workspace-initial-useCaseCard-search-button-createWorkspace'
+          ).should('not.exist');
+        });
+      });
+    }
+  });
+}
diff --git a/cypress/utils/plugins/security-dashboards-plugin/commands.js b/cypress/utils/plugins/security-dashboards-plugin/commands.js
index a0d901af0..f711487f6 100644
--- a/cypress/utils/plugins/security-dashboards-plugin/commands.js
+++ b/cypress/utils/plugins/security-dashboards-plugin/commands.js
@@ -29,6 +29,14 @@ Cypress.Commands.add('createInternalUser', (userID, userJson) => {
   cy.wait(10000);
 });
 
+Cypress.Commands.add('deleteInternalUser', (userID) => {
+  cy.request(
+    'DELETE',
+    `${Cypress.env('openSearchUrl')}${SEC_API.INTERNALUSERS_BASE}/${userID}`
+  );
+  cy.wait(10000);
+});
+
 Cypress.Commands.add('createRole', (roleID, roleJson) => {
   cy.request(
     'PUT',
@@ -38,6 +46,14 @@ Cypress.Commands.add('createRole', (roleID, roleJson) => {
   cy.wait(10000);
 });
 
+Cypress.Commands.add('deleteRole', (roleID) => {
+  cy.request(
+    'DELETE',
+    `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_BASE}/${roleID}`
+  );
+  cy.wait(10000);
+});
+
 Cypress.Commands.add('createRoleMapping', (roleID, rolemappingJson) => {
   cy.request(
     'PUT',
@@ -46,3 +62,11 @@ Cypress.Commands.add('createRoleMapping', (roleID, rolemappingJson) => {
   );
   cy.wait(10000);
 });
+
+Cypress.Commands.add('deleteRoleMapping', (roleID) => {
+  cy.request(
+    'DELETE',
+    `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_MAPPING_BASE}/${roleID}`
+  );
+  cy.wait(10000);
+});