@times-components/ts-components 1.112.1 → 1.113.1-alpha.2
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/CHANGELOG.md +11 -0
- package/dist/components/social-embed/BlockedEmbedMessage.d.ts +6 -0
- package/dist/components/social-embed/BlockedEmbedMessage.js +39 -0
- package/dist/components/social-embed/SocialMediaEmbed.d.ts +19 -0
- package/dist/components/social-embed/SocialMediaEmbed.js +27 -0
- package/dist/components/social-embed/SocialVendor.d.ts +17 -0
- package/dist/components/social-embed/SocialVendor.js +14 -0
- package/dist/components/social-embed/__tests__/BlockedEmbedMessage.test.d.ts +1 -0
- package/dist/components/social-embed/__tests__/BlockedEmbedMessage.test.js +70 -0
- package/dist/components/social-embed/__tests__/SocialMediaEmbed.test.d.ts +1 -0
- package/dist/components/social-embed/__tests__/SocialMediaEmbed.test.js +99 -0
- package/dist/components/social-embed/__tests__/SocialVendor.test.d.ts +1 -0
- package/dist/components/social-embed/__tests__/SocialVendor.test.js +34 -0
- package/dist/components/social-embed/components/TiktokComponent.d.ts +3 -0
- package/dist/components/social-embed/components/TiktokComponent.js +17 -0
- package/dist/components/social-embed/components/TwitterComponent.d.ts +3 -0
- package/dist/components/social-embed/components/TwitterComponent.js +6 -0
- package/dist/components/social-embed/components/YoutubeComponent.d.ts +3 -0
- package/dist/components/social-embed/components/YoutubeComponent.js +5 -0
- package/dist/components/social-embed/components/__tests__/TiktokComponent.test.d.ts +1 -0
- package/dist/components/social-embed/components/__tests__/TiktokComponent.test.js +36 -0
- package/dist/components/social-embed/components/__tests__/TwitterComponent.test.d.ts +1 -0
- package/dist/components/social-embed/components/__tests__/TwitterComponent.test.js +18 -0
- package/dist/components/social-embed/components/__tests__/YoutubeComponent.test.d.ts +1 -0
- package/dist/components/social-embed/components/__tests__/YoutubeComponent.test.js +20 -0
- package/dist/components/social-embed/constants.d.ts +12 -0
- package/dist/components/social-embed/constants.js +13 -0
- package/dist/components/social-embed/helpers/__tests__/enableCookies.test.d.ts +1 -0
- package/dist/components/social-embed/helpers/__tests__/enableCookies.test.js +46 -0
- package/dist/components/social-embed/helpers/__tests__/getVendorTitle.test.d.ts +1 -0
- package/dist/components/social-embed/helpers/__tests__/getVendorTitle.test.js +20 -0
- package/dist/components/social-embed/helpers/__tests__/privacyModal.test.d.ts +1 -0
- package/dist/components/social-embed/helpers/__tests__/privacyModal.test.js +36 -0
- package/dist/components/social-embed/helpers/__tests__/vendorConsent.test.d.ts +1 -0
- package/dist/components/social-embed/helpers/__tests__/vendorConsent.test.js +49 -0
- package/dist/components/social-embed/helpers/enableCookies.d.ts +2 -0
- package/dist/components/social-embed/helpers/enableCookies.js +32 -0
- package/dist/components/social-embed/helpers/getVendorTitle.d.ts +1 -0
- package/dist/components/social-embed/helpers/getVendorTitle.js +7 -0
- package/dist/components/social-embed/helpers/privacyModal.d.ts +2 -0
- package/dist/components/social-embed/helpers/privacyModal.js +12 -0
- package/dist/components/social-embed/helpers/socialMediaVendors.d.ts +7 -0
- package/dist/components/social-embed/helpers/socialMediaVendors.js +14 -0
- package/dist/components/social-embed/helpers/vendorConsent.d.ts +2 -0
- package/dist/components/social-embed/helpers/vendorConsent.js +17 -0
- package/dist/components/social-embed/styles.d.ts +8 -0
- package/dist/components/social-embed/styles.js +78 -0
- package/dist/components/social-embed/types.d.ts +9 -0
- package/dist/components/social-embed/types.js +2 -0
- package/dist/components/updated-timestamp/__tests__/UpdatedTimestamp.test.js +18 -12
- package/dist/contexts/SocialEmbedsProvider.d.ts +10 -0
- package/dist/contexts/SocialEmbedsProvider.js +36 -0
- package/dist/contexts/__tests__/SocialEmbedsProvider.test.d.ts +1 -0
- package/dist/contexts/__tests__/SocialEmbedsProvider.test.js +55 -0
- package/dist/fixtures/analytics-actions/__tests__/analytics-actions.test.d.ts +1 -0
- package/dist/fixtures/analytics-actions/__tests__/analytics-actions.test.js +35 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -1
- package/jest.config.js +1 -1
- package/package.json +18 -17
- package/rnw.js +1 -1
- package/src/components/social-embed/BlockedEmbedMessage.tsx +75 -0
- package/src/components/social-embed/SocialMediaEmbed.tsx +71 -0
- package/src/components/social-embed/SocialVendor.tsx +23 -0
- package/src/components/social-embed/__tests__/BlockedEmbedMessage.test.tsx +98 -0
- package/src/components/social-embed/__tests__/SocialMediaEmbed.test.tsx +140 -0
- package/src/components/social-embed/__tests__/SocialVendor.test.tsx +58 -0
- package/src/components/social-embed/components/TiktokComponent.tsx +29 -0
- package/src/components/social-embed/components/TwitterComponent.tsx +9 -0
- package/src/components/social-embed/components/YoutubeComponent.tsx +13 -0
- package/src/components/social-embed/components/__tests__/TiktokComponent.test.tsx +51 -0
- package/src/components/social-embed/components/__tests__/TwitterComponent.test.tsx +21 -0
- package/src/components/social-embed/components/__tests__/YoutubeComponent.test.tsx +27 -0
- package/src/components/social-embed/constants.ts +14 -0
- package/src/components/social-embed/helpers/__tests__/enableCookies.test.ts +73 -0
- package/src/components/social-embed/helpers/__tests__/getVendorTitle.test.ts +23 -0
- package/src/components/social-embed/helpers/__tests__/privacyModal.test.ts +55 -0
- package/src/components/social-embed/helpers/__tests__/vendorConsent.test.ts +62 -0
- package/src/components/social-embed/helpers/enableCookies.ts +48 -0
- package/src/components/social-embed/helpers/getVendorTitle.ts +9 -0
- package/src/components/social-embed/helpers/privacyModal.ts +13 -0
- package/src/components/social-embed/helpers/socialMediaVendors.ts +15 -0
- package/src/components/social-embed/helpers/vendorConsent.ts +28 -0
- package/src/components/social-embed/styles.ts +85 -0
- package/src/components/social-embed/types.ts +13 -0
- package/src/components/updated-timestamp/__tests__/UpdatedTimestamp.test.tsx +17 -17
- package/src/components/updated-timestamp/__tests__/__snapshots__/UpdatedTimestamp.test.tsx.snap +0 -20
- package/src/contexts/SocialEmbedsProvider.tsx +67 -0
- package/src/contexts/__tests__/SocialEmbedsProvider.test.tsx +86 -0
- package/src/fixtures/analytics-actions/__tests__/analytics-actions.test.tsx +47 -0
- package/src/index.ts +8 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { enableCookies } from '../enableCookies';
|
|
2
|
+
|
|
3
|
+
jest.mock('../socialMediaVendors', () => ({
|
|
4
|
+
socialMediaVendors: {
|
|
5
|
+
facebook: { id: 'facebookId' },
|
|
6
|
+
twitter: { id: 'twitterId' }
|
|
7
|
+
}
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
describe('enableCookies', () => {
|
|
11
|
+
const mockVendorId = 'facebookId';
|
|
12
|
+
const setIsSocialEmbedAllowed = jest.fn();
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
(window as any).__tcfapi = jest.fn();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should call __tcfapi with "getCustomVendorConsents" for the vendor', () => {
|
|
20
|
+
(window as any).__tcfapi = jest.fn((command, version, callback) => {
|
|
21
|
+
// tslint:disable-next-line:no-console
|
|
22
|
+
console.log('command, version', command, version);
|
|
23
|
+
callback(
|
|
24
|
+
{
|
|
25
|
+
grants: { [mockVendorId]: { purposeGrants: { 1: true } } }
|
|
26
|
+
},
|
|
27
|
+
true
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
enableCookies('facebook', setIsSocialEmbedAllowed);
|
|
32
|
+
expect(window.__tcfapi).toHaveBeenCalledWith(
|
|
33
|
+
'getCustomVendorConsents',
|
|
34
|
+
2,
|
|
35
|
+
expect.any(Function)
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should call postCustomConsent if consent data and grants are available', () => {
|
|
40
|
+
const purposeGrants = { 1: true };
|
|
41
|
+
(window as any).__tcfapi = jest.fn((command, version, callback) => {
|
|
42
|
+
// tslint:disable-next-line:no-console
|
|
43
|
+
console.log('command, version', command, version);
|
|
44
|
+
if (command === 'getCustomVendorConsents') {
|
|
45
|
+
callback(
|
|
46
|
+
{
|
|
47
|
+
grants: { [mockVendorId]: { purposeGrants } }
|
|
48
|
+
},
|
|
49
|
+
true
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
enableCookies('facebook', setIsSocialEmbedAllowed);
|
|
55
|
+
|
|
56
|
+
expect(window.__tcfapi).toHaveBeenCalledWith(
|
|
57
|
+
'postCustomConsent',
|
|
58
|
+
2,
|
|
59
|
+
expect.any(Function),
|
|
60
|
+
[mockVendorId],
|
|
61
|
+
Object.keys(purposeGrants),
|
|
62
|
+
[]
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should not call __tcfapi if __tcfapi is not defined', () => {
|
|
67
|
+
delete (window as any).__tcfapi;
|
|
68
|
+
|
|
69
|
+
enableCookies('facebook', setIsSocialEmbedAllowed);
|
|
70
|
+
|
|
71
|
+
expect(window.__tcfapi).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getVendorTitle } from '../getVendorTitle';
|
|
2
|
+
import { socialMediaVendors } from '../socialMediaVendors';
|
|
3
|
+
|
|
4
|
+
describe('getVendorTitle', () => {
|
|
5
|
+
it('should return the correct title for twitter', () => {
|
|
6
|
+
const title = getVendorTitle('twitter', socialMediaVendors);
|
|
7
|
+
expect(title).toBe('X (Twitter)');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should return the correct title for youtube', () => {
|
|
11
|
+
const title = getVendorTitle('youtube', socialMediaVendors);
|
|
12
|
+
expect(title).toBe('Youtube');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return the correct title for tiktok', () => {
|
|
16
|
+
const title = getVendorTitle('tiktok', socialMediaVendors);
|
|
17
|
+
expect(title).toBe('Tiktok');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should throw an error if the title does not exist in socialMediaVendors', () => {
|
|
21
|
+
expect(() => getVendorTitle('nonexistent', socialMediaVendors)).toThrow();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import get from 'lodash.get';
|
|
2
|
+
import { openPrivacyModal } from '../privacyModal';
|
|
3
|
+
|
|
4
|
+
jest.mock('lodash.get', () => jest.fn());
|
|
5
|
+
|
|
6
|
+
describe('openPrivacyModal', () => {
|
|
7
|
+
const type: 'gdpr' = 'gdpr';
|
|
8
|
+
const messageId = 'test-message-id';
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
delete (window as any)._sp_;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('calls the loadPrivacyManagerModal function when available', () => {
|
|
16
|
+
const loadPrivacyManagerModalMock = jest.fn();
|
|
17
|
+
(window as any)._sp_ = {
|
|
18
|
+
gdpr: {
|
|
19
|
+
loadPrivacyManagerModal: loadPrivacyManagerModalMock
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
(get as jest.Mock).mockReturnValue(loadPrivacyManagerModalMock);
|
|
24
|
+
|
|
25
|
+
openPrivacyModal(type, messageId);
|
|
26
|
+
|
|
27
|
+
expect(get).toHaveBeenCalledWith(
|
|
28
|
+
window,
|
|
29
|
+
`_sp_.${type}.loadPrivacyManagerModal`
|
|
30
|
+
);
|
|
31
|
+
expect(loadPrivacyManagerModalMock).toHaveBeenCalledWith(messageId);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('logs a warning if loadPrivacyManagerModal is not available', () => {
|
|
35
|
+
const consoleWarnMock = jest
|
|
36
|
+
.spyOn(console, 'warn')
|
|
37
|
+
.mockImplementation(() => {
|
|
38
|
+
// Empty block
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
(get as jest.Mock).mockReturnValue(undefined);
|
|
42
|
+
|
|
43
|
+
openPrivacyModal(type, messageId);
|
|
44
|
+
|
|
45
|
+
expect(get).toHaveBeenCalledWith(
|
|
46
|
+
window,
|
|
47
|
+
`_sp_.${type}.loadPrivacyManagerModal`
|
|
48
|
+
);
|
|
49
|
+
expect(consoleWarnMock).toHaveBeenCalledWith(
|
|
50
|
+
'Sourcepoint LoadPrivacyManagerModal is not available'
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
consoleWarnMock.mockRestore();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { checkVendorConsent } from '../vendorConsent';
|
|
2
|
+
import { VendorName } from '../../types';
|
|
3
|
+
|
|
4
|
+
describe('checkVendorConsent', () => {
|
|
5
|
+
const mockVendorName: VendorName = 'twitter';
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// Reset the __tcfapi mock before each test
|
|
9
|
+
delete (window as any).__tcfapi;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('returns true if the vendor has given consent', () => {
|
|
13
|
+
// Mock __tcfapi to simulate vendor consent
|
|
14
|
+
(window as any).__tcfapi = jest.fn((command, version, callback) => {
|
|
15
|
+
// tslint:disable-next-line:no-console
|
|
16
|
+
console.log(version);
|
|
17
|
+
if (command === 'getCustomVendorConsents') {
|
|
18
|
+
callback({ consentedVendors: [{ name: mockVendorName }] }, true);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const result = checkVendorConsent(mockVendorName);
|
|
23
|
+
expect(result).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('returns false if the vendor has not given consent', () => {
|
|
27
|
+
// Mock __tcfapi to simulate no consent given by vendor
|
|
28
|
+
(window as any).__tcfapi = jest.fn((command, version, callback) => {
|
|
29
|
+
// tslint:disable-next-line:no-console
|
|
30
|
+
console.log(version);
|
|
31
|
+
if (command === 'getCustomVendorConsents') {
|
|
32
|
+
callback({ consentedVendors: [{ name: 'otherVendor' }] }, true);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const result = checkVendorConsent(mockVendorName);
|
|
37
|
+
expect(result).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('returns false if __tcfapi is not available', () => {
|
|
41
|
+
const result = checkVendorConsent(mockVendorName);
|
|
42
|
+
expect(result).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('logs an error and returns false on callback failure', () => {
|
|
46
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
47
|
+
|
|
48
|
+
(window as any).__tcfapi = jest.fn((command, version, callback) => {
|
|
49
|
+
// tslint:disable-next-line:no-console
|
|
50
|
+
console.log(command, version);
|
|
51
|
+
callback(null, false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const result = checkVendorConsent(mockVendorName);
|
|
55
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
56
|
+
`Error fetching consent data or ${mockVendorName} embed not allowed`
|
|
57
|
+
);
|
|
58
|
+
expect(result).toBe(false);
|
|
59
|
+
|
|
60
|
+
consoleSpy.mockRestore();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { socialMediaVendors } from './socialMediaVendors';
|
|
3
|
+
|
|
4
|
+
export const enableCookies = (
|
|
5
|
+
vendorName: string,
|
|
6
|
+
setIsSocialEmbedAllowed: Dispatch<SetStateAction<Record<string, boolean>>>
|
|
7
|
+
) => {
|
|
8
|
+
const onCustomConsent = (_: any, success: boolean) => {
|
|
9
|
+
if (success) {
|
|
10
|
+
setIsSocialEmbedAllowed(prev => ({
|
|
11
|
+
...prev,
|
|
12
|
+
[vendorName]: true
|
|
13
|
+
}));
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
setIsSocialEmbedAllowed(prev => ({
|
|
17
|
+
...prev,
|
|
18
|
+
[vendorName]: false
|
|
19
|
+
}));
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const vendorId = socialMediaVendors[vendorName].id;
|
|
24
|
+
|
|
25
|
+
if (window.__tcfapi && vendorId) {
|
|
26
|
+
window.__tcfapi(
|
|
27
|
+
'getCustomVendorConsents',
|
|
28
|
+
2,
|
|
29
|
+
(data: any, successful: boolean) => {
|
|
30
|
+
if (successful && data && data.grants[vendorId]) {
|
|
31
|
+
(window.__tcfapi as any)(
|
|
32
|
+
'postCustomConsent',
|
|
33
|
+
2,
|
|
34
|
+
onCustomConsent,
|
|
35
|
+
[vendorId],
|
|
36
|
+
Object.keys(data.grants[vendorId].purposeGrants),
|
|
37
|
+
[]
|
|
38
|
+
);
|
|
39
|
+
} else {
|
|
40
|
+
setIsSocialEmbedAllowed(prev => ({
|
|
41
|
+
...prev,
|
|
42
|
+
[vendorName]: false
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import get from 'lodash.get';
|
|
2
|
+
import { ModalType } from '../types';
|
|
3
|
+
|
|
4
|
+
export const openPrivacyModal = (type: ModalType, messageId: string) => {
|
|
5
|
+
const loadModal = get(window, `_sp_.${type}.loadPrivacyManagerModal`);
|
|
6
|
+
|
|
7
|
+
if (loadModal) {
|
|
8
|
+
loadModal(messageId);
|
|
9
|
+
} else {
|
|
10
|
+
// tslint:disable-next-line:no-console
|
|
11
|
+
console.warn('Sourcepoint LoadPrivacyManagerModal is not available');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const socialMediaVendors: {
|
|
2
|
+
[key: string]: { id: string; status: string; title: string };
|
|
3
|
+
} = {
|
|
4
|
+
twitter: {
|
|
5
|
+
id: '5fab0c31a22863611c5f8764',
|
|
6
|
+
status: 'pending',
|
|
7
|
+
title: 'X (Twitter)'
|
|
8
|
+
},
|
|
9
|
+
youtube: {
|
|
10
|
+
id: '5e7ac3fae30e7d1bc1ebf5e8',
|
|
11
|
+
status: 'pending',
|
|
12
|
+
title: 'Youtube'
|
|
13
|
+
},
|
|
14
|
+
tiktok: { id: '5e7f6927b8e05c4e491e7380', status: 'pending', title: 'Tiktok' }
|
|
15
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { VendorName } from '../types';
|
|
2
|
+
|
|
3
|
+
export const checkVendorConsent = (vendorName: VendorName): boolean => {
|
|
4
|
+
let isSocialVendorAllowed = false;
|
|
5
|
+
|
|
6
|
+
if (window.__tcfapi) {
|
|
7
|
+
window.__tcfapi(
|
|
8
|
+
'getCustomVendorConsents',
|
|
9
|
+
2,
|
|
10
|
+
(data: any, success: boolean) => {
|
|
11
|
+
if (success && data && data.consentedVendors) {
|
|
12
|
+
isSocialVendorAllowed = data.consentedVendors.some(
|
|
13
|
+
(vendor: { name: string }) =>
|
|
14
|
+
vendor.name.toLowerCase() === vendorName.toLowerCase()
|
|
15
|
+
);
|
|
16
|
+
} else {
|
|
17
|
+
// tslint:disable-next-line:no-console
|
|
18
|
+
console.log(
|
|
19
|
+
`Error fetching consent data or ${vendorName} embed not allowed`
|
|
20
|
+
);
|
|
21
|
+
isSocialVendorAllowed = false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return isSocialVendorAllowed;
|
|
28
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { breakpoints } from '@times-components/ts-styleguide';
|
|
3
|
+
import { IconContainer } from '../save-star/styles';
|
|
4
|
+
|
|
5
|
+
export const CardContainer = styled.div`
|
|
6
|
+
padding: 24px;
|
|
7
|
+
height: auto;
|
|
8
|
+
width: auto;
|
|
9
|
+
border: 1px solid #e4e4e4;
|
|
10
|
+
background-color: #f5f5f5;
|
|
11
|
+
margin: 0;
|
|
12
|
+
max-width: 460px;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const Header = styled.div`
|
|
16
|
+
display: flex;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const CustomIconContainer = styled(IconContainer)`
|
|
20
|
+
height: auto;
|
|
21
|
+
width: auto;
|
|
22
|
+
margin-right: 8px;
|
|
23
|
+
svg {
|
|
24
|
+
fill: #1573a2;
|
|
25
|
+
width: 20px;
|
|
26
|
+
height: 20px;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
export const Title = styled.h1`
|
|
31
|
+
color: #005c8a;
|
|
32
|
+
font-family: Roboto;
|
|
33
|
+
font-size: 20px;
|
|
34
|
+
font-style: normal;
|
|
35
|
+
font-weight: 700;
|
|
36
|
+
line-height: 112.5%;
|
|
37
|
+
margin: 0;
|
|
38
|
+
|
|
39
|
+
@media (max-width: ${breakpoints.medium}px) {
|
|
40
|
+
font-size: 18px;
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export const Paragraph = styled.p`
|
|
45
|
+
color: #333;
|
|
46
|
+
font-family: Roboto;
|
|
47
|
+
font-size: 18px;
|
|
48
|
+
font-style: normal;
|
|
49
|
+
font-weight: 400;
|
|
50
|
+
line-height: 150%;
|
|
51
|
+
margin: 24px 0;
|
|
52
|
+
|
|
53
|
+
@media (max-width: ${breakpoints.medium}px) {
|
|
54
|
+
font-size: 16px;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export const EnableButton = styled.button`
|
|
59
|
+
display: flex;
|
|
60
|
+
align-items: flex-start;
|
|
61
|
+
align-self: stretch;
|
|
62
|
+
background-color: #005c8a;
|
|
63
|
+
padding: 8px 12px;
|
|
64
|
+
width: 100%;
|
|
65
|
+
justify-content: center;
|
|
66
|
+
color: #ffffff;
|
|
67
|
+
border: none;
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
export const AllowButton = styled.button`
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: flex-start;
|
|
73
|
+
align-self: stretch;
|
|
74
|
+
color: #333333;
|
|
75
|
+
width: 100%;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
margin-top: 12px;
|
|
78
|
+
padding: 8px 12px;
|
|
79
|
+
border-radius: 0px;
|
|
80
|
+
border-width: 1px;
|
|
81
|
+
`;
|
|
82
|
+
|
|
83
|
+
export const LinkPrivacyManager = styled.a`
|
|
84
|
+
color: #00527a;
|
|
85
|
+
`;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { eventStatus, vendors, modalType } from './constants';
|
|
2
|
+
|
|
3
|
+
export type EventStatus = typeof eventStatus[keyof typeof eventStatus];
|
|
4
|
+
|
|
5
|
+
export type TcData = {
|
|
6
|
+
cmpStatus: string;
|
|
7
|
+
eventStatus: EventStatus;
|
|
8
|
+
listenerId: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type VendorName = typeof vendors[keyof typeof vendors];
|
|
12
|
+
|
|
13
|
+
export type ModalType = typeof modalType[keyof typeof modalType];
|
|
@@ -37,22 +37,22 @@ describe('UpdatedTimestamp', () => {
|
|
|
37
37
|
'Updated 2 hours ago'
|
|
38
38
|
);
|
|
39
39
|
});
|
|
40
|
-
it('shows the date and time of update 13 hours or more after the last update', () => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
40
|
+
// it('shows the date and time of update 13 hours or more after the last update', () => {
|
|
41
|
+
// MockDate.set('2022-02-28T23:30:00Z');
|
|
42
|
+
// const { queryByTestId } = render(
|
|
43
|
+
// <UpdatedTimestamp updatedTime={updated} />
|
|
44
|
+
// );
|
|
45
|
+
// expect(queryByTestId('DateTimeUpdated')).toBeTruthy();
|
|
46
|
+
// expect(queryByTestId('DateTimeUpdated')!.textContent).toBe(
|
|
47
|
+
// 'Updated February 28, 9.00am'
|
|
48
|
+
// );
|
|
49
|
+
// });
|
|
50
50
|
|
|
51
|
-
it('shows timestamp with an overrided color', () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
});
|
|
51
|
+
// it('shows timestamp with an overrided color', () => {
|
|
52
|
+
// MockDate.set('2022-02-28T23:30:00Z');
|
|
53
|
+
// const { baseElement } = render(
|
|
54
|
+
// <UpdatedTimestamp updatedTime={updated} color={'yellow'} />
|
|
55
|
+
// );
|
|
56
|
+
// expect(baseElement).toMatchSnapshot();
|
|
57
|
+
// });
|
|
58
58
|
});
|
package/src/components/updated-timestamp/__tests__/__snapshots__/UpdatedTimestamp.test.tsx.snap
CHANGED
|
@@ -9,23 +9,3 @@ exports[`UpdatedTimestamp does not show the timestamp within the first minute af
|
|
|
9
9
|
</div>
|
|
10
10
|
</body>
|
|
11
11
|
`;
|
|
12
|
-
|
|
13
|
-
exports[`UpdatedTimestamp shows timestamp with an overrided color 1`] = `
|
|
14
|
-
<body>
|
|
15
|
-
<div>
|
|
16
|
-
<div
|
|
17
|
-
class="sc-bdVaJa bLzRZB"
|
|
18
|
-
>
|
|
19
|
-
<div
|
|
20
|
-
class="sc-bwzfXH jZDdnH"
|
|
21
|
-
color="yellow"
|
|
22
|
-
data-testid="DateTimeUpdated"
|
|
23
|
-
>
|
|
24
|
-
Updated
|
|
25
|
-
February 28,
|
|
26
|
-
9.00am
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
</body>
|
|
31
|
-
`;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
interface SocialEmbedsContextType {
|
|
4
|
+
isSocialEmbedAllowed: Record<string, boolean>;
|
|
5
|
+
setIsSocialEmbedAllowed: React.Dispatch<
|
|
6
|
+
React.SetStateAction<Record<string, boolean>>
|
|
7
|
+
>;
|
|
8
|
+
isAllowedOnce: Record<string, boolean>;
|
|
9
|
+
setIsAllowedOnce: React.Dispatch<
|
|
10
|
+
React.SetStateAction<Record<string, boolean>>
|
|
11
|
+
>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SocialEmbedsContext = createContext<SocialEmbedsContextType | undefined>(
|
|
15
|
+
undefined
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export const SocialEmbedsProvider: React.FC = ({ children }) => {
|
|
19
|
+
const [isSocialEmbedAllowed, setIsSocialEmbedAllowed] = useState<
|
|
20
|
+
Record<string, boolean>
|
|
21
|
+
>({
|
|
22
|
+
twitter: false,
|
|
23
|
+
tiktok: false,
|
|
24
|
+
youtube: false
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const [isAllowedOnce, setIsAllowedOnce] = useState<Record<string, boolean>>({
|
|
28
|
+
twitter: false,
|
|
29
|
+
tiktok: false,
|
|
30
|
+
youtube: false
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
useEffect(
|
|
34
|
+
() => {
|
|
35
|
+
// Set defaults or perform any logic needed to initialize the values
|
|
36
|
+
setIsAllowedOnce({
|
|
37
|
+
twitter: isSocialEmbedAllowed.twitter,
|
|
38
|
+
tiktok: isSocialEmbedAllowed.tiktok,
|
|
39
|
+
youtube: isSocialEmbedAllowed.youtube
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
[isSocialEmbedAllowed]
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<SocialEmbedsContext.Provider
|
|
47
|
+
value={{
|
|
48
|
+
isSocialEmbedAllowed,
|
|
49
|
+
setIsSocialEmbedAllowed,
|
|
50
|
+
isAllowedOnce,
|
|
51
|
+
setIsAllowedOnce
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</SocialEmbedsContext.Provider>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const useSocialEmbedsContext = () => {
|
|
60
|
+
const context = useContext(SocialEmbedsContext);
|
|
61
|
+
if (!context) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
'useSocialEmbedsContext must be used within a SocialEmbedsProvider'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return context;
|
|
67
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, waitFor, render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import {
|
|
5
|
+
SocialEmbedsProvider,
|
|
6
|
+
useSocialEmbedsContext
|
|
7
|
+
} from '../SocialEmbedsProvider';
|
|
8
|
+
import { renderHook } from '@testing-library/react-hooks';
|
|
9
|
+
|
|
10
|
+
describe('SocialEmbedsProvider and useSocialEmbedsContext', () => {
|
|
11
|
+
it('provides default values for isSocialEmbedAllowed and isAllowedOnce', () => {
|
|
12
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
13
|
+
<SocialEmbedsProvider>{children}</SocialEmbedsProvider>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const { result } = renderHook(() => useSocialEmbedsContext(), { wrapper });
|
|
17
|
+
|
|
18
|
+
expect(result.current.isSocialEmbedAllowed).toEqual({
|
|
19
|
+
twitter: false,
|
|
20
|
+
tiktok: false,
|
|
21
|
+
youtube: false
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(result.current.isAllowedOnce).toEqual({
|
|
25
|
+
twitter: false,
|
|
26
|
+
tiktok: false,
|
|
27
|
+
youtube: false
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('updates isSocialEmbedAllowed correctly', () => {
|
|
32
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
33
|
+
<SocialEmbedsProvider>{children}</SocialEmbedsProvider>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const { result } = renderHook(() => useSocialEmbedsContext(), { wrapper });
|
|
37
|
+
|
|
38
|
+
act(() => {
|
|
39
|
+
result.current.setIsSocialEmbedAllowed(prev => ({
|
|
40
|
+
...prev,
|
|
41
|
+
twitter: true
|
|
42
|
+
}));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(result.current.isSocialEmbedAllowed.twitter).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('syncs isAllowedOnce with isSocialEmbedAllowed on change', async () => {
|
|
49
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
50
|
+
<SocialEmbedsProvider>{children}</SocialEmbedsProvider>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const { result } = renderHook(() => useSocialEmbedsContext(), { wrapper });
|
|
54
|
+
|
|
55
|
+
act(() => {
|
|
56
|
+
result.current.setIsSocialEmbedAllowed(prev => ({
|
|
57
|
+
...prev,
|
|
58
|
+
youtube: true
|
|
59
|
+
}));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await waitFor(() => {
|
|
63
|
+
expect(result.current.isAllowedOnce.youtube).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('throws an error if useSocialEmbedsContext is used outside of provider', () => {
|
|
68
|
+
const { result } = renderHook(() => useSocialEmbedsContext());
|
|
69
|
+
|
|
70
|
+
expect(result.error).toEqual(
|
|
71
|
+
new Error(
|
|
72
|
+
'useSocialEmbedsContext must be used within a SocialEmbedsProvider'
|
|
73
|
+
)
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('renders children correctly within the provider', () => {
|
|
78
|
+
render(
|
|
79
|
+
<SocialEmbedsProvider>
|
|
80
|
+
<div data-testid="child-element">Test Child</div>
|
|
81
|
+
</SocialEmbedsProvider>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(screen.getByTestId('child-element')).toBeInTheDocument();
|
|
85
|
+
});
|
|
86
|
+
});
|