diff --git a/.prettierrc b/.prettierrc index 3352db80c5..97a20bd3fc 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { "semi": true, - "printWidth": 100, + "printWidth": 120, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5", diff --git a/src/containers/Auth/Auth.module.css b/src/containers/Auth/Auth.module.css index 4719d7b410..2161bb7e67 100644 --- a/src/containers/Auth/Auth.module.css +++ b/src/containers/Auth/Auth.module.css @@ -279,3 +279,15 @@ .Spacing { margin: 15px 0px; } + +.TermsOfUse a { + color: #93a29b !important; + font-size: 14px !important; + font-weight: 400 !important; + text-decoration: underline !important; +} + +.TermsOfUse { + text-align: center; + padding-bottom: 20px; +} \ No newline at end of file diff --git a/src/containers/Auth/Auth.tsx b/src/containers/Auth/Auth.tsx index 0a24d65714..aa030fe62b 100644 --- a/src/containers/Auth/Auth.tsx +++ b/src/containers/Auth/Auth.tsx @@ -6,7 +6,6 @@ import { useTranslation } from 'react-i18next'; import { Captcha } from 'components/UI/Form/Captcha/Captcha'; import WhatsAppIcon from 'assets/images/icons/Social/Whatsapp.svg?react'; -import { termsOfUse } from 'containers/Organization/Organization'; import { Button } from 'components/UI/Form/Button/Button'; import GlificLogo from 'assets/images/logo/Logo.svg'; import styles from './Auth.module.css'; @@ -14,6 +13,7 @@ import axios from 'axios'; import { ORGANIZATION_NAME } from 'config'; import setLogs from 'config/logs'; import { checkOrgStatus } from 'services/AuthService'; +import { TERMS_OF_USE_LINK } from 'common/constants'; // import { Promotion } from './Promotion/Promotion'; @@ -253,7 +253,13 @@ export const Auth = ({
{formElements} - {isRegistration && termsOfUse} + {isRegistration && ( +
+ + Read the applied terms of use + +
+ )}
{alternateText ? ( <> diff --git a/src/containers/Auth/ConfirmOTP/ConfirmOTP.test.tsx b/src/containers/Auth/ConfirmOTP/ConfirmOTP.test.tsx index 7bebf84772..e978091ec5 100644 --- a/src/containers/Auth/ConfirmOTP/ConfirmOTP.test.tsx +++ b/src/containers/Auth/ConfirmOTP/ConfirmOTP.test.tsx @@ -1,5 +1,5 @@ import { render, screen, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; +import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import { vi } from 'vitest'; import axios from 'axios'; @@ -10,6 +10,7 @@ import { ConfirmOTP } from './ConfirmOTP'; vi.mock('axios'); const mockedAxios = axios as any; +const user = userEvent.setup(); const mockedState = { state: { @@ -63,11 +64,11 @@ describe('', () => { await waitFor(() => { // enter the otp const input = screen.getByRole('textbox'); - UserEvent.type(input, '12345'); + user.type(input, '12345'); // click on continue const continueButton = screen.getByText('Continue'); - UserEvent.click(continueButton); + user.click(continueButton); }); await waitFor(() => {}); @@ -82,11 +83,11 @@ describe('', () => { await waitFor(() => { // enter the otp const input = screen.getByRole('textbox'); - UserEvent.type(input, '12345'); + user.type(input, '12345'); // click on continue const continueButton = screen.getByText('Continue'); - UserEvent.click(continueButton); + user.click(continueButton); }); await waitFor(() => {}); @@ -102,7 +103,7 @@ describe('', () => { await waitFor(() => { const resendButton = screen.getByTestId('resendOtp'); - UserEvent.click(resendButton); + user.click(resendButton); }); // click on resend button @@ -119,7 +120,7 @@ describe('', () => { await waitFor(() => { // click on resend button const resendButton = screen.getByTestId('resendOtp'); - UserEvent.click(resendButton); + user.click(resendButton); }); await waitFor(() => {}); diff --git a/src/containers/Auth/ResetPassword/ResetPasswordPhone.test.tsx b/src/containers/Auth/ResetPassword/ResetPasswordPhone.test.tsx index bfafd8e6d2..e4c5c48228 100644 --- a/src/containers/Auth/ResetPassword/ResetPasswordPhone.test.tsx +++ b/src/containers/Auth/ResetPassword/ResetPasswordPhone.test.tsx @@ -1,5 +1,5 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; +import userEvent from '@testing-library/user-event'; import { MemoryRouter, Route, Routes } from 'react-router'; import axios from 'axios'; import { vi } from 'vitest'; @@ -8,6 +8,7 @@ import { ResetPasswordPhone } from './ResetPasswordPhone'; vi.mock('axios'); const mockedAxios = axios as any; +const user = userEvent.setup(); export const postRequestMock = () => { const responseData = { data: { data: {} } }; @@ -56,7 +57,7 @@ describe('', () => { // click on GENERATE button const continueButton = screen.getByText('Generate OTP to confirm'); - UserEvent.click(continueButton); + user.click(continueButton); await waitFor(() => { expect(screen.getByTestId('AuthContainer')).toHaveTextContent( @@ -87,7 +88,7 @@ describe('', () => { expect(screen.getByText('Generate OTP to confirm')).toBeInTheDocument(); }); const continueButton = screen.getByText('Generate OTP to confirm'); - await UserEvent.click(continueButton); + await user.click(continueButton); await waitFor(() => { expect(screen.getByText('Confirm OTP')).toBeInTheDocument(); diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index e9b67e3c9b..0b572d7dae 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -496,6 +496,7 @@ export const ChatInput = ({ {selectedTemplate || Object.keys(interactiveMessageContent).length > 0 ? ( diff --git a/src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.test.tsx b/src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.test.tsx index 384bc6edb1..c87c3c1527 100644 --- a/src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.test.tsx @@ -24,7 +24,7 @@ vi.mock('react-player', () => { HTMLAnchorElement.prototype.click = vi.fn(); const insertedAt = '2020-06-19T18:44:02Z'; -const getProps: any = (type: any) => { +const getProps: any = (additionalProps: any) => { return { id: 1, body: '*Hello there!* visit https://www.google.com', @@ -39,7 +39,6 @@ const getProps: any = (type: any) => { popup: 1, open: true, insertedAt, - type, media: { url: 'http://glific.com' }, errors: '{}', contextMessage: { @@ -63,6 +62,7 @@ const getProps: any = (type: any) => { focus: true, interactiveContent: '{}', sendBy: 'test', + ...additionalProps, }; }; @@ -71,7 +71,7 @@ window.HTMLElement.prototype.scrollIntoView = vi.fn(); describe('', () => { const chatMessage = (type: any) => ( - + ); @@ -187,7 +187,7 @@ describe('', () => { }); }); - const props = getProps('TEXT'); + const props = getProps({ type: 'TEXT' }); test('it should render error with payload', async () => { props.errors = '{"payload": {"payload": {"reason": "Something went wrong"}}} '; render( @@ -200,7 +200,7 @@ describe('', () => { expect(errors).toBeInTheDocument(); }); - const imageProps = getProps('DOCUMENT'); + const imageProps = getProps({ type: 'DOCUMENT' }); test('it should render error with message', () => { imageProps.media = { url: 'https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf', @@ -350,4 +350,24 @@ describe('', () => { ); }); + + test('should render location request template', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByTestId('locationTemplate')).toBeInTheDocument(); + }); + }); }); diff --git a/src/containers/Chat/ChatMessages/ChatMessage/LocationRequestTemplate/LocationRequestTemplate.tsx b/src/containers/Chat/ChatMessages/ChatMessage/LocationRequestTemplate/LocationRequestTemplate.tsx index 30dff9dc1b..6aadac48b6 100644 --- a/src/containers/Chat/ChatMessages/ChatMessage/LocationRequestTemplate/LocationRequestTemplate.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessage/LocationRequestTemplate/LocationRequestTemplate.tsx @@ -22,7 +22,7 @@ export const LocationRequestTemplate = ({ const body = content.body.text; const locationPayload = SAMPLE_MEDIA_FOR_SIMULATOR[5].payload; return ( -
+
diff --git a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx index e5f8e119b0..6c1d92983c 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx @@ -6,13 +6,13 @@ import { SEARCH_QUERY } from 'graphql/queries/Search'; import ChatMessages from './ChatMessages'; import { MemoryRouter, Route, Routes } from 'react-router'; import { BrowserRouter as Router } from 'react-router-dom'; -import { getAttachmentPermissionMock } from 'mocks/Attachment'; +import { createMediaMessageMock, getAttachmentPermissionMock } from 'mocks/Attachment'; import { clearMessagesQuery, contactCollectionsQuery } from 'mocks/Contact'; import { OrganizationStateMock } from 'mocks/Organization'; import { CONVERSATION_MOCKS, conversationMock, - createAndSendMessageMutation2, + createAndSendMessageMutation, markAsReadMock, mocksWithConversation, sendMessageInWaGroup, @@ -25,6 +25,7 @@ import { setNotification } from 'common/notification'; import { waGroup, waGroupcollection } from 'mocks/Groups'; import { getContactSearchQuery } from 'mocks/Search'; import { getWhatsAppManagedPhonesStatusMock } from 'mocks/StatusBar'; +import { TEMPLATE_MOCKS } from 'mocks/Template'; vi.mock('common/notification', async (importOriginal) => { const mod = await importOriginal(); @@ -36,6 +37,15 @@ vi.mock('common/notification', async (importOriginal) => { }; }); +const mockIntersectionObserver = class { + constructor() {} + observe() {} + unobserve() {} + disconnect() {} +}; + +(window as any).IntersectionObserver = mockIntersectionObserver; + const messages = (limit: number, skip: number) => new Array(limit).fill(null).map((val: any, index: number) => ({ id: `${index + skip}`, @@ -250,7 +260,15 @@ const mocks = [ messageOpts: { limit: 20, offset: 0 }, filter: { id: '2', searchGroup: true }, }), - createAndSendMessageMutation2, + createAndSendMessageMutation({ + body: 'hey', + senderId: 1, + receiverId: '2', + flow: 'OUTBOUND', + interactiveTemplateId: undefined, + type: 'TEXT', + mediaId: null, + }), sendMessageMock, sendMessageInWaGroup, sendMessageInWaGroupCollection, @@ -260,6 +278,24 @@ const mocks = [ markAsReadMock('2'), markAsReadMock('3'), getWhatsAppManagedPhonesStatusMock, + ...TEMPLATE_MOCKS, + createMediaMessageMock({ + caption: 'some description', + sourceUrl: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg', + url: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg', + }), + createAndSendMessageMutation({ + body: '', + senderId: 1, + receiverId: '2', + flow: 'OUTBOUND', + interactiveTemplateId: undefined, + type: 'IMAGE', + mediaId: '1', + isHsm: true, + templateId: 3, + params: [], + }), ]; export const chatMocks = mocks; @@ -525,6 +561,83 @@ test('Load more messages for collections', async () => { }); }); +test('should send media template message to contact', async () => { + render(chatMessages); + + fireEvent.click(screen.getByTestId('shortcut-open-button')); + fireEvent.click(screen.getByText('Templates')); + + await waitFor(() => { + expect(screen.getByTestId('chatTemplates')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getAllByTestId('templateItem')[0]); + + fireEvent.click(screen.getByTestId('sendButton')); + + await waitFor(() => { + expect(screen.getByText('Add attachments to message')).toBeInTheDocument(); + }); +}); + +test('should send template message to contact', async () => { + render(chatMessages); + + fireEvent.click(screen.getByTestId('shortcut-open-button')); + fireEvent.click(screen.getByText('Templates')); + + await waitFor(() => { + expect(screen.getByTestId('chatTemplates')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getAllByTestId('templateItem')[1]); + + fireEvent.click(screen.getByTestId('removeMessage')); + + fireEvent.click(screen.getByTestId('shortcut-open-button')); + fireEvent.click(screen.getByText('Templates')); + + await waitFor(() => { + expect(screen.getByTestId('chatTemplates')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getAllByTestId('templateItem')[1]); + + fireEvent.click(screen.getByTestId('sendButton')); +}); + +test('should open attachment dialog', async () => { + render(chatMessages); + + fireEvent.click(screen.getByTestId('attachmentIcon')); + + await waitFor(() => { + expect(screen.getByText('Add attachments to message')).toBeInTheDocument(); + }); + + const autocomplete = screen.getByRole('combobox'); + autocomplete.focus(); + fireEvent.keyDown(autocomplete, { key: 'ArrowDown' }); + + fireEvent.click(screen.getByText('Image'), { key: 'Enter' }); + + fireEvent.change(screen.getByPlaceholderText('Attachment URL'), { + target: { value: 'https://www.buildquickbots.com/whatsapp/media/sample/jpg/sample01.jpg' }, + }); + + fireEvent.click(screen.getByText('Add')); +}); + +test('should open emoji picker', async () => { + render(chatMessages); + + fireEvent.click(screen.getByTestId('emoji-picker')); + + await waitFor(() => { + expect(screen.getByTestId('emoji-container')).toBeInTheDocument(); + }); +}); + const groupscache = new InMemoryCache({ addTypename: false }); groupscache.writeQuery(waGroup); groupscache.writeQuery(waGroupcollection); diff --git a/src/containers/Chat/ChatMessages/ConversationHeader/ConversationHeader.test.tsx b/src/containers/Chat/ChatMessages/ConversationHeader/ConversationHeader.test.tsx index ab86111d1b..f86da25c70 100644 --- a/src/containers/Chat/ChatMessages/ConversationHeader/ConversationHeader.test.tsx +++ b/src/containers/Chat/ChatMessages/ConversationHeader/ConversationHeader.test.tsx @@ -6,6 +6,7 @@ import { contactCollectionsQuery, updateContactCollectionQuery, clearMessagesQuery, + terminateFlowQuery, } from '../../../../mocks/Contact'; import { MemoryRouter } from 'react-router'; import { @@ -20,6 +21,7 @@ import { } from '../../../../mocks/Flow'; import { CONVERSATION_MOCKS } from '../../../../mocks/Chat'; import { searchGroupQuery } from 'mocks/Groups'; +import { setNotification } from 'common/notification'; const mocks = [ ...CONVERSATION_MOCKS, @@ -53,7 +55,7 @@ const propsWithBspStatusNone = { }; const component = ( - + @@ -87,6 +89,32 @@ test('it should have a session timer', async () => { }); }); +test('terminate a flow should show errors', async () => { + render( + + + + + + ); + + await waitFor(() => { + fireEvent.click(screen.getByTestId('dropdownIcon')?.querySelector('svg') as SVGElement); + }); + + fireEvent.click(screen.getByTestId('terminateButton')); + + await waitFor(() => { + expect(screen.getByText('Terminate flows!')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('ok-button')); + + await waitFor(() => { + expect(setNotification).toHaveBeenCalledWith('Some error occurred', 'warning'); + }); +}); + describe('Menu test', () => { beforeEach(async () => { render(component); @@ -210,6 +238,18 @@ describe('Menu test', () => { expect(getByTestId('disabledFlowButton')).toBeInTheDocument(); }); }); + + test('terminate a flow', async () => { + fireEvent.click(screen.getByTestId('terminateButton')); + fireEvent.click(screen.getByTestId('cancel-button')); + fireEvent.click(screen.getByTestId('terminateButton')); + + await waitFor(() => { + expect(screen.getByText('Terminate flows!')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('ok-button')); + }); }); describe('Collection test', () => { @@ -242,7 +282,7 @@ describe('Collection test', () => { expect(getByText('Default Collection')).toBeInTheDocument(); }); - test('clicking on start a flow shoul open dialog box', async () => { + test('clicking on start a flow should open dialog box', async () => { render(component); await waitFor(() => { fireEvent.click(screen.getByTestId('dropdownIcon')?.querySelector('svg') as SVGElement); @@ -255,6 +295,20 @@ describe('Collection test', () => { }); }); +test('should shorten collections list', async () => { + render( + + + + + + ); + + await waitFor(() => { + expect(screen.getByText('+1')).toBeInTheDocument(); + }); +}); + const route = '/group/chat'; const propsForGroups = { groups: true, diff --git a/src/containers/Collection/Collection.test.tsx b/src/containers/Collection/Collection.test.tsx index 72c80ce4b5..5350eff133 100644 --- a/src/containers/Collection/Collection.test.tsx +++ b/src/containers/Collection/Collection.test.tsx @@ -1,12 +1,15 @@ import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; import { MockedProvider } from '@apollo/client/testing'; import { vi } from 'vitest'; +import userEvent from '@testing-library/user-event'; + import { createCollectionQuery, getCollectionQuery, getCollectionsQuery, getCollectionUsersQuery, + updateCollectionQuery, + updateCollectionUsersQuery, } from 'mocks/Collection'; import { getUsersQuery } from 'mocks/User'; import { getOrganizationLanguagesQuery, getOrganizationQuery } from 'mocks/Organization'; @@ -29,6 +32,8 @@ const mocks = [ ...getCollectionsQuery, createCollectionQuery, getSearchCollectionQuery, + updateCollectionQuery, + updateCollectionUsersQuery, ]; const wrapper = ( @@ -49,6 +54,7 @@ vi.mock('common/notification', async (importOriginal) => { }; }); +const user = userEvent.setup(); const mockedUsedNavigate = vi.fn(); vi.mock('react-router-dom', async () => ({ ...(await vi.importActual('react-router-dom')), @@ -84,11 +90,11 @@ describe('collection', () => { // remove first user const removeUser = getAllByTestId('deleteIcon'); - UserEvent.click(removeUser[0]); + user.click(removeUser[0]); // click on SAVE const saveButton = getByTestId('submitActionButton'); await waitFor(() => { - UserEvent.click(saveButton); + user.click(saveButton); }); }); @@ -114,7 +120,7 @@ describe('collection', () => { fireEvent.change(collectionInputs[0], { target: { value: 'Sample Collection Title' } }); fireEvent.change(collectionInputs[1], { target: { value: 'Sample Collection Description' } }); - fireEvent.click(getByText('Save')); + user.click(getByText('Save')); }); test('should be able to check for existing collections', async () => { @@ -129,9 +135,9 @@ describe('collection', () => { const collectionInputs = getAllByRole('textbox'); fireEvent.change(collectionInputs[0], { target: { value: 'Staff group' } }); - fireEvent.click(collectionInputs[1]); + user.click(collectionInputs[1]); - fireEvent.click(getByText('Save')); + user.click(getByText('Save')); await waitFor(() => { expect(screen.getByText('Title already exists.')).toBeInTheDocument(); @@ -163,7 +169,7 @@ describe('collection', () => { expect(getByTestId('collection')).toBeInTheDocument(); }); - fireEvent.click(getByTestId('collection')); + user.click(getByTestId('collection')); await waitFor(() => { expect(mockCallback).toBeCalled(); diff --git a/src/containers/Flow/FlowList/FlowList.test.tsx b/src/containers/Flow/FlowList/FlowList.test.tsx index 18376583ef..686ed895e6 100644 --- a/src/containers/Flow/FlowList/FlowList.test.tsx +++ b/src/containers/Flow/FlowList/FlowList.test.tsx @@ -16,7 +16,7 @@ import { } from 'mocks/Flow'; import { getOrganizationQuery } from 'mocks/Organization'; import testJSON from 'mocks/ImportFlow.json'; -import { setUserSession } from 'services/AuthService'; +import { setOrganizationServices, setUserSession } from 'services/AuthService'; import { FlowList } from './FlowList'; import { Flow } from '../Flow'; import { getFilterTagQuery } from 'mocks/Tag'; @@ -67,7 +67,8 @@ vi.mock('react-router-dom', async () => { }; }); -setUserSession(JSON.stringify({ roles: ['Admin'] })); +setUserSession(JSON.stringify({ roles: [{ id: '1', label: 'Admin' }] })); +setOrganizationServices('{"__typename":"OrganizationServicesResult","rolesAndPermission":true}'); describe('', () => { test('should render Flow', async () => { @@ -172,6 +173,26 @@ describe('', () => { fireEvent.click(exportButton[0]); }); }); + + test('should create from scratch ', async () => { + render(flowList); + + await waitFor(() => { + expect(screen.getByText('Flows')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('newItemButton')); + + await waitFor(() => { + expect(screen.getByText('Create flow')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('middle-button')); + + await waitFor(() => { + expect(mockedUsedNavigate).toHaveBeenCalled(); + }); + }); }); describe('Template flows', () => { @@ -225,4 +246,30 @@ describe('Template flows', () => { expect(mockedUsedNavigate).toHaveBeenCalled(); }); }); + + test('click on Use it for templates', async () => { + render(flowList); + + await waitFor(() => { + expect(screen.getByText('Flows')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('newItemButton')); + + await waitFor(() => { + expect(screen.getByText('Create flow')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getByTestId('ok-button')); + + await waitFor(() => { + expect(screen.getByText('Template Flows')).toBeInTheDocument(); + }); + + fireEvent.click(screen.getAllByTestId('copyTemplate')[0]); + + await waitFor(() => { + expect(mockedUsedNavigate).toHaveBeenCalled(); + }); + }); }); diff --git a/src/containers/Flow/FlowList/FlowList.tsx b/src/containers/Flow/FlowList/FlowList.tsx index ada308699a..e1aa59562f 100644 --- a/src/containers/Flow/FlowList/FlowList.tsx +++ b/src/containers/Flow/FlowList/FlowList.tsx @@ -172,7 +172,7 @@ export const FlowList = () => { }, { label: 'Use it', - icon: , + icon: , parameter: 'id', insideMore: false, dialog: (id: any) => { diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index 21f671d4e5..c8e25d6039 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -152,6 +152,95 @@ export const FormLayout = ({ const [showConfirmationDialog, setShowConfirmationDialog] = useState(false); const params = useParams(); + const saveHandler = ({ languageId: languageIdValue, ...itemData }: any) => { + let payload = { + ...itemData, + ...defaultAttribute, + }; + + payload = languageSupport + ? { ...payload, languageId: Number(languageIdValue) } + : { ...payload }; + + // create custom payload for searches + if (setPayload) { + payload = setPayload(payload); + if (advanceSearch) { + const data = advanceSearch(payload); + + if (data && data.heading && type === 'search') return; + } + } + // remove fields from the payload that marked as skipPayload = true + formFields.forEach((field: any) => { + if (field.additionalState) { + additionalState(payload[field.additionalState]); + } + if (field.skipPayload) { + delete payload[field.name]; + } + }); + // for template create media for attachment + if (isAttachment && payload.type !== 'TEXT' && payload.type) { + getMediaId(payload) + .then((data: any) => { + if (data) { + const payloadCopy = payload; + delete payloadCopy.attachmentURL; + payloadCopy.messageMediaId = parseInt(data.data.createMessageMedia.messageMedia.id, 10); + performTask(payloadCopy); + } + }) + .catch((e: any) => { + setErrorMessage(e); + }); + } else { + performTask(payload); + } + }; + + const performTask = (payload: any) => { + if (itemId) { + if (isLoadedData) { + let idKey = idType; + let idVal = itemId; + + /** + * When idType is organizationId + * We are updating billing for given organization + * since params.id is orgId we want billing + * id to update billing details + */ + const payloadBody = { ...payload }; + if (idType === 'organizationId') { + idKey = 'id'; + idVal = payloadBody.billingId; + // Clearning unnecessary fields + delete payloadBody.billingId; + } + + updateItem({ + variables: { + [idKey]: idVal, + input: payloadBody, + }, + }); + } else { + createItem({ + variables: { + input: payload, + }, + }); + } + } else { + createItem({ + variables: { + input: payload, + }, + }); + } + }; + const formik = useFormik({ initialValues: { languageId, @@ -369,93 +458,6 @@ export const FormLayout = ({ setErrorMessage(error); return null; } - const performTask = (payload: any) => { - if (itemId) { - if (isLoadedData) { - let idKey = idType; - let idVal = itemId; - - /** - * When idType is organizationId - * We are updating billing for given organization - * since params.id is orgId we want billing - * id to update billing details - */ - const payloadBody = { ...payload }; - if (idType === 'organizationId') { - idKey = 'id'; - idVal = payloadBody.billingId; - // Clearning unnecessary fields - delete payloadBody.billingId; - } - - updateItem({ - variables: { - [idKey]: idVal, - input: payloadBody, - }, - }); - } else { - createItem({ - variables: { - input: payload, - }, - }); - } - } else { - createItem({ - variables: { - input: payload, - }, - }); - } - }; - const saveHandler = ({ languageId: languageIdValue, ...itemData }: any) => { - let payload = { - ...itemData, - ...defaultAttribute, - }; - - payload = languageSupport - ? { ...payload, languageId: Number(languageIdValue) } - : { ...payload }; - - // create custom payload for searches - if (setPayload) { - payload = setPayload(payload); - if (advanceSearch) { - const data = advanceSearch(payload); - - if (data && data.heading && type === 'search') return; - } - } - // remove fields from the payload that marked as skipPayload = true - formFields.forEach((field: any) => { - if (field.additionalState) { - additionalState(payload[field.additionalState]); - } - if (field.skipPayload) { - delete payload[field.name]; - } - }); - // for template create media for attachment - if (isAttachment && payload.type !== 'TEXT' && payload.type) { - getMediaId(payload) - .then((data: any) => { - if (data) { - const payloadCopy = payload; - delete payloadCopy.attachmentURL; - payloadCopy.messageMediaId = parseInt(data.data.createMessageMedia.messageMedia.id, 10); - performTask(payloadCopy); - } - }) - .catch((e: any) => { - setErrorMessage(e); - }); - } else { - performTask(payload); - } - }; const cancelHandler = () => { // for chat screen searches diff --git a/src/containers/MyAccount/MyAccount.test.tsx b/src/containers/MyAccount/MyAccount.test.tsx index 884a102bbf..8d30e7fe58 100644 --- a/src/containers/MyAccount/MyAccount.test.tsx +++ b/src/containers/MyAccount/MyAccount.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; +import userEvent from '@testing-library/user-event'; import { MockedProvider } from '@apollo/client/testing'; import axios from 'axios'; import { MemoryRouter } from 'react-router'; @@ -19,6 +19,7 @@ const mocks = [ vi.mock('axios'); const mockedAxios = axios as any; +const user = userEvent.setup(); const wrapper = ( @@ -48,7 +49,7 @@ describe('', () => { await waitFor(() => { // click on generate OTP const generateOTPButton = screen.getByText('Generate OTP'); - UserEvent.click(generateOTPButton); + user.click(generateOTPButton); }); // set the mock @@ -60,14 +61,14 @@ describe('', () => { await waitFor(() => { // click on resend button const resendButton = screen.getByTestId('resendOtp'); - UserEvent.click(resendButton); + user.click(resendButton); }); // trigger validation errors await waitFor(() => { // click on save button const saveButton = screen.getByText('Save'); - UserEvent.click(saveButton); + user.click(saveButton); }); // check for validation errors @@ -99,7 +100,7 @@ describe('', () => { await waitFor(() => { // click on generate OTP const generateOTPButton = screen.getByText('Generate OTP'); - UserEvent.click(generateOTPButton); + user.click(generateOTPButton); }); // close the alert @@ -107,7 +108,7 @@ describe('', () => { expect(screen.getByTestId('crossIcon')).toBeInTheDocument(); }); const closeAlert = screen.getByTestId('crossIcon'); - await UserEvent.click(closeAlert); + await user.click(closeAlert); }); test('generate OTP success flow with cancel', async () => { @@ -120,7 +121,7 @@ describe('', () => { await waitFor(() => { // click on generate OTP const generateOTPButton = screen.getByText('Generate OTP'); - UserEvent.click(generateOTPButton); + user.click(generateOTPButton); }); await waitFor(() => { @@ -128,11 +129,10 @@ describe('', () => { expect(screen.getByText('Cancel')).toBeInTheDocument(); }); const cancelButton = screen.getByText('Cancel'); - UserEvent.click(cancelButton); + user.click(cancelButton); }); test('generate OTP error with incorrect OTP', async () => { - const user = UserEvent.setup(); const { container } = render(wrapper); // let's mock successful sending of OTP @@ -142,7 +142,7 @@ describe('', () => { await waitFor(() => { // click on generate OTP const generateOTPButton = screen.getByText('Generate OTP'); - UserEvent.click(generateOTPButton); + user.click(generateOTPButton); }); // enter otp @@ -160,7 +160,7 @@ describe('', () => { expect(screen.getByText('Save')).toBeInTheDocument(); }); const saveButton = screen.getByText('Save'); - await UserEvent.click(saveButton); + await user.click(saveButton); // assert for incorrect OTP // await waitFor(() => { @@ -169,7 +169,6 @@ describe('', () => { }); test('generate OTP error with too many attempts', async () => { - const user = UserEvent.setup(); const { container } = render(wrapper); // let's mock successful sending of OTP @@ -179,7 +178,7 @@ describe('', () => { await waitFor(() => { // click on generate OTP const generateOTPButton = screen.getByText('Generate OTP'); - UserEvent.click(generateOTPButton); + user.click(generateOTPButton); }); // enter otp @@ -197,6 +196,6 @@ describe('', () => { expect(screen.getByText('Save')).toBeInTheDocument(); }); const saveButton = screen.getByText('Save'); - await UserEvent.click(saveButton); + await user.click(saveButton); }); }); diff --git a/src/containers/Organization/Organization.test.tsx b/src/containers/Organization/Organization.test.tsx deleted file mode 100644 index 3c50161209..0000000000 --- a/src/containers/Organization/Organization.test.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { MockedProvider } from '@apollo/client/testing'; -import { fireEvent, render, waitFor, screen } from '@testing-library/react'; -import * as Yup from 'yup'; -import UserEvent from '@testing-library/user-event'; -import { MemoryRouter } from 'react-router-dom'; - -import { Input } from 'components/UI/Form/Input/Input'; -import { Organization } from './Organization'; -import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; - -const schema = Yup.object().shape({ - name: Yup.string().required('NGO name is required'), -}); - -const props = { - pageTitle: 'Setup your NGO on Glific', - buttonText: 'Get Started', - formFields: [ - { - component: Input, - name: 'name', - type: 'text', - placeholder: 'NGO name', - }, - ], - validationSchema: schema, - saveHandler: vi.fn(), - initialFormValues: { - name: '', - }, -}; - -test('it should render component and show error messages', async () => { - render( - - - - - - - - ); - - const registration = screen.getByTestId('RegistrationContainer'); - expect(registration).toBeInTheDocument(); - - const captcha = screen.getByTestId('captcha-button'); - expect(captcha).toBeInTheDocument(); - - // We can't submit the form as we don't have correct api key - // May be we should start using github environment variables and store api key - // comment below till we find a way to test this. - // const submit = screen.getByTestId('SubmitButton'); - - // act(() => { - // UserEvent.click(captcha); - // UserEvent.click(submit); - // }); - - // expect(container.getElementsByClassName('ErrorMessage')[0]).toBeInTheDocument(); -}); - -test('Organization with success onboarding', () => { - render( - - - - - - - - ); - - const registration = screen.getByTestId('RegistrationContainer'); - expect(registration).toBeInTheDocument(); - - const captcha = screen.getByTestId('captcha-button'); - expect(captcha).toBeInTheDocument(); - - const inputElements = screen.getAllByRole('textbox'); - - UserEvent.type(inputElements[0], 'JaneDoe'); - - // click on continue - const button = screen.getByText('Get Started'); - fireEvent.click(button); - - waitFor(() => { - expect(props.saveHandler).toHaveBeenCalledWith({ name: 'test' }, true, vi.fn(), vi.fn()); - }); -}); diff --git a/src/containers/Organization/Organization.tsx b/src/containers/Organization/Organization.tsx deleted file mode 100644 index cc7538a37f..0000000000 --- a/src/containers/Organization/Organization.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { useState } from 'react'; -import { Formik, Form, Field } from 'formik'; -import { Typography } from '@mui/material'; - -import { Captcha } from 'components/UI/Form/Captcha/Captcha'; -import { TERMS_OF_USE_LINK } from 'common/constants'; -import GlificLogo from 'assets/images/logo/Logo.svg'; -import { Button } from 'components/UI/Form/Button/Button'; -import styles from './Organization.module.css'; - -export interface OrganizationProps { - pageTitle: string; - buttonText: string; - initialFormValues?: any; - saveHandler?: any; - formFields: Array; - setStates?: any; - states?: any; - handleSubmitAPI?: any; - APIFields?: any; - validationSchema?: any; - titleSubText?: string; - errorMessage?: any; -} - -export const termsOfUse = ( - -); - -export const Organization = ({ - pageTitle, - buttonText, - initialFormValues = null, - saveHandler, - formFields, - validationSchema, - titleSubText, - errorMessage, -}: OrganizationProps) => { - const [loading, setLoading] = useState(false); - const boxClass = [styles.Box, styles.RegistrationBox]; - const boxTitleClass = [styles.BoxTitle, styles.RegistrationBoxTitle]; - - let displayErrorMessage: any = null; - - /** - * Errors other than attribute errors will be - * displayed under form - */ - if (errorMessage) { - displayErrorMessage =
{errorMessage.global}
; - } - - // Stop loading if any error - if (loading && displayErrorMessage) setLoading(false); - - const formElements = ( - <> -
- - {pageTitle} - -
-
{titleSubText}
- - { - setLoading(true); - /** - * SetError and SetLoading is used to set server side messages - * and toggle loading on and off - */ - saveHandler(item, setErrors, setLoading); - }} - > - {({ submitForm, setFieldValue, values }) => ( -
-
- {formFields.map((field: any, index: number) => { - const key = index; - return ; - })} - -
- { - setFieldValue('token', token); - }} - disabled={!values.token || loading} - action="organization_registration" - > - {loading ? null : buttonText} - -
- - - {displayErrorMessage} - {termsOfUse} -
- )} -
- - ); - - return ( -
-
-
- Glific -
-
{formElements}
-
-
- ); -}; diff --git a/src/containers/Organization/Registration/Registration.module.css b/src/containers/Organization/Registration/Registration.module.css deleted file mode 100644 index 316d41ea89..0000000000 --- a/src/containers/Organization/Registration/Registration.module.css +++ /dev/null @@ -1,52 +0,0 @@ -.Tooltip { - width: 143px; - height: 48px; - background-color: #042c19 !important; - font-size: 10px; - line-height: 1.2; - border-radius: 8px; - font-weight: 400; -} - -.HelperLink { - margin-top: 4px !important; - text-align: right; - color: #93a29b !important; - line-height: 1 !important; - font-size: 14px !important; - font-weight: normal !important; - padding-right: 16px; -} - -.InputAdornment { - cursor: pointer !important; -} - -.Wrapper :global(.MuiFormControlLabel-root) { - display: flex; - align-items: flex-start; -} - -.Wrapper :global(.MuiFormControlLabel-label) { - color: #93a29b !important; - padding: 10px 0px; - line-height: 1.2; - font-size: 14px; - font-weight: 400 !important; -} - -.Wrapper :global(.MuiIconButton-label) { - position: relative; - z-index: 0; -} - -.Wrapper :global(.MuiIconButton-label:after) { - content: ''; - left: 4px; - top: 4px; - height: 15px; - width: 15px; - position: absolute; - background-color: white; - z-index: -1; -} diff --git a/src/containers/Organization/Registration/Registration.test.tsx b/src/containers/Organization/Registration/Registration.test.tsx deleted file mode 100644 index 0e161c171f..0000000000 --- a/src/containers/Organization/Registration/Registration.test.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { fireEvent, render, screen, waitFor, act } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; -import { MemoryRouter } from 'react-router-dom'; -import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; -import axios from 'axios'; -import { vi } from 'vitest'; - -import { Registration } from './Registration'; - -vi.mock('axios'); -const mockedAxios = axios as any; - -vi.mock('react-google-recaptcha-v3', async () => { - const mod = await vi.importActual('react-google-recaptcha-v3'); - return { - ...mod, - useGoogleReCaptcha: () => { - return { - executeRecaptcha: () => { - return 'test token'; - }, - }; - }, - }; -}); - -const props = { - title: 'Setup your NGO on Glific', - buttonText: 'GET STARTED', - handleStep: vi.fn(), -}; - -const wrapper = ( - - - - - -); - -describe('', () => { - beforeEach(() => { - vi.resetAllMocks(); - }); - - test('it should render correctly', async () => { - const { findByTestId } = render(wrapper); - - const registration = await findByTestId('RegistrationContainer'); - expect(registration).toHaveTextContent('Setup your NGO on Glific'); - }); - - test('onboard org correctly', async () => { - render(wrapper); - - const captcha = screen.getByTestId('captcha-button'); - expect(captcha).toBeInTheDocument(); - - waitFor(() => { - const inputElements = screen.getAllByRole('textbox'); - - fireEvent.change(inputElements[0], { target: { value: 'JaneDoe' } }); - fireEvent.change(inputElements[1], { target: { value: '919978776554' } }); - fireEvent.change(inputElements[2], { target: { value: 'Test App' } }); - fireEvent.change(inputElements[3], { target: { value: 'Vt5Ufo9RXpktxLdcX0awjrrYaWK0GowE' } }); - fireEvent.change(inputElements[4], { target: { value: 'test' } }); - fireEvent.change(inputElements[5], { target: { value: 'glific@glific.com' } }); - // click on continue - }); - const button = screen.getByText('GET STARTED'); - UserEvent.click(button); - - const responseData = { data: { is_valid: true, messages: [] } }; - act(() => { - mockedAxios.post.mockImplementationOnce(() => Promise.resolve(responseData)); - }); - }); - - test('it should submit the form correctly and give global error', async () => { - render(wrapper); - - const captcha = screen.getByTestId('captcha-button'); - expect(captcha).toBeInTheDocument(); - - waitFor(() => { - const inputElements = screen.getAllByRole('textbox'); - - fireEvent.change(inputElements[0], { target: { value: 'JaneDoe' } }); - fireEvent.change(inputElements[1], { target: { value: '919978776554' } }); - fireEvent.change(inputElements[2], { target: { value: 'Test App' } }); - fireEvent.change(inputElements[3], { target: { value: 'Vt5Ufo9RXpktxLdcX0awjrrYaWK0GowE' } }); - fireEvent.change(inputElements[4], { target: { value: 'test' } }); - fireEvent.change(inputElements[5], { target: { value: 'glific@glific.com' } }); - // click on continue - }); - const button = screen.getByText('GET STARTED'); - UserEvent.click(button); - - const responseData = { data: { is_valid: false, messages: [] } }; - act(() => { - mockedAxios.post.mockImplementationOnce(() => Promise.resolve(responseData)); - }); - }); -}); diff --git a/src/containers/Organization/Registration/Registration.tsx b/src/containers/Organization/Registration/Registration.tsx deleted file mode 100644 index d4236c5a5e..0000000000 --- a/src/containers/Organization/Registration/Registration.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import { useState } from 'react'; -import axios from 'axios'; -import { InputAdornment, Link } from '@mui/material'; -import * as Yup from 'yup'; - -import { Input } from 'components/UI/Form/Input/Input'; -import { PhoneInput } from 'components/UI/Form/PhoneInput/PhoneInput'; -import Tooltip from 'components/UI/Tooltip/Tooltip'; -import { Checkbox } from 'components/UI/Form/Checkbox/Checkbox'; -import { ONBOARD_URL } from 'config'; -import InfoIcon from 'assets/images/icons/Info.svg?react'; -import { GUPSHUP_ACCOUNT_CREATION } from 'common/constants'; -import { Organization } from '../Organization'; -import styles from './Registration.module.css'; - -export interface RegistrationProps { - title: string; - buttonText: string; - handleStep?: any; -} - -const InfoAdornment = ( - - - - - -); - -const HelperLink = ( - - Help? - -); - -const CheckBoxWrapper = (props: any) => ( -
- -
-); - -const FormSchema = Yup.object().shape({ - name: Yup.string().required('NGO name is required'), - phone: Yup.string().required('Your chatbot number is required'), - app_name: Yup.string().required('App name is required'), - api_key: Yup.string() - .test('len', 'Invalid API Key', (val) => val?.length === 32) - .required('API key is required'), - email: Yup.string().email().required('Email is required'), - shortcode: Yup.string() - .matches(/^[a-z0-9]+$/i, 'Only alphanumeric characters are allowed') - .required('NGO shortcode url is required'), -}); - -const initialFormValues = { - name: '', - phone: '', - app_name: '', - api_key: '', - email: '', - shortcode: '', - addSupportStaff: true, - token: '', -}; - -const supportCheckboxTitle = - 'I agree to let Glific team create a support staff account on my Glific setup. This allows us to get better troubleshooting response to our issues.'; - -export const Registration = ({ title, buttonText, handleStep }: RegistrationProps) => { - const [registrationError, setRegistrationError] = useState(''); - const [code, setCode] = useState('shortcode'); - const [redirect, setRedirect] = useState(false); - - if (redirect) { - handleStep(); - } - - const formFields = (shortcode: string) => [ - { - component: Input, - name: 'name', - type: 'text', - placeholder: 'NGO name', - darkMode: true, - }, - { - component: PhoneInput, - name: 'phone', - type: 'phone', - placeholder: 'NGO WhatsApp number', - helperText: 'Please enter a phone number.', - }, - { - component: Input, - name: 'app_name', - type: 'text', - placeholder: 'App name', - darkMode: true, - }, - { - component: Input, - name: 'api_key', - type: 'text', - placeholder: 'GupShup API keys', - helperText: HelperLink, - darkMode: true, - }, - { - component: Input, - name: 'shortcode', - type: 'text', - placeholder: 'URL Shortcode', - endAdornment: InfoAdornment, - darkMode: true, - helperText: `www.${shortcode}.tides.coloredcow.com`, - inputProp: { - onChange: (event: any) => { - const { value } = event.target; - let text = 'shortcode'; - if (value) text = value; - setCode(text); - }, - }, - }, - { - component: Input, - name: 'email', - type: 'text', - darkMode: true, - placeholder: 'Your email id', - }, - { - component: CheckBoxWrapper, - name: 'addSupportStaff', - title: supportCheckboxTitle, - darkCheckbox: false, - checkboxType: 'iagree', - }, - ]; - - const handleSubmit = (values: any, setErrors: any, setLoading: any) => { - if (!values.token) { - return; - } - axios - .post(ONBOARD_URL, values) - .then(({ data }: { data: any }) => { - if (data.is_valid) { - setRedirect(true); - } else { - setRegistrationError(data.messages?.global); - if (setErrors && setLoading) { - const errors = data.messages; - delete errors.global; - setErrors(errors); - setLoading(false); - } - } - }) - .catch((error: any) => { - if (error.response?.data && error.response?.data?.error) { - setRegistrationError({ - global: error.response.data.error.message, - }); - } else { - setRegistrationError({ - global: 'Sorry! an error occured. Please contact the technical team for support', - }); - } - setLoading(false); - }); - }; - - return ( - - ); -}; - -export default Registration; diff --git a/src/containers/Organization/RouteSetupSteps.test.tsx b/src/containers/Organization/RouteSetupSteps.test.tsx deleted file mode 100644 index 213f2615fd..0000000000 --- a/src/containers/Organization/RouteSetupSteps.test.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { render, act, fireEvent } from '@testing-library/react'; -import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; - -import RouteSetupSteps from './RouteSetupSteps'; - -it('it renders component correctly', () => { - const { getByText } = render( - - - - ); - - expect(getByText('Setup your NGO on Glific')).toBeInTheDocument(); - const continueButton = getByText('Continue'); - expect(continueButton).toBeInTheDocument(); - - act(() => { - fireEvent.click(continueButton); - }); - - expect(getByText('Setup your NGO on Glific')).toBeInTheDocument(); - - const getStartedButton = getByText('Get Started'); - expect(getStartedButton).toBeInTheDocument(); - - act(() => { - fireEvent.click(getStartedButton); - }); -}); diff --git a/src/containers/Organization/RouteSetupSteps.tsx b/src/containers/Organization/RouteSetupSteps.tsx deleted file mode 100644 index b0b37e2e3f..0000000000 --- a/src/containers/Organization/RouteSetupSteps.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { useState } from 'react'; - -import { FB_MANAGER_VERIFICATION, GUPSHUP_ACCOUNT_CREATION } from 'common/constants'; -import { StaticOrganizationContents } from './StaticOrganizationContents/StaticOrganizationContents'; -import { Registration } from './Registration/Registration'; - -export const RouteSetupSteps = () => { - const [currentStep, setCurrentStep] = useState(0); - - const links = [ - { - title: 'Facebook business manager verification', - link: FB_MANAGER_VERIFICATION, - }, - { - title: 'Gupshup account creation', - link: GUPSHUP_ACCOUNT_CREATION, - }, - ]; - - const handleStep = () => { - const nextStep = currentStep + 1; - setCurrentStep(nextStep); - }; - - switch (currentStep) { - case 0: - return ( - - ); - case 1: - return ( - - ); - case 2: - return ( - - ); - default: - return null; - } -}; -export default RouteSetupSteps; diff --git a/src/containers/SettingList/Organization/Organisation.test.tsx b/src/containers/SettingList/Organization/Organisation.test.tsx index 3393b2df8e..a814c10f6c 100644 --- a/src/containers/SettingList/Organization/Organisation.test.tsx +++ b/src/containers/SettingList/Organization/Organisation.test.tsx @@ -1,11 +1,12 @@ -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; +import { render, screen, waitFor } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import { BrowserRouter as Router, MemoryRouter } from 'react-router-dom'; +import userEvent from '@testing-library/user-event'; import { ORGANIZATION_MOCKS } from '../SettingList.test.helper'; import { Organization } from './Organization'; +const user = userEvent.setup(); const mocks = ORGANIZATION_MOCKS; const wrapper = ( @@ -53,7 +54,7 @@ test('it renders component and clicks cancel', async () => { const Button = screen.getByText('Cancel'); expect(Button).toBeInTheDocument(); // click on Cancel - UserEvent.click(Button); + user.click(Button); }); }); @@ -81,7 +82,7 @@ test('it renders component in edit mode', async () => { const lowBalanceThreshold = numberInputElements[0] as HTMLInputElement; const criticalBalanceThreshold = numberInputElements[1] as HTMLInputElement; - fireEvent.click(phoneNumber); + user.click(phoneNumber); expect(orgName?.value).toBe('Glific'); expect(signaturePhrase?.value).toBe('Please change me, NOW!'); expect(phoneNumber?.value).toBe('917834811114'); @@ -91,6 +92,6 @@ test('it renders component in edit mode', async () => { await waitFor(() => { const submit = getByTestId('submitActionButton'); - fireEvent.click(submit); + user.click(submit); }); }); diff --git a/src/containers/SettingList/OrganizationFlows/OrganisationFLows.test.tsx b/src/containers/SettingList/OrganizationFlows/OrganisationFLows.test.tsx index 7502a2b14c..963bb86a8e 100644 --- a/src/containers/SettingList/OrganizationFlows/OrganisationFLows.test.tsx +++ b/src/containers/SettingList/OrganizationFlows/OrganisationFLows.test.tsx @@ -1,7 +1,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; import { MockedProvider } from '@apollo/client/testing'; import { BrowserRouter as Router } from 'react-router-dom'; +import userEvent from '@testing-library/user-event'; import { ORGANIZATION_MOCKS } from '../SettingList.test.helper'; import { OrganizationFlows } from './OrganizationFlows'; @@ -16,6 +16,8 @@ const wrapper = (
); +const user = userEvent.setup(); + test('it renders component properly', async () => { const { getByText } = render(wrapper); // loading is show initially @@ -30,7 +32,7 @@ test('it renders component and clicks cancel', async () => { const Button = screen.getByText('Cancel'); expect(Button).toBeInTheDocument(); // click on Cancel - UserEvent.click(Button); + user.click(Button); }); }); @@ -54,12 +56,12 @@ test('it renders component in edit mode', async () => { const selectedOption = screen.getByText('Monday'); expect(selectedOption).toBeInTheDocument(); - fireEvent.click(selectedOption); + user.click(selectedOption); }); }); await waitFor(() => { const submit = getByTestId('submitActionButton'); - fireEvent.click(submit); + user.click(submit); }); }); diff --git a/src/containers/SettingList/Providers/Providers.test.tsx b/src/containers/SettingList/Providers/Providers.test.tsx index 89a05d030a..3975c4db39 100644 --- a/src/containers/SettingList/Providers/Providers.test.tsx +++ b/src/containers/SettingList/Providers/Providers.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; -import UserEvent from '@testing-library/user-event'; import { MockedProvider } from '@apollo/client/testing'; import { MemoryRouter, Route, BrowserRouter as Router, Routes } from 'react-router-dom'; +import userEvent from '@testing-library/user-event'; import { Providers } from './Providers'; import { LIST_ITEM_MOCKS } from '../SettingList.test.helper'; @@ -15,6 +15,7 @@ import { } from 'mocks/Organization'; const mocks = LIST_ITEM_MOCKS; +const user = userEvent.setup(); const wrapper = ( @@ -47,10 +48,10 @@ describe('', () => { expect(getByText('Loading...')).toBeInTheDocument(); await waitFor(() => { const checkbox = screen.getByRole('checkbox'); - UserEvent.click(checkbox); + user.click(checkbox); // click on SAVE const saveButton = screen.getByText('Save'); - UserEvent.click(saveButton); + user.click(saveButton); }); }); }); @@ -63,7 +64,7 @@ describe('', () => { await waitFor(() => { // click on Cancel const cancelButton = screen.getByText('Cancel'); - UserEvent.click(cancelButton); + user.click(cancelButton); }); }); }); @@ -97,18 +98,18 @@ describe('maytapi', () => { const inputs = screen.getAllByRole('textbox'); - fireEvent.click(screen.getByText('Active?')); + user.click(screen.getByText('Active?')); fireEvent.change(inputs[0], { target: { value: 'token' } }); fireEvent.change(inputs[1], { target: { value: 'product_id' } }); - fireEvent.click(screen.getByText('Save')); + user.click(screen.getByText('Save')); await waitFor(() => { expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); }); - fireEvent.click(screen.getByTestId('ok-button')); + user.click(screen.getByTestId('ok-button')); await waitFor(() => { expect(notificationspy).toHaveBeenCalled(); @@ -129,18 +130,18 @@ describe('maytapi', () => { const inputs = screen.getAllByRole('textbox'); - fireEvent.click(screen.getByText('Active?')); + user.click(screen.getByText('Active?')); fireEvent.change(inputs[0], { target: { value: 'token' } }); fireEvent.change(inputs[1], { target: { value: 'product_id' } }); - fireEvent.click(screen.getByText('Save')); + user.click(screen.getByText('Save')); await waitFor(() => { expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); }); - fireEvent.click(screen.getByTestId('ok-button')); + user.click(screen.getByTestId('ok-button')); await waitFor(() => { expect(errorMessageSpy).toHaveBeenCalled(); @@ -186,7 +187,7 @@ describe('update credentials', () => { fireEvent.change(inputs[0], { target: { value: 'token2' } }); fireEvent.change(inputs[1], { target: { value: 'product_id2' } }); - fireEvent.click(screen.getByTestId('submitActionButton')); + user.click(screen.getByTestId('submitActionButton')); await waitFor(() => { expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); @@ -200,7 +201,7 @@ describe('update credentials', () => { expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); }); - fireEvent.click(screen.getByTestId('ok-button')); + user.click(screen.getByTestId('ok-button')); await waitFor(() => { expect(screen.getByText('Token')).toBeInTheDocument(); @@ -229,13 +230,13 @@ describe('update credentials', () => { fireEvent.change(inputs[0], { target: { value: 'token2' } }); fireEvent.change(inputs[1], { target: { value: 'product_id2' } }); - fireEvent.click(screen.getByText('Save')); + user.click(screen.getByText('Save')); await waitFor(() => { expect(screen.getByTestId('dialogBox')).toBeInTheDocument(); }); - fireEvent.click(screen.getByTestId('ok-button')); + user.click(screen.getByTestId('ok-button')); await waitFor(() => { expect(errorMessageSpy).toHaveBeenCalled(); diff --git a/src/containers/StaffManagement/StaffManagement.test.helper.tsx b/src/containers/StaffManagement/StaffManagement.test.helper.tsx index 6b17463b2a..a6693a16c9 100644 --- a/src/containers/StaffManagement/StaffManagement.test.helper.tsx +++ b/src/containers/StaffManagement/StaffManagement.test.helper.tsx @@ -382,7 +382,7 @@ const createUserMockData = new Array(5).fill(null).map((val, idx) => { return { id: `${index}`, name: `NGO Main Account${index}`, - phone: `91987654321${index}`, + phone: `9198765432${index}`, accessRoles: [{ label: roles[idx] }], groups: [], contact: { diff --git a/src/containers/StaffManagement/StaffManagementList/StaffManagementList.test.tsx b/src/containers/StaffManagement/StaffManagementList/StaffManagementList.test.tsx index 0d2ead3018..1fa0be9f29 100644 --- a/src/containers/StaffManagement/StaffManagementList/StaffManagementList.test.tsx +++ b/src/containers/StaffManagement/StaffManagementList/StaffManagementList.test.tsx @@ -24,7 +24,9 @@ const staffManagement = ( ); test('StaffManagementList is rendered correctly', async () => { - setUserSession(JSON.stringify({ organization: { id: '1' }, roles: ['Manager'] })); + setUserSession( + JSON.stringify({ organization: { id: '1' }, roles: [{ id: '1', label: 'Manager' }] }) + ); render(staffManagement); await waitFor(() => { diff --git a/src/containers/Tag/Tag.test.tsx b/src/containers/Tag/Tag.test.tsx index 7bc5fa41a3..6422091e77 100644 --- a/src/containers/Tag/Tag.test.tsx +++ b/src/containers/Tag/Tag.test.tsx @@ -1,22 +1,25 @@ import { MockedProvider } from '@apollo/client/testing'; -import { render, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { MemoryRouter, Route, Routes } from 'react-router-dom'; import { vi } from 'vitest'; import { getOrganizationLanguagesQuery, getOrganizationQuery } from 'mocks/Organization'; -import { getTagQuery, filterTagQuery, getFilterTagQuery } from 'mocks/Tag'; +import { getTagQuery, filterTagQuery, getFilterTagQuery, createTag } from 'mocks/Tag'; import { Tag } from './Tag'; import { setOrganizationServices } from 'services/AuthService'; import { getRoleNameQuery } from 'mocks/Role'; +import * as Notification from 'common/notification'; setOrganizationServices('{"__typename":"OrganizationServicesResult","rolesAndPermission":true}'); const mocks = [ ...getOrganizationQuery, getTagQuery, + getTagQuery, filterTagQuery, getOrganizationLanguagesQuery, getFilterTagQuery, getRoleNameQuery, + createTag, ]; const mockUseLocationValue: any = { @@ -26,12 +29,12 @@ const mockUseLocationValue: any = { state: null, }; +const notificationSpy = vi.spyOn(Notification, 'setNotification'); vi.mock('react-router-dom', async () => ({ ...((await vi.importActual('react-router-dom')) as {}), useLocation: () => { return mockUseLocationValue; }, - useParams: () => ({ id: 13 }), })); const tag = () => ( @@ -49,6 +52,27 @@ it('should render Tag', async () => { }); }); +it('should create the tag', async () => { + render( + + + + + + ); + await waitFor(() => { + expect(screen.getByText('Add a new tag')).toBeInTheDocument(); + }); + + fireEvent.change(screen.getByRole('textbox'), { target: { value: 'tag' } }); + + fireEvent.click(screen.getByTestId('submitActionButton')); + + await waitFor(() => { + expect(notificationSpy).toHaveBeenCalled(); + }); +}); + it('should edit the tag', async () => { const edittag = () => ( diff --git a/src/containers/Ticket/TicketList/TicketList.test.tsx b/src/containers/Ticket/TicketList/TicketList.test.tsx index 045da7c841..8097f8b5a2 100644 --- a/src/containers/Ticket/TicketList/TicketList.test.tsx +++ b/src/containers/Ticket/TicketList/TicketList.test.tsx @@ -34,6 +34,7 @@ test('should load the ticket list', async () => { expect(getByTestId('loading')).toBeInTheDocument(); await waitFor(() => { expect(getByText('Tickets')).toBeInTheDocument(); + expect(getByText('field name')).toBeInTheDocument(); }); }); diff --git a/src/mocks/Chat.tsx b/src/mocks/Chat.tsx index c90ab9dbe4..534e24a0e5 100644 --- a/src/mocks/Chat.tsx +++ b/src/mocks/Chat.tsx @@ -761,17 +761,11 @@ const conversationWithMultipleMessages = { ], }; -export const createAndSendMessageMutation = { +export const createAndSendMessageMutation = (input: any) => ({ request: { query: CREATE_AND_SEND_MESSAGE_MUTATION, variables: { - input: { - body: 'Hey There Wow', - senderId: '1', - receiverId: '2', - type: 'TEXT', - flow: 'OUTBOUND', - }, + input, }, }, result: { @@ -791,42 +785,7 @@ export const createAndSendMessageMutation = { }, }, }, -}; - -export const createAndSendMessageMutation2 = { - request: { - query: CREATE_AND_SEND_MESSAGE_MUTATION, - variables: { - input: { - body: 'hey', - senderId: 1, - receiverId: '2', - flow: 'OUTBOUND', - interactiveTemplateId: undefined, - type: 'TEXT', - mediaId: null, - }, - }, - }, - result: { - data: { - createAndSendMessage: { - message: { - body: 'hey', - insertedAt: '2020-06-25T13:36:43Z', - id: '10388', - receiver: { - id: '2', - }, - sender: { - id: '1', - }, - media: null, - }, - }, - }, - }, -}; +}); export const sendMessageInWaGroup = { request: { @@ -949,7 +908,13 @@ const chatMessagesMocks = [ searchQuerywithFilter, searchQuerywithFilterOffset, searchQuerywithFilterOffset, - createAndSendMessageMutation, + createAndSendMessageMutation({ + body: 'Hey There Wow', + senderId: '1', + receiverId: '2', + type: 'TEXT', + flow: 'OUTBOUND', + }), ]; export const mocksWithConversation = [...chatMessagesMocks, getConversationQuery(conversation)]; diff --git a/src/mocks/Collection.tsx b/src/mocks/Collection.tsx index 1778a0c852..fd00e3d7c1 100644 --- a/src/mocks/Collection.tsx +++ b/src/mocks/Collection.tsx @@ -10,7 +10,12 @@ import { GET_COLLECTION_USERS, GET_ORGANIZATION_COLLECTIONS, } from 'graphql/queries/Collection'; -import { CREATE_COLLECTION, UPDATE_COLLECTION_CONTACTS } from 'graphql/mutations/Collection'; +import { + CREATE_COLLECTION, + UPDATE_COLLECTION, + UPDATE_COLLECTION_CONTACTS, + UPDATE_COLLECTION_USERS, +} from 'graphql/mutations/Collection'; import { CONTACTS_COLLECTION, WA_GROUPS_COLLECTION } from 'common/constants'; export const getCollectionQuery = { @@ -479,3 +484,47 @@ export const getCollectionsList = (label?: any) => ({ }, }, }); + +export const updateCollectionQuery = { + request: { + query: UPDATE_COLLECTION, + variables: { + id: '1', + input: { + label: 'Staff group', + description: 'Only for staff members', + addRoleIds: [], + deleteRoleIds: [], + groupType: 'WABA', + }, + }, + }, + result: { + data: { + updateGroup: { + group: { + id: '1', + label: 'Staff group', + description: 'Only for staff members', + }, + }, + }, + }, +}; + +export const updateCollectionUsersQuery = { + request: { + query: UPDATE_COLLECTION_USERS, + variables: { input: { addUserIds: [], groupId: '1', deleteUserIds: ['1', '2'] } }, + }, + result: { + data: { + updateGroupUsers: { + groupUsers: { + id: '1', + value: '', + }, + }, + }, + }, +}; diff --git a/src/mocks/Contact.tsx b/src/mocks/Contact.tsx index c1932e992b..1d9166efa2 100644 --- a/src/mocks/Contact.tsx +++ b/src/mocks/Contact.tsx @@ -18,8 +18,22 @@ import { UPDATE_CONTACT_COLLECTIONS } from 'graphql/mutations/Collection'; import { CLEAR_MESSAGES } from 'graphql/mutations/Chat'; import { setVariables } from 'common/constants'; import { getCurrentUserQuery } from './User'; +import { TERMINATE_FLOW } from 'graphql/mutations/Flow'; -export const contactCollectionsQuery = (id: number) => ({ +const groups = [ + { + id: '1', + label: 'Default Collection', + users: [], + }, + { + id: '2', + label: 'Staff Collection', + users: [], + }, +]; + +export const contactCollectionsQuery = (id: number, multipleGroups: boolean = false) => ({ request: { query: GET_CONTACT_COLLECTIONS, variables: { @@ -30,18 +44,9 @@ export const contactCollectionsQuery = (id: number) => ({ data: { contact: { contact: { - groups: [ - { - id: '1', - label: 'Default Collection', - users: [], - }, - { - id: '2', - label: 'Staff Collection', - users: [], - }, - ], + groups: multipleGroups + ? [...groups, { id: '3', label: 'Test collection', users: [] }] + : groups, }, }, }, @@ -719,3 +724,20 @@ export const importContacts = { }, variableMatcher: (variables: any) => true, }; + +export const terminateFlowQuery = (error: boolean = false) => ({ + request: { + query: TERMINATE_FLOW, + variables: { + contactId: '2', + }, + }, + result: { + data: { + terminateContactFlows: { + success: !error, + errors: error ? [{ message: 'Some error occurred' }] : null, + }, + }, + }, +}); diff --git a/src/mocks/Organization.tsx b/src/mocks/Organization.tsx index 95dcb749ef..e83b9dde4a 100644 --- a/src/mocks/Organization.tsx +++ b/src/mocks/Organization.tsx @@ -368,11 +368,10 @@ export const getProvidersQuery = [ variables: { id: '1', input: { - shortcode: 'gupshup', + shortcode: null, isActive: true, keys: '{"worker":"Glific.Providers.Gupshup.Worker","url":"https://gupshup.io/","handler":"Glific.Providers.Gupshup.Message","api_end_point":"https://api.gupshup.io/sm/api/v1"}', - secrets: - '{"app_name":"Please enter your App Name here","api_key":"Please enter your key here"}', + secrets: '{}', }, }, }, diff --git a/src/mocks/Tag.tsx b/src/mocks/Tag.tsx index 705a25f71c..9d06f9d97d 100644 --- a/src/mocks/Tag.tsx +++ b/src/mocks/Tag.tsx @@ -1,10 +1,11 @@ +import { CREATE_LABEL } from 'graphql/mutations/Tags'; import { GET_TAG, FILTER_TAGS, GET_TAGS, GET_TAG_COUNT } from 'graphql/queries/Tags'; export const getTagQuery = { request: { query: GET_TAG, variables: { - id: 13, + id: '13', }, }, @@ -109,3 +110,26 @@ export const countTagQuery = { }, }, }; + +export const createTag = { + request: { + query: CREATE_LABEL, + variables: { + input: { + label: 'tag', + language_id: '1', + }, + }, + }, + result: { + data: { + createTag: { + errors: null, + tag: { + id: '4', + label: 'tag', + }, + }, + }, + }, +}; diff --git a/src/mocks/Template.tsx b/src/mocks/Template.tsx index 244884460c..7f1782073a 100644 --- a/src/mocks/Template.tsx +++ b/src/mocks/Template.tsx @@ -39,12 +39,35 @@ const filterQuery = filterTemplatesQuery( numberParameters: 0, translations: '{"2":{"status":"approved","languageId":{"label":"Hindi","id":"2"},"label":"now","isHsm":false,"body":"hey","MessageMedia":null}}', - type: 'TEXT', + type: 'IMAGE', quality: null, language: { id: '1', label: 'Hindi', }, + MessageMedia: null, + }, + { + id: '94', + label: 'Message', + bspId: null, + body: 'some description', + shortcode: 'test', + isReserved: true, + isHsm: false, + isActive: true, + status: null, + reason: 'test reason', + updatedAt: '2020-12-01T18:00:32Z', + numberParameters: 0, + translations: '{}', + type: 'IMAGE', + language: { + id: '1', + label: 'Hindi', + }, + category: 'ACCOUNT_UPDATE', + quality: null, MessageMedia: { id: 1, caption: 'Test', @@ -52,20 +75,20 @@ const filterQuery = filterTemplatesQuery( }, }, { - id: '94', + id: '3', label: 'Message', bspId: null, body: 'some description', shortcode: 'test', isReserved: true, - isHsm: false, + isHsm: true, isActive: true, - status: null, + status: 'APPROVED', reason: 'test reason', updatedAt: '2020-12-01T18:00:32Z', numberParameters: 0, translations: '{}', - type: 'TEXT', + type: 'IMAGE', language: { id: '1', label: 'Hindi', @@ -78,6 +101,31 @@ const filterQuery = filterTemplatesQuery( sourceUrl: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg', }, }, + { + MessageMedia: null, + __typename: 'SessionTemplate', + body: 'You can now view your Account Balance or Mini statement for Account ending with {{1}} simply by selecting one of the options below. ', + bspId: '0922869a-cd33-4fed-83af-39376d8ccfb5', + category: 'ACCOUNT_UPDATE', + id: '11', + isActive: true, + isHsm: true, + isReserved: false, + label: 'account_statement', + language: { + __typename: 'Language', + id: '1', + label: 'English', + }, + numberParameters: 1, + quality: null, + reason: null, + shortcode: 'account_statement', + status: 'APPROVED', + translations: '{}', + type: 'TEXT', + updatedAt: '2024-10-02T05:02:29Z', + }, ], { isHsm: true } ); @@ -171,17 +219,13 @@ export const TEMPLATE_MOCKS = [ updatedAt: '2020-12-01T18:00:32Z', numberParameters: 0, translations: '{}', - type: 'TEXT', + type: 'IMAGE', quality: null, language: { id: '1', label: 'Hindi', }, - MessageMedia: { - id: 1, - caption: 'Test', - sourceUrl: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg', - }, + MessageMedia: null, }, ], { isHsm: true } diff --git a/src/mocks/Ticket.tsx b/src/mocks/Ticket.tsx index 7ace3f5590..0bd697f3f0 100644 --- a/src/mocks/Ticket.tsx +++ b/src/mocks/Ticket.tsx @@ -53,7 +53,7 @@ export const ticketListQuery = { contact: { id: '1', name: 'NGO support', - fields: null, + fields: '{}', maskedPhone: '9194*****449', }, id: '1', @@ -73,11 +73,11 @@ export const ticketListQuery = { contact: { id: '2', name: null, - fields: null, + fields: '{"name":{"value":"field name"}}', maskedPhone: '9194*****449', }, id: '2', - messageNumber: 23, + messageNumber: null, insertedAt: '2021-06-16T09:00:00.000Z', remarks: 'This issue is resolved', status: 'open', @@ -88,6 +88,46 @@ export const ticketListQuery = { name: 'Glific user', }, }, + { + body: '', + contact: { + id: '3', + name: null, + fields: '{}', + maskedPhone: '9194*****449', + }, + id: '3', + messageNumber: 23, + insertedAt: '2021-06-16T09:00:00.000Z', + remarks: 'This issue is resolved', + status: 'open', + topic: 'General', + updatedAt: '2021-06-16T09:00:00.000Z', + user: { + id: '1', + name: null, + }, + }, + { + body: '', + contact: { + id: '3', + name: null, + fields: '{}', + maskedPhone: null, + }, + id: '4', + messageNumber: 23, + insertedAt: '2021-06-16T09:00:00.000Z', + remarks: 'This issue is resolved', + status: 'open', + topic: 'General', + updatedAt: '2021-06-16T09:00:00.000Z', + user: { + id: '1', + name: null, + }, + }, ], }, }, diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx index cb51d5b93c..3900bf5e3e 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx @@ -25,21 +25,15 @@ const SpeedSendList = lazy(() => import('containers/Template/List/SpeedSendList/ const SpeedSend = lazy(() => import('containers/Template/Form/SpeedSend/SpeedSend')); const FlowList = lazy(() => import('containers/Flow/FlowList/FlowList')); const Flow = lazy(() => import('containers/Flow/Flow')); -const SheetIntegrationList = lazy( - () => import('containers/SheetIntegration/SheetIntegrationList/SheetIntegrationList') -); +const SheetIntegrationList = lazy(() => import('containers/SheetIntegration/SheetIntegrationList/SheetIntegrationList')); const SheetIntegration = lazy(() => import('containers/SheetIntegration/SheetIntegration')); const CollectionList = lazy(() => import('containers/Collection/CollectionList/CollectionList')); const Collection = lazy(() => import('containers/Collection/Collection')); -const CollectionContact = lazy( - () => import('containers/Collection/CollectionContact/CollectionContact') -); +const CollectionContact = lazy(() => import('containers/Collection/CollectionContact/CollectionContact')); const FlowEditor = lazy(() => import('components/floweditor/FlowEditor')); const SearchList = lazy(() => import('containers/Search/SearchList/SearchList')); const Search = lazy(() => import('containers/Search/Search')); -const StaffManagementList = lazy( - () => import('containers/StaffManagement/StaffManagementList/StaffManagementList') -); +const StaffManagementList = lazy(() => import('containers/StaffManagement/StaffManagementList/StaffManagementList')); const ContactManagement = lazy(() => import('containers/ContactManagement/ContactManagement')); const StaffManagement = lazy(() => import('containers/StaffManagement/StaffManagement')); const ContactProfile = lazy(() => import('containers/Profile/Contact/ContactProfile')); @@ -49,25 +43,15 @@ const HSM = lazy(() => import('containers/Template/Form/HSM/HSM')); const TicketList = lazy(() => import('containers/Ticket/TicketList/TicketList')); const SettingList = lazy(() => import('containers/SettingList/SettingList')); -const BlockContactList = lazy( - () => import('containers/BlockContact/BlockContactList/BlockContactList') -); -const WebhookLogsList = lazy( - () => import('containers/WebhookLogs/WebhookLogsList/WebhookLogsList') -); +const BlockContactList = lazy(() => import('containers/BlockContact/BlockContactList/BlockContactList')); +const WebhookLogsList = lazy(() => import('containers/WebhookLogs/WebhookLogsList/WebhookLogsList')); const TriggerList = lazy(() => import('containers/Trigger/TriggerList/TriggerList')); const Trigger = lazy(() => import('containers/Trigger/Trigger')); const NotificationList = lazy(() => import('containers/NotificationList/NotificationList')); const OrganizationList = lazy(() => import('containers/OrganizationList/OrganizationList')); -const ConsultingHourList = lazy( - () => import('containers/Consulting/ConsultingList/ConsultingList') -); -const ContactFieldList = lazy( - () => import('containers/ContactField/ContactFieldList/ContactFieldList') -); -const InteractiveMessageList = lazy( - () => import('containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList') -); +const ConsultingHourList = lazy(() => import('containers/Consulting/ConsultingList/ConsultingList')); +const ContactFieldList = lazy(() => import('containers/ContactField/ContactFieldList/ContactFieldList')); +const InteractiveMessageList = lazy(() => import('containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList')); const InteractiveMessage = lazy(() => import('containers/InteractiveMessage/InteractiveMessage')); const RoleList = lazy(() => import('containers/Role/RoleList/RoleList')); @@ -215,12 +199,7 @@ export const AuthenticatedRoute = () => { route = routeStaff; } - if ( - checkDynamicRole() || - userRole.includes('Manager') || - userRole.includes('Admin') || - userRole.includes('Glific_admin') - ) { + if (checkDynamicRole() || userRole.includes('Manager') || userRole.includes('Admin') || userRole.includes('Glific_admin')) { route = routeAdmin; } @@ -231,9 +210,7 @@ export const AuthenticatedRoute = () => {
{toastMessage} - } - > + }> {route} diff --git a/yarn.lock b/yarn.lock index 29117e4e9f..91d78c6a99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6444,4 +6444,4 @@ zen-observable-ts@^1.2.5: zen-observable@0.8.15: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" - integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== \ No newline at end of file