diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5353bb1b300..6cca31e960f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,7 +50,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,7 +61,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -75,4 +75,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/simorgh-e2e-tests.yml b/.github/workflows/simorgh-e2e-tests.yml index 8d88d98af43..ac1a3e1805e 100644 --- a/.github/workflows/simorgh-e2e-tests.yml +++ b/.github/workflows/simorgh-e2e-tests.yml @@ -24,9 +24,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run Simorgh E2Es - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v3 with: build: yarn build start: yarn start diff --git a/.github/workflows/simorgh-integration-tests.yml b/.github/workflows/simorgh-integration-tests.yml index 9c0add87650..3d51b6dd9c8 100644 --- a/.github/workflows/simorgh-integration-tests.yml +++ b/.github/workflows/simorgh-integration-tests.yml @@ -17,22 +17,22 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [16.x] env: CI: true LOG_LEVEL: 'error' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Cache Node Modules id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: node_modules key: node-modules-${{ hashFiles('yarn.lock') }} diff --git a/.github/workflows/simorgh-local-server-tests.yml b/.github/workflows/simorgh-local-server-tests.yml index 1e59058bead..ccc8dbb2157 100644 --- a/.github/workflows/simorgh-local-server-tests.yml +++ b/.github/workflows/simorgh-local-server-tests.yml @@ -17,21 +17,21 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [16.x] env: CI: true LOG_LEVEL: 'error' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Cache Node Modules id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: node_modules key: node-modules-${{ hashFiles('yarn.lock') }} diff --git a/.github/workflows/simorgh-misc-checks.yml b/.github/workflows/simorgh-misc-checks.yml index fa2b5ef31b3..538ec6ffa8c 100644 --- a/.github/workflows/simorgh-misc-checks.yml +++ b/.github/workflows/simorgh-misc-checks.yml @@ -14,23 +14,23 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [16.x] env: CI: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: '0' - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Cache Node Modules id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: node_modules key: node-modules-${{ hashFiles('yarn.lock') }} diff --git a/.github/workflows/simorgh-unit-tests.yml b/.github/workflows/simorgh-unit-tests.yml index f0d38d99335..cff9cf76c07 100644 --- a/.github/workflows/simorgh-unit-tests.yml +++ b/.github/workflows/simorgh-unit-tests.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [16.x] env: CI: true LOG_LEVEL: 'error' @@ -25,9 +25,9 @@ jobs: GIT_COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} @@ -43,7 +43,7 @@ jobs: - name: Cache Node Modules id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: node_modules key: node-modules-${{ hashFiles('yarn.lock') }} diff --git a/.nvmrc b/.nvmrc index 82f87fa0a57..e0325e5adb6 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v12.18.4 +v16.17.1 diff --git a/.yarn/cache/@testing-library-dom-npm-8.13.0-de21374654-880f1872b9.zip b/.yarn/cache/@testing-library-dom-npm-8.13.0-de21374654-880f1872b9.zip new file mode 100644 index 00000000000..d6bf3bd80e0 Binary files /dev/null and b/.yarn/cache/@testing-library-dom-npm-8.13.0-de21374654-880f1872b9.zip differ diff --git a/.yarn/cache/@testing-library-dom-npm-8.16.1-885df301df-eca86b69f2.zip b/.yarn/cache/@testing-library-dom-npm-8.16.1-885df301df-eca86b69f2.zip deleted file mode 100644 index 6f4845d6fce..00000000000 Binary files a/.yarn/cache/@testing-library-dom-npm-8.16.1-885df301df-eca86b69f2.zip and /dev/null differ diff --git a/.yarn/cache/@testing-library-dom-npm-8.19.0-1ae6733a53-6bb93fef96.zip b/.yarn/cache/@testing-library-dom-npm-8.19.0-1ae6733a53-6bb93fef96.zip new file mode 100644 index 00000000000..462e6e1e112 Binary files /dev/null and b/.yarn/cache/@testing-library-dom-npm-8.19.0-1ae6733a53-6bb93fef96.zip differ diff --git a/.yarn/cache/ansi-regex-npm-0.2.1-47771068a7-ce95ac031f.zip b/.yarn/cache/ansi-regex-npm-0.2.1-47771068a7-ce95ac031f.zip new file mode 100644 index 00000000000..bfbadc3ce75 Binary files /dev/null and b/.yarn/cache/ansi-regex-npm-0.2.1-47771068a7-ce95ac031f.zip differ diff --git a/.yarn/cache/ansi-regex-npm-2.1.1-ddd24d102b-190abd03e4.zip b/.yarn/cache/ansi-regex-npm-2.1.1-ddd24d102b-190abd03e4.zip new file mode 100644 index 00000000000..39b46403778 Binary files /dev/null and b/.yarn/cache/ansi-regex-npm-2.1.1-ddd24d102b-190abd03e4.zip differ diff --git a/.yarn/cache/async-npm-2.6.4-3155e80151-a52083fb32.zip b/.yarn/cache/async-npm-2.6.4-3155e80151-a52083fb32.zip new file mode 100644 index 00000000000..cb048fd1c6d Binary files /dev/null and b/.yarn/cache/async-npm-2.6.4-3155e80151-a52083fb32.zip differ diff --git a/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip b/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip deleted file mode 100644 index 06a6229a09e..00000000000 Binary files a/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip and /dev/null differ diff --git a/.yarn/cache/browserslist-npm-4.21.4-7d64a96afc-4af3793704.zip b/.yarn/cache/browserslist-npm-4.21.4-7d64a96afc-4af3793704.zip new file mode 100644 index 00000000000..581b52a1802 Binary files /dev/null and b/.yarn/cache/browserslist-npm-4.21.4-7d64a96afc-4af3793704.zip differ diff --git a/.yarn/cache/caniuse-lite-npm-1.0.30001332-48584c6396-e54182ea42.zip b/.yarn/cache/caniuse-lite-npm-1.0.30001332-48584c6396-e54182ea42.zip deleted file mode 100644 index 1303b788c21..00000000000 Binary files a/.yarn/cache/caniuse-lite-npm-1.0.30001332-48584c6396-e54182ea42.zip and /dev/null differ diff --git a/.yarn/cache/caniuse-lite-npm-1.0.30001431-6d607db8ef-bc8ab55cd1.zip b/.yarn/cache/caniuse-lite-npm-1.0.30001431-6d607db8ef-bc8ab55cd1.zip new file mode 100644 index 00000000000..aff5194fcf9 Binary files /dev/null and b/.yarn/cache/caniuse-lite-npm-1.0.30001431-6d607db8ef-bc8ab55cd1.zip differ diff --git a/.yarn/cache/css-what-npm-5.1.0-9991ae71a8-0b75d1bac9.zip b/.yarn/cache/css-what-npm-5.1.0-9991ae71a8-0b75d1bac9.zip new file mode 100644 index 00000000000..e3212a7beb2 Binary files /dev/null and b/.yarn/cache/css-what-npm-5.1.0-9991ae71a8-0b75d1bac9.zip differ diff --git a/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip b/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip deleted file mode 100644 index 7ae813a3909..00000000000 Binary files a/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip and /dev/null differ diff --git a/.yarn/cache/decompress-response-npm-6.0.0-359de2878c-d377cf47e0.zip b/.yarn/cache/decompress-response-npm-6.0.0-359de2878c-d377cf47e0.zip deleted file mode 100644 index bbc1db51877..00000000000 Binary files a/.yarn/cache/decompress-response-npm-6.0.0-359de2878c-d377cf47e0.zip and /dev/null differ diff --git a/.yarn/cache/electron-to-chromium-npm-1.4.121-4fcd7d467a-85be9ff2d5.zip b/.yarn/cache/electron-to-chromium-npm-1.4.121-4fcd7d467a-85be9ff2d5.zip deleted file mode 100644 index 17e6ffeb627..00000000000 Binary files a/.yarn/cache/electron-to-chromium-npm-1.4.121-4fcd7d467a-85be9ff2d5.zip and /dev/null differ diff --git a/.yarn/cache/electron-to-chromium-npm-1.4.284-2fb881a7ac-be496e9dca.zip b/.yarn/cache/electron-to-chromium-npm-1.4.284-2fb881a7ac-be496e9dca.zip new file mode 100644 index 00000000000..e4d02bcdcd8 Binary files /dev/null and b/.yarn/cache/electron-to-chromium-npm-1.4.284-2fb881a7ac-be496e9dca.zip differ diff --git a/.yarn/cache/follow-redirects-npm-1.14.9-522f191631-f5982e0eb4.zip b/.yarn/cache/follow-redirects-npm-1.14.9-522f191631-f5982e0eb4.zip deleted file mode 100644 index 61597430616..00000000000 Binary files a/.yarn/cache/follow-redirects-npm-1.14.9-522f191631-f5982e0eb4.zip and /dev/null differ diff --git a/.yarn/cache/follow-redirects-npm-1.15.2-1ec1dd82be-faa66059b6.zip b/.yarn/cache/follow-redirects-npm-1.15.2-1ec1dd82be-faa66059b6.zip new file mode 100644 index 00000000000..b50d7751a56 Binary files /dev/null and b/.yarn/cache/follow-redirects-npm-1.15.2-1ec1dd82be-faa66059b6.zip differ diff --git a/.yarn/cache/loader-utils-npm-1.4.0-a56254a277-d150b15e7a.zip b/.yarn/cache/loader-utils-npm-1.4.0-a56254a277-d150b15e7a.zip deleted file mode 100644 index c13e2dc4858..00000000000 Binary files a/.yarn/cache/loader-utils-npm-1.4.0-a56254a277-d150b15e7a.zip and /dev/null differ diff --git a/.yarn/cache/loader-utils-npm-2.0.0-cf7d5aadbf-6856423131.zip b/.yarn/cache/loader-utils-npm-2.0.0-cf7d5aadbf-6856423131.zip deleted file mode 100644 index 449a8ac6a65..00000000000 Binary files a/.yarn/cache/loader-utils-npm-2.0.0-cf7d5aadbf-6856423131.zip and /dev/null differ diff --git a/.yarn/cache/loader-utils-npm-2.0.2-c693411911-9078d1ed47.zip b/.yarn/cache/loader-utils-npm-2.0.3-4d761d6a51-d055c61ce5.zip similarity index 84% rename from .yarn/cache/loader-utils-npm-2.0.2-c693411911-9078d1ed47.zip rename to .yarn/cache/loader-utils-npm-2.0.3-4d761d6a51-d055c61ce5.zip index 9a9db60cf69..36be6468156 100644 Binary files a/.yarn/cache/loader-utils-npm-2.0.2-c693411911-9078d1ed47.zip and b/.yarn/cache/loader-utils-npm-2.0.3-4d761d6a51-d055c61ce5.zip differ diff --git a/.yarn/cache/mimic-response-npm-3.1.0-a4a24b4e96-25739fee32.zip b/.yarn/cache/mimic-response-npm-3.1.0-a4a24b4e96-25739fee32.zip deleted file mode 100644 index a47a9a62385..00000000000 Binary files a/.yarn/cache/mimic-response-npm-3.1.0-a4a24b4e96-25739fee32.zip and /dev/null differ diff --git a/.yarn/cache/nanoid-npm-3.3.1-bdd760bee0-4ef0969e1b.zip b/.yarn/cache/nanoid-npm-3.3.1-bdd760bee0-4ef0969e1b.zip new file mode 100644 index 00000000000..6953ccbb060 Binary files /dev/null and b/.yarn/cache/nanoid-npm-3.3.1-bdd760bee0-4ef0969e1b.zip differ diff --git a/.yarn/cache/node-releases-npm-2.0.3-42fb6ecea2-5e555fbbeb.zip b/.yarn/cache/node-releases-npm-2.0.3-42fb6ecea2-5e555fbbeb.zip deleted file mode 100644 index e62f4bde49e..00000000000 Binary files a/.yarn/cache/node-releases-npm-2.0.3-42fb6ecea2-5e555fbbeb.zip and /dev/null differ diff --git a/.yarn/cache/node-releases-npm-2.0.6-8accb3fefb-e86a926dc9.zip b/.yarn/cache/node-releases-npm-2.0.6-8accb3fefb-e86a926dc9.zip new file mode 100644 index 00000000000..7680ef91988 Binary files /dev/null and b/.yarn/cache/node-releases-npm-2.0.6-8accb3fefb-e86a926dc9.zip differ diff --git a/.yarn/cache/nth-check-npm-2.0.1-69558042d2-5386d035c4.zip b/.yarn/cache/nth-check-npm-2.0.1-69558042d2-5386d035c4.zip deleted file mode 100644 index 25527488737..00000000000 Binary files a/.yarn/cache/nth-check-npm-2.0.1-69558042d2-5386d035c4.zip and /dev/null differ diff --git a/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip b/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip new file mode 100644 index 00000000000..dc825e50b87 Binary files /dev/null and b/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip differ diff --git a/.yarn/cache/postcss-npm-7.0.39-0f8737296e-4ac793f506.zip b/.yarn/cache/postcss-npm-7.0.39-0f8737296e-4ac793f506.zip new file mode 100644 index 00000000000..525d4688e4d Binary files /dev/null and b/.yarn/cache/postcss-npm-7.0.39-0f8737296e-4ac793f506.zip differ diff --git a/.yarn/cache/postcss-npm-8.4.17-301c0fb6cf-a6d9096dd7.zip b/.yarn/cache/postcss-npm-8.4.18-f1d73c0a84-9349fd9984.zip similarity index 88% rename from .yarn/cache/postcss-npm-8.4.17-301c0fb6cf-a6d9096dd7.zip rename to .yarn/cache/postcss-npm-8.4.18-f1d73c0a84-9349fd9984.zip index d8d725d76aa..2955faf8c2c 100644 Binary files a/.yarn/cache/postcss-npm-8.4.17-301c0fb6cf-a6d9096dd7.zip and b/.yarn/cache/postcss-npm-8.4.18-f1d73c0a84-9349fd9984.zip differ diff --git a/.yarn/cache/simple-get-npm-3.1.1-dce5923dba-80195e70bf.zip b/.yarn/cache/simple-get-npm-3.1.1-dce5923dba-80195e70bf.zip new file mode 100644 index 00000000000..27c45759e44 Binary files /dev/null and b/.yarn/cache/simple-get-npm-3.1.1-dce5923dba-80195e70bf.zip differ diff --git a/.yarn/cache/simple-get-npm-4.0.1-fa2a97645d-e4132fd27c.zip b/.yarn/cache/simple-get-npm-4.0.1-fa2a97645d-e4132fd27c.zip deleted file mode 100644 index 95cce5fb23c..00000000000 Binary files a/.yarn/cache/simple-get-npm-4.0.1-fa2a97645d-e4132fd27c.zip and /dev/null differ diff --git a/.yarn/cache/terser-npm-4.8.1-16347908cf-b342819bf7.zip b/.yarn/cache/terser-npm-4.8.1-16347908cf-b342819bf7.zip new file mode 100644 index 00000000000..f1a2b061ef9 Binary files /dev/null and b/.yarn/cache/terser-npm-4.8.1-16347908cf-b342819bf7.zip differ diff --git a/.yarn/cache/terser-npm-5.14.2-b0f8815852-cabb50a640.zip b/.yarn/cache/terser-npm-5.14.2-b0f8815852-cabb50a640.zip deleted file mode 100644 index 237567439db..00000000000 Binary files a/.yarn/cache/terser-npm-5.14.2-b0f8815852-cabb50a640.zip and /dev/null differ diff --git a/.yarn/cache/terser-npm-5.15.1-63dec1247d-9880a1e095.zip b/.yarn/cache/terser-npm-5.15.1-63dec1247d-9880a1e095.zip new file mode 100644 index 00000000000..79fc04282b5 Binary files /dev/null and b/.yarn/cache/terser-npm-5.15.1-63dec1247d-9880a1e095.zip differ diff --git a/.yarn/cache/update-browserslist-db-npm-1.0.10-676baf0b9f-12db73b4f6.zip b/.yarn/cache/update-browserslist-db-npm-1.0.10-676baf0b9f-12db73b4f6.zip new file mode 100644 index 00000000000..b964a1a691a Binary files /dev/null and b/.yarn/cache/update-browserslist-db-npm-1.0.10-676baf0b9f-12db73b4f6.zip differ diff --git a/.yarn/cache/winston-npm-3.7.2-5336ad5eff-f1f1a860d2.zip b/.yarn/cache/winston-npm-3.7.2-5336ad5eff-f1f1a860d2.zip deleted file mode 100644 index 74ffcbc474f..00000000000 Binary files a/.yarn/cache/winston-npm-3.7.2-5336ad5eff-f1f1a860d2.zip and /dev/null differ diff --git a/.yarn/cache/winston-npm-3.8.2-2035e9cac4-f7b901798b.zip b/.yarn/cache/winston-npm-3.8.2-2035e9cac4-f7b901798b.zip new file mode 100644 index 00000000000..d5fc6900504 Binary files /dev/null and b/.yarn/cache/winston-npm-3.8.2-2035e9cac4-f7b901798b.zip differ diff --git a/.yarn/cache/winston-patch-745d73b4ce-29e1caa1c2.zip b/.yarn/cache/winston-patch-745d73b4ce-29e1caa1c2.zip new file mode 100644 index 00000000000..3c974820cb2 Binary files /dev/null and b/.yarn/cache/winston-patch-745d73b4ce-29e1caa1c2.zip differ diff --git a/README.md b/README.md index d367bc100bc..a5b1574852d 100644 --- a/README.md +++ b/README.md @@ -237,8 +237,9 @@ Services with variants can't be accessed using the format above, instead the var Topic pages use internal BBC APIs that are not publicly accessible. This can cause the following warnings to appear when developing locally: -envConfig/secret.env: No such file or directory -You will not have access to topics +``` +No BFF_PATH set as environment variable, you will not have access to topics +``` Internal developers who need to work on topic pages locally should contact the team for access. diff --git a/data/pidgin/articles/c8pd7gx243po.json b/data/pidgin/articles/c8pd7gx243po.json new file mode 100644 index 00000000000..923ce16cc22 --- /dev/null +++ b/data/pidgin/articles/c8pd7gx243po.json @@ -0,0 +1,504 @@ +{ + "metadata": { + "id": "urn:bbc:ares::article:c8pd7gx243po", + "locators": { + "optimoUrn": "urn:bbc:optimo:asset:c8pd7gx243po", + "canonicalUrl": "https://www.bbc.com/pidgin/articles/c8pd7gx243po" + }, + "type": "article", + "createdBy": "Pidgin", + "language": "pcm", + "lastUpdated": 1666708800881, + "firstPublished": 1666706395827, + "lastPublished": 1666707859180, + "timestamp": 1666707859180, + "options": {}, + "analyticsLabels": { + "contentId": "urn:bbc:optimo:asset:c8pd7gx243po", + "producer": "Pidgin", + "page": "pidgin.articles.c8pd7gx243po.page" + }, + "passport": { + "language": "pcm", + "home": "http://www.bbc.co.uk/ontologies/passport/home/Pidgin", + "locator": "urn:bbc:optimo:asset:c8pd7gx243po", + "availability": "AVAILABLE", + "taggings": [ + { + "predicate": "http://www.bbc.co.uk/ontologies/bbc/infoClass", + "value": "http://www.bbc.co.uk/things/0db2b959-cbf8-4661-965f-050974a69bb5#id" + } + ], + "schemaVersion": "1.4.0", + "publishedState": "PUBLISHED", + "predicates": { + "infoClass": [ + { + "value": "http://www.bbc.co.uk/things/0db2b959-cbf8-4661-965f-050974a69bb5#id", + "type": "infoClass" + } + ] + } + }, + "tags": {}, + "version": "v1.4.8", + "blockTypes": [ + "headline", + "text", + "paragraph", + "fragment", + "subheadline", + "social", + "renditions", + "aresOEmbed" + ], + "suitableForSyndication": true, + "readTime": 1, + "consumableAsSFV": false, + "allowAdvertising": true, + "consumableOnlyOnRedButton": false + }, + "content": { + "model": { + "blocks": [ + { + "type": "headline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Multiple Facebook Post Embed Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Multiple Facebook Post Embed Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "subheadline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "First Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "First Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "social", + "model": { + "source": "https://www.facebook.com/10downingstreet/posts/pfbid02EQPqk1y8kffBd1cdrPFmzs4RrVnw52Fkd9ufCsz11akAymrbHq1Ug6huD88nGjoml", + "providerName": "Facebook", + "blocks": [ + { + "type": "renditions", + "model": { + "locator": "urn:bbc:optimo:social:8cd62b89-8458-44b3-b1ca-6059c6873246", + "blocks": [ + { + "type": "aresOEmbed", + "model": { + "oembed": { + "version": "1.0", + "author_name": "UK Prime Minister", + "author_url": "https://www.facebook.com/10downingstreet", + "provider_name": "Facebook", + "provider_url": "https://www.facebook.com", + "html": "
Posted by UK Prime Minister on Tuesday, October 25, 2022
", + "width": 552 + } + } + } + ] + } + } + ] + } + }, + { + "type": "subheadline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Second Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Second Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "social", + "model": { + "source": "https://www.facebook.com/10downingstreet/posts/pfbid0MCXxKS4pqCmDK7QxtRTCG7XmY6eByLu41yf3ipE6gMN8LJRtaSWreLmUH9ZBUoMdl", + "providerName": "Facebook", + "blocks": [ + { + "type": "renditions", + "model": { + "locator": "urn:bbc:optimo:social:ac8c3828-9f4f-4821-b693-f40316fe9cce", + "blocks": [ + { + "type": "aresOEmbed", + "model": { + "oembed": { + "version": "1.0", + "author_name": "UK Prime Minister", + "author_url": "https://www.facebook.com/10downingstreet", + "provider_name": "Facebook", + "provider_url": "https://www.facebook.com", + "html": "
Posted by UK Prime Minister on Tuesday, October 25, 2022
", + "width": 552 + } + } + } + ] + } + } + ] + } + }, + { + "type": "subheadline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Third Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Third Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "social", + "model": { + "source": "https://www.youtube.com/watch?v=b_nZICOtzfI", + "providerName": "YouTube", + "blocks": [ + { + "type": "renditions", + "model": { + "locator": "urn:bbc:optimo:social:72503997-9ab6-4a02-856e-cc2f7cfded59", + "blocks": [ + { + "type": "aresOEmbed", + "model": { + "oembed": { + "version": "1.0", + "title": "India's top court judges split on the hijab in classrooms – BBC News", + "author_name": "BBC News", + "author_url": "https://www.youtube.com/c/BBCNews", + "provider_name": "YouTube", + "provider_url": "https://www.youtube.com/", + "thumbnail_url": "https://i.ytimg.com/vi/b_nZICOtzfI/hqdefault.jpg", + "thumbnail_width": 480, + "thumbnail_height": 360, + "html": "", + "width": 200, + "height": 113 + } + } + } + ] + } + } + ] + } + }, + { + "type": "subheadline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Fourth Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Fourth Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "social", + "model": { + "source": "https://www.tiktok.com/@cuppymusic/video/7086167423639997701", + "providerName": "TikTok", + "blocks": [ + { + "type": "renditions", + "model": { + "locator": "urn:bbc:optimo:social:5af67a78-54ec-4711-817d-15aaf393e900", + "blocks": [ + { + "type": "aresOEmbed", + "model": { + "oembed": { + "version": "1.0", + "title": "Cupcakes, You don watch my full interview for BBC Pidgin? How you see am? 🙊💖✨#BBCPidgin #CuppyOnAMission #CuppyxBBC", + "author_name": "Cuppy", + "author_url": "https://www.tiktok.com/@cuppymusic", + "provider_name": "TikTok", + "provider_url": "https://www.tiktok.com", + "thumbnail_url": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/328e9247ec2746b8992d5fcdde75affa_1649876928?x-expires=1666728000&x-signature=myBGnNBQ80H6rfzzi16h4OMMlwk%3D", + "thumbnail_width": 576, + "thumbnail_height": 1024, + "html": "
@cuppymusic

Cupcakes, You don watch my full interview for BBC Pidgin? How you see am? 🙊💖✨#BBCPidgin #CuppyOnAMission #CuppyxBBC

♬ original sound - Cuppy
" + } + } + } + ] + } + } + ] + } + }, + { + "type": "subheadline", + "model": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Fifth Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Fifth Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "type": "social", + "model": { + "source": "https://www.instagram.com/p/CiK2qRqtmjA/?utm_source=ig_web_copy_link", + "providerName": "Instagram", + "blocks": [ + { + "type": "renditions", + "model": { + "locator": "urn:bbc:optimo:social:74bf1d97-a4f1-43ea-8467-47c1e25826cb", + "blocks": [ + { + "type": "aresOEmbed", + "model": { + "oembed": { + "version": "1.0", + "author_name": "bbc6music", + "provider_name": "Instagram", + "provider_url": "https://www.instagram.com/", + "thumbnail_url": "https://scontent.cdninstagram.com/v/t51.2885-15/305114878_5408824352567542_9080036515091428792_n.jpg?stp=dst-jpg_e35_s640x640_sh0.08&_nc_ht=scontent.cdninstagram.com&_nc_cat=110&_nc_ohc=AcVlwsq5xK0AX85SsHD&edm=AMO9-JQAAAAA&ccb=7-5&oh=00_AT8efoKsBbbOr35Ct554efjuG5bj0HcQTs2Gob2WUtu9qA&oe=635872A4&_nc_sid=b9f2ee", + "thumbnail_width": 640, + "thumbnail_height": 640, + "html": "
View this post on Instagram

A post shared by BBC Radio 6 Music (@bbc6music)

", + "width": 658 + } + } + } + ] + } + } + ] + } + } + ] + } + }, + "promo": { + "locators": { + "optimoUrn": "urn:bbc:optimo:asset:c8pd7gx243po", + "canonicalUrl": "https://www.bbc.com/pidgin/articles/c8pd7gx243po" + }, + "timestamp": 1666707859180, + "suitableForSyndication": true, + "language": "pcm", + "headlines": { + "seoHeadline": "Single Facebook Post Video Embed Test", + "promoHeadline": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "Multiple Facebook Post Embed Test", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "Multiple Facebook Post Embed Test", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + } + }, + "images": {}, + "summary": { + "blocks": [ + { + "type": "text", + "model": { + "blocks": [ + { + "type": "paragraph", + "model": { + "text": "", + "blocks": [ + { + "type": "fragment", + "model": { + "text": "", + "attributes": [] + } + } + ] + } + } + ] + } + } + ] + }, + "passport": { + "language": "pcm", + "home": "http://www.bbc.co.uk/ontologies/passport/home/Pidgin", + "locator": "urn:bbc:optimo:asset:c8pd7gx243po", + "availability": "AVAILABLE", + "taggings": [ + { + "predicate": "http://www.bbc.co.uk/ontologies/bbc/infoClass", + "value": "http://www.bbc.co.uk/things/0db2b959-cbf8-4661-965f-050974a69bb5#id" + } + ], + "schemaVersion": "1.4.0", + "publishedState": "PUBLISHED", + "predicates": { + "infoClass": [ + { + "value": "http://www.bbc.co.uk/things/0db2b959-cbf8-4661-965f-050974a69bb5#id", + "type": "infoClass" + } + ] + } + }, + "id": "urn:bbc:ares::article:c8pd7gx243po", + "type": "optimo" + }, + "relatedContent": { + "site": { + "subType": "site", + "name": "Pidgin", + "uri": "/pidgin", + "type": "simple" + }, + "groups": [] + } +} diff --git a/package.json b/package.json index 2abce64f2fb..8b7903d2c3f 100644 --- a/package.json +++ b/package.json @@ -14,28 +14,12 @@ "@emotion/sheet": "1.2.0", "@emotion/utils": "1.2.0", "@optimizely/js-sdk-utils": "0.4.0", - "ansi-html": "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "ansi-regex": "5.0.1", - "browserslist": "4.20.3", - "css-what": "6.1.0", - "follow-redirects": "1.14.9", "glob-parent": "6.0.2", - "immer": "9.0.15", - "json-schema": "0.4.0", - "nanoid": "3.3.4", - "node-fetch": "2.6.7", - "node-forge": "1.3.1", - "nth-check": "2.0.1", - "postcss": "8.4.17", "prismjs": "1.28.0", "react-is": "17.0.2", - "simple-get": "4.0.1", "trim": "1.0.1", - "minimist": "1.2.7", - "async": "3.2.4", - "terser": "5.14.2", - "moment": "2.29.4", - "@testing-library/dom": "8.16.1" + "loader-utils": "2.0.3", + "winston@3.8.2": "patch:winston@npm:3.8.2#.yarn/patches/winston-npm-3.8.2-2035e9cac4.patch" }, "scripts": { "type-check": "tsc", @@ -52,13 +36,13 @@ "cypress:interactive": "cypress open", "cypress:3rdParty": "yarn cypress -- --project ./3rdPartyCypress/.", "cypress:adhoc": "yarn cypress:interactive -- --project ./AdHocCypress/.", - "setupDevEnv": "cp envConfig/local.env .env && cat envConfig/secret.env >> .env || echo 'You will not have access to topics'", + "setupDevEnv": "cp envConfig/local.env .env && rm -rf envConfig/secret.env && ./scripts/checkSecretEnvVariables.sh", "dev": "yarn setupDevEnv && rm -rf build && run-p webpack:dev:client webpack:dev:server", "lighthouse": "./scripts/lighthouseRun.sh", "postshrinkwrap": "test -z $CI && ./scripts/packagelockHttps.sh; git update-index --assume-unchanged .env", "prepare": "husky install", "preinstall": "node scripts/check-package-manager.js", - "start": "NODE_ENV=production node build/server.js", + "start": "NODE_ENV=production node --max-old-space-size=3500 build/server.js", "stop": "./scripts/killApp.sh", "storybook": "node .storybook/buildFontPreloads && start-storybook -p 9001 -s .storybook/static -c .storybook", "test": "yarn build && yarn test:local", @@ -134,7 +118,7 @@ "react-router-dom": "5.3.4", "url-parse": "1.5.10", "uuid": "8.3.2", - "winston": "3.7.2", + "winston": "patch:winston@3.8.2#./patches/winston-file-descriptor.patch", "xmldoc": "1.1.2" }, "devDependencies": { diff --git a/patches/winston-file-descriptor.patch b/patches/winston-file-descriptor.patch new file mode 100644 index 00000000000..54223137b81 --- /dev/null +++ b/patches/winston-file-descriptor.patch @@ -0,0 +1,48 @@ +diff --git a/lib/winston/transports/file.js b/lib/winston/transports/file.js +index 60af7f5806f7de9dafcdb88bbcc215e426c879b9..2802601ad73b24aabe966de652d17dae40d61b95 100644 +--- a/lib/winston/transports/file.js ++++ b/lib/winston/transports/file.js +@@ -89,6 +89,11 @@ module.exports = class File extends TransportStream { + this._opening = false; + this._ending = false; + ++ // https://github.com/winstonjs/winston/issues/2100 ++ // Array to collect write streams created in this transport ++ // for destruction later ++ this._writeStreams = []; ++ + if (this.dirname) this._createLogDirIfNotExist(this.dirname); + this.open(); + } +@@ -400,6 +405,13 @@ module.exports = class File extends TransportStream { + debug('stat done: %s { size: %s }', this.filename, size); + this._size = size; + this._dest = this._createStream(this._stream); ++ ++ // https://github.com/winstonjs/winston/issues/2100 ++ // Collect the write stream created here - at some point a new stream is created and assigned to ++ // this._dest before _this.cleanupStream is called; this ensures we collect all streams we need to ++ // cleanup to prevent a file descriptor leak. ++ this._writeStreams.push(this._dest); ++ + this._opening = false; + this.once('open', () => { + if (this._stream.eventNames().includes('rotate')) { +@@ -502,7 +514,16 @@ module.exports = class File extends TransportStream { + */ + _cleanupStream(stream) { + stream.removeListener('error', this._onError); +- ++ ++ // https://github.com/winstonjs/winston/issues/2100 ++ // In testing it was found more than one stream is created beyond the one passed to this function; ++ // this logic ensures any streams are destroyed to prevent a file descriptor leak - ++ // the cause of additional stream is still unknown ++ let streamToClose = this._writeStreams.pop(); ++ while (streamToClose) { ++ streamToClose.destroy(); ++ streamToClose = this._writeStreams.pop(); ++ } + return stream; + } + diff --git a/scripts/checkSecretEnvVariables.sh b/scripts/checkSecretEnvVariables.sh new file mode 100755 index 00000000000..cc5081bf3f1 --- /dev/null +++ b/scripts/checkSecretEnvVariables.sh @@ -0,0 +1,3 @@ +if [ -z "$BFF_PATH" ]; then + echo No BFF_PATH set as environment variable, you will not have access to topics; +fi diff --git a/src/app/components/EmbedConsentBanner/ConsentBanner.styles.tsx b/src/app/components/EmbedConsentBanner/ConsentBanner.styles.tsx index f2f5439757d..a1b3a9dd1ce 100644 --- a/src/app/components/EmbedConsentBanner/ConsentBanner.styles.tsx +++ b/src/app/components/EmbedConsentBanner/ConsentBanner.styles.tsx @@ -6,7 +6,6 @@ export default { css({ backgroundColor: palette.WHITE, padding: `${pixelsToRem(16)}rem`, - minHeight: 280, display: 'flex', flexDirection: 'column', justifyContent: 'center', diff --git a/src/app/components/EmbedConsentBanner/ConsentBanner.tsx b/src/app/components/EmbedConsentBanner/ConsentBanner.tsx index 79f2e6186f7..183fdb01817 100644 --- a/src/app/components/EmbedConsentBanner/ConsentBanner.tsx +++ b/src/app/components/EmbedConsentBanner/ConsentBanner.tsx @@ -6,17 +6,22 @@ import pathOr from 'ramda/src/pathOr'; import Text from '../Text'; import Paragraph from '../Paragraph'; import { ServiceContext } from '../../contexts/ServiceContext'; -import useViewTracker from '../../hooks/useViewTracker'; -import { SocialEmbedProviders } from '../../models/types/global'; import { Translations } from '../../models/types/translations'; +import useViewTracker from '../../hooks/useViewTracker'; import consentBannerCss from './ConsentBanner.styles'; import { ConsentBannerProviders, getEventTrackingData } from '.'; -const defaultTranslations: Translations['socialEmbed']['consentBanner'] = { - heading: 'Allow [social_media_site] content?', - body: `This article contains content provided by [social_media_site]. We ask for your permission before anything is loaded, as they may be using cookies and other technologies. You may want to read [social_media_site] [link] cookie policy [/link] and [link] privacy policy [/link] before accepting. To view this content choose 'accept and continue'.`, - button: 'Accept and continue', +type BannerUrls = { + cookiesUrl: { + [key in ConsentBannerProviders]: string; + }; + privacyUrl: { + [key in ConsentBannerProviders]: string; + }; +}; + +const BANNER_URLS: BannerUrls = { cookiesUrl: { youtube: 'https://policies.google.com/technologies/cookies', tiktok: 'https://www.tiktok.com/legal/cookie-policy', @@ -27,12 +32,15 @@ const defaultTranslations: Translations['socialEmbed']['consentBanner'] = { }, }; -const getProviderName = (provider: SocialEmbedProviders) => { +const DEFAULT_TRANSLATIONS: Translations['socialEmbed']['consentBanner'] = { + heading: 'Allow [social_media_site] content?', + body: `This article contains content provided by [social_media_site]. We ask for your permission before anything is loaded, as they may be using cookies and other technologies. You may want to read [social_media_site] [link] cookie policy [/link] and [link] privacy policy [/link] before accepting. To view this content choose 'accept and continue'.`, + button: 'Accept and continue', +}; + +const getProviderName = (provider: ConsentBannerProviders) => { return { - instagram: 'Instagram', - twitter: 'Twitter', youtube: 'Google YouTube', - facebook: 'Facebook', tiktok: 'TikTok', }[provider]; }; @@ -43,35 +51,23 @@ const getTranslations = ( externalLinkText: string, ) => { const headingTranslations = pathOr( - defaultTranslations.heading, + DEFAULT_TRANSLATIONS.heading, ['socialEmbed', 'consentBanner', 'heading'], translations, ); const bodyTranslations = pathOr( - defaultTranslations.body, + DEFAULT_TRANSLATIONS.body, ['socialEmbed', 'consentBanner', 'body'], translations, ); const buttonTranslations = pathOr( - defaultTranslations.button, + DEFAULT_TRANSLATIONS.button, ['socialEmbed', 'consentBanner', 'button'], translations, ); - const cookiesUrl = pathOr( - defaultTranslations.cookiesUrl[provider], - ['socialEmbed', 'consentBanner', 'cookiesUrl', provider], - translations, - ); - - const privacyUrl = pathOr( - defaultTranslations.privacyUrl[provider], - ['socialEmbed', 'consentBanner', 'privacyUrl', provider], - translations, - ); - const providerName = getProviderName(provider); const providerNameDelimiter = '[social_media_site]'; @@ -96,6 +92,9 @@ const getTranslations = ( }; } + const cookiesUrl = BANNER_URLS.cookiesUrl?.[provider]; + const privacyUrl = BANNER_URLS.privacyUrl?.[provider]; + const linkHtmlElements = [ linkTextElements.length > 0 && cookiesUrl && ( { }; export default { - title: 'NewComponents/Heading', + title: 'New Components/Heading', Component: HeadingStory, decorators: [withKnobs, withServicesKnob()], parameters: { diff --git a/src/app/components/InlineLink/index.stories.tsx b/src/app/components/InlineLink/index.stories.tsx index 2cbde4e4c07..08f972f65a2 100644 --- a/src/app/components/InlineLink/index.stories.tsx +++ b/src/app/components/InlineLink/index.stories.tsx @@ -76,7 +76,7 @@ export const InlineLinkInsideText = ({ }; export default { - title: 'NewComponents/InlineLink', + title: 'New Components/InlineLink', Component: InternalInlineLink, decorators: [withKnobs, withServicesKnob()], parameters: { diff --git a/src/app/components/Paragraph/index.stories.tsx b/src/app/components/Paragraph/index.stories.tsx index 0a3dceb20c0..a4e906c119e 100644 --- a/src/app/components/Paragraph/index.stories.tsx +++ b/src/app/components/Paragraph/index.stories.tsx @@ -74,7 +74,7 @@ const ParagraphStory = ({ service, variant, text }: Props) => { }; export default { - title: 'NewComponents/Paragraph', + title: 'New Components/Paragraph', Component: ParagraphStory, decorators: [withKnobs, withServicesKnob()], parameters: { diff --git a/src/app/components/Text/index.stories.tsx b/src/app/components/Text/index.stories.tsx index 6c9b5e413e2..9dbbfd834d7 100644 --- a/src/app/components/Text/index.stories.tsx +++ b/src/app/components/Text/index.stories.tsx @@ -75,7 +75,7 @@ const TextStory = ({ service, variant, text }: Props) => { }; export default { - title: 'NewComponents/Text', + title: 'New Components/Text', Component: TextStory, decorators: [withKnobs, withServicesKnob()], parameters: { diff --git a/src/app/legacy/components/Promo/media-icon.jsx b/src/app/legacy/components/Promo/media-icon.jsx index 9f0a39e0c63..75db6247eb4 100644 --- a/src/app/legacy/components/Promo/media-icon.jsx +++ b/src/app/legacy/components/Promo/media-icon.jsx @@ -39,9 +39,9 @@ const formatChildren = children => { }; const MediaIcon = ({ script, service, children, type }) => { - if (!type) return null; + if (!type || !mediaIcons[type]) return null; return ( - + diff --git a/src/app/legacy/containers/PageHandlers/withRUM/index.jsx b/src/app/legacy/containers/PageHandlers/withRUM/index.jsx index 7d4cd4eeb48..5a6c3447ebd 100644 --- a/src/app/legacy/containers/PageHandlers/withRUM/index.jsx +++ b/src/app/legacy/containers/PageHandlers/withRUM/index.jsx @@ -1,6 +1,7 @@ import React from 'react'; import { Helmet } from 'react-helmet'; import isLive from '#lib/utilities/isLive'; +import useOperaMiniDetection from '../../../../hooks/useOperaMiniDetection'; // Note - if changing one of these constants, the other will also need to change // See https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity @@ -63,12 +64,19 @@ const RUMLoader = Component => { 'arn:aws:iam::923061562593:role/RUM-Monitor-eu-west-1-923061562593-2635993079561-Unauth', }; - return ( - <> - {buildScript(isLive() ? liveConfig : testConfig)} - - - ); + const ComponentWithRum = () => { + const isOperaMini = useOperaMiniDetection(); + const scriptElement = buildScript(isLive() ? liveConfig : testConfig); + + return ( + <> + {!isOperaMini ? scriptElement : null} + + + ); + }; + + return ; }; return withRum; diff --git a/src/app/legacy/containers/PageHandlers/withRUM/index.test.jsx b/src/app/legacy/containers/PageHandlers/withRUM/index.test.jsx new file mode 100644 index 00000000000..bf59d5f93f8 --- /dev/null +++ b/src/app/legacy/containers/PageHandlers/withRUM/index.test.jsx @@ -0,0 +1,19 @@ +import React from 'react'; +import withRUM from '#containers/PageHandlers/withRUM'; +import { render, waitFor } from '@testing-library/react'; + +describe('withRum', () => { + const Component = () =>

test

; + const RumHoc = withRUM(Component); + + it('should add RUM on canonical', async () => { + render(); + await waitFor(() => { + const scriptEl = document.querySelector('script'); + expect(scriptEl).toBeInTheDocument(); + expect(scriptEl.src).toEqual( + 'https://client.rum.us-east-1.amazonaws.com/1.2.1/cwr.js', + ); + }); + }); +}); diff --git a/src/app/legacy/containers/SocialEmbed/Cps/__snapshots__/index.test.jsx.snap b/src/app/legacy/containers/SocialEmbed/Cps/__snapshots__/index.test.jsx.snap index 4150ca43578..8326e0e91f1 100644 --- a/src/app/legacy/containers/SocialEmbed/Cps/__snapshots__/index.test.jsx.snap +++ b/src/app/legacy/containers/SocialEmbed/Cps/__snapshots__/index.test.jsx.snap @@ -710,7 +710,9 @@ exports[`CpsSocialEmbedContainer Canonical should render correctly without an em
-

+

Content is not available

`; +exports[`SocialEmbedContainer Canonical should render a Facebook Post block and unmount correctly 1`] = ` +@media (max-width: 14.9375rem) { + .emotion-0 { + padding: 0 0.5rem; + margin-left: 0%; + } +} + +@media (min-width: 15rem) and (max-width: 24.9375rem) { + .emotion-0 { + padding: 0 0.5rem; + margin-left: 0%; + } +} + +@media (min-width: 25rem) and (max-width: 37.4375rem) { + .emotion-0 { + padding: 0 1rem; + margin-left: 0%; + } +} + +@media (min-width: 37.5rem) and (max-width: 62.9375rem) { + .emotion-0 { + padding: 0 1rem; + margin-left: 0%; + } +} + +@media (min-width: 63rem) and (max-width: 79.9375rem) { + .emotion-0 { + margin-left: 20%; + } +} + +@media (min-width: 80rem) { + .emotion-0 { + margin-left: 40%; + } +} + +@supports (display: grid) { + .emotion-0 { + display: block; + width: initial; + margin: 0; + } + + @media (max-width: 14.9375rem) { + .emotion-0 { + grid-template-columns: repeat(6, 1fr); + grid-column-end: span 6; + padding: 0 0.5rem; + grid-column-start: 1; + } + } + + @media (min-width: 15rem) and (max-width: 24.9375rem) { + .emotion-0 { + grid-template-columns: repeat(6, 1fr); + grid-column-end: span 6; + padding: 0 0.5rem; + grid-column-start: 1; + } + } + + @media (min-width: 25rem) and (max-width: 37.4375rem) { + .emotion-0 { + grid-template-columns: repeat(6, 1fr); + grid-column-end: span 6; + padding: 0 1rem; + grid-column-start: 1; + } + } + + @media (min-width: 37.5rem) and (max-width: 62.9375rem) { + .emotion-0 { + grid-template-columns: repeat(5, 1fr); + grid-column-end: span 5; + padding: 0 1rem; + grid-column-start: 1; + } + } + + @media (min-width: 63rem) and (max-width: 79.9375rem) { + .emotion-0 { + grid-template-columns: repeat(5, 1fr); + grid-column-end: span 5; + grid-column-start: 2; + } + } + + @media (min-width: 80rem) { + .emotion-0 { + grid-template-columns: repeat(10, 1fr); + grid-column-end: span 10; + grid-column-start: 5; + } + } +} + +.emotion-2 { + margin-bottom: 1.5rem; + max-width: 31.25rem; + min-height: 14rem; +} + +.emotion-4 { + position: relative; +} + +.emotion-6 { + font-family: ReithSans,Helvetica,Arial,sans-serif; + font-weight: 400; + font-style: normal; + font-size: 0.875rem; + line-height: 1rem; + background-color: #FFFFFF; + border: 0.125rem solid #222222; + display: block; + left: 0; + line-height: 1; + padding: 0.75rem; + position: absolute; + -webkit-text-decoration: none; + text-decoration: none; + top: 0; + z-index: 10; +} + +@media (min-width: 20rem) and (max-width: 37.4375rem) { + .emotion-6 { + line-height: 1.125rem; + } +} + +@media (min-width: 37.5rem) { + .emotion-6 { + font-size: 0.8125rem; + } +} + +.emotion-6 span { + color: #222222; +} + +.emotion-6:hover span, +.emotion-6:focus span { + color: #B80000; + border-bottom: 2px solid #B80000; +} + +.emotion-6:not(:focus):not(:active) { + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + clip: rect(1px, 1px, 1px, 1px); + height: 1px; + overflow: hidden; + position: absolute; + width: 1px; + margin: 0; +} + +.emotion-8 { + margin: 0; + background-color: transparent; +} + +.emotion-10 { + position: relative; + overflow: hidden; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; +} + +.emotion-10 .fb_iframe_widget { + position: unset; +} + +.emotion-10 .fb_iframe_widget>span { + position: unset; +} + +.emotion-10 iframe { + background-color: white; + left: 0; + top: 0; + height: 100%!important; + width: 100%!important; + position: absolute!important; +} + +.emotion-12 { + font-family: ReithSans,Helvetica,Arial,sans-serif; + font-weight: 400; + font-style: normal; + font-size: 0.875rem; + line-height: 1rem; + color: #545658; + padding: 0.5rem 0; +} + +@media (min-width: 20rem) and (max-width: 37.4375rem) { + .emotion-12 { + line-height: 1.125rem; + } +} + +@media (min-width: 37.5rem) { + .emotion-12 { + font-size: 0.8125rem; + } +} + +.emotion-12>span { + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + clip: rect(1px, 1px, 1px, 1px); + height: 1px; + overflow: hidden; + position: absolute; + width: 1px; + margin: 0; +} + +.emotion-14 { + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + clip: rect(1px, 1px, 1px, 1px); + height: 1px; + overflow: hidden; + position: absolute; + width: 1px; + margin: 0; +} + +
+
+
+ + + Skip Facebook content + + +
+
+
+ + +

Had a fantastic time at @thescriptofficial concert in LA this week, what a gig!! Have a great US tour guys! Don’t miss...

Posted by Rick Astley on Friday, April 1, 2022
', + type: 'rich', + version: '1.0', + width: 552, + }, + }, + }, + ], + }, +}; + +export const facebookVideoBlockEmbed = { + type: 'renditions', + model: { + locator: 'urn:bbc:optimo:social:d4ae3e6f-51cf-4899-bbd4-16d14882cbc7', + blocks: [ + { + type: 'aresOEmbed', + model: { + oembed: { + author_name: 'Rick Astley', + author_url: 'https://www.facebook.com/RickAstley', + provider_url: 'https://www.facebook.com', + provider_name: 'Facebook', + height: 888, + html: '
\n

Saw another great gig in LA this week, I went to see Inhaler in the @belascola and they were fantastic! Have a great show in New York tomorrow guys! Rick x @inhalerdublin

Posted by Rick Astley on Saturday, April 2, 2022
', + type: 'video', + version: '1.0', + width: 500, + }, + }, + }, + ], + }, +}; diff --git a/src/app/legacy/containers/SocialEmbed/index.jsx b/src/app/legacy/containers/SocialEmbed/index.jsx index 3e1f3b9e538..a02a90f44cc 100644 --- a/src/app/legacy/containers/SocialEmbed/index.jsx +++ b/src/app/legacy/containers/SocialEmbed/index.jsx @@ -6,7 +6,6 @@ import { AmpSocialEmbed, CanonicalSocialEmbed, } from '#psammead/psammead-social-embed/src'; -import isLive from '#lib/utilities/isLive'; import { RequestContext } from '#contexts/RequestContext'; import { GridItemMedium } from '#components/Grid'; @@ -28,9 +27,6 @@ const SocialEmbedContainer = ({ blocks, source }) => { const { model } = blocks[0]; const provider = getProviderFromSource(source); - // TODO: Remove once TikTok is allowed to go on Live - if (provider === 'tiktok' && isLive()) return null; - const id = getIdFromSource(source); const oEmbed = path(['blocks', 0, 'model', 'oembed'], model); @@ -76,6 +72,7 @@ const SocialEmbedContainer = ({ blocks, source }) => { fallback={fallback} skipLink={skipLink} caption={caption} + source={source} /> ) : ( diff --git a/src/app/legacy/containers/SocialEmbed/index.stories.jsx b/src/app/legacy/containers/SocialEmbed/index.stories.jsx index d67e5f54f26..8ec052c0189 100644 --- a/src/app/legacy/containers/SocialEmbed/index.stories.jsx +++ b/src/app/legacy/containers/SocialEmbed/index.stories.jsx @@ -14,6 +14,8 @@ import { instagramBlockNoEmbed, youtubeBlockEmbed, tiktokBlockEmbed, + facebookPostBlockEmbed, + facebookVideoBlockEmbed, } from './common/fixtures'; import OptimoSocialEmbedContainer from '.'; import withContexts from './common/testHelper'; @@ -123,3 +125,39 @@ export const YoutubeWithConsentBannerAmp = props => ( /> ); YoutubeWithConsentBannerAmp.decorators = [AmpDecorator]; + +export const FacebookPostCanonicalExample = props => ( + +); + +export const FacebookPostAmpExample = props => ( + +); +FacebookPostAmpExample.decorators = [AmpDecorator]; + +export const FacebookVideoCanonicalExample = props => ( + +); + +export const FacebookVideoAmpExample = props => ( + +); +FacebookVideoAmpExample.decorators = [AmpDecorator]; diff --git a/src/app/legacy/containers/SocialEmbed/index.test.jsx b/src/app/legacy/containers/SocialEmbed/index.test.jsx index 05001bedadc..0acc737c105 100644 --- a/src/app/legacy/containers/SocialEmbed/index.test.jsx +++ b/src/app/legacy/containers/SocialEmbed/index.test.jsx @@ -13,6 +13,8 @@ import { instagramBlock, youtubeBlockEmbed, tiktokBlockEmbed, + facebookPostBlockEmbed, + facebookVideoBlockEmbed, } from './common/fixtures'; /* eslint-disable react/prop-types */ @@ -122,6 +124,62 @@ describe('SocialEmbedContainer', () => { unmount(); }); + it('should render a Facebook Post block and unmount correctly', () => { + const { container, unmount } = render( + , + { service: 'news', isAmp: false, pageType: ARTICLE_PAGE }, + ); + + expect(container.firstChild).toMatchSnapshot(); + expect( + document.querySelector( + 'head script[src="https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v15.0"]', + ), + ).toBeTruthy(); + expect(loggerMock.info).toHaveBeenCalledTimes(1); + expect(loggerMock.info).toHaveBeenCalledWith(SOCIAL_EMBED_RENDERED, { + provider: 'facebook', + href: 'https://www.facebook.com/RickAstley/posts/545713756920775', + }); + unmount(); + expect( + document.querySelector( + 'head script[src="https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v15.0"]', + ), + ).toBeFalsy(); + }); + + it('should render a Facebook Video block and unmount correctly', () => { + const { container, unmount } = render( + , + { service: 'news', isAmp: false, pageType: ARTICLE_PAGE }, + ); + + expect(container.firstChild).toMatchSnapshot(); + expect( + document.querySelector( + 'head script[src="https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v15.0"]', + ), + ).toBeTruthy(); + expect(loggerMock.info).toHaveBeenCalledTimes(1); + expect(loggerMock.info).toHaveBeenCalledWith(SOCIAL_EMBED_RENDERED, { + provider: 'facebook', + href: 'https://www.facebook.com/RickAstley/videos/1378590239249667', + }); + unmount(); + expect( + document.querySelector( + 'head script[src="https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v15.0"]', + ), + ).toBeFalsy(); + }); + it('should render the correct skip link text when indexOfType is provided (means this is one of multiple e.g. Twitter embeds in the article)', () => { render( { if (source.match(/^https:\/\/www\.tiktok\.com/)) { return PROVIDERS.TIKTOK; } + if (source.match(/^https:\/\/www\.facebook\.com/)) { + return PROVIDERS.FACEBOOK; + } return PROVIDERS.UNKNOWN; }; @@ -42,6 +46,7 @@ export const getIdFromSource = source => { youtube: /\/watch\?v=([0-9A-Z a-z_-]+)/, instagram: /\/p\/([0-9A-Za-z_-]+)/, tiktok: /\/video\/([0-9]+)/, + facebook: /\/(?:posts|videos)\/([0-9A-Za-z]+)/, }; const NO_ID = ''; const provider = getProviderFromSource(source); @@ -51,6 +56,7 @@ export const getIdFromSource = source => { PROVIDERS.YOUTUBE, PROVIDERS.INSTAGRAM, PROVIDERS.TIKTOK, + PROVIDERS.FACEBOOK, ].includes(provider) ) { const id = source.match(sourceIds[provider]); diff --git a/src/app/legacy/containers/SocialEmbed/sourceHelpers.test.js b/src/app/legacy/containers/SocialEmbed/sourceHelpers.test.js index 1c03fa3914c..436c39e8a75 100644 --- a/src/app/legacy/containers/SocialEmbed/sourceHelpers.test.js +++ b/src/app/legacy/containers/SocialEmbed/sourceHelpers.test.js @@ -9,6 +9,10 @@ describe('sourceHelpers', () => { const YOUTUBE_SOURCE = 'https://www.youtube.com/watch?v=1e05_rwHvOM'; const TIKTOK_SOURCE = 'https://www.tiktok.com/@cuppymusic/video/7086167423639997701'; + const FACEBOOK_POST_SOURCE = + 'https://www.facebook.com/RickAstley/posts/545713756920775'; + const FACEBOOK_VIDEO_SOURCE = + 'https://www.facebook.com/RickAstley/videos/1378590239249667'; const UNKNOWN_SOURCE = 'https://www.randomSource.com/watch?v=XWxjmToNSjQ'; describe('getProviderFromSource', () => { @@ -44,6 +48,16 @@ describe('sourceHelpers', () => { expect(getIdFromSource(TIKTOK_SOURCE)).toEqual('7086167423639997701'); }); + it('should return a social embed ID for a valid Facebook Post source', () => { + expect(getIdFromSource(FACEBOOK_POST_SOURCE)).toEqual('545713756920775'); + }); + + it('should return a social embed ID for a valid Facebook Video source', () => { + expect(getIdFromSource(FACEBOOK_VIDEO_SOURCE)).toEqual( + '1378590239249667', + ); + }); + it('should return an empty string for an unknown or invalid source', () => { expect(getIdFromSource(UNKNOWN_SOURCE)).toEqual(''); expect(getIdFromSource('https://twitter.com/BBCNews')).toEqual(''); diff --git a/src/app/legacy/psammead/psammead-social-embed/src/Amp/index.jsx b/src/app/legacy/psammead/psammead-social-embed/src/Amp/index.jsx index e1d9f5d25e6..f219e978abb 100644 --- a/src/app/legacy/psammead/psammead-social-embed/src/Amp/index.jsx +++ b/src/app/legacy/psammead/psammead-social-embed/src/Amp/index.jsx @@ -60,6 +60,38 @@ const TikTok = ({ id }) => ( ); +const Facebook = ({ source }) => { + const getEmbedType = () => { + switch (true) { + case source?.includes('posts'): + return 'post'; + case source?.includes('videos'): + return 'video'; + default: + return 'post'; + } + }; + + return ( + <> + +