@capillarytech/creatives-library 8.0.26 → 8.0.28
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.
- package/containers/Cap/tests/selectors.test.js +28 -0
- package/containers/TagList/constants.js +2 -0
- package/containers/TestPage/constants.js +7 -0
- package/containers/TestPage/index.js +31 -0
- package/containers/TestPage/messages.js +13 -0
- package/containers/TestPage/reducer.js +21 -0
- package/containers/TestPage/sagas.js +11 -0
- package/containers/Testv2/actions.js +15 -0
- package/containers/Testv2/constants.js +7 -0
- package/containers/Testv2/index.js +47 -0
- package/containers/Testv2/messages.js +21 -0
- package/containers/Testv2/reducer.js +23 -0
- package/containers/Testv2/sagas.js +11 -0
- package/containers/Testv2/selectors.js +25 -0
- package/package.json +1 -1
- package/reducers.js +77 -0
- package/store.js +61 -0
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +20 -15
- package/tests/integration/TemplateCreation/api-response.js +18748 -0
- package/tests/integration/TemplateCreation/msw-handler.js +27 -2
- package/utils/tests/asyncInjectors.test.js +173 -0
- package/v2Components/CapTagList/index.js +116 -30
- package/v2Containers/Cap/index.js +0 -5
- package/v2Containers/Cap/tests/Cap.test.js +4 -8
- package/v2Containers/CreativesContainer/index.js +1 -1
- package/v2Containers/MobilePush/Edit/index.js +7 -8
- package/v2Containers/TemplatesV2/index.js +4 -4
- package/v2Containers/TestPage/constants.js +7 -0
- package/v2Containers/TestPage/index.js +31 -0
- package/v2Containers/TestPage/messages.js +13 -0
- package/v2Containers/TestPage/reducer.js +21 -0
- package/v2Containers/TestPage/sagas.js +11 -0
- package/v2Containers/Testv2/actions.js +15 -0
- package/v2Containers/Testv2/constants.js +7 -0
- package/v2Containers/Testv2/index.js +47 -0
- package/v2Containers/Testv2/messages.js +21 -0
- package/v2Containers/Testv2/reducer.js +23 -0
- package/v2Containers/Testv2/sagas.js +11 -0
- package/v2Containers/Testv2/selectors.js +25 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { fromJS } from 'immutable';
|
|
2
|
+
|
|
3
|
+
import { makeSelectLocationState } from 'containers/Cap/selectors';
|
|
4
|
+
|
|
5
|
+
describe('makeSelectLocationState', () => {
|
|
6
|
+
it('should select the route as a plain JS object', () => {
|
|
7
|
+
const route = fromJS({
|
|
8
|
+
locationBeforeTransitions: null,
|
|
9
|
+
});
|
|
10
|
+
const mockedState = fromJS({
|
|
11
|
+
route,
|
|
12
|
+
});
|
|
13
|
+
expect(makeSelectLocationState()(mockedState)).toEqual(route.toJS());
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return cached js routeState for same concurrent calls', () => {
|
|
17
|
+
const route = fromJS({
|
|
18
|
+
locationBeforeTransitions: null,
|
|
19
|
+
});
|
|
20
|
+
const mockedState = fromJS({
|
|
21
|
+
route,
|
|
22
|
+
});
|
|
23
|
+
const selectLocationState = makeSelectLocationState();
|
|
24
|
+
|
|
25
|
+
const firstRouteStateJS = selectLocationState(mockedState);
|
|
26
|
+
expect(selectLocationState(mockedState)).toBe(firstRouteStateJS);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import React from "react";
|
|
3
|
+
import SmsTest from '../../components/SmsTest';
|
|
4
|
+
|
|
5
|
+
export default class TestPage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
|
|
6
|
+
render() {
|
|
7
|
+
return (
|
|
8
|
+
<SmsTest />
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// const schema = {
|
|
14
|
+
// title: "Todo",
|
|
15
|
+
// type: "object",
|
|
16
|
+
// required: ["title"],
|
|
17
|
+
// properties: {
|
|
18
|
+
// title: {type: "string", title: "Title", default: "A new task"},
|
|
19
|
+
// done: {type: "boolean", title: "Done?", default: false},
|
|
20
|
+
// },
|
|
21
|
+
// };
|
|
22
|
+
|
|
23
|
+
// const log = (type) => console.log.bind(console, type);
|
|
24
|
+
|
|
25
|
+
// render((
|
|
26
|
+
// <div>
|
|
27
|
+
// <SmsTest
|
|
28
|
+
// />
|
|
29
|
+
// </div>
|
|
30
|
+
// ), document.getElementById("app"));
|
|
31
|
+
//export default TestPage;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* NotFoundPage Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the NotFoundPage component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
header: {
|
|
10
|
+
id: 'creatives.components.TestPage.header',
|
|
11
|
+
defaultMessage: 'Looks like youas are lost!',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Dashboard reducer
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { fromJS } from 'immutable';
|
|
8
|
+
import { DEFAULT_ACTION } from './constants';
|
|
9
|
+
|
|
10
|
+
const initialState = fromJS({});
|
|
11
|
+
|
|
12
|
+
function TestPageReducer(state = initialState, action) {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case DEFAULT_ACTION:
|
|
15
|
+
return state;
|
|
16
|
+
default:
|
|
17
|
+
return state;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default TestPageReducer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// import { take, call, put, select } from 'redux-saga/effects';
|
|
2
|
+
|
|
3
|
+
// Individual exports for testing
|
|
4
|
+
export function* defaultSaga() {
|
|
5
|
+
// See example in containers/HomePage/sagas.js
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// All sagas to be loaded
|
|
9
|
+
export default [
|
|
10
|
+
defaultSaga,
|
|
11
|
+
];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Testv2
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { connect } from 'react-redux';
|
|
11
|
+
import Helmet from 'react-helmet';
|
|
12
|
+
import { FormattedMessage } from 'react-intl';
|
|
13
|
+
import { createStructuredSelector } from 'reselect';
|
|
14
|
+
import makeSelectTestv2 from './selectors';
|
|
15
|
+
import messages from './messages';
|
|
16
|
+
|
|
17
|
+
export class Testv2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
18
|
+
render() {
|
|
19
|
+
return (
|
|
20
|
+
<div>
|
|
21
|
+
<Helmet
|
|
22
|
+
title={<FormattedMessage {...messages.testv2} />}
|
|
23
|
+
meta={[
|
|
24
|
+
{ name: 'description', content: <FormattedMessage {...messages.descriptionTestv2} /> },
|
|
25
|
+
]}
|
|
26
|
+
/>
|
|
27
|
+
<FormattedMessage {...messages.header} />
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Testv2.propTypes = {
|
|
34
|
+
dispatch: PropTypes.func.isRequired,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const mapStateToProps = createStructuredSelector({
|
|
38
|
+
Testv2: makeSelectTestv2(),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
function mapDispatchToProps(dispatch) {
|
|
42
|
+
return {
|
|
43
|
+
dispatch,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Testv2);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Testv2 Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the Testv2 component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
header: {
|
|
10
|
+
id: 'creatives.containers.Testv2.header',
|
|
11
|
+
defaultMessage: 'This is Testv2 container !',
|
|
12
|
+
},
|
|
13
|
+
testv2: {
|
|
14
|
+
id: 'creatives.containers.Testv2.testv2',
|
|
15
|
+
defaultMessage: 'Testv2',
|
|
16
|
+
},
|
|
17
|
+
descriptionTestv2: {
|
|
18
|
+
id: 'creatives.containers.Testv2.descriptionTestv2',
|
|
19
|
+
defaultMessage: 'Description of Testv2',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Testv2 reducer
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { fromJS } from 'immutable';
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_ACTION,
|
|
10
|
+
} from './constants';
|
|
11
|
+
|
|
12
|
+
const initialState = fromJS({});
|
|
13
|
+
|
|
14
|
+
function testv2Reducer(state = initialState, action) {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case DEFAULT_ACTION:
|
|
17
|
+
return state;
|
|
18
|
+
default:
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default testv2Reducer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// import { take, call, put, select } from 'redux-saga/effects';
|
|
2
|
+
|
|
3
|
+
// Individual exports for testing
|
|
4
|
+
export function* defaultSaga() {
|
|
5
|
+
// See example in containers/HomePage/sagas.js
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// All sagas to be loaded
|
|
9
|
+
export default [
|
|
10
|
+
defaultSaga,
|
|
11
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createSelector } from 'reselect';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Direct selector to the testv2 state domain
|
|
5
|
+
*/
|
|
6
|
+
const selectTestv2Domain = () => (state) => state.get('testv2');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Other specific selectors
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default selector used by Testv2
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const makeSelectTestv2 = () => createSelector(
|
|
18
|
+
selectTestv2Domain(),
|
|
19
|
+
(substate) => substate.toJS()
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export default makeSelectTestv2;
|
|
23
|
+
export {
|
|
24
|
+
selectTestv2Domain,
|
|
25
|
+
};
|
package/package.json
CHANGED
package/reducers.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combine all reducers in this file and export the combined reducers.
|
|
3
|
+
* If we were to do this in store.js, reducers wouldn't be hot reloadable.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { combineReducers } from 'redux-immutable';
|
|
7
|
+
import { fromJS } from 'immutable';
|
|
8
|
+
import { LOCATION_CHANGE } from 'react-router-redux';
|
|
9
|
+
|
|
10
|
+
import languageProviderReducer from 'v2Containers/LanguageProvider/reducer';
|
|
11
|
+
import beeEditorReducer from 'v2Containers/BeeEditor/reducer';
|
|
12
|
+
import CapFacebookPreviewReducer from 'v2Containers/CapFacebookPreview/reducer';
|
|
13
|
+
|
|
14
|
+
import capReducer from 'containers/Cap/reducer';
|
|
15
|
+
import appReducer from 'containers/App/reducer';
|
|
16
|
+
import createSmsReducer from 'containers/Sms/Create/reducer';
|
|
17
|
+
import editSmsReducer from 'containers/Sms/Edit/reducer';
|
|
18
|
+
import templateReducer from 'containers/Templates/reducer';
|
|
19
|
+
import tagsReducer from 'containers/TagList/reducer';
|
|
20
|
+
import emailReducer from 'containers/Email/reducer';
|
|
21
|
+
import ebillReducer from 'containers/Ebill/reducer';
|
|
22
|
+
import ftpReducer from 'v2Containers/FTP/reducer';
|
|
23
|
+
import galleryReducer from './v2Containers/Assets/Gallery/reducer';
|
|
24
|
+
import { AIRA_REDUCER_DOMAIN, askAiraReducer } from '@capillarytech/cap-ui-library/CapAskAira';
|
|
25
|
+
import CapCollapsibleLeftNavigationReducer from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer';
|
|
26
|
+
/*
|
|
27
|
+
* routeReducer
|
|
28
|
+
*
|
|
29
|
+
* The reducer merges route location changes into our immutable state.
|
|
30
|
+
* The change is necessitated by moving to react-router-redux@4
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
// Initial routing state
|
|
35
|
+
const routeInitialState = fromJS({
|
|
36
|
+
locationBeforeTransitions: null,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Merge route into the global application state
|
|
41
|
+
*/
|
|
42
|
+
function routeReducer(state = routeInitialState, action) {
|
|
43
|
+
switch (action.type) {
|
|
44
|
+
/* istanbul ignore next */
|
|
45
|
+
case LOCATION_CHANGE:
|
|
46
|
+
return state.merge({
|
|
47
|
+
locationBeforeTransitions: action.payload,
|
|
48
|
+
});
|
|
49
|
+
default:
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Creates the main reducer with the asynchronously loaded ones
|
|
56
|
+
*/
|
|
57
|
+
export default function createReducer(asyncReducers) {
|
|
58
|
+
return combineReducers({
|
|
59
|
+
route: routeReducer,
|
|
60
|
+
language: languageProviderReducer,
|
|
61
|
+
cap: capReducer,
|
|
62
|
+
app: appReducer,
|
|
63
|
+
create: createSmsReducer,
|
|
64
|
+
edit: editSmsReducer,
|
|
65
|
+
templates: templateReducer,
|
|
66
|
+
tagList: tagsReducer,
|
|
67
|
+
email: emailReducer,
|
|
68
|
+
ebill: ebillReducer,
|
|
69
|
+
beeEditor: beeEditorReducer,
|
|
70
|
+
facebookPreview: CapFacebookPreviewReducer,
|
|
71
|
+
FTP: ftpReducer,
|
|
72
|
+
gallery: galleryReducer,
|
|
73
|
+
navigationConfig: CapCollapsibleLeftNavigationReducer,
|
|
74
|
+
[AIRA_REDUCER_DOMAIN]: askAiraReducer,
|
|
75
|
+
...asyncReducers,
|
|
76
|
+
});
|
|
77
|
+
}
|
package/store.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create the store with asynchronously loaded reducers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createStore, applyMiddleware, compose } from 'redux';
|
|
6
|
+
import { fromJS } from 'immutable';
|
|
7
|
+
import { routerMiddleware } from 'react-router-redux';
|
|
8
|
+
import createSagaMiddleware from 'redux-saga';
|
|
9
|
+
// import { createMiddleware } from 'redux-beacon';
|
|
10
|
+
// import { logger } from 'redux-beacon/extensions/logger';
|
|
11
|
+
// import { GoogleTagManager } from 'redux-beacon/targets/google-tag-manager';
|
|
12
|
+
import createReducer from './reducers';
|
|
13
|
+
// import eventsMap from './gtm/eventDefinitionsMap';
|
|
14
|
+
|
|
15
|
+
const sagaMiddleware = createSagaMiddleware();
|
|
16
|
+
// const gtmMiddleware = createMiddleware(eventsMap, GoogleTagManager());
|
|
17
|
+
|
|
18
|
+
export default function configureStore(initialState = {}, history) {
|
|
19
|
+
const middlewares = [
|
|
20
|
+
sagaMiddleware,
|
|
21
|
+
routerMiddleware(history),
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const enhancers = [
|
|
25
|
+
applyMiddleware(...middlewares),
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
|
|
29
|
+
/* eslint-disable no-underscore-dangle */
|
|
30
|
+
const composeEnhancers =
|
|
31
|
+
process.env.NODE_ENV !== 'production' &&
|
|
32
|
+
typeof window === 'object' &&
|
|
33
|
+
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
|
|
34
|
+
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose;
|
|
35
|
+
/* eslint-enable */
|
|
36
|
+
|
|
37
|
+
const store = createStore(
|
|
38
|
+
createReducer(),
|
|
39
|
+
fromJS(initialState),
|
|
40
|
+
composeEnhancers(...enhancers)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Extensions
|
|
44
|
+
store.runSaga = sagaMiddleware.run;
|
|
45
|
+
store.asyncReducers = {}; // Async reducer registry
|
|
46
|
+
|
|
47
|
+
// Make reducers hot reloadable, see http://mxs.is/googmo
|
|
48
|
+
/* istanbul ignore next */
|
|
49
|
+
if (module.hot) {
|
|
50
|
+
module.hot.accept('./reducers', () => {
|
|
51
|
+
import('./reducers').then((reducerModule) => {
|
|
52
|
+
const createReducers = reducerModule.default;
|
|
53
|
+
const nextReducers = createReducers(store.asyncReducers);
|
|
54
|
+
|
|
55
|
+
store.replaceReducer(nextReducers);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return store;
|
|
61
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
fireEvent,
|
|
10
10
|
screen,
|
|
11
11
|
within,
|
|
12
|
+
waitFor,
|
|
12
13
|
} from '../../../utils/test-utils';
|
|
13
14
|
|
|
14
15
|
import { configureStore } from '@capillarytech/vulcan-react-sdk/utils';
|
|
@@ -31,7 +32,7 @@ jest.mock('@capillarytech/cap-ui-utils', () => ({
|
|
|
31
32
|
},
|
|
32
33
|
}));
|
|
33
34
|
|
|
34
|
-
jest.setTimeout(
|
|
35
|
+
jest.setTimeout(80000);
|
|
35
36
|
|
|
36
37
|
const initializeCreatives = () => {
|
|
37
38
|
const store = configureStore(mockInitialState, initialReducer, history);
|
|
@@ -93,8 +94,8 @@ describe("Creatives testing template creation", () => {
|
|
|
93
94
|
name: globalMessages.email.defaultMessage,
|
|
94
95
|
});
|
|
95
96
|
await userEvent.click(whatsapp);
|
|
96
|
-
expect(creativesScreen.
|
|
97
|
-
|
|
97
|
+
expect(await creativesScreen.findByText(
|
|
98
|
+
/Whatsapp accounts are not setup for your brand/i, undefined, { timeout: 10000 })
|
|
98
99
|
).toBeInTheDocument();
|
|
99
100
|
await userEvent.click(line);
|
|
100
101
|
//assertions for template filters for line channel
|
|
@@ -108,24 +109,28 @@ describe("Creatives testing template creation", () => {
|
|
|
108
109
|
userEvent.click(creativesScreen.getByText(/image/i));
|
|
109
110
|
expect(creativesScreen.getByText(/text/i)).toBeInTheDocument();
|
|
110
111
|
userEvent.click(creativesScreen.getByText(/text/i));
|
|
111
|
-
await userEvent.click(facebook);
|
|
112
112
|
|
|
113
113
|
//Currently weChat tab has been disabled as we dont suppport it anymore
|
|
114
114
|
// await userEvent.click(wechat);
|
|
115
115
|
// expect(creativesScreen.getByText(/wechat account/i)).toBeInTheDocument();
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
// fireEvent.click(mpush);
|
|
117
|
+
// screen.debug(null, Infinity);
|
|
118
|
+
// await waitFor(() => {
|
|
119
|
+
// expect(
|
|
120
|
+
// screen.findByText(/Push notifications are not setup for your brand/i, undefined, { timeout: 10000 })
|
|
121
|
+
// ).toBeInTheDocument();
|
|
122
|
+
// }, { timeout: 50000, interval: 500 });
|
|
123
|
+
fireEvent.click(email);
|
|
121
124
|
|
|
122
125
|
//start of rcs template creation
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
fireEvent.click(rcs);
|
|
127
|
+
await waitFor(() => {
|
|
128
|
+
const createButton = creativesScreen.findByRole('button', {
|
|
129
|
+
name: /create new/i,
|
|
130
|
+
});
|
|
131
|
+
userEvent.click(createButton);
|
|
132
|
+
}, { timeout: 50000, interval: 1000 });
|
|
133
|
+
// expect(await creativesScreen.findByText(/Creative name/i, undefined, {timeout: 10000})).toBeInTheDocument();
|
|
129
134
|
const templateNameInput = await creativesScreen.findByTestId(
|
|
130
135
|
/template_name/,
|
|
131
136
|
{},
|