diff --git a/src/components/test/context.jsx b/src/components/test/context.jsx index 2081b94d..67135961 100644 --- a/src/components/test/context.jsx +++ b/src/components/test/context.jsx @@ -7,6 +7,7 @@ import styles from './test.css'; const cx = classNames.bind(styles); +const videoRegEx = /(?:mp4|webm)$/i; const imgRegEx = /(?:png|jpe?g|gif)$/i; const protocolRegEx = /^(?:(?:https?|ftp):\/\/)/i; const urlRegEx = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/ // eslint-disable-line @@ -24,6 +25,26 @@ class TestContext extends Component { ]) }; + renderVideo = (ctx, title) => { + const isUrl = urlRegEx.test(ctx); + const hasProtocol = protocolRegEx.test(ctx); + const linkUrl = (isUrl && !hasProtocol) ? `http://${ctx}` : ctx; + + return ( + + ); + } + renderImage = (ctx, title) => { const isUrl = urlRegEx.test(ctx); const hasProtocol = protocolRegEx.test(ctx); @@ -56,6 +77,11 @@ class TestContext extends Component { } renderContextContent = (content, title, highlight = false) => { + // Videos + if (videoRegEx.test(content)) { + return this.renderVideo(content, title); + } + // Images if (imgRegEx.test(content)) { return this.renderImage(content, title); diff --git a/src/components/test/test.css b/src/components/test/test.css index 79aa3c4d..45b2c625 100644 --- a/src/components/test/test.css +++ b/src/components/test/test.css @@ -253,13 +253,13 @@ } } -.image-link { +.image-link, .video-link { display: inline-block; font-size: 11px; padding: 0 1em 1em 1em; } -.image { +.image, .video { display: block; max-width: 100%; height: auto; diff --git a/test/spec/components/test/context.test.jsx b/test/spec/components/test/context.test.jsx index c5af660a..f006e015 100644 --- a/test/spec/components/test/context.test.jsx +++ b/test/spec/components/test/context.test.jsx @@ -18,6 +18,8 @@ describe('', () => { ctxItems: wrapper.find('.test-context-item'), img: wrapper.find('.test-image'), imgLink: wrapper.find('.test-image-link'), + video: wrapper.find('.test-video'), + videoLink: wrapper.find('.test-video-link'), link: wrapper.find('.test-text-link'), snippet: wrapper.find(CodeSnippet) }; @@ -134,6 +136,44 @@ describe('', () => { expect(snippet).to.have.lengthOf(0); expect(img).to.have.lengthOf(1); }); + + it('renders local video', () => { + const context = '/testvideo.mp4'; + const { wrapper, snippet, video } = getInstance({ + context: JSON.stringify(context), + className: 'test' + }); + expect(wrapper).to.have.className('test'); + expect(snippet).to.have.lengthOf(0); + expect(wrapper).to.have.exactly(1).descendants('video'); + expect(video).to.have.attr('src', '/testvideo.mp4'); + }); + + it('renders video url with protocol', () => { + const context = 'http://test.url.com/testvideo.mp4'; + const { wrapper, snippet, videoLink } = getInstance({ + context: JSON.stringify(context), + className: 'test' + }); + expect(wrapper).to.have.className('test'); + expect(snippet).to.have.lengthOf(0); + expect(wrapper).to.have.exactly(1).descendants('video'); + expect(wrapper).to.have.exactly(1).descendants('a.test-video-link'); + expect(videoLink).to.have.attr('href', 'http://test.url.com/testvideo.mp4'); + }); + + it('renders image url without protocol', () => { + const context = 'test.url.com/testvideo.mp4'; + const { wrapper, snippet, videoLink } = getInstance({ + context: JSON.stringify(context), + className: 'test' + }); + expect(wrapper).to.have.className('test'); + expect(snippet).to.have.lengthOf(0); + expect(wrapper).to.have.exactly(1).descendants('video'); + expect(wrapper).to.have.exactly(1).descendants('a.test-video-link'); + expect(videoLink).to.have.attr('href', 'http://test.url.com/testvideo.mp4'); + }); }); describe('when context is an object', () => {