diff --git a/projects/angular-editor/src/lib/angular-editor.service.spec.ts b/projects/angular-editor/src/lib/angular-editor.service.spec.ts index e23e3ec1..0b0d8413 100644 --- a/projects/angular-editor/src/lib/angular-editor.service.spec.ts +++ b/projects/angular-editor/src/lib/angular-editor.service.spec.ts @@ -4,14 +4,128 @@ import {AngularEditorService} from './angular-editor.service'; import {HttpClientModule} from '@angular/common/http'; describe('AngularEditorService', () => { + let service: AngularEditorService; beforeEach(() => { TestBed.configureTestingModule({ imports: [ HttpClientModule ], providers: [AngularEditorService] }); + service = TestBed.inject(AngularEditorService); }); - it('should be created', inject([AngularEditorService], (service: AngularEditorService) => { + it('should be created', () => { expect(service).toBeTruthy(); - })); + }); + + it('#isYoutubeVideoUrl should return true for a valid Youtube URL', () => { + const videoUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'; + const result = service.isYoutubeVideoUrl(videoUrl); + + expect(result).toBeTrue(); + }); + + it('#isYoutubeVideoUrl should return true for a Youtube short URL', () => { + const videoUrl = 'https://youtu.be/123ABC'; + const result = service.isYoutubeVideoUrl(videoUrl); + + expect(result).toBeTrue(); + }); + + it('#isYoutubeVideoUrl should return true for an URL without a protocol', () => { + const videoUrl = 'www.youtube.com/watch?v=123ABC'; + const result = service.isYoutubeVideoUrl(videoUrl); + + expect(result).toBeTrue(); + }); + + it('#isYoutubeVideoUrl should return false for a non-Youtube URL', () => { + const videoUrl = 'https://www.notyoutube.com/'; + const result = service.isYoutubeVideoUrl(videoUrl); + + expect(result).toBeFalse(); + }); + + it('#getYoutubeVideoId should return video id from a Youtube URL', () => { + const videoUrl = 'https://www.youtube.com/watch?v=jNQXAC9IVRw'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube short URL', () => { + const videoUrl = 'https://youtu.be/jNQXAC9IVRw'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube URL with other query parameters', () => { + const videoUrl = 'https://www.youtube.com/watch?v=jNQXAC9IVRw&p=abc123'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube URL ending with /', () => { + const videoUrl = 'https://www.youtube.com/watch?v=jNQXAC9IVRw/'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube URL ending with whitespace', () => { + const videoUrl = 'https://www.youtube.com/watch?v=jNQXAC9IVRw '; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube short URL with query parameters', () => { + const videoUrl = 'https://youtu.be/jNQXAC9IVRw?si=123abc&p=abc123'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube short URL ending with /', () => { + const videoUrl = 'https://youtu.be/jNQXAC9IVRw/'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + it('#getYoutubeVideoId should return video id from a Youtube short URL ending with whitespace', () => { + const videoUrl = 'https://youtu.be/jNQXAC9IVRw '; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + + + + it('#getYoutubeVideoId should return video id from a Youtube URL without a protocol', () => { + const videoUrl = 'youtu.be/jNQXAC9IVRw'; + const expectedId = 'jNQXAC9IVRw'; + + const actualId = service.getYoutubeVideoId(videoUrl); + + expect(actualId).toBe(expectedId); + }); + }); diff --git a/projects/angular-editor/src/lib/angular-editor.service.ts b/projects/angular-editor/src/lib/angular-editor.service.ts index a0b9a77f..a8345e6e 100644 --- a/projects/angular-editor/src/lib/angular-editor.service.ts +++ b/projects/angular-editor/src/lib/angular-editor.service.ts @@ -189,7 +189,7 @@ export class AngularEditorService { } insertVideo(videoUrl: string) { - if (videoUrl.match('www.youtube.com')) { + if (this.isYoutubeVideoUrl(videoUrl)) { this.insertYouTubeVideoTag(videoUrl); } if (videoUrl.match('vimeo.com')) { @@ -197,8 +197,20 @@ export class AngularEditorService { } } + isYoutubeVideoUrl(videoUrl: string): boolean { + const youtubeRegex = '^(?:https?://)?(?:www.)?youtube.com|youtu.be'; + return videoUrl.match(youtubeRegex) !== null; + } + + getYoutubeVideoId(videoUrl: string): string | undefined { + const youtubeRegex = /(?:https?:\/\/)?(?:youtu\.be\/|watch\?v=)([^&?/\s]*)/; + const match = videoUrl.match(youtubeRegex); + + return match?.[1]; + } + private insertYouTubeVideoTag(videoUrl: string): void { - const id = videoUrl.split('v=')[1]; + const id = this.getYoutubeVideoId(videoUrl); const imageUrl = `https://img.youtube.com/vi/${id}/0.jpg`; const thumbnail = `