Mholloway has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/396031 )
Change subject: Media: Update selector blacklist ...................................................................... Media: Update selector blacklist Exclude a few more categories: * Images in error page templates for nonexisting articles * SiteNotice images * Slideshow gallery thumbnails Corresponds with https://github.com/wikimedia/mediawiki-extensions-MultimediaViewer/blob/42b577bae97e8079d7695b2684c78c826c2fb846/resources/mmv/mmv.bootstrap.js#L165-L173. Bug: T177430 Change-Id: I9c4d424dcbb5513d717b38f14c48a1944d756f44 --- M lib/selectors.js A test/lib/media/media-test-inclusion.js A test/lib/media/media-test-metadata.js D test/lib/media/media-test.js 4 files changed, 156 insertions(+), 133 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/mobileapps refs/changes/31/396031/1 diff --git a/lib/selectors.js b/lib/selectors.js index 0aa87b9..63c7b76 100644 --- a/lib/selectors.js +++ b/lib/selectors.js @@ -13,9 +13,14 @@ 'span.IPA+small a[rel=mw:MediaLink]' ]; +// Exclusions for various categories of content. See MMVB.isAllowedThumb in mediawiki-extensions- +// MultimediaViewer. const MediaBlacklist = [ + '.metadata', '.noviewer', - '.metadata' + '.noarticletext', + '#siteNotice', + 'ul.mw-gallery-slideshow li.gallerybox' // thumbnails of a slideshow gallery ]; const ImageSelectors = MediaSelectors.filter(selector => selector.includes('Image')); diff --git a/test/lib/media/media-test-inclusion.js b/test/lib/media/media-test-inclusion.js new file mode 100644 index 0000000..c3df360 --- /dev/null +++ b/test/lib/media/media-test-inclusion.js @@ -0,0 +1,70 @@ +/* eslint-disable max-len */ + +'use strict'; + +const assert = require('../../utils/assert'); +const media = require('../../../lib/media'); + +const imageFigure = '<figure typeof="mw:Image"><img resource="./File:Foo"/></figure>'; +const imageSpan = '<span typeof="mw:Image"><img resource="./File:Foo"/></span>'; +const imageFigureInline = '<figure-inline typeof="mw:Image"><img resource="./File:Foo"/></figure-inline>'; + +const imageThumbFigure = '<figure typeof="mw:Image/Thumb"><img resource="./File:Foo"/></figure>'; +const imageThumbSpan = '<span typeof="mw:Image/Thumb"><img resource="./File:Foo"/></span>'; +const imageThumbFigureInline = '<figure-inline typeof="mw:Image/Thumb"><img resource="./File:Foo"/></figure-inline>'; + +const videoFigure = '<figure typeof="mw:Video"><video resource="./File:Foo"/></figure>'; +const videoSpan = '<span typeof="mw:Video"><video resource="./File:Foo"/></span>'; +const videoFigureInline = '<figure-inline typeof="mw:Video"><video resource="./File:Foo"/></figure-inline>'; + +const videoThumbFigure = '<figure typeof="mw:Video/Thumb"><video resource="./File:Foo"/></figure>'; +const videoThumbSpan = '<span typeof="mw:Video/Thumb"><video resource="./File:Foo"/></span>'; +const videoThumbFigureInline = '<figure-inline typeof="mw:Video/Thumb"><video resource="./File:Foo"/></figure-inline>'; + +const audioFigure = '<figure typeof="mw:Audio"><video resource="./File:Foo"/></figure>'; +const audioSpan = '<span typeof="mw:Audio"><video resource="./File:Foo"/></span>'; +const audioFigureInline = '<figure-inline typeof="mw:Audio"><video resource="./File:Foo"/></figure-inline>'; + +const noTypeFigure = '<figure><video resource="./File:Foo"/></figure>'; +const noTypeSpan = '<span><video resource="./File:Foo"/></span>'; +const noTypeFigureInline = '<figure-inline><video resource="./File:Foo"/></figure-inline>'; + +const imageNoViewer = '<figure typeof="mw:Image" class="noviewer"><img resource="./File:Foo"/></figure>'; +const imageMetadata = '<span class="metadata"><figure typeof="mw:Image"><img resource="./File:Foo"/></figure></span>'; +const imageNoArticleText = '<span class="noarticletext"><figure typeof="mw:Image"><img resource="./File:Foo"/></figure></span>'; +const imageSiteNotice = '<span id="siteNotice"><figure typeof="mw:Image"><img resource="./File:Foo"/></figure></span>'; +const imageSlideshowGallery = + '<ul class="mw-gallery-slideshow">' + + '<li class="gallerybox">' + + '<figure typeof="mw:Image"><img resource="./File:Foo"/></figure>' + + '</li>' + + '</ul>'; + +const images = [imageFigure, imageSpan, imageFigureInline, imageThumbFigure, imageThumbSpan, imageThumbFigureInline]; +const videos = [videoFigure, videoSpan, videoFigureInline, videoThumbFigure, videoThumbSpan, videoThumbFigureInline]; +const audio = [audioFigure, audioSpan, audioFigureInline]; +const validItems = images.concat(videos).concat(audio); + +const noType = [noTypeFigure, noTypeSpan, noTypeFigureInline]; +const blacklisted = [imageNoViewer, imageMetadata, imageNoArticleText, imageSiteNotice, imageSlideshowGallery]; +const invalidItems = noType.concat(blacklisted); + +describe('lib:media expected items are included or excluded', () => { + + it('items should be found for expected selectors', () => { + const page = validItems.join(''); + const result = media.getMediaItemInfoFromPage(page); + assert.deepEqual(result.length, validItems.length); + assert.deepEqual(result.filter(i => i.title === 'File:Foo').length, validItems.length); + assert.deepEqual(result.filter(i => i.type === media.Image.name).length, images.length); + assert.deepEqual(result.filter(i => i.type === media.Video.name).length, videos.length); + assert.deepEqual(result.filter(i => i.type === media.Audio.name).length, audio.length); + }); + + it('items should not be found for other selectors', () => { + const page = invalidItems.join(''); + const result = media.getMediaItemInfoFromPage(page); + assert.deepEqual(result.length, 0); + }); + +}); diff --git a/test/lib/media/media-test-metadata.js b/test/lib/media/media-test-metadata.js new file mode 100644 index 0000000..d472a2c --- /dev/null +++ b/test/lib/media/media-test-metadata.js @@ -0,0 +1,80 @@ +'use strict'; + +const assert = require('../../utils/assert'); +const media = require('../../../lib/media'); + +const imageWithCaption = + '<figure typeof="mw:Image">' + + '<img resource="./File:Foo"/>' + + '<figcaption>An <i>example</i> image</figcaption>' + + '</figure>'; + +const videoWithMetadata = + '<figure typeof="mw:Video" data-mw=\'{"starttime": "1", "thumbtime": "2", "endtime": "3"}\'>' + + '<video resource="./File:Foo"/>' + + '</figure>'; + +const videoWithDerivative = + '<figure typeof="mw:Video">' + + '<video resource="./File:Foo">' + + '<source src="https://example.com/Foo.ogv"' + + ' type=\'video/ogg; codecs="theora, vorbis"\'' + + ' data-title="Foo"' + + ' data-shorttitle="Foo"' + + ' data-file-width="120"' + + ' data-file-height="120"' + + '/>' + + '</video>' + + '</figure>'; + +const spokenWikipedia = + '<div id="section_SpokenWikipedia">' + + '<figure typeof="mw:Audio"><video resource="./File:Foo"/></figure>' + + '</div>'; + +const pronunciationAudio = + '<span class="IPA"></span>' + + '<small>' + + '<a rel="mw:MediaLink" title="Foo">Pronunciation</a>' + + '</small>'; + +describe('lib:media metadata is correctly parsed from HTML', () => { + + it('all expected captions are present', () => { + const result = media.getMediaItemInfoFromPage(imageWithCaption)[0]; + assert.deepEqual(result.caption.html, 'An <i>example</i> image'); + assert.deepEqual(result.caption.text, 'An example image'); + }); + + it('all expected data-mw properties are present', () => { + const result = media.getMediaItemInfoFromPage(videoWithMetadata)[0]; + assert.deepEqual(result.start_time, 1); + assert.deepEqual(result.thumb_time, 2); + assert.deepEqual(result.end_time, 3); + }); + + it('all expected derivative properties are present', () => { + const result = media.getMediaItemInfoFromPage(videoWithDerivative)[0]; + const derivative = result.sources[0]; + assert.deepEqual(derivative.source, 'https://example.com/Foo.ogv'); + assert.deepEqual(derivative.mime, 'video/ogg'); + assert.deepEqual(derivative.codecs, [ "theora", "vorbis" ]); + assert.deepEqual(derivative.name, 'Foo'); + assert.deepEqual(derivative.short_name, 'Foo'); + assert.deepEqual(derivative.width, 120); + assert.deepEqual(derivative.height, 120); + }); + + it('spoken Wikipedia file is correctly identified', () => { + const result = media.getMediaItemInfoFromPage(spokenWikipedia)[0]; + assert.deepEqual(result.audio_type, 'spoken'); + }); + + it('pronunciation audio file is correctly identified', () => { + const result = media.getMediaItemInfoFromPage(pronunciationAudio)[0]; + assert.deepEqual(result.title, 'File:Foo'); + assert.deepEqual(result.type, 'audio'); + assert.deepEqual(result.audio_type, 'pronunciation'); + }); + +}); diff --git a/test/lib/media/media-test.js b/test/lib/media/media-test.js deleted file mode 100644 index c4ea7eb..0000000 --- a/test/lib/media/media-test.js +++ /dev/null @@ -1,132 +0,0 @@ -/* eslint-disable max-len */ - -'use strict'; - -const assert = require('../../utils/assert'); -const media = require('../../../lib/media'); - -const imageFigure = '<figure typeof="mw:Image"><img resource="./File:Foo"/></figure>'; -const imageSpan = '<span typeof="mw:Image"><img resource="./File:Foo"/></span>'; -const imageFigureInline = '<figure-inline typeof="mw:Image"><img resource="./File:Foo"/></figure-inline>'; - -const imageThumbFigure = '<figure typeof="mw:Image/Thumb"><img resource="./File:Foo"/></figure>'; -const imageThumbSpan = '<span typeof="mw:Image/Thumb"><img resource="./File:Foo"/></span>'; -const imageThumbFigureInline = '<figure-inline typeof="mw:Image/Thumb"><img resource="./File:Foo"/></figure-inline>'; - -const videoFigure = '<figure typeof="mw:Video"><video resource="./File:Foo"/></figure>'; -const videoSpan = '<span typeof="mw:Video"><video resource="./File:Foo"/></span>'; -const videoFigureInline = '<figure-inline typeof="mw:Video"><video resource="./File:Foo"/></figure-inline>'; - -const videoThumbFigure = '<figure typeof="mw:Video/Thumb"><video resource="./File:Foo"/></figure>'; -const videoThumbSpan = '<span typeof="mw:Video/Thumb"><video resource="./File:Foo"/></span>'; -const videoThumbFigureInline = '<figure-inline typeof="mw:Video/Thumb"><video resource="./File:Foo"/></figure-inline>'; - -const audioFigure = '<figure typeof="mw:Audio"><video resource="./File:Foo"/></figure>'; -const audioSpan = '<span typeof="mw:Audio"><video resource="./File:Foo"/></span>'; -const audioFigureInline = '<figure-inline typeof="mw:Audio"><video resource="./File:Foo"/></figure-inline>'; - -const noTypeFigure = '<figure><video resource="./File:Foo"/></figure>'; -const noTypeSpan = '<span><video resource="./File:Foo"/></span>'; -const noTypeFigureInline = '<figure-inline><video resource="./File:Foo"/></figure-inline>'; - -const imageNoViewer = '<figure typeof="mw:Image" class="noviewer"><img resource="./File:Foo"/></figure>'; -const imageMetadata = '<span class="metadata"><figure typeof="mw:Image"><img resource="./File:Foo"/></figure></span>'; - -const images = [imageFigure, imageSpan, imageFigureInline, imageThumbFigure, imageThumbSpan, imageThumbFigureInline]; -const videos = [videoFigure, videoSpan, videoFigureInline, videoThumbFigure, videoThumbSpan, videoThumbFigureInline]; -const audio = [audioFigure, audioSpan, audioFigureInline]; - -const validItems = images.concat(videos).concat(audio); -const invalidItems = [noTypeFigure, noTypeSpan, noTypeFigureInline, imageNoViewer, imageMetadata]; - -const imageWithCaption = - '<figure typeof="mw:Image">' + - '<img resource="./File:Foo"/>' + - '<figcaption>An <i>example</i> image</figcaption>' + - '</figure>'; - -const videoWithMetadata = - '<figure typeof="mw:Video" data-mw=\'{"starttime": "1", "thumbtime": "2", "endtime": "3"}\'>' + - '<video resource="./File:Foo"/>' + - '</figure>'; - -const videoWithDerivative = - '<figure typeof="mw:Video">' + - '<video resource="./File:Foo">' + - '<source src="https://example.com/Foo.ogv"' + - ' type=\'video/ogg; codecs="theora, vorbis"\'' + - ' data-title="Foo"' + - ' data-shorttitle="Foo"' + - ' data-file-width="120"' + - ' data-file-height="120"' + - '/>' + - '</video>' + - '</figure>'; - -const spokenWikipedia = - '<div id="section_SpokenWikipedia">' + - '<figure typeof="mw:Audio"><video resource="./File:Foo"/></figure>' + - '</div>'; - -const pronunciationAudio = - '<span class="IPA"></span>' + - '<small>' + - '<a rel="mw:MediaLink" title="Foo">Pronunciation</a>' + - '</small>'; - -describe('lib:media', () => { - - it('items should be found for expected selectors', () => { - const page = validItems.join(''); - const result = media.getMediaItemInfoFromPage(page); - assert.deepEqual(result.length, validItems.length); - assert.deepEqual(result.filter(i => i.title === 'File:Foo').length, validItems.length); - assert.deepEqual(result.filter(i => i.type === media.Image.name).length, images.length); - assert.deepEqual(result.filter(i => i.type === media.Video.name).length, videos.length); - assert.deepEqual(result.filter(i => i.type === media.Audio.name).length, audio.length); - }); - - it('items should not be found for other selectors', () => { - const page = invalidItems.join(''); - const result = media.getMediaItemInfoFromPage(page); - assert.deepEqual(result.length, 0); - }); - - it('all expected captions are present', () => { - const result = media.getMediaItemInfoFromPage(imageWithCaption)[0]; - assert.deepEqual(result.caption.html, 'An <i>example</i> image'); - assert.deepEqual(result.caption.text, 'An example image'); - }); - - it('all expected data-mw properties are present', () => { - const result = media.getMediaItemInfoFromPage(videoWithMetadata)[0]; - assert.deepEqual(result.start_time, 1); - assert.deepEqual(result.thumb_time, 2); - assert.deepEqual(result.end_time, 3); - }); - - it('all expected derivative properties are present', () => { - const result = media.getMediaItemInfoFromPage(videoWithDerivative)[0]; - const derivative = result.sources[0]; - assert.deepEqual(derivative.source, 'https://example.com/Foo.ogv'); - assert.deepEqual(derivative.mime, 'video/ogg'); - assert.deepEqual(derivative.codecs, [ "theora", "vorbis" ]); - assert.deepEqual(derivative.name, 'Foo'); - assert.deepEqual(derivative.short_name, 'Foo'); - assert.deepEqual(derivative.width, 120); - assert.deepEqual(derivative.height, 120); - }); - - it('spoken Wikipedia file is correctly identified', () => { - const result = media.getMediaItemInfoFromPage(spokenWikipedia)[0]; - assert.deepEqual(result.audio_type, 'spoken'); - }); - - it('pronunciation audio file is correctly identified', () => { - const result = media.getMediaItemInfoFromPage(pronunciationAudio)[0]; - assert.deepEqual(result.title, 'File:Foo'); - assert.deepEqual(result.type, 'audio'); - assert.deepEqual(result.audio_type, 'pronunciation'); - }); - -}); -- To view, visit https://gerrit.wikimedia.org/r/396031 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9c4d424dcbb5513d717b38f14c48a1944d756f44 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/services/mobileapps Gerrit-Branch: master Gerrit-Owner: Mholloway <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
