@times-components/ts-components 1.104.1-alpha.75 → 1.104.1-alpha.78
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/dist/components/social-embed/BlockedEmbedMessage.d.ts +1 -1
- package/dist/components/social-embed/BlockedEmbedMessage.js +8 -50
- package/dist/components/social-embed/SocialMediaEmbed.d.ts +7 -1
- package/dist/components/social-embed/SocialMediaEmbed.js +29 -33
- package/dist/components/social-embed/__tests__/BlockedEmbedMessage.test.js +24 -77
- package/dist/components/social-embed/__tests__/SocialMediaEmbed.test.d.ts +1 -1
- package/dist/components/social-embed/__tests__/SocialMediaEmbed.test.js +71 -114
- package/dist/hooks/__tests__/useConsent.test.d.ts +1 -0
- package/dist/hooks/__tests__/useConsent.test.js +53 -0
- package/dist/hooks/__tests__/useSessionStorage.test.d.ts +1 -0
- package/dist/hooks/__tests__/useSessionStorage.test.js +55 -0
- package/dist/hooks/useConsent.d.ts +1 -0
- package/dist/hooks/useConsent.js +32 -0
- package/dist/hooks/useSessionStorage.d.ts +7 -0
- package/dist/hooks/useSessionStorage.js +31 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/package.json +4 -3
- package/rnw.js +1 -1
- package/src/components/social-embed/BlockedEmbedMessage.tsx +8 -66
- package/src/components/social-embed/SocialMediaEmbed.tsx +35 -29
- package/src/components/social-embed/__tests__/BlockedEmbedMessage.test.tsx +25 -116
- package/src/components/social-embed/__tests__/SocialMediaEmbed.test.tsx +77 -217
- package/src/hooks/__tests__/useConsent.test.ts +80 -0
- package/src/hooks/__tests__/useSessionStorage.test.ts +87 -0
- package/src/hooks/useConsent.ts +38 -0
- package/src/hooks/useSessionStorage.ts +59 -0
- package/src/index.ts +4 -0
|
@@ -2,6 +2,6 @@ import { FC, Dispatch, SetStateAction } from 'react';
|
|
|
2
2
|
import { VendorName } from './types';
|
|
3
3
|
export declare type BlockedEmbedMessageProps = {
|
|
4
4
|
vendorName: VendorName;
|
|
5
|
-
|
|
5
|
+
setIsAllowedOnce: Dispatch<SetStateAction<boolean>>;
|
|
6
6
|
};
|
|
7
7
|
export declare const BlockedEmbedMessage: FC<BlockedEmbedMessageProps>;
|
|
@@ -6,60 +6,18 @@ import { enableCookies } from './helpers/enableCookies';
|
|
|
6
6
|
import { openPrivacyModal } from './helpers/privacyModal';
|
|
7
7
|
import { socialMediaVendors } from './helpers/socialMediaVendors';
|
|
8
8
|
import { modalType } from './constants';
|
|
9
|
-
export const BlockedEmbedMessage = ({ vendorName,
|
|
9
|
+
export const BlockedEmbedMessage = ({ vendorName, setIsAllowedOnce }) => {
|
|
10
10
|
// Allow cookies once - custom hook
|
|
11
11
|
const allowCookiesOnce = () => {
|
|
12
|
-
const vendorId = socialMediaVendors[vendorName].id;
|
|
13
|
-
const CONSENT_GRANTED_KEY = `consentGranted_${vendorId}`;
|
|
12
|
+
/* const vendorId = socialMediaVendors[vendorName].id; */
|
|
14
13
|
// Check if consent has already been granted for this vendor
|
|
15
|
-
const consentAlreadyGranted = sessionStorage.getItem(
|
|
14
|
+
const consentAlreadyGranted = sessionStorage.getItem('consentedVendors');
|
|
16
15
|
if (consentAlreadyGranted) {
|
|
17
|
-
|
|
16
|
+
setIsAllowedOnce(true);
|
|
18
17
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
setIsSocialEmbedAllowed(false);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
// Use __tcfapi to check and request consent if now previously granted
|
|
26
|
-
window.__tcfapi('getCustomVendorConsents', 2, (data, success) => {
|
|
27
|
-
if (success && data && data.grants && data.grants[vendorId]) {
|
|
28
|
-
const vendorConsent = data.grants[vendorId].vendorGrant;
|
|
29
|
-
if (vendorConsent) {
|
|
30
|
-
// Store consent status to avoid future prompts during the session
|
|
31
|
-
sessionStorage.setItem(CONSENT_GRANTED_KEY, 'true');
|
|
32
|
-
setIsSocialEmbedAllowed(true);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
if (!window.__tcfapi) {
|
|
36
|
-
// tslint:disable-next-line:no-console
|
|
37
|
-
console.error('TCF API is not available!');
|
|
38
|
-
setIsSocialEmbedAllowed(false);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
// Request consent via postCustomConsent
|
|
42
|
-
window.__tcfapi('postCustomConsent', 2, (postConsentData, postSuccess) => {
|
|
43
|
-
if (postSuccess) {
|
|
44
|
-
sessionStorage.setItem(CONSENT_GRANTED_KEY, 'true');
|
|
45
|
-
// tslint:disable-next-line:no-console
|
|
46
|
-
console.log('postConsentData', postConsentData);
|
|
47
|
-
setIsSocialEmbedAllowed(true);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
// tslint:disable-next-line:no-console
|
|
51
|
-
console.error(`Failed to obtain consent for vendor: ${vendorId}`);
|
|
52
|
-
setIsSocialEmbedAllowed(false);
|
|
53
|
-
}
|
|
54
|
-
}, [vendorId], Object.keys(data.grants[vendorId].purposeGrants), []);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// tslint:disable-next-line:no-console
|
|
59
|
-
console.error(`Consent data for vendor ${vendorId} not available or request failed.`);
|
|
60
|
-
setIsSocialEmbedAllowed(false);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
18
|
+
// Store consent status to avoid future prompts during the session
|
|
19
|
+
sessionStorage.setItem('consentedVendors', `['${vendorName}']`);
|
|
20
|
+
setIsAllowedOnce(true);
|
|
63
21
|
};
|
|
64
22
|
const handlePrivacyManagerClick = (e) => {
|
|
65
23
|
e.preventDefault();
|
|
@@ -79,4 +37,4 @@ export const BlockedEmbedMessage = ({ vendorName, setIsSocialEmbedAllowed }) =>
|
|
|
79
37
|
React.createElement(EnableButton, { onClick: () => enableCookies(vendorName) }, "Enable cookies"),
|
|
80
38
|
React.createElement(AllowButton, { onClick: () => allowCookiesOnce() }, "Allow cookies once")));
|
|
81
39
|
};
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmxvY2tlZEVtYmVkTWVzc2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3NvY2lhbC1lbWJlZC9CbG9ja2VkRW1iZWRNZXNzYWdlLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQW1ELE1BQU0sT0FBTyxDQUFDO0FBQ3hFLE9BQU8sRUFDTCxXQUFXLEVBQ1gsYUFBYSxFQUNiLG1CQUFtQixFQUNuQixZQUFZLEVBQ1osTUFBTSxFQUNOLGtCQUFrQixFQUNsQixTQUFTLEVBQ1QsS0FBSyxFQUNOLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRWxFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFPeEMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQWlDLENBQUMsRUFDaEUsVUFBVSxFQUNWLGdCQUFnQixFQUNqQixFQUFFLEVBQUU7SUFDSCxtQ0FBbUM7SUFDbkMsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLEVBQUU7UUFDNUIseURBQXlEO1FBRXpELDREQUE0RDtRQUM1RCxNQUFNLHFCQUFxQixHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUV6RSxJQUFJLHFCQUFxQixFQUFFO1lBQ3pCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3hCO1FBRUQsa0VBQWtFO1FBQ2xFLGNBQWMsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDO1FBQ2hFLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQztJQUVGLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxDQUFnQyxFQUFFLEVBQUU7UUFDckUsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ25CLGdCQUFnQixDQUNkLFNBQVMsQ0FBQyxJQUFJLEVBQ2QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQ2xELENBQUM7SUFDSixDQUFDLENBQUM7SUFFRixPQUFPLENBQ0wsb0JBQUMsYUFBYTtRQUNaLG9CQUFDLE1BQU07WUFDTCxvQkFBQyxtQkFBbUI7Z0JBQ2xCLG9CQUFDLFFBQVEsT0FBRyxDQUNRO1lBQ3RCLG9CQUFDLEtBQUs7Z0JBQ0gsY0FBYyxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQzttQ0FDekMsQ0FDRDtRQUNULG9CQUFDLFNBQVM7O1lBRTJDLEdBQUc7WUFDdEQsb0JBQUMsa0JBQWtCLElBQUMsSUFBSSxFQUFDLEdBQUcsRUFBQyxPQUFPLEVBQUUseUJBQXlCLHVCQUUxQyxDQUNYO1FBQ1osb0JBQUMsWUFBWSxJQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLHFCQUV2QztRQUNmLG9CQUFDLFdBQVcsSUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUseUJBRWhDLENBQ0EsQ0FDakIsQ0FBQztBQUNKLENBQUMsQ0FBQyJ9
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
1
|
+
import { FC, Dispatch, SetStateAction } from 'react';
|
|
2
2
|
import { TcData, VendorName } from './types';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
@@ -15,5 +15,11 @@ export declare type SocialMediaEmbedProps = {
|
|
|
15
15
|
url: string;
|
|
16
16
|
vendorName: VendorName;
|
|
17
17
|
id: string;
|
|
18
|
+
socialEmbed: {
|
|
19
|
+
isSocialEmbedAllowed: boolean;
|
|
20
|
+
setIsSocialEmbedAllowed: Dispatch<SetStateAction<boolean>>;
|
|
21
|
+
isAllowedOnce: boolean;
|
|
22
|
+
setIsAllowedOnce: Dispatch<SetStateAction<boolean>>;
|
|
23
|
+
};
|
|
18
24
|
};
|
|
19
25
|
export declare const SocialMediaEmbed: FC<SocialMediaEmbedProps>;
|
|
@@ -1,49 +1,45 @@
|
|
|
1
|
-
import React, { useEffect
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { BlockedEmbedMessage } from './BlockedEmbedMessage';
|
|
3
3
|
import { checkVendorConsent } from './helpers/vendorConsent';
|
|
4
4
|
import { eventStatus } from './constants';
|
|
5
|
-
export const SocialMediaEmbed = ({ id, url, vendorName }) => {
|
|
6
|
-
const
|
|
7
|
-
const [data, setData] = useState(null);
|
|
5
|
+
export const SocialMediaEmbed = ({ id, url, vendorName, socialEmbed }) => {
|
|
6
|
+
const { isSocialEmbedAllowed, setIsSocialEmbedAllowed, isAllowedOnce, setIsAllowedOnce } = socialEmbed;
|
|
8
7
|
useEffect(() => {
|
|
9
8
|
if (window.__tcfapi) {
|
|
10
9
|
window.__tcfapi('addEventListener', 2, (tcData, success) => {
|
|
11
|
-
if (success && tcData.eventStatus === eventStatus.tcLoaded) {
|
|
12
|
-
setData({
|
|
13
|
-
cmpStatus: tcData.cmpStatus,
|
|
14
|
-
eventStatus: tcData.eventStatus,
|
|
15
|
-
listenerId: tcData.listenerId
|
|
16
|
-
});
|
|
17
|
-
setIsSocialEmbedAllowed(checkVendorConsent(vendorName));
|
|
18
|
-
}
|
|
19
10
|
if (success &&
|
|
20
|
-
tcData.eventStatus === eventStatus.
|
|
21
|
-
|
|
22
|
-
cmpStatus: tcData.cmpStatus,
|
|
23
|
-
eventStatus: tcData.eventStatus,
|
|
24
|
-
listenerId: tcData.listenerId
|
|
25
|
-
});
|
|
11
|
+
(tcData.eventStatus === eventStatus.tcLoaded ||
|
|
12
|
+
tcData.eventStatus === eventStatus.userActionComplete)) {
|
|
26
13
|
setIsSocialEmbedAllowed(checkVendorConsent(vendorName));
|
|
27
14
|
}
|
|
28
15
|
});
|
|
29
16
|
}
|
|
17
|
+
/* return () => {
|
|
18
|
+
if (window.__tcfapi && data && data.listenerId) {
|
|
19
|
+
window.__tcfapi(
|
|
20
|
+
'removeEventListener',
|
|
21
|
+
2,
|
|
22
|
+
success => {
|
|
23
|
+
if (success) {
|
|
24
|
+
// tslint:disable-next-line:no-console
|
|
25
|
+
console.log(success);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
data.listenerId
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}; */
|
|
32
|
+
}, [isSocialEmbedAllowed]);
|
|
33
|
+
useEffect(() => {
|
|
30
34
|
// Trigger Twitter embed load when isSocialEmbedAllowed switches to true
|
|
31
|
-
if (isSocialEmbedAllowed
|
|
35
|
+
if ((isSocialEmbedAllowed || isAllowedOnce) &&
|
|
36
|
+
window.twttr &&
|
|
37
|
+
window.twttr.widgets) {
|
|
32
38
|
window.twttr.widgets.load();
|
|
33
39
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
window.__tcfapi('removeEventListener', 2, success => {
|
|
37
|
-
if (success) {
|
|
38
|
-
// tslint:disable-next-line:no-console
|
|
39
|
-
console.log(success);
|
|
40
|
-
}
|
|
41
|
-
}, data.listenerId);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}, [isSocialEmbedAllowed]);
|
|
45
|
-
return isSocialEmbedAllowed ? (React.createElement("div", { id: id },
|
|
40
|
+
}, [isSocialEmbedAllowed, isAllowedOnce]);
|
|
41
|
+
return isSocialEmbedAllowed || isAllowedOnce ? (React.createElement("div", { id: id },
|
|
46
42
|
React.createElement("blockquote", { className: "twitter-tweet" },
|
|
47
|
-
React.createElement("a", { href: url })))) : (React.createElement(BlockedEmbedMessage, { vendorName: vendorName,
|
|
43
|
+
React.createElement("a", { href: url })))) : (React.createElement(BlockedEmbedMessage, { vendorName: vendorName, setIsAllowedOnce: setIsAllowedOnce }));
|
|
48
44
|
};
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29jaWFsTWVkaWFFbWJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3NvY2lhbC1lbWJlZC9Tb2NpYWxNZWRpYUVtYmVkLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFNLFNBQVMsRUFBNEIsTUFBTSxPQUFPLENBQUM7QUFDdkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQWdDMUMsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQThCLENBQUMsRUFDMUQsRUFBRSxFQUNGLEdBQUcsRUFDSCxVQUFVLEVBQ1YsV0FBVyxFQUNaLEVBQUUsRUFBRTtJQUNILE1BQU0sRUFDSixvQkFBb0IsRUFDcEIsdUJBQXVCLEVBQ3ZCLGFBQWEsRUFDYixnQkFBZ0IsRUFDakIsR0FBRyxXQUFXLENBQUM7SUFFaEIsU0FBUyxDQUNQLEdBQUcsRUFBRTtRQUNILElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRTtZQUNuQixNQUFNLENBQUMsUUFBUSxDQUFDLGtCQUFrQixFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRTtnQkFDekQsSUFDRSxPQUFPO29CQUNQLENBQUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsUUFBUTt3QkFDMUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsa0JBQWtCLENBQUMsRUFDeEQ7b0JBQ0EsdUJBQXVCLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztpQkFDekQ7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNKO1FBRUQ7Ozs7Ozs7Ozs7Ozs7O2FBY0s7SUFDUCxDQUFDLEVBQ0QsQ0FBQyxvQkFBb0IsQ0FBQyxDQUN2QixDQUFDO0lBRUYsU0FBUyxDQUNQLEdBQUcsRUFBRTtRQUNILHdFQUF3RTtRQUN4RSxJQUNFLENBQUMsb0JBQW9CLElBQUksYUFBYSxDQUFDO1lBQ3ZDLE1BQU0sQ0FBQyxLQUFLO1lBQ1osTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQ3BCO1lBQ0EsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDN0I7SUFDSCxDQUFDLEVBQ0QsQ0FBQyxvQkFBb0IsRUFBRSxhQUFhLENBQUMsQ0FDdEMsQ0FBQztJQUVGLE9BQU8sb0JBQW9CLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUM3Qyw2QkFBSyxFQUFFLEVBQUUsRUFBRTtRQUNULG9DQUFZLFNBQVMsRUFBQyxlQUFlO1lBQ25DLDJCQUFHLElBQUksRUFBRSxHQUFHLEdBQUksQ0FDTCxDQUNULENBQ1AsQ0FBQyxDQUFDLENBQUMsQ0FDRixvQkFBQyxtQkFBbUIsSUFDbEIsVUFBVSxFQUFFLFVBQVUsRUFDdEIsZ0JBQWdCLEVBQUUsZ0JBQWdCLEdBQ2xDLENBQ0gsQ0FBQztBQUNKLENBQUMsQ0FBQyJ9
|
|
@@ -2,95 +2,42 @@ import React from 'react';
|
|
|
2
2
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
3
3
|
import { BlockedEmbedMessage } from '../BlockedEmbedMessage';
|
|
4
4
|
import { enableCookies } from '../helpers/enableCookies';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
jest.mock('../helpers/
|
|
9
|
-
|
|
10
|
-
}));
|
|
11
|
-
jest.mock('../helpers/socialMediaVendors', () => ({
|
|
12
|
-
socialMediaVendors: {
|
|
13
|
-
twitter: { id: 'twitterId' }
|
|
14
|
-
}
|
|
5
|
+
// Mock dependencies
|
|
6
|
+
jest.mock('../helpers/enableCookies');
|
|
7
|
+
jest.mock('../helpers/privacyModal');
|
|
8
|
+
jest.mock('../helpers/getVendorTitle', () => ({
|
|
9
|
+
getVendorTitle: jest.fn(() => 'Vendor Title')
|
|
15
10
|
}));
|
|
16
11
|
describe('BlockedEmbedMessage', () => {
|
|
17
|
-
const
|
|
12
|
+
const vendorName = 'facebook';
|
|
13
|
+
const setIsAllowedOnce = jest.fn();
|
|
18
14
|
const defaultProps = {
|
|
19
|
-
vendorName
|
|
20
|
-
|
|
15
|
+
vendorName,
|
|
16
|
+
setIsAllowedOnce
|
|
21
17
|
};
|
|
22
18
|
beforeEach(() => {
|
|
23
19
|
jest.clearAllMocks();
|
|
24
|
-
window.__tcfapi = jest.fn();
|
|
25
20
|
sessionStorage.clear();
|
|
26
21
|
});
|
|
27
|
-
it('
|
|
28
|
-
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
29
|
-
fireEvent.click(screen.getByRole('button', { name: /Enable cookies/i }));
|
|
30
|
-
expect(enableCookies).toHaveBeenCalledWith('twitter');
|
|
31
|
-
});
|
|
32
|
-
it('should call allowCookiesOnce when "Allow cookies once" button is clicked', () => {
|
|
33
|
-
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
34
|
-
fireEvent.click(screen.getByRole('button', { name: /Allow cookies once/i }));
|
|
35
|
-
expect(window.__tcfapi).toHaveBeenCalledWith('getCustomVendorConsents', 2, expect.any(Function));
|
|
36
|
-
});
|
|
37
|
-
it('should set consentGranted in session storage and allow embed if consent is granted', () => {
|
|
38
|
-
window.__tcfapi = jest.fn((command, version, callback) => {
|
|
39
|
-
// tslint:disable-next-line:no-console
|
|
40
|
-
console.log('version', version);
|
|
41
|
-
if (command === 'getCustomVendorConsents') {
|
|
42
|
-
callback({
|
|
43
|
-
grants: {
|
|
44
|
-
twitterId: { vendorGrant: true, purposeGrants: { 1: true } }
|
|
45
|
-
}
|
|
46
|
-
}, true);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
50
|
-
fireEvent.click(screen.getByRole('button', { name: /Allow cookies once/i }));
|
|
51
|
-
expect(sessionStorage.getItem('consentGranted_twitterId')).toBe('true');
|
|
52
|
-
expect(mockSetIsSocialEmbedAllowed).toHaveBeenCalledWith(true);
|
|
53
|
-
});
|
|
54
|
-
it('should handle missing consent data gracefully and not allow embed', () => {
|
|
55
|
-
window.__tcfapi = jest.fn((command, version, callback) => {
|
|
56
|
-
// tslint:disable-next-line:no-console
|
|
57
|
-
console.log('command, version', command, version);
|
|
58
|
-
callback(null, false); // Simulate unsuccessful consent request
|
|
59
|
-
});
|
|
22
|
+
it('calls enableCookies when Enable cookies button is clicked', () => {
|
|
60
23
|
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expect(
|
|
24
|
+
const enableButton = screen.getByText('Enable cookies');
|
|
25
|
+
fireEvent.click(enableButton);
|
|
26
|
+
expect(enableCookies).toHaveBeenCalledWith(vendorName);
|
|
64
27
|
});
|
|
65
|
-
it('
|
|
66
|
-
window.__tcfapi = jest.fn((command, version, callback) => {
|
|
67
|
-
// tslint:disable-next-line:no-console
|
|
68
|
-
console.log('version', version);
|
|
69
|
-
if (command === 'getCustomVendorConsents') {
|
|
70
|
-
callback({
|
|
71
|
-
grants: {
|
|
72
|
-
twitterId: { vendorGrant: false, purposeGrants: { 1: true } }
|
|
73
|
-
}
|
|
74
|
-
}, true);
|
|
75
|
-
}
|
|
76
|
-
if (command === 'postCustomConsent') {
|
|
77
|
-
callback({}, true);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
28
|
+
it('calls allowCookiesOnce when Allow cookies once button is clicked and updates session storage', () => {
|
|
80
29
|
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
expect(
|
|
30
|
+
const allowButton = screen.getByText('Allow cookies once');
|
|
31
|
+
fireEvent.click(allowButton);
|
|
32
|
+
expect(setIsAllowedOnce).toHaveBeenCalledWith(true);
|
|
33
|
+
expect(sessionStorage.getItem('consentedVendors')).toBe(`['${vendorName}']`);
|
|
84
34
|
});
|
|
85
|
-
it('
|
|
86
|
-
|
|
87
|
-
console.error = jest.fn();
|
|
88
|
-
delete window.__tcfapi;
|
|
35
|
+
it('grants consent if vendor is already in session storage', () => {
|
|
36
|
+
sessionStorage.setItem('consentedVendors', `['${vendorName}']`);
|
|
89
37
|
render(React.createElement(BlockedEmbedMessage, Object.assign({}, defaultProps)));
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
expect(
|
|
93
|
-
expect(mockSetIsSocialEmbedAllowed).toHaveBeenCalledWith(false);
|
|
38
|
+
const allowButton = screen.getByText('Allow cookies once');
|
|
39
|
+
fireEvent.click(allowButton);
|
|
40
|
+
expect(setIsAllowedOnce).toHaveBeenCalledWith(true);
|
|
94
41
|
});
|
|
95
42
|
});
|
|
96
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmxvY2tlZEVtYmVkTWVzc2FnZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc29jaWFsLWVtYmVkL19fdGVzdHNfXy9CbG9ja2VkRW1iZWRNZXNzYWdlLnRlc3QudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNuRSxPQUFPLEVBQ0wsbUJBQW1CLEVBRXBCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3pELG9CQUFvQjtBQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUM7QUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUM1QyxjQUFjLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxjQUFjLENBQUM7Q0FDOUMsQ0FBQyxDQUFDLENBQUM7QUFFSixRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO0lBQ25DLE1BQU0sVUFBVSxHQUFHLFVBQXdCLENBQUM7SUFDNUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7SUFFbkMsTUFBTSxZQUFZLEdBQTZCO1FBQzdDLFVBQVU7UUFDVixnQkFBZ0I7S0FDakIsQ0FBQztJQUVGLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDJEQUEyRCxFQUFFLEdBQUcsRUFBRTtRQUNuRSxNQUFNLENBQUMsb0JBQUMsbUJBQW1CLG9CQUFLLFlBQVksRUFBSSxDQUFDLENBQUM7UUFDbEQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3hELFNBQVMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDhGQUE4RixFQUFFLEdBQUcsRUFBRTtRQUN0RyxNQUFNLENBQUMsb0JBQUMsbUJBQW1CLG9CQUFLLFlBQVksRUFBSSxDQUFDLENBQUM7UUFDbEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzNELFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDckQsS0FBSyxVQUFVLElBQUksQ0FDcEIsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEdBQUcsRUFBRTtRQUNoRSxjQUFjLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEtBQUssVUFBVSxJQUFJLENBQUMsQ0FBQztRQUNoRSxNQUFNLENBQUMsb0JBQUMsbUJBQW1CLG9CQUFLLFlBQVksRUFBSSxDQUFDLENBQUM7UUFDbEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzNELFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|
|
1
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
@@ -1,129 +1,86 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen,
|
|
2
|
+
import { render, screen, cleanup } from '@testing-library/react';
|
|
3
3
|
import { SocialMediaEmbed } from '../SocialMediaEmbed';
|
|
4
|
-
import '
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
jest.mock('
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
import { BlockedEmbedMessage } from '../BlockedEmbedMessage';
|
|
5
|
+
import { eventStatus } from '../constants';
|
|
6
|
+
import { checkVendorConsent } from '../helpers/vendorConsent';
|
|
7
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
8
|
+
jest.mock('../BlockedEmbedMessage', () => ({
|
|
9
|
+
BlockedEmbedMessage: jest.fn(() => React.createElement("div", null, "Blocked Embed Message"))
|
|
10
|
+
}));
|
|
11
|
+
jest.mock('../helpers/vendorConsent', () => ({
|
|
12
|
+
checkVendorConsent: jest.fn()
|
|
13
|
+
}));
|
|
14
|
+
describe('SocialMediaEmbed component', () => {
|
|
15
|
+
const defaultProps = {
|
|
16
|
+
id: 'test-embed',
|
|
17
|
+
url: 'https://twitter.com/test/status/123',
|
|
18
|
+
vendorName: 'twitter',
|
|
19
|
+
socialEmbed: {
|
|
20
|
+
isSocialEmbedAllowed: false,
|
|
21
|
+
setIsSocialEmbedAllowed: jest.fn(),
|
|
22
|
+
isAllowedOnce: false,
|
|
23
|
+
setIsAllowedOnce: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
};
|
|
11
26
|
beforeEach(() => {
|
|
12
|
-
|
|
13
|
-
window.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
window.__tcfapi = jest.fn();
|
|
28
|
+
window.twttr = {
|
|
29
|
+
widgets: {
|
|
30
|
+
load: jest.fn()
|
|
31
|
+
}
|
|
32
|
+
};
|
|
18
33
|
});
|
|
19
34
|
afterEach(() => {
|
|
20
|
-
|
|
35
|
+
cleanup();
|
|
36
|
+
jest.clearAllMocks();
|
|
37
|
+
delete window.__tcfapi;
|
|
38
|
+
delete window.twttr;
|
|
21
39
|
});
|
|
22
|
-
it('renders
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
key: 'twitter-embed'
|
|
30
|
-
};
|
|
31
|
-
const url = 'https://twitter.com';
|
|
32
|
-
render(React.createElement(SocialMediaEmbed, { element: mockElement, url: url, vendorName: 'twitter', id: '222' }));
|
|
33
|
-
// const twitterEmbedElement = document.querySelector('twitter-embed');
|
|
34
|
-
// expect(twitterEmbedElement).toHaveAttribute('url', url);
|
|
35
|
-
});
|
|
36
|
-
it('renders blocked content message if consent for Twitter is not given', () => {
|
|
37
|
-
mockTcfApi.mockImplementation((_, __, callback) => {
|
|
38
|
-
callback({ consentedVendors: [] }, true);
|
|
39
|
-
});
|
|
40
|
-
const mockElement = {
|
|
41
|
-
attributes: {},
|
|
42
|
-
value: 'Twitter content',
|
|
43
|
-
key: 'twitter-embed'
|
|
44
|
-
};
|
|
45
|
-
const url = 'https://twitter.com';
|
|
46
|
-
render(React.createElement(SocialMediaEmbed, { element: mockElement, url: url, vendorName: 'twitter', id: '222' }));
|
|
47
|
-
expect(screen.getByText('X (Twitter) content blocked')).toBeInTheDocument();
|
|
48
|
-
expect(screen.getByText('privacy manager.')).toBeInTheDocument();
|
|
49
|
-
expect(screen.getByRole('button', { name: /Enable cookies/i })).toBeInTheDocument();
|
|
50
|
-
expect(screen.getByRole('button', { name: /Allow cookies once/i })).toBeInTheDocument();
|
|
40
|
+
it('renders BlockedEmbedMessage when social embed is not allowed', () => {
|
|
41
|
+
render(React.createElement(SocialMediaEmbed, Object.assign({}, defaultProps)));
|
|
42
|
+
expect(screen.getByText('Blocked Embed Message')).toBeInTheDocument();
|
|
43
|
+
expect(BlockedEmbedMessage).toHaveBeenCalledWith(expect.objectContaining({
|
|
44
|
+
vendorName: defaultProps.vendorName,
|
|
45
|
+
setIsAllowedOnce: defaultProps.socialEmbed.setIsAllowedOnce
|
|
46
|
+
}), {});
|
|
51
47
|
});
|
|
52
|
-
it('
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
const mockElement = {
|
|
61
|
-
attributes: {},
|
|
62
|
-
value: 'Twitter content',
|
|
63
|
-
key: 'twitter-embed'
|
|
48
|
+
it('renders the Twitter embed when social embed is allowed', () => {
|
|
49
|
+
const allowedProps = {
|
|
50
|
+
...defaultProps,
|
|
51
|
+
socialEmbed: {
|
|
52
|
+
...defaultProps.socialEmbed,
|
|
53
|
+
isSocialEmbedAllowed: true
|
|
54
|
+
}
|
|
64
55
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
fireEvent.click(screen.getByRole('button', { name: /Enable cookies/i }));
|
|
68
|
-
expect(mockTcfApi).toHaveBeenCalledWith('getCustomVendorConsents', 2, expect.any(Function));
|
|
69
|
-
expect(mockTcfApi).toHaveBeenCalledWith('postCustomConsent', 2, expect.any(Function), ['5fab0c31a22863611c5f8764'], expect.any(Array), []);
|
|
70
|
-
// const twitterEmbedElement = document.querySelector('twitter-embed');
|
|
71
|
-
// expect(twitterEmbedElement).toHaveAttribute('url', url);
|
|
56
|
+
render(React.createElement(SocialMediaEmbed, Object.assign({}, allowedProps)));
|
|
57
|
+
expect(screen.getByRole('link')).toHaveAttribute('href', defaultProps.url);
|
|
72
58
|
});
|
|
73
|
-
it('
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
'5fab0c31a22863611c5f8764': { purposeGrants: { '1': true } }
|
|
79
|
-
}
|
|
80
|
-
}, true);
|
|
81
|
-
});
|
|
82
|
-
const mockElement = {
|
|
83
|
-
attributes: {},
|
|
84
|
-
value: 'Twitter content',
|
|
85
|
-
key: 'twitter-embed'
|
|
59
|
+
it('calls checkVendorConsent and sets consent on tcLoaded event', () => {
|
|
60
|
+
const tcData = {
|
|
61
|
+
cmpStatus: 'loaded',
|
|
62
|
+
eventStatus: eventStatus.tcLoaded,
|
|
63
|
+
listenerId: 1
|
|
86
64
|
};
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
render(React.createElement(SocialMediaEmbed, { element: mockElement, url: url, vendorName: 'twitter', id: '222' }));
|
|
94
|
-
expect(screen.getByText('X (Twitter) content blocked')).toBeInTheDocument();
|
|
95
|
-
});
|
|
96
|
-
it('opens privacy modal when available', () => {
|
|
97
|
-
const mockLoadPrivacyManagerModal = jest.fn();
|
|
98
|
-
window.__TIMES_CONFIG__ = {
|
|
99
|
-
sourcepoint: {
|
|
100
|
-
gdprMessageId: 'messageIdForGDPR'
|
|
65
|
+
const setIsSocialEmbedAllowed = jest.fn();
|
|
66
|
+
const updatedProps = {
|
|
67
|
+
...defaultProps,
|
|
68
|
+
socialEmbed: {
|
|
69
|
+
...defaultProps.socialEmbed,
|
|
70
|
+
setIsSocialEmbedAllowed
|
|
101
71
|
}
|
|
102
72
|
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const url = 'https://twitter.com';
|
|
110
|
-
render(React.createElement(SocialMediaEmbed, { element: mockElement, url: url, vendorName: 'twitter', id: '222' }));
|
|
111
|
-
const privacyManagerLink = screen.getByText('privacy manager.');
|
|
112
|
-
fireEvent.click(privacyManagerLink);
|
|
113
|
-
expect(mockLoadPrivacyManagerModal).toHaveBeenCalledWith('messageIdForGDPR');
|
|
73
|
+
checkVendorConsent.mockReturnValue(true);
|
|
74
|
+
render(React.createElement(SocialMediaEmbed, Object.assign({}, updatedProps)));
|
|
75
|
+
const [callback] = window.__tcfapi.mock.calls[0].slice(2);
|
|
76
|
+
callback(tcData, true);
|
|
77
|
+
expect(checkVendorConsent).toHaveBeenCalledWith(defaultProps.vendorName);
|
|
78
|
+
expect(setIsSocialEmbedAllowed).toHaveBeenCalledWith(true);
|
|
114
79
|
});
|
|
115
|
-
it('
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
value: 'Twitter content',
|
|
120
|
-
key: 'twitter-embed'
|
|
121
|
-
};
|
|
122
|
-
const url = 'https://twitter.com';
|
|
123
|
-
render(React.createElement(SocialMediaEmbed, { element: mockElement, url: url, vendorName: 'twitter', id: '222' }));
|
|
124
|
-
const privacyManagerLink = screen.getByText('privacy manager.');
|
|
125
|
-
fireEvent.click(privacyManagerLink);
|
|
126
|
-
expect(global.console.warn).toHaveBeenCalledWith('Sourcepoint LoadPrivacyManagerModal is not available');
|
|
80
|
+
it('does not trigger Twitter widget load if twttr is undefined', () => {
|
|
81
|
+
delete window.twttr;
|
|
82
|
+
render(React.createElement(SocialMediaEmbed, Object.assign({}, defaultProps)));
|
|
83
|
+
expect(window.twttr).toBeUndefined();
|
|
127
84
|
});
|
|
128
85
|
});
|
|
129
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
86
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29jaWFsTWVkaWFFbWJlZC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc29jaWFsLWVtYmVkL19fdGVzdHNfXy9Tb2NpYWxNZWRpYUVtYmVkLnRlc3QudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQXlCLE1BQU0scUJBQXFCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU5RCxPQUFPLHlDQUF5QyxDQUFDO0FBRWpELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUN6QyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLHlEQUFnQyxDQUFDO0NBQ3JFLENBQUMsQ0FBQyxDQUFDO0FBRUosSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7Q0FDOUIsQ0FBQyxDQUFDLENBQUM7QUFFSixRQUFRLENBQUMsNEJBQTRCLEVBQUUsR0FBRyxFQUFFO0lBQzFDLE1BQU0sWUFBWSxHQUEwQjtRQUMxQyxFQUFFLEVBQUUsWUFBWTtRQUNoQixHQUFHLEVBQUUscUNBQXFDO1FBQzFDLFVBQVUsRUFBRSxTQUFTO1FBQ3JCLFdBQVcsRUFBRTtZQUNYLG9CQUFvQixFQUFFLEtBQUs7WUFDM0IsdUJB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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|