Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[FIX] Save edited tags for omnichannel departments #26481

Merged
merged 22 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e09010e
workaround
tiagoevanp Aug 4, 2022
6acb606
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 5, 2022
b04e0cf
Merge branch 'develop' of github.com:RocketChat/Rocket.Chat into fix/…
tiagoevanp Aug 5, 2022
b46a9fb
Merge branch 'fix/edit-department-tag' of github.com:RocketChat/Rocke…
tiagoevanp Aug 5, 2022
a05b453
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 5, 2022
87c6f5c
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 6, 2022
2ed5bfe
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 8, 2022
e105b28
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 8, 2022
4fbb9fb
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 9, 2022
155d282
Merge branch 'develop' into fix/edit-department-tag
ggazzo Aug 10, 2022
a67f7e1
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 10, 2022
82968d7
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 11, 2022
2724ea9
test + improvements
tiagoevanp Aug 11, 2022
cfe4675
Merge branch 'fix/edit-department-tag' of github.com:RocketChat/Rocke…
tiagoevanp Aug 11, 2022
748cc18
fix tests
tiagoevanp Aug 12, 2022
3145e5e
Merge branch 'develop' into fix/edit-department-tag
tiagoevanp Aug 12, 2022
b5c4b2b
Chore: Refactored to compare states in order to detect a tag change
aleksandernsilva Aug 16, 2022
baf0ebf
Merge branch 'develop' into fix/edit-department-tag
ggazzo Aug 17, 2022
97b81be
Update apps/meteor/client/views/omnichannel/departments/EditDepartmen…
tiagoevanp Aug 17, 2022
5d742b4
Chore: Review proposal (#26604)
ggazzo Aug 17, 2022
d5dbaaa
Merge branch 'develop' into fix/edit-department-tag
kodiakhq[bot] Aug 17, 2022
05f9397
Merge branch 'develop' into fix/edit-department-tag
kodiakhq[bot] Aug 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@
}
],
"typescript.tsdk": "./node_modules/typescript/lib",
"cSpell.words": ["photoswipe", "tmid"]
"cSpell.words": [
"livechat",
"omnichannel",
"photoswipe",
"tmid"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from '@rocket.chat/fuselage';
import { useMutableCallback, useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useToastMessageDispatch, useRoute, useMethod, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts';
import React, { useMemo, useState, useRef } from 'react';
import React, { useMemo, useState, useRef, useCallback } from 'react';

import { validateEmail } from '../../../../lib/emailValidator';
import Page from '../../../components/Page';
Expand Down Expand Up @@ -58,7 +58,9 @@ function EditDepartment({ data, id, title, reload, allowedToForwardData }) {

const { department } = data || { department: {} };

const [[tags, tagsText], setTagsState] = useState(() => [department?.chatClosingTags ?? [], '']);
const [initialTags] = useState(() => department?.chatClosingTags ?? []);
const [[tags, tagsText], setTagsState] = useState(() => [initialTags, '']);
const hasTagChanges = useMemo(() => tags.toString() !== initialTags.toString(), [tags, initialTags]);

const { values, handlers, hasUnsavedChanges } = useForm({
name: withDefault(department?.name, ''),
Expand Down Expand Up @@ -120,7 +122,7 @@ function EditDepartment({ data, id, title, reload, allowedToForwardData }) {
setTagsState(([tags, tagsText]) => [tags.filter((_tag) => _tag !== tag), tagsText]);
};

const handleTagTextSubmit = useMutableCallback(() => {
const handleTagTextSubmit = useCallback(() => {
setTagsState((state) => {
const [tags, tagsText] = state;

Expand All @@ -130,7 +132,7 @@ function EditDepartment({ data, id, title, reload, allowedToForwardData }) {

return [[...tags, tagsText], ''];
});
});
}, []);

const handleTagTextChange = (e) => {
setTagsState(([tags]) => [tags, e.target.value]);
Expand Down Expand Up @@ -232,7 +234,11 @@ function EditDepartment({ data, id, title, reload, allowedToForwardData }) {
});

const invalidForm =
!name || !email || !validateEmail(email) || !hasUnsavedChanges || (requestTagBeforeClosingChat && (!tags || tags.length === 0));
!name ||
!email ||
!validateEmail(email) ||
!(hasUnsavedChanges || hasTagChanges) ||
(requestTagBeforeClosingChat && (!tags || tags.length === 0));

const formId = useUniqueId();

Expand Down Expand Up @@ -441,7 +447,13 @@ function EditDepartment({ data, id, title, reload, allowedToForwardData }) {
onChange={handleTagTextChange}
placeholder={t('Enter_a_tag')}
/>
<Button mis='x8' title={t('add')} onClick={handleTagTextSubmit}>
<Button
disabled={Boolean(!tagsText.trim()) || tags.includes(tagsText)}
data-qa='DepartmentEditAddButton-ConversationClosingTags'
mis='x8'
title={t('add')}
onClick={handleTagTextSubmit}
>
{t('Add')}
</Button>
</Field.Row>
Expand Down
126 changes: 99 additions & 27 deletions apps/meteor/tests/e2e/omnichannel-departaments.spec.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,123 @@
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';

import { test, expect } from './utils/test';
import { OmnichannelDepartaments } from './page-objects';
import { OmnichannelDepartments } from './page-objects';

test.use({ storageState: 'admin-session.json' });

test.describe.serial('omnichannel-departaments', () => {
let poOmnichannelDepartaments: OmnichannelDepartaments;
test.describe.serial('omnichannel-departments', () => {
let poOmnichannelDepartments: OmnichannelDepartments;

const departmentName = faker.datatype.uuid();
let departmentName: string;
test.beforeAll(() => {
departmentName = faker.datatype.uuid();
});

test.beforeEach(async ({ page }) => {
poOmnichannelDepartaments = new OmnichannelDepartaments(page);
test.beforeEach(async ({ page }: { page: Page }) => {
poOmnichannelDepartments = new OmnichannelDepartments(page);

await page.goto('/omnichannel');
await poOmnichannelDepartaments.sidenav.linkDepartments.click();
await poOmnichannelDepartments.sidenav.linkDepartments.click();
});

test('expect create new department', async () => {
await poOmnichannelDepartaments.btnNew.click();
await poOmnichannelDepartaments.btnEnabled.click();
await poOmnichannelDepartaments.inputName.fill(departmentName);
await poOmnichannelDepartaments.inputEmail.fill(faker.internet.email());
await poOmnichannelDepartaments.btnSave.click();

await poOmnichannelDepartaments.inputSearch.fill(departmentName);
await expect(poOmnichannelDepartaments.firstRowInTable).toBeVisible();
await poOmnichannelDepartments.btnNew.click();
await poOmnichannelDepartments.btnEnabled.click();
await poOmnichannelDepartments.inputName.fill(departmentName);
await poOmnichannelDepartments.inputEmail.fill(faker.internet.email());
await poOmnichannelDepartments.btnSave.click();

await poOmnichannelDepartments.inputSearch.fill(departmentName);
await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible();
});

test('expect update department name', async () => {
await poOmnichannelDepartaments.inputSearch.fill(departmentName);
await poOmnichannelDepartments.inputSearch.fill(departmentName);

await poOmnichannelDepartments.firstRowInTable.locator(`text=${departmentName}`).click();
await poOmnichannelDepartments.inputName.fill(`edited-${departmentName}`);
await poOmnichannelDepartments.btnSave.click();

await poOmnichannelDepartments.inputSearch.fill(`edited-${departmentName}`);
await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible();
});

test.describe('Tags', () => {
test.beforeEach(async () => {
await poOmnichannelDepartments.inputSearch.fill(departmentName);
await poOmnichannelDepartments.firstRowInTable.locator(`text=${departmentName}`).click();
});

test('expect save form button be disabled', async () => {
await expect(poOmnichannelDepartments.btnSave).toBeDisabled();
});

test('Disabled tags state', async () => {
await test.step('expect to have department tags toggle button', async () => {
await expect(poOmnichannelDepartments.toggleRequestTags).toBeVisible();
});
await test.step('expect have no add tag to department', async () => {
await expect(poOmnichannelDepartments.inputTags).not.toBeVisible();
await expect(poOmnichannelDepartments.btnTagsAdd).not.toBeVisible();
});
});

await poOmnichannelDepartaments.firstRowInTable.locator(`text=${departmentName}`).click();
await poOmnichannelDepartaments.inputName.fill(`edited-${departmentName}`);
await poOmnichannelDepartaments.btnSave.click();
test('Enabled tags state', async ({ page }) => {
await test.step('expect to have form save option disabled', async () => {
await expect(poOmnichannelDepartments.btnSave).toBeDisabled();
});

await poOmnichannelDepartaments.inputSearch.fill(`edited-${departmentName}`);
await expect(poOmnichannelDepartaments.firstRowInTable).toBeVisible();
await test.step('expect clicking on toggle button to enable tags', async () => {
await poOmnichannelDepartments.toggleRequestTags.click();
await expect(poOmnichannelDepartments.inputTags).toBeVisible();
await expect(poOmnichannelDepartments.btnTagsAdd).toBeVisible();
});
await test.step('expect to be invalid if there is no tag added', async () => {
await expect(poOmnichannelDepartments.btnSave).toBeDisabled();
await expect(poOmnichannelDepartments.invalidInputTags).toBeVisible();
});

await test.step('expect to be not possible adding empty tags', async () => {
await poOmnichannelDepartments.inputTags.fill('');
await expect(poOmnichannelDepartments.btnTagsAdd).toBeDisabled();
});

await test.step('expect to have add and remove one tag properly tags', async () => {
const tagName = faker.datatype.string(5);
await poOmnichannelDepartments.inputTags.fill(tagName);
await poOmnichannelDepartments.btnTagsAdd.click();

await expect(page.locator(`button`, { hasText: tagName })).toBeVisible();

await expect(poOmnichannelDepartments.btnSave).toBeEnabled();

await page.locator(`button`, { hasText: tagName }).click();
await expect(poOmnichannelDepartments.invalidInputTags).toBeVisible();
await expect(poOmnichannelDepartments.btnSave).toBeDisabled();
});
await test.step('expect to not be possible adding same tag twice', async () => {
const tagName = faker.datatype.string(5);
await poOmnichannelDepartments.inputTags.fill(tagName);
await poOmnichannelDepartments.btnTagsAdd.click();
await poOmnichannelDepartments.inputTags.fill(tagName);
await expect(poOmnichannelDepartments.btnTagsAdd).toBeDisabled();
});
});
});

test('expect delete department', async () => {
await poOmnichannelDepartaments.inputSearch.fill(`edited-${departmentName}`);
test('expect delete department', async ({ page }) => {
await expect(poOmnichannelDepartments.firstRowInTable).toBeVisible();

await poOmnichannelDepartments.inputSearch.fill(`edited-${departmentName}`);

await page.waitForRequest('**/livechat/department**');

await poOmnichannelDepartments.btnDeleteFirstRowInTable.click();
await poOmnichannelDepartments.btnModalConfirmDelete.click();

await poOmnichannelDepartaments.btnDeletefirstRowInTable.click();
await poOmnichannelDepartaments.btnModalConfirmDelete.click();
await poOmnichannelDepartments.inputSearch.fill(`edited-${departmentName}`);

await poOmnichannelDepartaments.inputSearch.fill(`edited-${departmentName}`);
await expect(poOmnichannelDepartaments.firstRowInTable).toBeHidden();
await expect(poOmnichannelDepartments.firstRowInTable).toHaveCount(0);
});
});
2 changes: 1 addition & 1 deletion apps/meteor/tests/e2e/page-objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export * from './auth';
export * from './home-channel';
export * from './home-discussion';
export * from './omnichannel-agents';
export * from './omnichannel-departaments';
export * from './omnichannel-departments';
export * from './omnichannel-livechat';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Page } from '@playwright/test';

import { OmnichannelSidenav } from './fragments';

export class OmnichannelDepartaments {
export class OmnichannelDepartments {
private readonly page: Page;

readonly sidenav: OmnichannelSidenav;
Expand Down Expand Up @@ -32,6 +32,22 @@ export class OmnichannelDepartaments {
return this.page.locator('[data-qa="DepartmentEditTextInput-Email"]');
}

get toggleRequestTags() {
return this.page.locator('[data-qa="DiscussionToggle-RequestTagBeforeCLosingChat"] span label');
}

get inputTags() {
return this.page.locator('[data-qa="DepartmentEditTextInput-ConversationClosingTags"]');
}

get invalidInputTags() {
return this.page.locator('[data-qa="DepartmentEditTextInput-ConversationClosingTags"]:invalid');
}

get btnTagsAdd() {
return this.page.locator('[data-qa="DepartmentEditAddButton-ConversationClosingTags"]');
}

get btnSave() {
return this.page.locator('button.rcx-button--primary.rcx-button >> text="Save"');
}
Expand All @@ -40,7 +56,7 @@ export class OmnichannelDepartaments {
return this.page.locator('table tr:first-child td:first-child');
}

get btnDeletefirstRowInTable() {
get btnDeleteFirstRowInTable() {
return this.page.locator('table tr:first-child td:nth-child(6) button');
}

Expand Down