From 12d3c9684f911173121087f0e0f7b7bc8cc3efc0 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Tue, 10 Oct 2023 13:56:24 +0530 Subject: [PATCH 01/11] Modified regex in embedvideo.js to accommodate 'h' parameter --- funnel/assets/js/utils/embedvideo.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/funnel/assets/js/utils/embedvideo.js b/funnel/assets/js/utils/embedvideo.js index b02b0d743..1e677c420 100644 --- a/funnel/assets/js/utils/embedvideo.js +++ b/funnel/assets/js/utils/embedvideo.js @@ -8,7 +8,7 @@ const Video = { */ getVideoTypeAndId(url) { const regexMatch = url.match( - /(http:|https:|)\/\/(player.|www.)?(y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(&\S+)?/ + /(http:|https:|)\/\/(player.|www.)?(y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(&\S+)?(\?h=([^&]+))?/ ); let type = ''; if (regexMatch && regexMatch.length > 5) { @@ -16,6 +16,11 @@ const Video = { type = 'youtube'; } else if (regexMatch[3].indexOf('vimeo') > -1) { type = 'vimeo'; + return { + type, + videoId: regexMatch[6], + paramId: regexMatch[9], + }; } return { type, @@ -29,11 +34,11 @@ const Video = { }, embedIframe(videoWrapper, videoUrl) { let videoEmbedUrl = ''; - const { type, videoId } = this.getVideoTypeAndId(videoUrl); + const { type, videoId, paramId } = this.getVideoTypeAndId(videoUrl); if (type === 'youtube') { videoEmbedUrl = ``; } else if (type === 'vimeo') { - videoEmbedUrl = ``; + videoEmbedUrl = ``; } if (videoEmbedUrl) { videoWrapper.innerHTML = videoEmbedUrl; From a0aafbf0a4ae8833552e4182ccc81139d1576713 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Tue, 10 Oct 2023 13:58:35 +0530 Subject: [PATCH 02/11] Allowed vimeo subdomain --- funnel/forms/project.py | 1 + 1 file changed, 1 insertion(+) diff --git a/funnel/forms/project.py b/funnel/forms/project.py index 546bd969a..b70ff6489 100644 --- a/funnel/forms/project.py +++ b/funnel/forms/project.py @@ -166,6 +166,7 @@ class ProjectLivestreamForm(forms.Form): 'y2u.be', 'www.vimeo.com', 'vimeo.com', + 'player.vimeo.com', ), message_schemes=__("A https:// URL is required"), message_domains=__("Livestream must be on YouTube or Vimeo"), From eab1da08262571df60aa732e4b3bb4b94f1a9a0e Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Tue, 10 Oct 2023 16:52:26 +0530 Subject: [PATCH 03/11] Used named patterns instead of numbers --- funnel/assets/js/utils/embedvideo.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/funnel/assets/js/utils/embedvideo.js b/funnel/assets/js/utils/embedvideo.js index 1e677c420..88a65e588 100644 --- a/funnel/assets/js/utils/embedvideo.js +++ b/funnel/assets/js/utils/embedvideo.js @@ -8,18 +8,21 @@ const Video = { */ getVideoTypeAndId(url) { const regexMatch = url.match( - /(http:|https:|)\/\/(player.|www.)?(y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(&\S+)?(\?h=([^&]+))?/ + /(http:|https:|)\/\/(player.|www.)?(?y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?(?[A-Za-z0-9._%-]*)(&\S+)?(\?h=(?[^&]+))?/ ); let type = ''; if (regexMatch && regexMatch.length > 5) { - if (regexMatch[3].indexOf('youtu') > -1 || regexMatch[3].indexOf('y2u') > -1) { + if ( + regexMatch.groups.service.indexOf('youtu') > -1 || + regexMatch.groups.service.indexOf('y2u') > -1 + ) { type = 'youtube'; - } else if (regexMatch[3].indexOf('vimeo') > -1) { + } else if (regexMatch.groups.service.indexOf('vimeo') > -1) { type = 'vimeo'; return { type, - videoId: regexMatch[6], - paramId: regexMatch[9], + videoId: regexMatch.groups.videoId, + paramId: regexMatch.groups.paramId, }; } return { @@ -38,7 +41,9 @@ const Video = { if (type === 'youtube') { videoEmbedUrl = ``; } else if (type === 'vimeo') { - videoEmbedUrl = ``; + videoEmbedUrl = ``; } if (videoEmbedUrl) { videoWrapper.innerHTML = videoEmbedUrl; From 4943b06146242d7ad96c389e219c06167e1eafa8 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Wed, 18 Oct 2023 00:57:49 +0530 Subject: [PATCH 04/11] updated regex --- funnel/assets/js/utils/embedvideo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funnel/assets/js/utils/embedvideo.js b/funnel/assets/js/utils/embedvideo.js index 88a65e588..224314517 100644 --- a/funnel/assets/js/utils/embedvideo.js +++ b/funnel/assets/js/utils/embedvideo.js @@ -8,7 +8,7 @@ const Video = { */ getVideoTypeAndId(url) { const regexMatch = url.match( - /(http:|https:|)\/\/(player.|www.)?(?y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?(?[A-Za-z0-9._%-]*)(&\S+)?(\?h=(?[^&]+))?/ + /(http:|https:|)\/\/(player.|www.)?(?y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?(?[A-Za-z0-9._%-]*)(&\S+)?((\?h=)(?[^&]+))?/ ); let type = ''; if (regexMatch && regexMatch.length > 5) { From c70083c7b34b2ea6ceec4cc8f597402417f80580 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Tue, 5 Dec 2023 12:26:27 +0530 Subject: [PATCH 05/11] Update embedvideo.js --- funnel/assets/js/utils/embedvideo.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/funnel/assets/js/utils/embedvideo.js b/funnel/assets/js/utils/embedvideo.js index 224314517..6bb13a164 100644 --- a/funnel/assets/js/utils/embedvideo.js +++ b/funnel/assets/js/utils/embedvideo.js @@ -19,11 +19,6 @@ const Video = { type = 'youtube'; } else if (regexMatch.groups.service.indexOf('vimeo') > -1) { type = 'vimeo'; - return { - type, - videoId: regexMatch.groups.videoId, - paramId: regexMatch.groups.paramId, - }; } return { type, From 240c4cc21aa12a8beb850d2277f71f5635b6aa09 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Wed, 13 Dec 2023 15:45:09 +0530 Subject: [PATCH 06/11] Added playwright test for livestream url --- tests/e2e/basic/video_test.py | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/e2e/basic/video_test.py diff --git a/tests/e2e/basic/video_test.py b/tests/e2e/basic/video_test.py new file mode 100644 index 000000000..128acce8b --- /dev/null +++ b/tests/e2e/basic/video_test.py @@ -0,0 +1,51 @@ +"""Test livestream urls.""" + +import pytest +from playwright.sync_api import Page, expect + +VETINARI_EMAIL = 'vetinari@example.org' +VETINARI_PASSWORD = 've@pwd3289' # nosec + + +def wait_until_recaptcha_loaded(page: Page) -> None: + page.wait_for_selector( + '#form-passwordlogin > div.g-recaptcha > div > div.grecaptcha-logo > iframe', + timeout=10000, + ) + + +@pytest.mark.enable_socket() +def test_login_add_livestream( + db_session, live_server, user_vetinari, project_expo2010, page: Page +): + user_vetinari.add_email(VETINARI_EMAIL) + user_vetinari.password = VETINARI_PASSWORD + db_session.commit() + page.goto(live_server.url) + page.get_by_role("link", name="Login").click() + wait_until_recaptcha_loaded(page) + page.wait_for_selector('input[name=username]').fill(VETINARI_EMAIL) + page.click('#use-password-login') + page.wait_for_selector('input[name=password]').fill(VETINARI_PASSWORD) + page.click('#login-btn') + assert ( + page.wait_for_selector('.alert__text').inner_text() == "You are now logged in" + ) + page.goto(project_expo2010.absolute_url) + page.get_by_label("Update livestream URLs").click() + page.get_by_label("Livestream URLs. One per line").click() + page.get_by_label("Livestream URLs. One per line").fill( + "https://youtube.com/live/JdHDG6Zudi4?feature=share\nhttps://vimeo.com/828748049?share=copy" + ) + page.get_by_role("button", name="Save changes").click() + expect( + page.frame_locator( + "internal:role=tabpanel[name=\"Livestream\"i] >> iframe" + ).get_by_role("link", name="Faster, Better, Cheaper -") + ).to_be_visible() + page.get_by_role("tab", name="Livestream 2").click() + expect( + page.frame_locator( + "internal:role=tabpanel[name=\"Livestream\"i] >> iframe" + ).get_by_role("banner") + ).to_contain_text("How to do AI right - Workshop Promo") From 14096fa198683588237911137ca7ff5c60306940 Mon Sep 17 00:00:00 2001 From: Vidya Ramakrishnan Date: Thu, 14 Dec 2023 10:59:39 +0530 Subject: [PATCH 07/11] Simplify regex --- funnel/assets/js/utils/embedvideo.js | 58 ++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/funnel/assets/js/utils/embedvideo.js b/funnel/assets/js/utils/embedvideo.js index 6bb13a164..29d50255c 100644 --- a/funnel/assets/js/utils/embedvideo.js +++ b/funnel/assets/js/utils/embedvideo.js @@ -6,29 +6,53 @@ const Video = { The videoID is then used to generate the iframe html. The generated iframe is added to the video container element. */ - getVideoTypeAndId(url) { - const regexMatch = url.match( - /(http:|https:|)\/\/(player.|www.)?(?y2u\.be|vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|live\/|watch\?v=|v\/)?(?[A-Za-z0-9._%-]*)(&\S+)?((\?h=)(?[^&]+))?/ - ); - let type = ''; - if (regexMatch && regexMatch.length > 5) { - if ( - regexMatch.groups.service.indexOf('youtu') > -1 || - regexMatch.groups.service.indexOf('y2u') > -1 - ) { - type = 'youtube'; - } else if (regexMatch.groups.service.indexOf('vimeo') > -1) { + validHostnames: [ + 'www.youtube.com', + 'youtube.com', + 'youtu.be', + 'y2u.be', + 'www.vimeo.com', + 'vimeo.com', + 'player.vimeo.com', + ], + getVideoTypeAndId(videoUrl) { + let videoId; + let paramId; + let type; + const url = new URL(videoUrl); + const { hostname } = url; + let regexMatch; + if (this.validHostnames.includes(hostname)) { + if (hostname.includes('vimeo')) { type = 'vimeo'; + paramId = url.searchParams.get('h'); + if (paramId) { + regexMatch = url.pathname.match(/\/(video\/)?(?[A-Za-z0-9._%-]*)/); + videoId = regexMatch.groups.videoId; + } else { + regexMatch = url.pathname.match( + /\/(video\/)?(?[A-Za-z0-9._%-]*)?(\/)?(?[A-Za-z0-9._%-]*)/ + ); + videoId = regexMatch.groups.videoId; + paramId = regexMatch.groups.paramId; + } + } else { + type = 'youtube'; + videoId = url.searchParams.get('v'); + if (!videoId) { + regexMatch = url.pathname.match( + /\/(embed\/|live\/)?(?[A-Za-z0-9._%-]*)/ + ); + videoId = regexMatch.groups.videoId; + } } return { type, - videoId: regexMatch[6], + videoId, + paramId, }; } - return { - type, - videoId: url, - }; + return {}; }, embedIframe(videoWrapper, videoUrl) { let videoEmbedUrl = ''; From 973c96bb681cc75782997e0634dc0925c82458c5 Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Thu, 14 Dec 2023 12:17:01 +0530 Subject: [PATCH 08/11] Fix pytestmark --- tests/e2e/account/register_test.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/e2e/account/register_test.py b/tests/e2e/account/register_test.py index cabce120c..9c6707ee1 100644 --- a/tests/e2e/account/register_test.py +++ b/tests/e2e/account/register_test.py @@ -10,7 +10,13 @@ from funnel import models scenarios('account/register.feature') -pytestmark = pytest.mark.usefixtures('live_server') +pytestmark = [ + pytest.mark.usefixtures('live_server'), + pytest.mark.filterwarnings( + "ignore:Object of type not in session", + "ignore:Object of type not in session", + ), +] TWOFLOWER_EMAIL = 'twoflower@example.org' TWOFLOWER_PHONE = '+12015550123' @@ -18,11 +24,6 @@ ANONYMOUS_PHONE = '8123456789' ANONYMOUS_EMAIL = 'anon@example.com' -pytestmark = pytest.mark.filterwarnings( - "ignore:Object of type not in session", - "ignore:Object of type not in session", -) - @pytest.fixture() def published_project(db_session, new_project: models.Project) -> models.Project: From eb10a7a711e10045c0de6449c76105d7842c083b Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Thu, 14 Dec 2023 12:42:19 +0530 Subject: [PATCH 09/11] Enable pytest socket to all the tests using live_server fixture --- tests/e2e/basic/video_test.py | 2 -- tests/e2e/conftest.py | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/e2e/basic/video_test.py b/tests/e2e/basic/video_test.py index 128acce8b..51c968d79 100644 --- a/tests/e2e/basic/video_test.py +++ b/tests/e2e/basic/video_test.py @@ -1,6 +1,5 @@ """Test livestream urls.""" -import pytest from playwright.sync_api import Page, expect VETINARI_EMAIL = 'vetinari@example.org' @@ -14,7 +13,6 @@ def wait_until_recaptcha_loaded(page: Page) -> None: ) -@pytest.mark.enable_socket() def test_login_add_livestream( db_session, live_server, user_vetinari, project_expo2010, page: Page ): diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index c867f8843..48f340257 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -2,7 +2,6 @@ # pylint: disable=redefined-outer-name import pytest -from pytest_socket import enable_socket @pytest.fixture() @@ -11,5 +10,7 @@ def db_session(db_session_truncate): return db_session_truncate -def pytest_runtest_setup() -> None: - enable_socket() +def pytest_collection_modifyitems(items): + for item in items: + if 'live_server' in getattr(item, 'fixturenames', ()): + item.add_marker(pytest.mark.enable_socket()) From 722ed0c9bce2afd4547c3c657263faf42f327f2c Mon Sep 17 00:00:00 2001 From: Amogh M Aradhya Date: Thu, 14 Dec 2023 14:02:50 +0530 Subject: [PATCH 10/11] Added private vimeo link --- tests/e2e/basic/video_test.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/e2e/basic/video_test.py b/tests/e2e/basic/video_test.py index 51c968d79..f8cc4c86c 100644 --- a/tests/e2e/basic/video_test.py +++ b/tests/e2e/basic/video_test.py @@ -33,17 +33,25 @@ def test_login_add_livestream( page.get_by_label("Update livestream URLs").click() page.get_by_label("Livestream URLs. One per line").click() page.get_by_label("Livestream URLs. One per line").fill( - "https://youtube.com/live/JdHDG6Zudi4?feature=share\nhttps://vimeo.com/828748049?share=copy" + "https://www.youtube.com/watch?v=dQw4w9WgXcQ\nhttps://vimeo.com/336892869\nhttps://player.vimeo.com/video/860038461?h=87fb31038b" ) page.get_by_role("button", name="Save changes").click() expect( page.frame_locator( "internal:role=tabpanel[name=\"Livestream\"i] >> iframe" - ).get_by_role("link", name="Faster, Better, Cheaper -") - ).to_be_visible() + ).get_by_label("YouTube Video Player") + ).to_contain_text("Rick Astley - Never Gonna Give You Up (Official Music Video)") page.get_by_role("tab", name="Livestream 2").click() expect( page.frame_locator( "internal:role=tabpanel[name=\"Livestream\"i] >> iframe" ).get_by_role("banner") - ).to_contain_text("How to do AI right - Workshop Promo") + ).to_contain_text("Rick Astley - Never Gonna Give You Up (Video)") + page.get_by_role("tab", name="Livestream 3").click() + expect( + page.frame_locator( + "internal:role=tabpanel[name=\"Livestream\"i] >> iframe" + ).get_by_role("banner") + ).to_contain_text( + "Practical SLSA for developers and application security professionals" + ) From c69865caa27d784bfe295e983bbcaf0c2c5fd903 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 07:51:39 +0000 Subject: [PATCH 11/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/e2e/basic/video_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/basic/video_test.py b/tests/e2e/basic/video_test.py index dd3e0ad3f..84fa703ef 100644 --- a/tests/e2e/basic/video_test.py +++ b/tests/e2e/basic/video_test.py @@ -1,9 +1,10 @@ """Test livestream urls.""" from playwright.sync_api import Page, expect + from funnel import models -from ...conftest import scoped_session +from ...conftest import scoped_session VETINARI_EMAIL = 'vetinari@example.org' VETINARI_PASSWORD = 've@pwd3289' # nosec