@capillarytech/creatives-library 8.0.141 → 8.0.142

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/initialReducer.js +2 -0
  2. package/package.json +2 -2
  3. package/services/api.js +5 -0
  4. package/services/tests/api.test.js +17 -0
  5. package/v2Components/MobilePushPreviewV2/index.js +8 -0
  6. package/v2Components/NavigationBar/saga.js +1 -1
  7. package/v2Components/NavigationBar/tests/saga.test.js +2 -2
  8. package/v2Components/TemplatePreview/assets/images/empty_android.svg +8 -0
  9. package/v2Components/TemplatePreview/assets/images/empty_ios.svg +5 -0
  10. package/v2Components/TemplatePreview/index.js +28 -2
  11. package/v2Containers/BeePopupEditor/constants.js +10 -0
  12. package/v2Containers/BeePopupEditor/index.js +169 -0
  13. package/v2Containers/BeePopupEditor/tests/index.test.js +628 -0
  14. package/v2Containers/CreativesContainer/SlideBoxContent.js +26 -8
  15. package/v2Containers/CreativesContainer/index.js +12 -2
  16. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +5 -0
  17. package/v2Containers/InApp/actions.js +7 -0
  18. package/v2Containers/InApp/constants.js +5 -1
  19. package/v2Containers/InApp/index.js +76 -53
  20. package/v2Containers/InApp/reducer.js +17 -0
  21. package/v2Containers/InApp/sagas.js +27 -0
  22. package/v2Containers/InApp/selectors.js +23 -1
  23. package/v2Containers/InApp/tests/index.test.js +0 -9
  24. package/v2Containers/InApp/tests/reducer.test.js +33 -0
  25. package/v2Containers/InApp/tests/sagas.test.js +57 -1
  26. package/v2Containers/InApp/tests/selector.test.js +612 -0
  27. package/v2Containers/InappAdvanced/index.js +459 -0
  28. package/v2Containers/InappAdvanced/index.scss +11 -0
  29. package/v2Containers/InappAdvanced/tests/index.test.js +442 -0
  30. package/v2Containers/InappWrapper/_inappWrapper.scss +19 -0
  31. package/v2Containers/InappWrapper/index.js +194 -0
  32. package/v2Containers/InappWrapper/messages.js +38 -0
  33. package/v2Containers/InappWrapper/tests/index.test.js +247 -0
  34. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  35. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  36. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  37. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  38. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +18 -0
  39. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  40. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -0
