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

Refactoring: Separating HSM and Speed sends #3063

Merged
merged 34 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ce6857a
separated hsm and speed sends
akanshaaa19 Sep 4, 2024
494216b
fixed errors
akanshaaa19 Sep 20, 2024
915b068
Merge branch 'master' of github.com:glific/glific-frontend into templ…
akanshaaa19 Sep 20, 2024
a259362
added speed sends
akanshaaa19 Sep 20, 2024
f7f0614
updated test cases
akanshaaa19 Sep 21, 2024
60a7001
updated test cases
akanshaaa19 Sep 23, 2024
5974f21
updated test cases
akanshaaa19 Sep 24, 2024
eaa1db0
updated test cases
akanshaaa19 Sep 24, 2024
8861d52
updated test cases
akanshaaa19 Sep 24, 2024
9fb0c96
fixed failing test
akanshaaa19 Sep 24, 2024
98446d3
fixed failing test
akanshaaa19 Sep 24, 2024
22bfcb2
refactoring
akanshaaa19 Sep 29, 2024
c59d867
Merge branch 'master' of github.com:glific/glific-frontend into templ…
akanshaaa19 Sep 29, 2024
f4ee730
fixed test cases
akanshaaa19 Sep 29, 2024
023e5cf
Merge branch 'master' of github.com:glific/glific-frontend into templ…
akanshaaa19 Oct 2, 2024
a6386eb
updated mocks
akanshaaa19 Oct 2, 2024
dffa130
updated test cases
akanshaaa19 Oct 8, 2024
fd535ae
updated test cases
akanshaaa19 Oct 8, 2024
58b7404
updated test cases
akanshaaa19 Oct 9, 2024
2ba366e
Merge branch 'master' into templates-refactoring
kurund Oct 11, 2024
53f4e0f
seprated list components
akanshaaa19 Oct 16, 2024
b765d86
Merge branch 'templates-refactoring' of github.com:glific/glific-fron…
akanshaaa19 Oct 16, 2024
c5a36b9
fixed test case
akanshaaa19 Oct 17, 2024
7b21e31
Merge branch 'master' of github.com:glific/glific-frontend into templ…
akanshaaa19 Dec 17, 2024
d1ff71e
minor fixes
akanshaaa19 Dec 18, 2024
910ea99
deepscan fixes
akanshaaa19 Dec 18, 2024
0a27dd2
refactoring hsm
akanshaaa19 Jan 2, 2025
be3401e
removed console logs
akanshaaa19 Jan 2, 2025
cc5e856
fixed deepscan issues
akanshaaa19 Jan 2, 2025
5b65e56
fixed deepscan issues
akanshaaa19 Jan 2, 2025
f2aca7c
refactoring hsm
akanshaaa19 Jan 3, 2025
161c74e
Merge branch 'master' into templates-refactoring
kurund Jan 3, 2025
27742a7
helper function - update text
kurund Jan 3, 2025
78a5145
styling fixes for speed sends
kurund Jan 3, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/cypress-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
git clone https://github.com/glific/cypress-testing.git
echo done. go to dir.
cd cypress-testing
git checkout main
git checkout templates
cd ..
cp -r cypress-testing/cypress cypress
yarn add [email protected]
Expand Down
4 changes: 3 additions & 1 deletion src/components/UI/Form/AutoComplete/AutoComplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ export const AutoComplete = ({
freeSolo={freeSolo}
autoSelect={autoSelect}
disableClearable={disableClearable}
getOptionLabel={(option: any) => (option[optionLabel] != null ? option[optionLabel] : option)}
getOptionLabel={(option: any) =>
option[optionLabel] != null ? option[optionLabel] : typeof option === 'string' ? option : ''
}
getOptionDisabled={getOptionDisabled}
isOptionEqualToValue={(option, value) => {
if (value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { render, fireEvent, cleanup, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';

import { SAVE_MESSAGE_TEMPLATE_MUTATION } from 'graphql/mutations/MessageTemplate';
import { TEMPLATE_MOCKS } from 'mocks/Template';
import { filterTemplatesQuery } from 'mocks/Template';
import AddToMessageTemplate from './AddToMessageTemplate';

let resultReturned = false;

const mocks = [
...TEMPLATE_MOCKS,
filterTemplatesQuery('', {}),
{
request: {
query: SAVE_MESSAGE_TEMPLATE_MUTATION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { render, waitFor, fireEvent, screen } from '@testing-library/react';
import { vi } from 'vitest';

import ChatInput from './ChatInput';
import { TEMPLATE_MOCKS } from 'mocks/Template';
import { createMediaMessageMock, getAttachmentPermissionMock, uploadBlobMock } from 'mocks/Attachment';
import { searchInteractive, searchInteractiveHi } from 'mocks/InteractiveMessage';
import '../VoiceRecorder/VoiceRecorder';
import { LexicalWrapper } from 'common/LexicalWrapper';
import { TEMPLATE_MOCKS } from 'mocks/Template';

const mocks = [
searchInteractive,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MockedProvider } from '@apollo/client/testing';
import ChatTemplates from './ChatTemplates';
import { TEMPLATE_MOCKS } from '../../../../mocks/Template';
import { render, fireEvent, waitFor } from '@testing-library/react';
import { TEMPLATE_MOCKS } from 'mocks/Template';

const mocks = TEMPLATE_MOCKS;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const TemplateButtons = ({
onClick={() => handleButtonClick(type, value)}
startIcon={icon}
disabled={!isSimulator}
data-testid="templateButton"
>
{title}
</Button>
Expand Down
2 changes: 1 addition & 1 deletion src/containers/Form/FormLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const FormLayout = ({
}
});
// for template create media for attachment
if (isAttachment && payload.type !== 'TEXT' && payload.type) {
if (isAttachment && payload.type !== 'TEXT' && payload.type && !entityId) {
getMediaId(payload)
.then((data: any) => {
if (data) {
Expand Down
106 changes: 106 additions & 0 deletions src/containers/HSM/HSM.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { CALL_TO_ACTION, MEDIA_MESSAGE_TYPES, QUICK_REPLY } from 'common/constants';

export interface CallToActionTemplate {
type: string;
title: string;
value: string;
}

export interface QuickReplyTemplate {
value: string;
}

export const mediaOptions = MEDIA_MESSAGE_TYPES.map((option: string) => ({ id: option, label: option })).filter(
({ label }) => label !== 'AUDIO' && label !== 'STICKER'
);

export const removeFirstLineBreak = (text: any) =>
text?.length === 1 ? text.slice(0, 1).replace(/(\r\n|\n|\r)/, '') : text;

/**
* Function to convert buttons to template format
*
* @param templateButtons buttons that need to be converted to gupshup format
* @param templateType depending on template type convert button to gupshup format
*
* @return array result
*/
export const convertButtonsToTemplate = (templateButtons: Array<any>, templateType: string | null) =>
templateButtons.reduce((result: any, temp: any) => {
const { title, value } = temp;
if (templateType === CALL_TO_ACTION && value && title) {
result.push(`[${title}, ${value}]`);
}
if (templateType === QUICK_REPLY && value) {
result.push(`[${value}]`);
}
return result;
}, []);

/**
* As messages and buttons are now separated
* we are combining both message and buttons,
* so that you can see preview in simulator
*
* @param templateType template type
* @param message
* @param buttons
*
* @return object {buttons, template}
*/
export const getTemplateAndButtons = (templateType: string, message: string, buttons: string) => {
const templateButtons = JSON.parse(buttons);
let result: any;
if (templateType === CALL_TO_ACTION) {
result = templateButtons.map((button: any) => {
const { phone_number: phoneNo, url, type, text } = button;
return { type, value: url || phoneNo, title: text };
});
}

if (templateType === QUICK_REPLY) {
result = templateButtons.map((button: any) => {
const { text, type } = button;
return { type, value: text };
});
}

// Getting in template format of gupshup
const templateFormat = convertButtonsToTemplate(result, templateType);
// Pre-pending message with buttons
const template = `${message} | ${templateFormat.join(' | ')}`;
return { buttons: result, template };
};

export const getExampleFromBody = (body: string, variables: Array<any>) => {
return body.replace(/{{(\d+)}}/g, (match, number) => {
let index = parseInt(number) - 1;

return variables[index]?.text ? (variables[index] ? `[${variables[index]?.text}]` : match) : `{{${number}}}`;
});
};

export const getVariables = (message: string, variables: any) => {
const regex = /{{\d+}}/g;
const matches = message.match(regex);

if (!matches) {
return [];
}

return matches.map((match, index) => (variables[index]?.text ? variables[index] : { text: '', id: index + 1 }));
};

export const getExampleValue = (example: string) => {
const regex = /\[([^\]]+)\]/g;
let match;
const variables = [];
let id = 1;

while ((match = regex.exec(example)) !== null) {
variables.push({ text: match[1], id });
id++;
}

return variables;
};
102 changes: 102 additions & 0 deletions src/containers/HSM/HSM.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
.Template {
margin: 20px auto;
width: 80%;
text-align: center;
box-shadow: 0 2px 3px #cccccc;
border: 1px solid #eeeeee;
padding: 10px;
box-sizing: border-box;
}

@media (min-width: 600px) {
.Template {
width: 500px;
}
}

.DeleteIcon {
margin-right: 9px !important;
}

.DialogText {
margin-top: 0px;
text-align: center;
color: #073f24;
font-weight: 400;
}

.DeleteButton {
margin-left: auto !important;
}

.Title {
margin-left: 24px !important;
margin-top: 16px !important;
vertical-align: middle;
font-weight: 500 !important;
color: #073f24;
}

.Input {
display: flex;
padding: 8px;
}

.Label {
width: 50%;
align-self: center;
font-weight: bold;
}

.TemplateAdd {
width: fit-content;
}

.Form {
padding: 16px 16px;
width: 470px;
}

.Buttons {
margin-top: 24px;
margin-left: 8px;
display: flex;
justify-content: flex-start;
}

.Icon {
background-color: #eaedec !important;
margin-right: 10px !important;
}

.ButtonsCenter {
justify-content: center !important;
}

.Button {
margin-right: 24px !important;
}

.Warning {
color: #ff0000;
margin-left: -43px;
}

.IsActive {
color: #555555;
font-weight: 400;
line-height: 18px;
font-size: 16px;
}

.TemplateIcon {
width: 29px;
height: 29px;
}

.Checkbox {
color: #555555;
font-weight: 400;
line-height: 18px;
font-size: 16px;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { render, waitFor, within, fireEvent, screen } from '@testing-library/react';
import { render, waitFor, within, fireEvent, screen, cleanup } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import userEvent from '@testing-library/user-event';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { HSM } from './HSM';
import {
TEMPLATE_MOCKS,
getHSMTemplateTypeMedia,
getHSMTemplateTypeText,
} from 'containers/Template/Template.test.helper';
import { HSM_TEMPLATE_MOCKS, getHSMTemplateTypeMedia, getHSMTemplateTypeText } from 'mocks/Template';
import { setNotification } from 'common/notification';

const mocks = TEMPLATE_MOCKS;
const mocks = HSM_TEMPLATE_MOCKS;

vi.mock('common/notification', async (importOriginal) => {
const mod = await importOriginal<typeof import('common/notification')>();
return {
...mod,
setNotification: vi.fn((...args) => {
return args[1];
}),
};
});

beforeEach(() => {
vi.restoreAllMocks();
cleanup();
});

vi.mock('lexical-beautiful-mentions', async (importOriginal) => {
Expand Down Expand Up @@ -80,6 +87,7 @@ describe('Add mode', () => {
</MemoryRouter>
</MockedProvider>
);

const user = userEvent.setup();

test('check for validations for the HSM form', async () => {
Expand Down Expand Up @@ -120,7 +128,6 @@ describe('Add mode', () => {
const inputs = screen.getAllByRole('textbox');

fireEvent.change(inputs[0], { target: { value: 'element_name' } });
fireEvent.change(inputs[1], { target: { value: 'element_name' } });
const lexicalEditor = inputs[2];

await user.click(lexicalEditor);
Expand All @@ -144,11 +151,19 @@ describe('Add mode', () => {
await waitFor(() => {
expect(screen.getByText('Hi, How are you {{1}}')).toBeInTheDocument();
});
fireEvent.change(inputs[1], { target: { value: 'element_name' } });

fireEvent.change(screen.getByPlaceholderText('Define value'), { target: { value: 'User' } });

autocompletes[3].focus();
fireEvent.keyDown(autocompletes[3], { key: 'ArrowDown' });
fireEvent.click(screen.getByText('Messages'), { key: 'Enter' });
fireEvent.change(inputs[1], { target: { value: 'title' } });

fireEvent.click(screen.getByTestId('submitActionButton'));

await waitFor(() => {
expect(setNotification).toHaveBeenCalled();
});
});

test('it should add and remove variables', async () => {
Expand Down Expand Up @@ -176,6 +191,10 @@ describe('Add mode', () => {
});

fireEvent.click(screen.getAllByTestId('delete-variable')[0]);

await waitFor(() => {
expect(screen.queryByPlaceholderText('Define value ')).not.toBeInTheDocument();
});
});

test('it adds quick reply buttons', async () => {
Expand Down Expand Up @@ -224,7 +243,10 @@ describe('Add mode', () => {
fireEvent.click(screen.getByText('ACCOUNT_UPDATE'), { key: 'Enter' });

fireEvent.click(screen.getByTestId('submitActionButton'));
fireEvent.click(screen.getByTestId('submitActionButton'));

await waitFor(() => {
expect(setNotification).toHaveBeenCalled();
});
});

test('it adds call to action buttons', async () => {
Expand Down Expand Up @@ -272,7 +294,10 @@ describe('Add mode', () => {
fireEvent.click(screen.getByText('ACCOUNT_UPDATE'), { key: 'Enter' });

fireEvent.click(screen.getByTestId('submitActionButton'));
fireEvent.click(screen.getByTestId('submitActionButton'));

await waitFor(() => {
expect(setNotification).toHaveBeenCalled();
});
});

test('adding attachments', async () => {
Expand Down
Loading
Loading