snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console @compliance_export
|
||||
|
||||
import {verifyExportedMessagesCount, editLastPost} from './helpers';
|
||||
|
||||
describe('Compliance Export', () => {
|
||||
let teamName;
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('Compliance');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
MessageExportSettings: {
|
||||
ExportFormat: 'csv',
|
||||
DownloadExportResults: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
teamName = team.name;
|
||||
});
|
||||
|
||||
// # Visit a channel and post a message so it has something to be exported initially
|
||||
cy.visit('/');
|
||||
cy.postMessage('hello');
|
||||
|
||||
// # Go to compliance page, enable export and do initial export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport();
|
||||
cy.uiExportCompliance();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1177_1 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
|
||||
// # Visit town-square channel
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
|
||||
// # Post messages
|
||||
cy.postMessage('Testing one');
|
||||
cy.postMessage('Testing two');
|
||||
|
||||
// # Edit last post
|
||||
editLastPost('This is Edit Post');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 3 messages should be exported
|
||||
verifyExportedMessagesCount('3');
|
||||
});
|
||||
|
||||
it('MM-T1177_2 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
|
||||
// # Visit town-square channel
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
|
||||
// # Post a Message
|
||||
cy.postMessage('Testing');
|
||||
|
||||
// # Edit last post
|
||||
editLastPost('This is Edit One');
|
||||
|
||||
// # Post a Message
|
||||
cy.postMessage('This is Edit Two');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 3 messages should be exported
|
||||
verifyExportedMessagesCount('3');
|
||||
});
|
||||
|
||||
it('MM-T1177_3 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
|
||||
// # Navigate to a team and post a message
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
cy.postMessage('Testing');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Editing previously exported post
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
editLastPost('This is Edit Three');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 2 messages should be exported
|
||||
verifyExportedMessagesCount('2');
|
||||
});
|
||||
|
||||
it('MM-T1177_4 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
|
||||
// # Navigate to a team and post a Message
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
cy.postMessage('Testing');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Editing previously exported post
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
editLastPost('This is Edit Three');
|
||||
|
||||
// # Post new message
|
||||
cy.postMessage('This is the post');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 3 messages should be exported
|
||||
verifyExportedMessagesCount('3');
|
||||
});
|
||||
|
||||
it('MM-T1177_5 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
|
||||
// # Visit town-square channel
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
|
||||
// # Navigate to a team and post a message
|
||||
cy.postMessage('Testing');
|
||||
|
||||
// # Editing previously exported post
|
||||
editLastPost('This is Edit Four');
|
||||
editLastPost('This is Edit Five');
|
||||
|
||||
// # Go to compliance page and export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 3 messages should be exported
|
||||
verifyExportedMessagesCount('3');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,171 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console @compliance_export
|
||||
|
||||
import {verifyExportedMessagesCount, gotoTeamAndPostImage} from './helpers';
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
describe('Compliance Export', () => {
|
||||
let teamName;
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('Compliance');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
MessageExportSettings: {
|
||||
ExportFormat: 'csv',
|
||||
DownloadExportResults: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
teamName = team.name;
|
||||
});
|
||||
|
||||
// # Visit a channel and post a message so it has something to be exported initially
|
||||
cy.visit('/');
|
||||
cy.postMessage('hello');
|
||||
|
||||
// # Go to compliance page, enable export and do initial export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport();
|
||||
cy.uiExportCompliance();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3435 - Download Compliance Export Files - CSV Format', () => {
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Get the first row
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
|
||||
// # Get the download link
|
||||
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
|
||||
const fileURL = fileAttachment.attr('href');
|
||||
|
||||
// * Download and verify export file properties
|
||||
cy.apiDownloadFileAndVerifyContentType(fileURL);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3438 - Download Compliance Export Files when 0 messages exported', () => {
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Get the first row
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
|
||||
// # Get the download link
|
||||
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
|
||||
const fileURL = fileAttachment.attr('href');
|
||||
|
||||
// * Download and verify export file properties
|
||||
cy.apiDownloadFileAndVerifyContentType(fileURL);
|
||||
|
||||
// # Export compliance again
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * Download link should not exist this time
|
||||
cy.get('.job-table__table').
|
||||
find('tbody > tr:eq(0)').
|
||||
findByText('Download').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1168 - Compliance Export - Run Now, entry appears in job table', () => {
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Get the first row
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
|
||||
// * Verify table header
|
||||
cy.get('@firstheader').within(() => {
|
||||
cy.get('th:eq(0)').should('have.text', 'Status');
|
||||
cy.get('th:eq(1)').should('have.text', 'Finish Time');
|
||||
cy.get('th:eq(2)').should('have.text', 'Run Time');
|
||||
cy.get('th:eq(3)').should('have.text', 'Files');
|
||||
cy.get('th:eq(4)').should('have.text', 'Details');
|
||||
});
|
||||
|
||||
// * Verify first row (last run job) data
|
||||
cy.get('@firstRow').within(() => {
|
||||
cy.get('td:eq(0)').should('have.text', 'Success');
|
||||
cy.get('td:eq(2)').contains('seconds');
|
||||
cy.get('td:eq(3)').should('have.text', 'Download');
|
||||
cy.get('td:eq(4)').should('have.text', '1 message exported.');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1169 - Compliance Export - CSV and Global Relay', () => {
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Post 9 text messages
|
||||
Cypress._.times(9, (i) => {
|
||||
cy.postMessage(`This is the post ${i}`);
|
||||
});
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * 10 messages should be exported
|
||||
verifyExportedMessagesCount('10');
|
||||
});
|
||||
|
||||
it('MM-T1165 - Compliance Export - Fields disabled when disabled', () => {
|
||||
// # Go to compliance page and disable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.findByTestId('enableComplianceExportfalse').click();
|
||||
|
||||
// * Verify that exported button is disabled
|
||||
cy.findByRole('button', {name: /run compliance export job now/i}).should('be.not.enabled');
|
||||
});
|
||||
|
||||
it('MM-T1167 - Compliance Export job can be canceled', () => {
|
||||
// # Go to compliance page and enable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport();
|
||||
|
||||
// # Click the export job button
|
||||
cy.findByRole('button', {name: /run compliance export job now/i}).click();
|
||||
|
||||
// # Click X button to cancel import
|
||||
cy.findByTitle(/cancel/i, {timeout: TIMEOUTS.FIVE_SEC}).should('be.visible').click();
|
||||
|
||||
// # Get the first row
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
|
||||
// * Canceled text should be shown in the first row of the table
|
||||
cy.get('@firstRow').find('td:eq(0)').should('have.text', 'Canceled');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,306 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console
|
||||
|
||||
import {
|
||||
gotoGlobalPolicy,
|
||||
editGlobalPolicyMessageRetention,
|
||||
runDataRetentionAndVerifyPostDeleted,
|
||||
verifyPostNotDeleted,
|
||||
} from './helpers';
|
||||
|
||||
describe('Data Retention - Global and Custom Policy Only', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let users;
|
||||
let channelA;
|
||||
let channelB;
|
||||
let channelC;
|
||||
let newTeam;
|
||||
const postText = 'This is testing';
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('DataRetention');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableUserAccessTokens: true,
|
||||
},
|
||||
});
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
users = user.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiDeleteAllCustomRetentionPolicies();
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: '/api/v4/data_retention/policies',
|
||||
}).as('createCustomPolicy');
|
||||
|
||||
// # Go to data retention settings
|
||||
cy.uiGoToDataRetentionPage();
|
||||
});
|
||||
|
||||
it('MM-T4093 - Assign Global Policy = 10 Days & Custom Policy = None to channel', () => {
|
||||
gotoGlobalPolicy();
|
||||
|
||||
// # Edit global policy message retention
|
||||
editGlobalPolicyMessageRetention('10', '10 days');
|
||||
|
||||
// * Verify there is no any team and channel assigned
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
|
||||
});
|
||||
|
||||
let testChannel2;
|
||||
cy.apiCreateChannel(testTeam.id, 'test_channel', 'testChannel2').then(({channel}) => {
|
||||
testChannel2 = channel;
|
||||
});
|
||||
|
||||
// # Create 13 days older post
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setDate(new Date().getDate() - 13);
|
||||
const createDate2 = new Date().setDate(new Date().getDate() - 7);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDate2);
|
||||
|
||||
// * Run the job and verify 13 days older post has been deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 7 days older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, testChannel2, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4099 - Assign Global Policy = 10 Days & Custom Policy = 5 days to Channels', () => {
|
||||
// # Edit Global Policy to 10 days
|
||||
gotoGlobalPolicy();
|
||||
editGlobalPolicyMessageRetention('10', '10 days');
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// # Create channel-A
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel-1').then(({channel}) => {
|
||||
channelA = channel;
|
||||
});
|
||||
|
||||
// # Create channel-B
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Custom-Channel1').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
// # Create channel-C
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Global-Channel-2').then(({channel}) => {
|
||||
channelC = channel;
|
||||
});
|
||||
|
||||
// * Verify create policy api response
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more than 3,7, and 12 days older post
|
||||
// # Get Epoch value
|
||||
const createDate1 = new Date().setDate(new Date().getDate() - 7);
|
||||
const createDate2 = new Date().setDate(new Date().getDate() - 3);
|
||||
const createDate3 = new Date().setDate(new Date().getDate() - 12);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
|
||||
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate2);
|
||||
cy.apiPostWithCreateDate(channelC.id, postText, token, createDate3);
|
||||
|
||||
// * Run the job and verify 7 days older post is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 7 days older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, channelA, postText);
|
||||
|
||||
// * Verify 3 days older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, channelB, postText);
|
||||
|
||||
// * Verify 12 days older post is deleted
|
||||
verifyPostNotDeleted(testTeam, channelC, postText, 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4101 - Assign Global Policy = 5 days & Custom Policy = None to Teams', () => {
|
||||
// # Edit global policy to 5 days
|
||||
gotoGlobalPolicy();
|
||||
editGlobalPolicyMessageRetention('5', '5 days');
|
||||
|
||||
// * Verify there is no any team and channel assigned
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
|
||||
});
|
||||
|
||||
// # Create new channel
|
||||
let testChannel2;
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'OtherChannel ').then(({channel}) => {
|
||||
testChannel2 = channel;
|
||||
});
|
||||
|
||||
// # Create new Team and Channel
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
|
||||
newTeam = team;
|
||||
channelA = channel;
|
||||
});
|
||||
});
|
||||
|
||||
// # Create 3 and 7 days older posts
|
||||
// # Get Epoch value
|
||||
const createDays1 = new Date().setDate(new Date().getDate() - 7);
|
||||
const createDays2 = new Date().setDate(new Date().getDate() - 3);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDays1);
|
||||
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDays1);
|
||||
cy.apiPostWithCreateDate(channelA.id, postText, token, createDays2);
|
||||
|
||||
// * Run the job and verify 7 days older posts have been deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel2, postText);
|
||||
|
||||
// * Verify 3 days older post was not deleted
|
||||
verifyPostNotDeleted(newTeam, channelA, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4103 - Assign Global Policy = 10 days & Custom Policy = 5 days to Team', () => {
|
||||
// # Edit global policy to 5 days
|
||||
gotoGlobalPolicy();
|
||||
editGlobalPolicyMessageRetention('10', '10 days');
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create channel-A
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel-1').then(({channel}) => {
|
||||
channelA = channel;
|
||||
});
|
||||
|
||||
// # Create a new Team and Channel
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
newTeam = team;
|
||||
cy.apiCreateChannel(newTeam.id, 'test_channel', 'Channel-A').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
// # Create a new channel in newTeam
|
||||
cy.apiCreateChannel(newTeam.id, 'channel-test', 'Global-Channel-2').then(({channel}) => {
|
||||
channelC = channel;
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more than 3,7, and 12 days older posts
|
||||
// # Get Epoch value
|
||||
const createDate1 = new Date().setDate(new Date().getDate() - 7);
|
||||
const createDate2 = new Date().setDate(new Date().getDate() - 3);
|
||||
const createDate3 = new Date().setDate(new Date().getDate() - 12);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
|
||||
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate1);
|
||||
cy.apiPostWithCreateDate(channelC.id, postText, token, createDate3);
|
||||
|
||||
// * Run the job and verify 7 days older post is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 7 days older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, channelA, postText);
|
||||
|
||||
// * Verify 3 days older post is not deleted
|
||||
verifyPostNotDeleted(newTeam, channelB, postText);
|
||||
|
||||
// * Verify 12 days older post is deleted
|
||||
verifyPostNotDeleted(newTeam, channelC, postText, 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4096 - Assign Global Policy = 1 Year & Custom Policy = None to channel', () => {
|
||||
// # Edit global policy to 1 year
|
||||
gotoGlobalPolicy();
|
||||
editGlobalPolicyMessageRetention('365', '1 year');
|
||||
|
||||
// * Verify there is no any team and channel assigned
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
|
||||
});
|
||||
|
||||
// # Create a new channel
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel ').then(({channel}) => {
|
||||
channelA = channel;
|
||||
});
|
||||
|
||||
// # Create less than one year and one year older post
|
||||
// # Get Epoch value
|
||||
const createDate1 = new Date().setMonth(new Date().getMonth() - 14);
|
||||
const createDate2 = new Date().setMonth(new Date().getMonth() - 10);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
|
||||
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
|
||||
|
||||
// * Run the job and verify 1 year older post has been deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify less than one year post was not deleted
|
||||
verifyPostNotDeleted(testTeam, channelA, postText);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,350 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console
|
||||
|
||||
import {
|
||||
runDataRetentionAndVerifyPostDeleted,
|
||||
gotoGlobalPolicy,
|
||||
editGlobalPolicyMessageRetention,
|
||||
verifyPostNotDeleted,
|
||||
} from './helpers';
|
||||
|
||||
describe('Data Retention - Custom Policy Only', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let users;
|
||||
const postText = 'This is testing';
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('DataRetention');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableUserAccessTokens: true,
|
||||
},
|
||||
});
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
users = user.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiDeleteAllCustomRetentionPolicies();
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: '/api/v4/data_retention/policies',
|
||||
}).as('createCustomPolicy');
|
||||
|
||||
// # Go to data retention settings page
|
||||
cy.uiGoToDataRetentionPage();
|
||||
});
|
||||
|
||||
it('MM-T4097 - Assign Global Policy = Forever & Custom Policy = 10 days to Channel', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '10');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '10 days', '0 teams, 1 channel');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create new Channel
|
||||
let channelB;
|
||||
cy.apiCreateChannel(testTeam.id, 'test_channel', 'channelB').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
// # Create 12 days older posts
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setDate(new Date().getDate() - 12);
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
|
||||
|
||||
// * Run the job and verify 12 days older post is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 12 days older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, channelB, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4098 - Assign Global Policy = Forever & Custom Policy = 1 year to Channels', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '365');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '1 year', '0 teams, 1 channel');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create new Channel
|
||||
let channelB;
|
||||
cy.apiCreateChannel(testTeam.id, 'test_channel', ' channelB').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
// # Create more than one year older posts
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setMonth(new Date().getMonth() - 14);
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
|
||||
|
||||
// * Run the job and verify more than one year older post is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify more than one year older post is not deleted
|
||||
verifyPostNotDeleted(testTeam, channelB, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4105 - Assign Global Policy = Forever & Custom Policy = 1 year to Teams', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '365');
|
||||
|
||||
// # Add a team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '1 year', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create new Team and Channel
|
||||
let newTeam;
|
||||
let channelB;
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'channelB').then(({channel}) => {
|
||||
newTeam = team;
|
||||
channelB = channel;
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more than one year older posts
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setMonth(new Date().getMonth() - 14);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
|
||||
|
||||
// * Run the job and verify more than one year older post has been deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify more then one year older post is not deleted
|
||||
verifyPostNotDeleted(newTeam, channelB, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4102 - Assign Global Policy = Forever & Custom Policy = 30 days to Teams', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '30');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '30 days', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create new Team and Channel
|
||||
let channelB;
|
||||
let newTeam;
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'channelB').then(({channel}) => {
|
||||
channelB = channel;
|
||||
newTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more than one year older post
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setDate(new Date().getDate() - 32);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
|
||||
|
||||
// * Run the job and verify 32 days older post is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 32 days old post is not deleted
|
||||
verifyPostNotDeleted(newTeam, channelB, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4104 - Assign Global policy = Forever & Custom Policy = 5 and 10 days to Teams', () => {
|
||||
// # Create a new Channel
|
||||
let testChannel2;
|
||||
cy.apiCreateChannel(testTeam.id, 'test_channel', 'TestChannel2').then(({channel}) => {
|
||||
testChannel2 = channel;
|
||||
});
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create new Team and Channels
|
||||
let newTeam;
|
||||
let channelA;
|
||||
let channelB;
|
||||
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
newTeam = team;
|
||||
|
||||
// # Create new Channel
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'test_channelC').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
|
||||
channelA = channel;
|
||||
|
||||
// # Create second policy
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy1', 'days', '10');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([newTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy1', '10 days', '1 team, 0 channels');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more 3,7, and 12 days older posts
|
||||
// # Get Epoch values
|
||||
const createDate1 = new Date().setDate(new Date().getDate() - 7);
|
||||
const createDate2 = new Date().setDate(new Date().getDate() - 3);
|
||||
const createDate3 = new Date().setDate(new Date().getDate() - 12);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
|
||||
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDate2);
|
||||
|
||||
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate3);
|
||||
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate2);
|
||||
|
||||
// * Run the job and Verify 7 days older post in testChannel is deleted
|
||||
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
|
||||
|
||||
// * Verify 3 days older post in testChennel2 is not deleted
|
||||
verifyPostNotDeleted(testTeam, testChannel2, postText);
|
||||
|
||||
// * Verify 12 days older post in ChannelA is deleted
|
||||
cy.visit(`/${newTeam.name}/channels/${channelA.name}`);
|
||||
cy.findAllByTestId('postView').should('have.length', 1);
|
||||
cy.findAllByTestId('postView').should('not.contain', postText);
|
||||
|
||||
// * Verify 3 days older post in channelB is not deleted
|
||||
verifyPostNotDeleted(newTeam, channelB, postText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4019 - Global Data Retention policy', () => {
|
||||
[
|
||||
{input: '365', result: '1 year'},
|
||||
{input: '700', result: '700 days'},
|
||||
{input: '730', result: '2 years'},
|
||||
{input: '600', result: '600 days'},
|
||||
].forEach(({input, result}) => {
|
||||
gotoGlobalPolicy();
|
||||
|
||||
// # Edit global policy message retention
|
||||
editGlobalPolicyMessageRetention(input, result);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console
|
||||
|
||||
import {
|
||||
runDataRetentionAndVerifyPostDeleted,
|
||||
gotoGlobalPolicy,
|
||||
editGlobalPolicyMessageRetention,
|
||||
} from './helpers';
|
||||
|
||||
describe('Data Retention - Global and Custom Policy', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let users;
|
||||
const postText = 'This is testing';
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('DataRetention');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableUserAccessTokens: true,
|
||||
},
|
||||
});
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
users = user.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiDeleteAllCustomRetentionPolicies();
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: '/api/v4/data_retention/policies',
|
||||
}).as('createCustomPolicy');
|
||||
|
||||
// # Go to data retention settings page
|
||||
cy.uiGoToDataRetentionPage();
|
||||
});
|
||||
|
||||
it('MM-T4100 - Assign Global Policy = 5 days & Custom Policy = 10 days to channels', () => {
|
||||
let newChannel;
|
||||
let newTeam;
|
||||
|
||||
// # Edit Global Policy to 5 days
|
||||
gotoGlobalPolicy();
|
||||
editGlobalPolicyMessageRetention('5', '5 days');
|
||||
|
||||
// # Create a new team
|
||||
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
|
||||
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
|
||||
newChannel = channel;
|
||||
newTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '10');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
const policyId = interception.response.body.id;
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '10 days', '0 teams, 1 channel');
|
||||
});
|
||||
});
|
||||
|
||||
// # Create more than 7 days older post
|
||||
// # Get Epoch value
|
||||
const createDate = new Date().setDate(new Date().getDate() - 7);
|
||||
|
||||
cy.apiCreateToken(users).then(({token}) => {
|
||||
// # Create posts
|
||||
cy.apiPostWithCreateDate(newChannel.id, postText, token, createDate);
|
||||
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
|
||||
|
||||
// * Run the job and verify 7 days older post in newChannel has been deleted
|
||||
runDataRetentionAndVerifyPostDeleted(newTeam, newChannel, postText);
|
||||
|
||||
// * Verify 7 days older post in testChannel was not deleted
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.findAllByTestId('postView').should('have.length', 2);
|
||||
cy.findAllByTestId('postView').should('contain', postText);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,561 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @enterprise @system_console @with_feature_flag
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
describe('Data Retention', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('DataRetention');
|
||||
|
||||
cy.apiInitSetup().then(({team, channel}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiDeleteAllCustomRetentionPolicies();
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: '/api/v4/data_retention/policies',
|
||||
}).as('createCustomPolicy');
|
||||
|
||||
// # Go to data retention settings page
|
||||
cy.uiGoToDataRetentionPage();
|
||||
});
|
||||
|
||||
describe('Custom policy creation', () => {
|
||||
it('MM-T4005 - Create custom policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Add 1 channel to the policy from the modal
|
||||
cy.uiAddRandomChannelToCustomPolicy(1);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Check custom policy table is visible
|
||||
cy.get('#custom_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 1, 1, 60, 'Policy 1');
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(interception.response.body.id, 'Policy 1', '60 days', '1 team, 1 channel');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4006 - Policies count', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 2', 'days', '160');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 3', 'days', '100');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Assert the pagination is correct
|
||||
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
|
||||
|
||||
cy.apiGetCustomRetentionPolicies().then((result) => {
|
||||
// * Assert the total policy count is 3
|
||||
expect(result.body.total_count).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4007 - show policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Add 1 channel to the policy from the modal
|
||||
cy.uiAddRandomChannelToCustomPolicy(1);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
cy.findByText('1 - 1 of 1').scrollIntoView().should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T4008 - Update custom policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 2', 'years', '2');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddRandomTeamToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Check custom policy table is visible
|
||||
cy.get('#custom_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 1, 0, 730, 'Policy 2');
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 2', '2 years', '1 team, 0 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
|
||||
// * Verify custom policy page header
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// # Remove team from policy
|
||||
cy.get('.PolicyTeamsList .DataGrid').within(() => {
|
||||
cy.findByRole('link', {name: 'Remove'}).should('be.visible').click();
|
||||
});
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Check custom policy table is visible
|
||||
cy.get('#custom_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 2', '2 years', '0 teams, 1 channel');
|
||||
});
|
||||
|
||||
// # Send GET request to verify policy updated correctly
|
||||
cy.apiGetCustomRetentionPolicy(policyId).then((result) => {
|
||||
// * Assert response body team_count is 0
|
||||
expect(result.body.team_count).to.equal(0);
|
||||
|
||||
// * Assert response body channel_count is 1
|
||||
expect(result.body.channel_count).to.equal(1);
|
||||
|
||||
// * Assert response body post_duration is 730
|
||||
expect(result.body.post_duration).to.equal(730);
|
||||
|
||||
// * Assert response body display_name is correct
|
||||
expect(result.body.display_name).to.equal('Policy 2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4009 - Delete a custom policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Add policy name
|
||||
cy.uiGetTextbox('Policy name').clear().type('Policy 3');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Check custom policy table is visible
|
||||
cy.get('#custom_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 0, 1, -1, 'Policy 3');
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 3', 'Keep forever', '0 teams, 1 channel');
|
||||
|
||||
cy.get(`#customWrapper-${policyId}`).trigger('mouseover').click();
|
||||
|
||||
// # Delete a policy
|
||||
cy.findByRole('button', {name: 'Delete'}).should('be.visible').click();
|
||||
|
||||
// # Wait for deletion
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Assert the policy row no longer exists
|
||||
cy.get(`#customDescription-${policyId}`).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Teams in a custom Policy', () => {
|
||||
it('MM-T4010 - Show policy teams information', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 1, 0, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '1 team, 0 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// * Verify Team data table exists
|
||||
cy.get('.PolicyTeamsList .DataGrid').within(() => {
|
||||
cy.get(`#team-name-${testTeam.id}`).should('be.visible');
|
||||
});
|
||||
|
||||
// * GET the team for the policy and verify it is correct
|
||||
cy.apiGetCustomRetentionPolicyTeams(policyId).then((result) => {
|
||||
expect(result.body.teams[0].id).to.equal(testTeam.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4012 - Search teams in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomTeamToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 2, 0, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '2 teams, 0 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
cy.get('.PolicyTeamsList .DataGrid').within(() => {
|
||||
// # Find the team table search box and type in team name
|
||||
cy.findByRole('textbox').should('be.visible').clear().type(testTeam.name);
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Verify the team is visible after search
|
||||
cy.get(`#team-name-${testTeam.id}`).should('be.visible').invoke('text').should('include', testTeam.display_name);
|
||||
});
|
||||
|
||||
// * Search the team for the policy using the API and verify it is correct
|
||||
cy.apiSearchCustomRetentionPolicyTeams(policyId, testTeam.display_name).then((result) => {
|
||||
expect(result.body[0].id).to.equal(testTeam.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4018 - Number of teams in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Add channels to the policy
|
||||
cy.uiAddRandomTeamToCustomPolicy(2);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 3, 0, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '3 teams, 0 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// * Verify team table pagination
|
||||
cy.get('.PolicyTeamsList .DataGrid').within(() => {
|
||||
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
|
||||
});
|
||||
|
||||
// * GET the teams for the policy and verify the count is correct
|
||||
cy.apiGetCustomRetentionPolicyTeams(policyId).then((result) => {
|
||||
expect(result.body.teams.length).to.equal(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4011 - Add team in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '60');
|
||||
|
||||
// # Add team to the policy
|
||||
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Verify team table pagination
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.get('.DataGrid_rows .DataGrid_cell').first().should('contain.text', 'MyPolicy').click();
|
||||
});
|
||||
cy.get('.DataGrid_row .DataGrid_cell').first().should('contain', testTeam.display_name);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Channels in a custom Policy', () => {
|
||||
it('MM-T4017 - Total channels in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Add 2 channels to the policy from the modal
|
||||
cy.uiAddRandomChannelToCustomPolicy(2);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 0, 3, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 3 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// * Verify Channel pagination
|
||||
cy.get('.PolicyChannelsList .DataGrid').within(() => {
|
||||
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
|
||||
});
|
||||
|
||||
// * GET the channels for the policy and verify the count
|
||||
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
|
||||
expect(result.body.channels.length).to.equal(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4014 - Add channel in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 0, 1, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 1 channel');
|
||||
|
||||
// * GET the channel for the policy and verify it is correct
|
||||
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
|
||||
expect(result.body.channels[0].id).to.equal(testChannel.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4015 - Delete channel in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '1');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Add 2 channels to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy(2);
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 0, 3, 365, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '1 year', '0 teams, 3 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// # Remove channel from policy
|
||||
cy.get('.PolicyChannelsList .DataGrid').within(() => {
|
||||
cy.findAllByRole('link', {name: 'Remove'}).first().should('exist').click();
|
||||
});
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '1 year', '0 teams, 2 channels');
|
||||
|
||||
// * GET the channel for the policy and verify the count is correct
|
||||
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
|
||||
expect(result.body.channels.length).to.equal(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4016 - Search channels in policy', () => {
|
||||
// # Go to create custom data retention page
|
||||
cy.uiClickCreatePolicy();
|
||||
|
||||
// # Fill out policy details
|
||||
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
|
||||
|
||||
// # Add channel to the policy
|
||||
cy.uiAddRandomChannelToCustomPolicy();
|
||||
|
||||
// # Save policy
|
||||
cy.uiGetButton('Save').click();
|
||||
|
||||
cy.wait('@createCustomPolicy').then((interception) => {
|
||||
// * Verify create policy api response
|
||||
cy.uiVerifyPolicyResponse(interception.response.body, 0, 2, 730, 'Policy 1');
|
||||
|
||||
const policyId = interception.response.body.id;
|
||||
|
||||
// * Verify custom policy data table
|
||||
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 2 channels');
|
||||
|
||||
// # Go to edit custom data retention page
|
||||
cy.get('#custom_policy_table .DataGrid').within(() => {
|
||||
cy.uiClickEditCustomPolicyRow(policyId);
|
||||
});
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
|
||||
|
||||
// # Scroll down the custom policy form page
|
||||
cy.get('.DataRetentionSettings .admin-console__wrapper').scrollTo('bottom');
|
||||
|
||||
cy.get('.PolicyChannelsList .DataGrid').within(() => {
|
||||
// This will not type the space for display name?
|
||||
cy.findByRole('textbox').should('be.visible').clear().type(testChannel.name);
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get(`#channel-name-${testChannel.id}`).should('be.visible').invoke('text').should('include', testChannel.display_name);
|
||||
});
|
||||
|
||||
cy.apiSearchCustomRetentionPolicyChannels(policyId, testChannel.display_name).then((result) => {
|
||||
expect(result.body[0].id).to.equal(testChannel.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console @compliance_export
|
||||
|
||||
import {
|
||||
downloadAndUnzipExportFile,
|
||||
verifyActianceXMLFile,
|
||||
verifyPostsCSVFile,
|
||||
} from './helpers';
|
||||
|
||||
describe('Compliance Export', () => {
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
let newTeam;
|
||||
let newChannel;
|
||||
let botId;
|
||||
let botName;
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('Compliance');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
MessageExportSettings: {
|
||||
ExportFormat: 'csv',
|
||||
DownloadExportResults: true,
|
||||
},
|
||||
ServiceSettings: {
|
||||
EnforceMultifactorAuthentication: false,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
|
||||
//# Create a test bot
|
||||
cy.apiCreateBot().then(({bot}) => {
|
||||
({user_id: botId, display_name: botName} = bot);
|
||||
cy.apiPatchUserRoles(bot.user_id, ['system_admin', 'system_user']);
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, channel}) => {
|
||||
newTeam = team;
|
||||
newChannel = channel;
|
||||
|
||||
// # Do initial export
|
||||
exportCompliance();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.shellRm('-rf', downloadsFolder);
|
||||
});
|
||||
|
||||
it('MM-T1175_1 - UserType identifies that the message is posted by a bot', () => {
|
||||
const message = `This is CSV bot message from ${botName} at ${Date.now()}`;
|
||||
|
||||
// # Post bot message
|
||||
postBotMessage(newTeam, newChannel, botId, message);
|
||||
|
||||
// # Go to Compliance page and run report
|
||||
exportCompliance();
|
||||
|
||||
// # Download and Unzip exported file
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Export file should contain bot messages
|
||||
verifyPostsCSVFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
`${message},message,bot`,
|
||||
);
|
||||
});
|
||||
|
||||
it('MM-T1175_2 - UserType identifies that the message is posted by a bot', () => {
|
||||
const message = `This is XML bot message from ${botName} at ${Date.now()}`;
|
||||
|
||||
// # Post bot message
|
||||
postBotMessage(newTeam, newChannel, botId, message);
|
||||
|
||||
// # Go to Compliance and enable run export
|
||||
exportCompliance('Actiance XML');
|
||||
|
||||
// # Download and Unzip exported File
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Export file should message from bot
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
message,
|
||||
);
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
'<UserType>bot</UserType>',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function postBotMessage(newTeam, newChannel, botId, message) {
|
||||
cy.apiCreateToken(botId).then(({token}) => {
|
||||
// # Logout to allow posting as bot
|
||||
cy.apiLogout();
|
||||
cy.apiCreatePost(newChannel.id, message, '', {attachments: [{pretext: 'Look some text', text: 'This is text'}]}, token);
|
||||
|
||||
// # Re-login to validate post presence
|
||||
cy.apiAdminLogin();
|
||||
cy.visit(`/${newTeam.name}/channels/${newChannel.name}`);
|
||||
|
||||
// * Validate post was created
|
||||
cy.findByText(message).should('be.visible');
|
||||
});
|
||||
}
|
||||
|
||||
function exportCompliance(type) {
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport(type);
|
||||
cy.uiExportCompliance();
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @system_console @compliance_export
|
||||
|
||||
import {
|
||||
downloadAndUnzipExportFile,
|
||||
editLastPost,
|
||||
gotoTeamAndPostImage,
|
||||
verifyActianceXMLFile,
|
||||
verifyPostsCSVFile,
|
||||
} from './helpers';
|
||||
|
||||
describe('Compliance Export', () => {
|
||||
const ExportFormatActiance = 'Actiance XML';
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
let newTeam;
|
||||
let newUser;
|
||||
let newChannel;
|
||||
let adminUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiRequireLicenseForFeature('Compliance');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
MessageExportSettings: {
|
||||
ExportFormat: 'csv',
|
||||
DownloadExportResults: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
adminUser = sysadmin;
|
||||
cy.apiLogin(adminUser);
|
||||
cy.apiInitSetup().then(({team, user, channel}) => {
|
||||
newTeam = team;
|
||||
newUser = user;
|
||||
newChannel = channel;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.shellRm('-rf', downloadsFolder);
|
||||
});
|
||||
|
||||
it('MM-T1172 - Compliance Export - Deleted file is indicated in CSV File Export', () => {
|
||||
// # Go to compliance page and enable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport();
|
||||
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${newTeam.name}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Deleting last post
|
||||
deleteLastPost();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract export zip file
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains delete
|
||||
verifyPostsCSVFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
'deleted attachment',
|
||||
);
|
||||
});
|
||||
|
||||
it('MM-T1173 - Compliance Export - Deleted file is indicated in Actiance XML File Export', () => {
|
||||
// # Go to compliance page and enable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport(ExportFormatActiance);
|
||||
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${newTeam.name}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Delete last post
|
||||
deleteLastPost();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract exported zip file
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains deleted image
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
'delete file uploaded-image-400x400.jpg',
|
||||
);
|
||||
|
||||
// * Verifying if image has been downloaded
|
||||
cy.shellFind(targetFolder, /image-400x400.jpg/).then((files) => {
|
||||
expect(files.length).not.to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3436 - Download Compliance Export Files - Actiance XML Format', () => {
|
||||
// # Go to compliance page and enable export in Actiance XML format
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport(ExportFormatActiance);
|
||||
|
||||
// # Navigate to a team and post a message with an attachment
|
||||
cy.visit(`/${newTeam.name}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// * Verify the Download option is provided for the export job
|
||||
cy.get('@firstRow').findByText('Download').should('exist');
|
||||
|
||||
// # Download and extract exported zip file
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains the posted message content
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
'file uploaded-image-400x400.jpg',
|
||||
);
|
||||
|
||||
// * Verifying if the attached file is included in the export
|
||||
cy.shellFind(targetFolder, /image-400x400.jpg/).then((files) => {
|
||||
expect(files.length).not.to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1176 - Compliance export should include updated post after editing', () => {
|
||||
// # Go to compliance page and enable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport(ExportFormatActiance);
|
||||
|
||||
// # Navigate to a team and post a message
|
||||
cy.visit(`/${newTeam.name}/channels/town-square`);
|
||||
cy.postMessage('Testing');
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Visit town-square channel and edit the last post
|
||||
cy.visit(`/${newTeam.name}/channels/town-square`);
|
||||
editLastPost('Hello');
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract exported zip file
|
||||
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains edited text
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
'<Content>Hello</Content>',
|
||||
);
|
||||
});
|
||||
|
||||
it('MM-T3305 - Verify Deactivated users are displayed properly in Compliance Exports', () => {
|
||||
// # Post a message by Admin
|
||||
cy.postMessageAs({
|
||||
sender: adminUser,
|
||||
message: `@${newUser.username} : Admin 1`,
|
||||
channelId: newChannel.id,
|
||||
});
|
||||
|
||||
cy.visit(`/${newTeam.name}/channels/${newChannel.id}`);
|
||||
|
||||
// # Deactivate the newly created user
|
||||
cy.apiDeactivateUser(newUser.id);
|
||||
|
||||
// # Go to compliance page and enable export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport(ExportFormatActiance);
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract exported zip file
|
||||
let targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains deactivated user info
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
|
||||
);
|
||||
|
||||
// # Post a message by Admin
|
||||
cy.postMessageAs({
|
||||
sender: adminUser,
|
||||
message: `@${newUser.username} : Admin2`,
|
||||
channelId: newChannel.id,
|
||||
});
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract exported zip file
|
||||
targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying export file should not contain deactivated user name
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'not.have.string',
|
||||
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
|
||||
);
|
||||
|
||||
// # Re-activate the user
|
||||
cy.apiActivateUser(newUser.id);
|
||||
|
||||
// # Post a message by Admin
|
||||
cy.postMessageAs({
|
||||
sender: adminUser,
|
||||
message: `@${newUser.username} : Admin3`,
|
||||
channelId: newChannel.id,
|
||||
});
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Download and extract exported zip file
|
||||
targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
|
||||
downloadAndUnzipExportFile(targetFolder);
|
||||
|
||||
// * Verifying if export file contains deactivated user name
|
||||
verifyActianceXMLFile(
|
||||
targetFolder,
|
||||
'have.string',
|
||||
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function deleteLastPost() {
|
||||
cy.apiGetTeamsForUser().then(({teams}) => {
|
||||
const team = teams[0];
|
||||
cy.visit(`/${team.name}/channels/town-square`);
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
// # Click post dot menu in center.
|
||||
cy.clickPostDotMenu(lastPostId);
|
||||
|
||||
// # Scan inside the post menu dropdown
|
||||
cy.get(`#CENTER_dropdown_${lastPostId}`).should('exist').within(() => {
|
||||
// # Click on the delete post button from the dropdown
|
||||
cy.findByText('Delete').should('exist').click();
|
||||
});
|
||||
});
|
||||
cy.get('.a11y__modal.modal-dialog').should('exist').and('be.visible').
|
||||
within(() => {
|
||||
// # Confirm click on the delete button for the post
|
||||
cy.findByText('Delete').should('be.visible').click();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
export function downloadAndUnzipExportFile(targetFolder = '') {
|
||||
// # Get the download link
|
||||
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
|
||||
// # Getting export file url
|
||||
const fileURL = fileAttachment.attr('href');
|
||||
const targetFilePath = path.join(targetFolder);
|
||||
const zipFile = targetFilePath + '.zip';
|
||||
|
||||
// # Download zip file
|
||||
cy.request({url: fileURL, encoding: 'binary'}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
cy.writeFile(zipFile, response.body, 'binary');
|
||||
});
|
||||
|
||||
// # Unzip exported file then "csv_export.zip"
|
||||
cy.shellUnzip(zipFile, targetFilePath);
|
||||
cy.shellFind(targetFilePath, /csv_export.zip/).then((files) => {
|
||||
cy.shellUnzip(files[files.length - 1], targetFilePath);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function verifyPostsCSVFile(targetFolder, type, match) {
|
||||
cy.readFile(`${targetFolder}/posts.csv`).
|
||||
should('exist').
|
||||
and(type, match);
|
||||
}
|
||||
|
||||
export function verifyActianceXMLFile(targetFolder, type, match) {
|
||||
cy.readFile(`${targetFolder}/actiance_export.xml`).
|
||||
should('exist').
|
||||
and(type, match);
|
||||
}
|
||||
|
||||
export function verifyExportedMessagesCount(expectedNumber) {
|
||||
// * Verifying number of exported messages
|
||||
cy.get('@firstRow').find('td:eq(4)').should('have.text', `${expectedNumber} messages exported.`);
|
||||
}
|
||||
|
||||
export function editLastPost(message) {
|
||||
cy.getLastPostId().then(() => {
|
||||
cy.uiGetPostTextBox().clear().type('{uparrow}');
|
||||
|
||||
// # Edit Post Input should appear
|
||||
cy.get('#edit_textbox').should('be.visible');
|
||||
|
||||
// # Update the post message and type ENTER
|
||||
cy.get('#edit_textbox').invoke('val', '').type(message);
|
||||
cy.get('#create_post').findByText('Save').should('be.visible').click();
|
||||
|
||||
// * Edit modal should not be visible
|
||||
cy.get('#edit_textbox').should('not.exist');
|
||||
});
|
||||
}
|
||||
|
||||
export function gotoTeamAndPostImage() {
|
||||
cy.uiGetPostTextBox().then((createPostEl) => {
|
||||
if (createPostEl.find('.file-preview__container').length === 1) {
|
||||
// # Remove images from post message footer if exist
|
||||
cy.waitUntil(() => cy.uiGetFileUploadPreview().then((filePreviewEl) => {
|
||||
if (filePreviewEl.find('.post-image.normal').length > 0) {
|
||||
cy.get('.file-preview__remove > .icon').click();
|
||||
}
|
||||
return filePreviewEl.find('.post-image.normal').length === 0;
|
||||
}));
|
||||
}
|
||||
|
||||
const file = {
|
||||
filename: 'image-400x400.jpg',
|
||||
originalSize: {width: 400, height: 400},
|
||||
thumbnailSize: {width: 400, height: 400},
|
||||
};
|
||||
cy.get('#fileUploadInput').attachFile(file.filename);
|
||||
|
||||
// # Wait until the image is uploaded
|
||||
cy.uiWaitForFileUploadPreview();
|
||||
|
||||
cy.postMessage(`file uploaded-${file.filename}`);
|
||||
});
|
||||
}
|
||||
|
||||
export function gotoGlobalPolicy() {
|
||||
// # Click edit on global policy data table
|
||||
cy.get('#global_policy_table .DataGrid .MenuWrapper').trigger('mouseover').click();
|
||||
cy.findByRole('button', {name: /edit/i}).should('be.visible').click();
|
||||
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Global Retention Policy');
|
||||
}
|
||||
|
||||
export function editGlobalPolicyMessageRetention(input, result) {
|
||||
cy.get('.DataRetentionSettings #global_direct_message_dropdown #DropdownInput_channel_message_retention').as('dropDown');
|
||||
|
||||
// * Checking if Global Policy is already created
|
||||
cy.request({
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
url: '/api/v4/data_retention/policy',
|
||||
method: 'GET',
|
||||
}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
if (response.body.message_deletion_enabled === true) {
|
||||
// # Click message retention dropdown and select 'Keep forever' option
|
||||
cy.get('@dropDown').click();
|
||||
cy.get('.channel_message_retention_dropdown__menu .channel_message_retention_dropdown__option span.option_forever').should('be.visible').click();
|
||||
}
|
||||
});
|
||||
|
||||
// # Click message retention dropdown and select 'Days' option
|
||||
cy.get('@dropDown').click();
|
||||
cy.get('.channel_message_retention_dropdown__menu .channel_message_retention_dropdown__option span.option_days').should('be.visible').click();
|
||||
|
||||
// # Input retention days
|
||||
cy.get('.DataRetentionSettings #global_direct_message_dropdown input#channel_message_retention_input').clear().type(input);
|
||||
|
||||
// # Save Global Policy
|
||||
cy.findByRole('button', {name: 'Save'}).should('be.visible').click();
|
||||
|
||||
// * Assert global policy data table is visible
|
||||
cy.get('#global_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
// * Assert global policy message retention is correct
|
||||
cy.findByTestId('global_message_retention_cell').within(() => {
|
||||
cy.get('span').should('have.text', result);
|
||||
});
|
||||
}
|
||||
|
||||
export function editGlobalPolicyFileRetention(input, result) {
|
||||
// # Click file retention dropdown
|
||||
cy.get('.DataRetentionSettings #global_file_dropdown #DropdownInput_file_retention').should('be.visible').click();
|
||||
|
||||
// # Select days from file retention dropdown
|
||||
cy.get('.file_retention_dropdown__menu .file_retention_dropdown__option span.option_days').should('be.visible').click();
|
||||
|
||||
// # Input retention days
|
||||
cy.get('.DataRetentionSettings #global_file_dropdown input#file_retention_input').clear().type(input);
|
||||
|
||||
// # Save Global Policy
|
||||
cy.findByRole('button', {name: 'Save'}).should('be.visible').click();
|
||||
|
||||
// * Assert global policy data table is visible
|
||||
cy.get('#global_policy_table .DataGrid').should('be.visible');
|
||||
|
||||
// * Assert global policy file retention is correct
|
||||
cy.findByTestId('global_file_retention_cell').within(() => {
|
||||
cy.get('span').should('have.text', result);
|
||||
});
|
||||
}
|
||||
|
||||
export function runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText) {
|
||||
cy.uiGoToDataRetentionPage();
|
||||
|
||||
cy.findByRole('button', {name: 'Run Deletion Job Now'}).click();
|
||||
|
||||
// # Small wait to ensure new row is add
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
// # Waiting for Data Retention process to finish
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
cy.get('@firstRow').within(() => {
|
||||
cy.get('td:eq(0)', {timeout: TIMEOUTS.FOUR_MIN}).should('have.text', 'Success');
|
||||
});
|
||||
|
||||
// * Verifying if post has been deleted
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.reload();
|
||||
cy.findAllByTestId('postView').should('have.length', 1);
|
||||
cy.findAllByTestId('postView').should('not.contain', postText);
|
||||
}
|
||||
|
||||
export function verifyPostNotDeleted(testTeam, testChannel, postText, expectedNoOfPosts = 2) {
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.findAllByTestId('postView').should('have.length', expectedNoOfPosts);
|
||||
|
||||
if (expectedNoOfPosts === 2) {
|
||||
cy.findAllByTestId('postView').should('contain', postText);
|
||||
} else {
|
||||
cy.findAllByTestId('postView').should('not.contain', postText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @enterprise @system_console @compliance_export @not_cloud
|
||||
|
||||
// Requires "mattermost-minio" docker instance to be accessible at http://localhost:9000
|
||||
// and a bucket named "mattermost-test". Bucket can be created manually in the UI or by:
|
||||
// ``docker exec mattermost-minio sh -c 'mkdir -p /data/mattermost-test'``
|
||||
|
||||
import {gotoTeamAndPostImage} from './helpers';
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
describe('Compliance Export', () => {
|
||||
let teamName;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicenseForFeature('Compliance');
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
MessageExportSettings: {
|
||||
ExportFormat: 'csv',
|
||||
DownloadExportResults: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
teamName = team.name;
|
||||
});
|
||||
|
||||
// # Visit a channel and post a message so it has something to be exported initially
|
||||
cy.visit('/');
|
||||
cy.postMessage('hello');
|
||||
|
||||
// # Go to compliance page, enable export and do export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiEnableComplianceExport();
|
||||
cy.uiExportCompliance();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3439 - Download Compliance Export Files - S3 Bucket Storage', () => {
|
||||
// # Go to file storage settings Page
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and('have.text', 'File Storage');
|
||||
|
||||
const {
|
||||
minioAccessKey,
|
||||
minioSecretKey,
|
||||
minioS3Bucket,
|
||||
minioS3Endpoint,
|
||||
minioS3SSL,
|
||||
} = Cypress.expose();
|
||||
|
||||
// # Update S3 Storage settings
|
||||
cy.findByTestId('FileSettings.DriverNamedropdown').select('amazons3');
|
||||
cy.findByTestId('FileSettings.AmazonS3Bucketinput').clear().type(minioS3Bucket);
|
||||
cy.findByTestId('FileSettings.AmazonS3AccessKeyIdinput').clear().type(minioAccessKey);
|
||||
cy.findByTestId('FileSettings.AmazonS3SecretAccessKeyinput').clear().type(minioSecretKey);
|
||||
cy.findByTestId('FileSettings.AmazonS3Endpointinput').clear().type(minioS3Endpoint);
|
||||
cy.findByTestId(`FileSettings.AmazonS3SSL${minioS3SSL}`).check();
|
||||
|
||||
// # Save file storage settings
|
||||
cy.uiSaveConfig();
|
||||
|
||||
// # Test connection and verify that it's successful
|
||||
cy.findByRole('button', {name: 'Test Connection'}).click();
|
||||
cy.findByText('Connection was successful').should('be.visible');
|
||||
|
||||
// # Navigate to a team and post an attachment
|
||||
cy.visit(`/${teamName}/channels/town-square`);
|
||||
gotoTeamAndPostImage();
|
||||
|
||||
// # Go to compliance page and start export
|
||||
cy.uiGoToCompliancePage();
|
||||
cy.uiExportCompliance();
|
||||
|
||||
// # Get the first row
|
||||
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
|
||||
|
||||
// # Get the download link
|
||||
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
|
||||
const fileURL = fileAttachment.attr('href');
|
||||
|
||||
// * Download link should not exist this time
|
||||
cy.apiDownloadFileAndVerifyContentType(fileURL);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user