@@ -1267,7 +1267,7 @@ export class Creatives extends React.Component {
1267
1267
  shouldShowFooter = () => {
1268
1268
  const { isFullMode } = this.props;
1269
1269
  const {
1270
- slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
1270
+ slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
1271
1271
  } = this.state;
1272
1272
  const channel = currentChannel.toUpperCase();
1273
1273
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1310,6 +1310,13 @@ export class Creatives extends React.Component {
1310
1310
  showFooter = true;
1311
1311
  }
1312
1312
 
1313
+ if (channel === constants.INAPP &&
1314
+ ((slidBoxContent === 'createTemplate' && !isEmpty(inAppCreateMode))
1315
+ || (slidBoxContent === 'editTemplate' && currentStep === 'modeSelection')) &&
1316
+ templateNameExists) {
1317
+ showFooter = true;
1318
+ }
1319
+
1313
1320
  if (showFooter) {
1314
1321
  if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent') ||
1315
1322
  ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
@@ -1430,7 +1437,7 @@ export class Creatives extends React.Component {
1430
1437
  } else if (currentChannel.toUpperCase() === constants.WECHAT) {
1431
1438
  isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
1432
1439
  } else if (currentChannel.toUpperCase() === constants.INAPP) {
1433
- isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1440
+ isShowContinueFooter = !isEmpty(inAppCreateMode) && currentStep === "modeSelection";
1434
1441
  }
1435
1442
 
1436
1443
  return isShowContinueFooter;
@@ -1467,6 +1474,7 @@ export class Creatives extends React.Component {
1467
1474
  templateStep,
1468
1475
  isLoadingContent,
1469
1476
  mobilePushCreateMode,
1477
+ inAppCreateMode,
1470
1478
  isDiscardMessage,
1471
1479
  weChatTemplateType,
1472
1480
  weChatMaptemplateStep,
@@ -1569,6 +1577,8 @@ export class Creatives extends React.Component {
1569
1577
  setIsLoadingContent={this.setIsLoadingContent}
1570
1578
  onMobilepushModeChange={this.onMobilepushModeChange}
1571
1579
  mobilePushCreateMode={mobilePushCreateMode}
1580
+ inAppCreateMode={inAppCreateMode}
1581
+ onInAppModeChange={this.onInAppModeChange}
1572
1582
  showTemplateName={this.showTemplateName}
1573
1583
  onValidationFail={this.onValidationFail}
1574
1584
  channelsToHide={channelsToHide}
@@ -31,6 +31,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click rcs
31
31
  onEnterTemplateName={[Function]}
32
32
  onFTPSubmit={[MockFunction]}
33
33
  onFacebookSubmit={[MockFunction]}
34
+ onInAppModeChange={[Function]}
34
35
  onMobilepushModeChange={[Function]}
35
36
  onPreviewTemplate={[Function]}
36
37
  onRemoveTemplateName={[Function]}
@@ -116,6 +117,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click wha
116
117
  onEnterTemplateName={[Function]}
117
118
  onFTPSubmit={[MockFunction]}
118
119
  onFacebookSubmit={[MockFunction]}
120
+ onInAppModeChange={[Function]}
119
121
  onMobilepushModeChange={[Function]}
120
122
  onPreviewTemplate={[Function]}
121
123
  onRemoveTemplateName={[Function]}
@@ -201,6 +203,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
201
203
  onEnterTemplateName={[Function]}
202
204
  onFTPSubmit={[MockFunction]}
203
205
  onFacebookSubmit={[MockFunction]}
206
+ onInAppModeChange={[Function]}
204
207
  onMobilepushModeChange={[Function]}
205
208
  onPreviewTemplate={[Function]}
206
209
  onRemoveTemplateName={[Function]}
@@ -298,6 +301,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
298
301
  onEnterTemplateName={[Function]}
299
302
  onFTPSubmit={[MockFunction]}
300
303
  onFacebookSubmit={[MockFunction]}
304
+ onInAppModeChange={[Function]}
301
305
  onMobilepushModeChange={[Function]}
302
306
  onPreviewTemplate={[Function]}
303
307
  onRemoveTemplateName={[Function]}
@@ -395,6 +399,7 @@ exports[`Test SlideBoxContent container it should clear the url, on channel chan
395
399
  onEnterTemplateName={[Function]}
396
400
  onFTPSubmit={[MockFunction]}
397
401
  onFacebookSubmit={[MockFunction]}
402
+ onInAppModeChange={[Function]}
398
403
  onMobilepushModeChange={[Function]}
399
404
  onPreviewTemplate={[Function]}
400
405
  onRemoveTemplateName={[Function]}
@@ -7,6 +7,7 @@ import {
7
7
  UPLOAD_INAPP_ASSET_REQUEST,
8
8
  CLEAR_INAPP_ASSET,
9
9
  INAPP_EDIT_TEMPLATE_REQUEST,
10
+ GET_BEE_POPUP_BUILDER_TOKEN_REQUEST,
10
11
  } from "./constants";
11
12
 
12
13
  export function createInAppTemplate(payload, callback) {
@@ -62,3 +63,9 @@ export const clearInAppAsset = (templateType) => ({
62
63
  type: CLEAR_INAPP_ASSET,
63
64
  templateType,
64
65
  });
66
+
67
+ export function getBeePopupBuilderToken() {
68
+ return {
69
+ type: GET_BEE_POPUP_BUILDER_TOKEN_REQUEST,
70
+ };
71
+ }
@@ -34,6 +34,10 @@ export const UPLOAD_INAPP_ASSET_SUCCESS = `${prefix}/UPLOAD_INAPP_ASSET_SUCCESS`
34
34
  export const UPLOAD_INAPP_ASSET_FAILURE = `${prefix}/UPLOAD_INAPP_ASSET_FAILURE`;
35
35
  export const CLEAR_INAPP_ASSET = `${prefix}/CLEAR_INAPP_ASSET`;
36
36
 
37
+ export const GET_BEE_POPUP_BUILDER_TOKEN_REQUEST = `${prefix}/GET_BEE_POPUP_BUILDER_TOKEN_REQUEST`;
38
+ export const GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS = `${prefix}/GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS`;
39
+ export const GET_BEE_POPUP_BUILDER_TOKEN_FAILURE = `${prefix}/GET_BEE_POPUP_BUILDER_TOKEN_FAILURE`;
40
+
37
41
  export const INAPP_MEDIA_TYPES = {
38
42
  TEXT: "TEXT",
39
43
  IMAGE: "IMAGE",
@@ -159,4 +163,4 @@ export const INAPP_LAYOUT_DETAILS = {
159
163
  };
160
164
 
161
165
  export const DEVICE_SUPPORTED = '1';
162
- export const AI_CONTENT_BOT_DISABLED = "AI_CONTENT_BOT_DISABLED";
166
+ export const AI_CONTENT_BOT_DISABLED = "AI_CONTENT_BOT_DISABLED";
@@ -7,21 +7,20 @@ import { injectIntl, FormattedMessage } from "react-intl";
7
7
  import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
8
8
  import CapHeading from "@capillarytech/cap-ui-library/CapHeading";
9
9
  import CapSpin from "@capillarytech/cap-ui-library/CapSpin";
10
- import CapInput from "@capillarytech/cap-ui-library/CapInput";
11
10
  import CapRadioGroup from "@capillarytech/cap-ui-library/CapRadioGroup";
12
11
  import CapRow from "@capillarytech/cap-ui-library/CapRow";
13
12
  import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
14
13
  import CapButton from "@capillarytech/cap-ui-library/CapButton";
15
14
  import CapTab from "@capillarytech/cap-ui-library/CapTab";
16
15
  import CapNotification from "@capillarytech/cap-ui-library/CapNotification";
17
- import { makeSelectInApp, makeSelectAccount } from "./selectors";
16
+ import { makeSelectInApp, makeSelectAccount, makeSelectGetTemplateDetailsInProgress } from "./selectors";
18
17
  import * as globalActions from '../Cap/actions';
19
18
  import {
20
19
  isLoadingMetaEntities,
21
20
  makeSelectMetaEntities,
22
21
  setInjectedTags,
23
22
  selectCurrentOrgDetails,
24
- selectLiquidStateDetails
23
+ selectLiquidStateDetails,
25
24
  } from "../Cap/selectors";
26
25
  import * as inAppActions from "./actions";
27
26
  import './index.scss';
@@ -59,6 +58,7 @@ import { validateInAppContent } from "../../utils/commonUtils";
59
58
  import ErrorInfoNote from "../../v2Components/ErrorInfoNote";
60
59
  import { hasLiquidSupportFeature } from "../../utils/common";
61
60
  import formBuilderMessages from "../../v2Components/FormBuilder/messages";
61
+ import InappAdvanced from "../InappAdvanced/index";
62
62
 
63
63
  let editContent = {};
64
64
 
@@ -82,6 +82,18 @@ export const InApp = (props) => {
82
82
  selectedOfferDetails,
83
83
  currentOrgDetails,
84
84
  fetchingLiquidValidation,
85
+ templateName,
86
+ setTemplateName,
87
+ getTemplateDetailsInProgress,
88
+ isEditInApp,
89
+ setIsLoadingContent,
90
+ query,
91
+ inAppCreateMode,
92
+ isGetFormData,
93
+ showTemplateName,
94
+ onValidationFail,
95
+ type,
96
+ forwardedTags,
85
97
  } = props || {};
86
98
 
87
99
  const { formatMessage } = intl;
@@ -90,7 +102,7 @@ export const InApp = (props) => {
90
102
  const [templateMediaType, setTemplateMediaType] = useState(
91
103
  INAPP_MEDIA_TYPES.TEXT
92
104
  );
93
- const [templateName, setTemplateName] = useState("");
105
+
94
106
  const [templateLayoutType, setTemplateLayoutType] = useState(
95
107
  INAPP_MESSAGE_LAYOUT_TYPES.MODAL
96
108
  );
@@ -116,6 +128,7 @@ export const InApp = (props) => {
116
128
  const [tags, updateTags] = useState([]);
117
129
  //for edit only
118
130
  const [isEditFlow, setEditFlow] = useState(false);
131
+ const [tempName, setTempName] = useState("");
119
132
  const [templateDate, setTemplateDate] = useState("");
120
133
 
121
134
  //buttons
@@ -191,8 +204,8 @@ export const InApp = (props) => {
191
204
  } = isFullMode ? editData?.templateDetails || {} : templateData || {};
192
205
  editContent = get(versions, `base.content`, {});
193
206
  if (editContent && !isEmpty(editContent)) {
207
+ setTempName(name);
194
208
  setEditFlow(true);
195
- setTemplateName(name);
196
209
  setTemplateDate(createdAt);
197
210
  setTemplateLayoutType(editContent?.ANDROID?.bodyType);
198
211
  const androidContent = editContent?.ANDROID;
@@ -344,10 +357,6 @@ export const InApp = (props) => {
344
357
  };
345
358
  // tag Code end
346
359
 
347
- const onTemplateNameChange = ({ target: { value } }) => {
348
- setTemplateName(value);
349
- };
350
-
351
360
  const onTemplateLayoutTypeChange = ({ target: { value } }) => {
352
361
  setTemplateLayoutType(value);
353
362
  };
@@ -460,22 +469,6 @@ export const InApp = (props) => {
460
469
  },
461
470
  ];
462
471
 
463
- const createModeContent = (
464
- <CapRow>
465
- {/* template name */}
466
- <CapHeading type="h4">
467
- <FormattedMessage {...messages.creativeName} />
468
- </CapHeading>
469
- <CapInput
470
- id="inapp-template-name-input"
471
- className="inapp-template-name-input"
472
- onChange={onTemplateNameChange}
473
- placeholder={formatMessage(globalMessages.templateNamePlaceholder)}
474
- value={templateName}
475
- size="default"
476
- />
477
- </CapRow>
478
- );
479
472
  //create methods end
480
473
 
481
474
  //used by create and edit
@@ -526,10 +519,6 @@ export const InApp = (props) => {
526
519
  const isDisableDone = (device) => {
527
520
  const isIosDevice = device === IOS;
528
521
  const isAndroidDevice = device === ANDROID;
529
- //if template name is not entered
530
- if (isFullMode && templateName.trim() === '') {
531
- return true;
532
- }
533
522
  //if template message is not entered
534
523
  //for android
535
524
  if (isAndroidDevice && (templateMessageAndroid.trim() === '' || templateMessageErrorAndroid)) {
@@ -619,7 +608,7 @@ export const InApp = (props) => {
619
608
  sourceAccountIdentifier = "",
620
609
  id,
621
610
  } = accountObj;
622
-
611
+
623
612
  // Construct Android content if not disabled
624
613
  const androidContent = !isDisableDone(ANDROID) ? {
625
614
  ...commonDevicePayload,
@@ -639,7 +628,7 @@ export const InApp = (props) => {
639
628
  ctas: [{type: DEEP_LINK, actionLink: deepLinkValueAndroid}],
640
629
  }),
641
630
  } : {};
642
-
631
+
643
632
  // Construct iOS content if not disabled
644
633
  const iosContent = !isDisableDone(IOS) ? {
645
634
  ...commonDevicePayload,
@@ -659,9 +648,9 @@ export const InApp = (props) => {
659
648
  ctas: [{type: DEEP_LINK, actionLink: deepLinkValueIos}],
660
649
  }),
661
650
  } : {};
662
-
651
+
663
652
  const data = {
664
- name: templateName,
653
+ name: isEditFlow ? tempName : templateName,
665
654
  versions: {
666
655
  base: {
667
656
  content: {
@@ -684,7 +673,7 @@ export const InApp = (props) => {
684
673
  if (!errorMessage) {
685
674
  CapNotification.success({
686
675
  message: isEditFlow ? formatMessage(messages.inAppEditNotification, {
687
- name: templateName,
676
+ name: tempName,
688
677
  }) : formatMessage(messages.inAppCreateNotification, {
689
678
  name: templateName,
690
679
  }),
@@ -785,30 +774,63 @@ export const InApp = (props) => {
785
774
  };
786
775
 
787
776
  const isLiquidFlow = hasLiquidSupportFeature();
777
+ const isBEEeditor = get(editData, 'templateDetails.versions.base.content.ANDROID.isBEEeditor') || get(templateData, 'versions.base.content.ANDROID.isBEEeditor');
778
+ // Early returns to avoid nested ternary
779
+ if (isEditInApp && getTemplateDetailsInProgress) {
780
+ return <CapSpin spinning={getTemplateDetailsInProgress} />;
781
+ }
782
+
783
+ if (isEditInApp && isBEEeditor) {
784
+ return (
785
+ <InappAdvanced
786
+ getFormData={getFormData}
787
+ setIsLoadingContent={setIsLoadingContent}
788
+ defaultData={{ "template-name": tempName }}
789
+ location={{
790
+ pathname: `/inapp/edit`,
791
+ query,
792
+ search: '',
793
+ }}
794
+ params={{ mode: inAppCreateMode, id: params.id }}
795
+ isFullMode={isFullMode}
796
+ isGetFormData={isGetFormData}
797
+ showTemplateName={showTemplateName}
798
+ route={{ name: "inapp" }}
799
+ getDefaultTags={type}
800
+ onValidationFail={onValidationFail}
801
+ templateData={templateData}
802
+ templateName={tempName}
803
+ setTemplateName={setTempName}
804
+ forwardedTags={forwardedTags}
805
+ selectedOfferDetails={selectedOfferDetails}
806
+ onCreateComplete={onCreateComplete}
807
+ />
808
+ );
809
+ }
810
+
788
811
  return (
789
812
  <CapSpin spinning={spin || fetchingLiquidValidation} tip={fetchingLiquidValidation ? <FormattedMessage {...formBuilderMessages.liquidSpinText} /> : ""}>
790
813
  <CapRow className="cap-inapp-creatives">
791
814
  <CapColumn span={14}>
792
- {isFullMode && createModeContent}
793
815
  {/* Creative layout type*/}
794
816
  {(isFullMode || !isEditFlow) && (
795
- <>
796
- <CapRow className="inapp-creative-layout">
797
- <CapHeading type="h4">
798
- <FormattedMessage {...messages.creativeLayout} />
799
- </CapHeading>
800
- <CapHeading type="h6" className="inapp-creative-layout-desc">
801
- <FormattedMessage {...messages.creativeLayoutDesc} />
802
- </CapHeading>
803
- </CapRow>
804
- <CapRadioGroup
805
- id="inapp-layout-radio"
806
- options={LAYOUT_RADIO_OPTIONS}
807
- value={templateLayoutType}
808
- onChange={onTemplateLayoutTypeChange}
809
- className="inapp-layout-radio"
810
- />
811
- </>
817
+ <>
818
+ <CapRow className="inapp-creative-layout">
819
+ <CapHeading type="h4">
820
+ <FormattedMessage {...messages.creativeLayout} />
821
+ </CapHeading>
822
+ <CapHeading type="h6" className="inapp-creative-layout-desc">
823
+ <FormattedMessage {...messages.creativeLayoutDesc} />
824
+ </CapHeading>
825
+ </CapRow>
826
+ <CapRadioGroup
827
+ id="inapp-layout-radio"
828
+ options={LAYOUT_RADIO_OPTIONS}
829
+ value={templateLayoutType}
830
+ onChange={onTemplateLayoutTypeChange}
831
+ className="inapp-layout-radio"
832
+ />
833
+ </>
812
834
  )}
813
835
  {/* device tab */}
814
836
  <CapTab
@@ -868,7 +890,8 @@ const mapStateToProps = createStructuredSelector({
868
890
  loadingTags: isLoadingMetaEntities(),
869
891
  injectedTags: setInjectedTags(),
870
892
  currentOrgDetails: selectCurrentOrgDetails(),
871
- fetchingLiquidValidation: selectLiquidStateDetails()
893
+ fetchingLiquidValidation: selectLiquidStateDetails(),
894
+ getTemplateDetailsInProgress: makeSelectGetTemplateDetailsInProgress(),
872
895
  });
873
896
 
874
897
  const mapDispatchToProps = (dispatch) => ({
@@ -15,12 +15,19 @@ import {
15
15
  INAPP_EDIT_TEMPLATE_REQUEST,
16
16
  INAPP_EDIT_TEMPLATE_SUCCESS,
17
17
  INAPP_EDIT_TEMPLATE_FAILURE,
18
+ GET_BEE_POPUP_BUILDER_TOKEN_REQUEST,
19
+ GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS,
20
+ GET_BEE_POPUP_BUILDER_TOKEN_FAILURE,
18
21
  } from './constants';
19
22
 
20
23
  const initialState = fromJS({
21
24
  uploadedAssetData: {},
22
25
  createTemplateInProgress: false,
23
26
  editTemplateInProgress: false,
27
+ beePopupBuilderTokenFetching: false,
28
+ beePopupBuilderToken: {},
29
+ beePopupBuilderTokenError: false,
30
+ beePopupBuilderTokenErrorMessage: '',
24
31
  });
25
32
 
26
33
  function inAppReducer(state = initialState, action) {
@@ -101,6 +108,16 @@ function inAppReducer(state = initialState, action) {
101
108
  ? `uploadedAssetData${action.templateType}`
102
109
  : 'uploadedAssetData',
103
110
  );
111
+ case GET_BEE_POPUP_BUILDER_TOKEN_REQUEST:
112
+ return state.set('beePopupBuilderTokenFetching', true);
113
+ case GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS:
114
+ return state
115
+ .set('beePopupBuilderTokenFetching', false)
116
+ .set('beePopupBuilderToken', action.data);
117
+ case GET_BEE_POPUP_BUILDER_TOKEN_FAILURE:
118
+ return state
119
+ .set('beePopupBuilderTokenFetching', false)
120
+ .set('beePopupBuilderTokenError', fromJS(action.error));
104
121
  default:
105
122
  return state;
106
123
  }
@@ -15,6 +15,9 @@ import {
15
15
  GET_INAPP_TEMPLATE_DETAILS_SUCCESS,
16
16
  GET_INAPP_TEMPLATE_DETAILS_FAILURE,
17
17
  GET_INAPP_TEMPLATE_DETAILS_REQUEST,
18
+ GET_BEE_POPUP_BUILDER_TOKEN_REQUEST,
19
+ GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS,
20
+ GET_BEE_POPUP_BUILDER_TOKEN_FAILURE,
18
21
  } from './constants';
19
22
  import { INAPP } from '../CreativesContainer/constants';
20
23
 
@@ -136,11 +139,34 @@ export function* watchGetTemplateDetails() {
136
139
 
137
140
  }
138
141
 
142
+ export function* getBeePopupBuilderToken() {
143
+ try {
144
+ const result = yield call(Api.getBeePopupBuilderToken);
145
+ if (result.success) {
146
+ yield put({
147
+ type: GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS,
148
+ data: result.response,
149
+ });
150
+ } else {
151
+ yield put({ type: GET_BEE_POPUP_BUILDER_TOKEN_FAILURE, error: result.message });
152
+ }
153
+ } catch (error) {
154
+ yield put({ type: GET_BEE_POPUP_BUILDER_TOKEN_FAILURE, error });
155
+ }
156
+ }
157
+ export function* watchGetBeePopupBuilderToken() {
158
+ yield takeLatest(
159
+ GET_BEE_POPUP_BUILDER_TOKEN_REQUEST,
160
+ getBeePopupBuilderToken,
161
+ );
162
+ }
163
+
139
164
  export default [
140
165
  watchCreateTemplate,
141
166
  watchGetTemplateDetails,
142
167
  watchUploadInAppAsset,
143
168
  watchEditTemplate,
169
+ watchGetBeePopupBuilderToken,
144
170
  ];
145
171
 
146
172
  export function* v2InAppSagas() {
@@ -149,5 +175,6 @@ export function* v2InAppSagas() {
149
175
  watchGetTemplateDetails(),
150
176
  watchUploadInAppAsset(),
151
177
  watchEditTemplate(),
178
+ watchGetBeePopupBuilderToken(),
152
179
  ]);
153
180
  }
@@ -9,4 +9,26 @@ const makeSelectInApp = () =>
9
9
  const makeSelectAccount = () =>
10
10
  createSelector(selectAccountDomain(), (substate) => substate.toJS());
11
11
 
12
- export { makeSelectInApp, makeSelectAccount };
12
+ const makeSelectBeePopupBuilderTokenFetching = () => createSelector(
13
+ selectInAppDomain(),
14
+ (substate) => substate.get('beePopupBuilderTokenFetching'),
15
+ );
16
+
17
+ const makeSelectBeePopupBuilderToken = () => createSelector(
18
+ selectInAppDomain(),
19
+ (substate) => substate.get('beePopupBuilderToken'),
20
+ );
21
+
22
+ const makeSelectGetTemplateDetailsInProgress = () => createSelector(
23
+ selectInAppDomain(),
24
+ (substate) => substate.get('getTemplateDetailsInProgress'),
25
+ );
26
+
27
+
28
+ export {
29
+ makeSelectInApp,
30
+ makeSelectAccount,
31
+ makeSelectBeePopupBuilderTokenFetching,
32
+ makeSelectBeePopupBuilderToken,
33
+ makeSelectGetTemplateDetailsInProgress,
34
+ };
@@ -60,11 +60,6 @@ describe('Test activity inApp container', () => {
60
60
  isFullMode: true,
61
61
  params: { id: 'test'},
62
62
  });
63
- const inputBox = await screen.findAllByPlaceholderText(
64
- 'Enter template name',
65
- );
66
- fireEvent.change(inputBox[0], { target: { value: 'Hello, welcome' } });
67
- inputBox[0].focus();
68
63
  const iosTab = screen.getByRole('tab', {
69
64
  name: /ios/i,
70
65
  });
@@ -73,10 +68,6 @@ describe('Test activity inApp container', () => {
73
68
  name: /android/i,
74
69
  });
75
70
  fireEvent.click(within(androidTab).getByText(/android/i));
76
- const inputNameBox = await screen.findAllByPlaceholderText(
77
- 'Enter template name',
78
- );
79
- fireEvent.change(inputNameBox[0], { target: { value: 'Hello, welcome' } });
80
71
  const msgBox = screen.getAllByPlaceholderText(/Please input in-app notification message content/i);
81
72
  msgBox[0].focus();
82
73
  fireEvent.change(msgBox[0], { target: { value: 'val' }});
@@ -260,4 +260,37 @@ describe("zalo reducer", () => {
260
260
  expect(inAppReducer(state, action)).toEqual(expectedResult);
261
261
  });
262
262
  });
263
+ describe("Reducer : GET_BEE_POPUP_BUILDER_TOKEN_REQUEST", () => {
264
+ it.concurrent("should handle GET_BEE_POPUP_BUILDER_TOKEN_REQUEST action", () => {
265
+ const state = fromJS({
266
+ beePopupBuilderTokenFetching: false,
267
+ });
268
+ const expectedResult = state.set("beePopupBuilderTokenFetching", true);
269
+ expect(inAppReducer(state, actions.getBeePopupBuilderToken({}))).toEqual(expectedResult);
270
+ });
271
+ it.concurrent("should handle GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS action", () => {
272
+ const state = fromJS({
273
+ beePopupBuilderTokenFetching: false,
274
+ beePopupBuilderToken: 'data',
275
+ });
276
+ const action = {
277
+ type: types.GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS,
278
+ data: 'data',
279
+ };
280
+ const expectedResult = state.set("beePopupBuilderTokenFetching", false).set("beePopupBuilderToken", 'data');
281
+ expect(inAppReducer(state, action)).toEqual(expectedResult);
282
+ });
283
+ it.concurrent("should handle GET_BEE_POPUP_BUILDER_TOKEN_FAILURE action", () => {
284
+ const state = fromJS({
285
+ beePopupBuilderTokenFetching: false,
286
+ beePopupBuilderTokenError: 'error',
287
+ });
288
+ const action = {
289
+ type: types.GET_BEE_POPUP_BUILDER_TOKEN_FAILURE,
290
+ error: 'error',
291
+ };
292
+ const expectedResult = state.set("beePopupBuilderTokenFetching", false).set("beePopupBuilderTokenError", 'error');
293
+ expect(inAppReducer(state, action)).toEqual(expectedResult);
294
+ });
295
+ });
263
296
  });
@@ -397,7 +397,63 @@ describe('test for getTemplateDetails', () => {
397
397
  });
398
398
  });
399
399
 
400
-
400
+ describe('test for getBeePopupBuilderToken', () => {
401
+ it('should call getBeePopupBuilderToken when GET_BEE_POPUP_BUILDER_TOKEN_REQUEST action is dispatched', () => {
402
+ const watcher = sagas.watchGetBeePopupBuilderToken();
403
+ const gen = watcher.next().value;
404
+ expect(gen).toEqual(takeLatest(types.GET_BEE_POPUP_BUILDER_TOKEN_REQUEST, sagas.getBeePopupBuilderToken));
405
+ });
406
+ it('should cancel the watcher watchGetBeePopupBuilderToken', () => {
407
+ const gen = sagas.watchGetBeePopupBuilderToken();
408
+ const mockTask = createMockTask();
409
+ expect(gen.next().value).toEqual(takeLatest(types.GET_BEE_POPUP_BUILDER_TOKEN_REQUEST, sagas.getBeePopupBuilderToken));
410
+ expect(gen.next(mockTask).done).toBe(true);
411
+ expect(mockTask.isRunning()).toBe(true);
412
+ expect(gen.next().value).toEqual(undefined);
413
+ });
414
+ it('should handle GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS', () => {
415
+ const payload = {}; // Add your payload for testing
416
+ const mockResult = {
417
+ success: true,
418
+ status: {
419
+ code: 200,
420
+ },
421
+ response: { /* mock response */ },
422
+ };
423
+ const iterator = sagas.getBeePopupBuilderToken({ payload, callback: jest.fn() });
424
+ expect(iterator.next().value).toEqual(call(Api.getBeePopupBuilderToken));
425
+ expect(iterator.next(mockResult).value).toEqual(
426
+ put({ type: types.GET_BEE_POPUP_BUILDER_TOKEN_SUCCESS, data: mockResult.response })
427
+ );
428
+ expect(iterator.next().done).toBe(true);
429
+ });
430
+ it('should handle GET_BEE_POPUP_BUILDER_TOKEN_FAILURE', () => {
431
+ const payload = {};
432
+ const error = new Error('Test error');
433
+ const iterator = sagas.getBeePopupBuilderToken({ payload });
434
+ expect(iterator.next().value).toEqual(call(Api.getBeePopupBuilderToken));
435
+ expect(iterator.throw(error).value).toEqual(
436
+ put({ type: types.GET_BEE_POPUP_BUILDER_TOKEN_FAILURE, error })
437
+ );
438
+ expect(iterator.next().done).toBe(true);
439
+ });
440
+ it('should handle error case', () => {
441
+ const payload = {};
442
+ const mockResult = {
443
+ success: false,
444
+ status: {
445
+ code: 400,
446
+ },
447
+ message: 'Test error',
448
+ };
449
+ const iterator = sagas.getBeePopupBuilderToken({ payload });
450
+ expect(iterator.next().value).toEqual(call(Api.getBeePopupBuilderToken));
451
+ expect(iterator.next(mockResult).value).toEqual(
452
+ put({ type: types.GET_BEE_POPUP_BUILDER_TOKEN_FAILURE, error: mockResult.message })
453
+ );
454
+ expect(iterator.next().done).toBe(true);
455
+ });
456
+ });
401
457
 
402
458
 
403
459
  describe("v2InAppSagas Combined", () => {