Skip to content
Snippets Groups Projects
Unverified Commit af9373f1 authored by Guilherme Gazzo's avatar Guilherme Gazzo Committed by GitHub
Browse files

Chore: fix EmailInbox intermittent e2e tests (#27573)


Co-authored-by: default avatarDiego Sampaio <chinello@gmail.com>
Co-authored-by: default avatardougfabris <devfabris@gmail.com>
parent a6939814
No related branches found
No related tags found
No related merge requests found
import { Pagination, States, StatesIcon, StatesTitle } from '@rocket.chat/fuselage';
import { useRoute, useTranslation } from '@rocket.chat/ui-contexts';
import { Pagination, States, StatesAction, StatesActions, StatesIcon, StatesTitle } from '@rocket.chat/fuselage';
import { useRoute, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React, { useMemo, useCallback } from 'react';
......@@ -14,39 +15,13 @@ import {
} from '../../../components/GenericTable';
import { usePagination } from '../../../components/GenericTable/hooks/usePagination';
import { useSort } from '../../../components/GenericTable/hooks/useSort';
import { useEndpointData } from '../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../lib/asyncState/AsyncStatePhase';
import SendTestButton from './SendTestButton';
const useQuery = (
{
itemsPerPage,
current,
}: {
itemsPerPage: number;
current: number;
},
[column, direction]: string[],
): {
offset?: number;
count?: number;
sort: string;
} =>
useMemo(
() => ({
sort: JSON.stringify({ [column]: direction === 'asc' ? 1 : -1 }),
...(itemsPerPage && { count: itemsPerPage }),
...(current && { offset: current }),
}),
[column, current, direction, itemsPerPage],
);
const EmailInboxTable = (): ReactElement => {
const t = useTranslation();
const router = useRoute('admin-email-inboxes');
const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination();
const { sortBy, sortDirection, setSort } = useSort<'name' | 'email' | 'active'>('name');
const query = useQuery({ itemsPerPage, current }, [sortBy, sortDirection]);
const onClick = useCallback(
(_id) => (): void => {
......@@ -58,7 +33,15 @@ const EmailInboxTable = (): ReactElement => {
[router],
);
const { phase, value: { emailInboxes = [], count = 0 } = {} } = useEndpointData('/v1/email-inbox.list', query);
const endpoint = useEndpoint('GET', '/v1/email-inbox.list');
const query = {
sort: JSON.stringify({ [sortBy]: sortDirection === 'asc' ? 1 : -1 }),
...(itemsPerPage && { count: itemsPerPage }),
...(current && { offset: current }),
};
const result = useQuery(['email-list', query], () => endpoint(query));
const headers = useMemo(
() => [
......@@ -78,18 +61,20 @@ const EmailInboxTable = (): ReactElement => {
return (
<>
{phase === AsyncStatePhase.LOADING && (
{result.isLoading && (
<GenericTable>
<GenericTableHeader>{headers}</GenericTableHeader>
<GenericTableBody>{phase === AsyncStatePhase.LOADING && <GenericTableLoadingTable headerCells={4} />}</GenericTableBody>
<GenericTableBody>
<GenericTableLoadingTable headerCells={4} />
</GenericTableBody>
</GenericTable>
)}
{emailInboxes && emailInboxes.length > 0 && phase === AsyncStatePhase.RESOLVED && (
{result.isSuccess && result.data.emailInboxes.length > 0 && (
<>
<GenericTable>
<GenericTableHeader>{headers}</GenericTableHeader>
<GenericTableBody>
{emailInboxes.map((emailInbox) => (
{result.data.emailInboxes.map((emailInbox) => (
<GenericTableRow
key={emailInbox._id}
onKeyDown={onClick(emailInbox._id)}
......@@ -108,21 +93,32 @@ const EmailInboxTable = (): ReactElement => {
</GenericTableBody>
</GenericTable>
<Pagination
divider
current={current}
itemsPerPage={itemsPerPage}
count={count}
count={result.data.count}
onSetItemsPerPage={onSetItemsPerPage}
onSetCurrent={onSetCurrent}
{...paginationProps}
/>
</>
)}
{phase === AsyncStatePhase.RESOLVED && emailInboxes.length === 0 && (
{result.isSuccess && result.data.emailInboxes.length === 0 && (
<States>
<StatesIcon name='magnifier' />
<StatesTitle>{t('No_results_found')}</StatesTitle>
</States>
)}
{result.isError && (
<States>
<StatesIcon name='warning' variation='danger' />
<StatesTitle>{t('Something_went_wrong')}</StatesTitle>
<StatesActions>
<StatesAction onClick={() => result.refetch()}>{t('Reload_page')}</StatesAction>
</StatesActions>
</States>
)}
</>
);
};
......
......@@ -30,63 +30,67 @@ export async function configureEmailInboxes(): Promise<void> {
inboxes.clear();
for await (const emailInboxRecord of emailInboxesCursor) {
logger.info(`Setting up email interceptor for ${emailInboxRecord.email}`);
try {
logger.info(`Setting up email interceptor for ${emailInboxRecord.email}`);
const imap = new IMAPInterceptor(
{
password: emailInboxRecord.imap.password,
user: emailInboxRecord.imap.username,
host: emailInboxRecord.imap.server,
port: emailInboxRecord.imap.port,
...(emailInboxRecord.imap.secure
? {
tls: emailInboxRecord.imap.secure,
tlsOptions: {
rejectUnauthorized: false,
},
}
: {}),
},
{
deleteAfterRead: false,
filter: [['UNSEEN'], ['SINCE', emailInboxRecord._createdAt]],
rejectBeforeTS: emailInboxRecord._createdAt,
markSeen: true,
maxRetries: emailInboxRecord.imap.maxRetries,
},
emailInboxRecord._id,
);
const imap = new IMAPInterceptor(
{
password: emailInboxRecord.imap.password,
user: emailInboxRecord.imap.username,
host: emailInboxRecord.imap.server,
port: emailInboxRecord.imap.port,
...(emailInboxRecord.imap.secure
? {
tls: emailInboxRecord.imap.secure,
tlsOptions: {
rejectUnauthorized: false,
},
}
: {}),
},
{
deleteAfterRead: false,
filter: [['UNSEEN'], ['SINCE', emailInboxRecord._createdAt]],
rejectBeforeTS: emailInboxRecord._createdAt,
markSeen: true,
maxRetries: emailInboxRecord.imap.maxRetries,
},
emailInboxRecord._id,
);
imap.on(
'email',
Meteor.bindEnvironment(async (email) => {
if (!email.messageId) {
return;
}
imap.on(
'email',
Meteor.bindEnvironment(async (email) => {
if (!email.messageId) {
return;
}
try {
await EmailMessageHistory.create({ _id: email.messageId, email: emailInboxRecord.email });
onEmailReceived(email, emailInboxRecord.email, emailInboxRecord.department);
} catch (e: any) {
// In case the email message history has been received by other instance..
logger.error(e);
}
}),
);
try {
await EmailMessageHistory.create({ _id: email.messageId, email: emailInboxRecord.email });
onEmailReceived(email, emailInboxRecord.email, emailInboxRecord.department);
} catch (e: any) {
// In case the email message history has been received by other instance..
logger.error(e);
}
}),
);
imap.start();
imap.start();
const smtp = nodemailer.createTransport({
host: emailInboxRecord.smtp.server,
port: emailInboxRecord.smtp.port,
secure: emailInboxRecord.smtp.secure,
auth: {
user: emailInboxRecord.smtp.username,
pass: emailInboxRecord.smtp.password,
},
});
const smtp = nodemailer.createTransport({
host: emailInboxRecord.smtp.server,
port: emailInboxRecord.smtp.port,
secure: emailInboxRecord.smtp.secure,
auth: {
user: emailInboxRecord.smtp.username,
pass: emailInboxRecord.smtp.password,
},
});
inboxes.set(emailInboxRecord.email, { imap, smtp, config: emailInboxRecord });
inboxes.set(emailInboxRecord.email, { imap, smtp, config: emailInboxRecord });
} catch (err) {
logger.error({ msg: `Error setting up email interceptor for ${emailInboxRecord.email}`, err });
}
}
logger.info(`Configured a total of ${inboxes.size} inboxes`);
......
......@@ -20,7 +20,8 @@ test.describe.serial('email-inboxes', () => {
test('expect create an email inbox', async () => {
await poAdminEmailInboxes.btnNewEmailInbox.click();
await poAdminEmailInboxes.inputName.type(faker.name.firstName());
const name = faker.name.firstName();
await poAdminEmailInboxes.inputName.type(name);
await poAdminEmailInboxes.inputEmail.type(email);
// SMTP
......@@ -37,13 +38,13 @@ test.describe.serial('email-inboxes', () => {
await poAdminEmailInboxes.btnSave.click();
expect(poUtils.toastBarSuccess).toBeVisible();
await expect(poAdminEmailInboxes.itemRow(name)).toBeVisible();
});
test('expect delete an email inbox', async () => {
await poAdminEmailInboxes.findEmailInbox(email).click();
await poAdminEmailInboxes.btnDelete.click();
await poUtils.btnModalConfirmDelete.click();
expect(poUtils.toastBarSuccess).toBeVisible();
await expect(poUtils.toastBarSuccess).toBeVisible();
});
});
......@@ -61,6 +61,10 @@ export class AdminEmailInboxes {
return this.page.locator('button >> text=Delete');
}
itemRow(name: string): Locator {
return this.page.locator(`td >> text=${name}`);
}
findEmailInbox(email: string): Locator {
return this.page.locator(`td >> text=${email}`);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment