Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions funnel/assets/js/utils/embedvideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,63 @@ 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+)?/
);
let type = '';
if (regexMatch && regexMatch.length > 5) {
if (regexMatch[3].indexOf('youtu') > -1 || regexMatch[3].indexOf('y2u') > -1) {
type = 'youtube';
} else if (regexMatch[3].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\/)?(?<videoId>[A-Za-z0-9._%-]*)/);
videoId = regexMatch.groups.videoId;
} else {
regexMatch = url.pathname.match(
/\/(video\/)?(?<videoId>[A-Za-z0-9._%-]*)?(\/)?(?<paramId>[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\/)?(?<videoId>[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 = '';
const { type, videoId } = this.getVideoTypeAndId(videoUrl);
const { type, videoId, paramId } = this.getVideoTypeAndId(videoUrl);
if (type === 'youtube') {
videoEmbedUrl = `<iframe src='//www.youtube.com/embed/${videoId}' frameborder='0' allowfullscreen></iframe>`;
} else if (type === 'vimeo') {
videoEmbedUrl = `<iframe src='https://player.vimeo.com/video/${videoId}' frameborder='0' allowfullscreen></iframe>`;
videoEmbedUrl = `<iframe src='https://player.vimeo.com/video/${videoId}${
paramId ? `?h=${paramId}` : ''
}' frameborder='0' allowfullscreen></iframe>`;
}
if (videoEmbedUrl) {
videoWrapper.innerHTML = videoEmbedUrl;
Expand Down
1 change: 1 addition & 0 deletions funnel/forms/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,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"),
Expand Down
13 changes: 7 additions & 6 deletions tests/e2e/account/register_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@
from ...conftest import scoped_session

scenarios('account/register.feature')
pytestmark = pytest.mark.usefixtures('live_server')
pytestmark = [
pytest.mark.usefixtures('live_server'),
pytest.mark.filterwarnings(
"ignore:Object of type <AccountPhone> not in session",
"ignore:Object of type <AccountEmail> not in session",
),
]

TWOFLOWER_EMAIL = '[email protected]'
TWOFLOWER_PHONE = '+12015550123'
TWOFLOWER_PASSWORD = 'te@pwd3289' # nosec
ANONYMOUS_PHONE = '8123456789'
ANONYMOUS_EMAIL = '[email protected]'

pytestmark = pytest.mark.filterwarnings(
"ignore:Object of type <AccountPhone> not in session",
"ignore:Object of type <AccountEmail> not in session",
)


@pytest.fixture()
def published_project(
Expand Down
65 changes: 65 additions & 0 deletions tests/e2e/basic/video_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""Test livestream urls."""

from playwright.sync_api import Page, expect

from funnel import models

from ...conftest import scoped_session

VETINARI_EMAIL = '[email protected]'
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,
)


def test_login_add_livestream(
db_session: scoped_session,
live_server,
user_vetinari,
project_expo2010: models.Project,
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://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_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("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"
)
7 changes: 4 additions & 3 deletions tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# pylint: disable=redefined-outer-name

import pytest
from pytest_socket import enable_socket
from sqlalchemy.orm import scoped_session


Expand All @@ -13,5 +12,7 @@ def db_session(db_session_truncate: scoped_session) -> scoped_session:
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())