Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Protection banner/testcases
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- Load necessary modules local mProtectionBanner = require('Module:Protection banner/sandbox') local ScribuntoUnit = require('Module:ScribuntoUnit') -- Get the classes local Protection = mProtectionBanner._exportClasses().Protection local Blurb = mProtectionBanner._exportClasses().Blurb local BannerTemplate = mProtectionBanner._exportClasses().BannerTemplate local Banner = mProtectionBanner._exportClasses().Banner local Padlock = mProtectionBanner._exportClasses().Padlock -- Initialise test suite local suite = ScribuntoUnit:new() -------------------------------------------------------------------------------- -- Default values -------------------------------------------------------------------------------- local d = {} d.reason = 'vandalism' d.action = 'edit' d.level = 'sysop' d.page = 'User:Example' d.talkPage = 'User talk:Example' d.baseText = 'Example' d.namespace = 2 -- Namespace of d.page d.namespaceFragment = 'user' -- namespace fragment of d.page for makeProtectionCategory d.categoryNamespaceKeys = {[d.namespace] = d.namespaceFragment} -- namespace key config table d.expiry = '1 January 9999' d.expiryU = 253370764800 -- d.expiry in Unix time d.expiryFragment = 'temp' -- expiry fragment of d.expiry for makeProtectionCategory d.protectionDate = '1 January 2000' d.protectionDateU = 946684800 -- d.protectionDate in Unix time -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- function suite:assertError(func, args, msg) args = args or {} local success, result = pcall(func, unpack(args)) self:assertFalse(success) if msg then self:assertStringContains(msg, result, true) -- does a plain match end end function suite:assertNotError(func, args) args = args or {} local success, result = pcall(func, unpack(args)) self:assertTrue(success) end local function makeTitleObject(options) local title = mw.title.new(options.page) -- Set protection levels local levels = { edit = {}, move = {}, autoreview = {} } for _, action in ipairs{'edit', 'move', 'autoreview'} do local level = options[action] if level then levels[action][1] = level end end rawset(title, 'protectionLevels', levels) -- Set content model rawset(title, 'contentModel', options.contentModel or 'wikitext') return title end local function makeDefaultTitleObject() return makeTitleObject{page = d.page, [d.action] = d.level} end -- Make an alias, to be clear the object is for a protected page. local makeProtectedTitleObject = makeDefaultTitleObject local function makeConfig(t) local cfg = { masterBanner = {}, padlockIndicatorNames = {}, indefImageReasons = {}, reasonsWithNamespacePriority = {}, categoryNamespaceKeys = {}, protectionCategories = {}, reasonsWithoutExpiryCheck = {}, expiryCheckActions = {}, pagetypes = {}, indefStrings = {}, hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, wrappers = {}, msg = {} } local protLevelFields = { 'defaultBanners', 'banners', 'protectionBlurbs', 'explanationBlurbs', 'protectionLevels', 'images', 'imageLinks' } for _, field in ipairs(protLevelFields) do cfg[field] = { edit = {}, move = {}, autoreview = {} } end -- Add fields that cause errors if not present cfg.masterBanner.text = 'reason text' -- Add custom fields for k, v in pairs(t or {}) do cfg[k] = v end return cfg end local function makeDefaultProtectionObject(cfg) cfg = makeConfig(cfg) if next(cfg.categoryNamespaceKeys) == nil then -- cfg.categoryNamespaceKeys is empty cfg.categoryNamespaceKeys = d.categoryNamespaceKeys end local obj = Protection.new( {d.reason, action = d.action, expiry = d.expiry}, cfg, makeDefaultTitleObject() ) obj.expiry = d.expiryU -- Hack to override [[Module:Effective protection expiry]] return obj end local function makeProtectionCategoryKey(testFragments, defaults) local fragments = { expiry = 'all', namespace = 'all', reason = 'all', level = 'all', action = 'all' } for i, t in ipairs{defaults or {}, testFragments} do for k, v in pairs(t) do fragments[k] = v end end local key = { fragments.expiry, fragments.namespace, fragments.reason, fragments.level, fragments.action } return table.concat(key, '|') end local function makeDefaultProtectionCategoryKey(testFragments) local defaults = { expiry = d.expiryFragment, namespace = d.namespaceFragment, reason = d.reason, level = d.level, action = d.action } return makeProtectionCategoryKey(testFragments, defaults) end local function makeDefaultBlurbObject(cfg) cfg = makeConfig(cfg) return Blurb.new( makeDefaultProtectionObject(), {}, cfg ) end local function makeDefaultBannerTemplateObject(cfg) cfg = makeConfig(cfg) return BannerTemplate.new( makeDefaultProtectionObject(), cfg ) end local function makeDefaultBannerObject(cfg) cfg = makeConfig(cfg) return Banner.new( makeDefaultProtectionObject(), makeDefaultBlurbObject(), cfg ) end local function makeDefaultPadlockObject(cfg) cfg = makeConfig(cfg) return Padlock.new( makeDefaultProtectionObject(), makeDefaultBlurbObject(), cfg ) end local padlockPattern = '\127[^\127]*UNIQ%-%-indicator%-%x+%-QINU[^\127]*\127' function suite:assertIsPadlock(s, msg) self:assertStringContains( padlockPattern, s, false, msg ) end function suite:assertNoPadlock(s, msg) self:assertNotStringContains( padlockPattern, s, false, msg ) end function suite:assertIsBanner(s, msg) self:assertStringContains( 'class="[^"]*mbox[^"]*"', s, false, msg ) self:assertStringContains( 'role="presentation"', s, true, msg ) self:assertNotStringContains( 'id="protected-icon"', s, true, msg ) self:assertNotStringContains( 'topicon', s, true, msg ) end function suite:assertNoBanner(s, msg) self:assertNotStringContains( 'class="[^"]*mbox[^"]*"', s, false, msg ) self:assertNotStringContains( 'role="presentation"', s, true, msg ) self:assertNotStringContains( 'id="protected-icon"', s, true, msg ) self:assertNotStringContains( 'topicon', s, true, msg ) end -------------------------------------------------------------------------------- -- Protection object tests -------------------------------------------------------------------------------- -- Protection action function suite:testProtectionActionError() suite:assertError( Protection.new, {{action = 'foo'}, makeConfig()}, 'invalid action: foo' ) end function suite:testProtectionActionEdit() local obj = Protection.new({action = 'edit'}, makeConfig()) suite:assertEquals('edit', obj.action) end function suite:testProtectionActionMove() local obj = Protection.new({action = 'move'}, makeConfig()) suite:assertEquals('move', obj.action) end function suite:testProtectionActionAutoreview() local obj = Protection.new({action = 'autoreview'}, makeConfig()) suite:assertEquals('autoreview', obj.action) end function suite:testProtectionActionUpload() local obj = Protection.new({action = 'upload'}, makeConfig()) suite:assertEquals('upload', obj.action) end function suite:testProtectionNoAction() local obj = Protection.new({}, makeConfig()) suite:assertEquals('edit', obj.action) end -- Protection level function suite:testProtectionSemi() local obj = Protection.new( {action = 'edit'}, makeConfig(), makeTitleObject{page = 'Foo', edit = 'autoconfirmed'} ) self:assertEquals('autoconfirmed', obj.level) end function suite:testProtectionFull() local obj = Protection.new( {action = 'edit'}, makeConfig(), makeTitleObject{page = 'Foo', edit = 'sysop'} ) self:assertEquals('sysop', obj.level) end function suite:testProtectionUnprotected() local obj = Protection.new( {action = 'edit'}, makeConfig(), makeTitleObject{page = 'Foo', edit = nil} ) self:assertEquals('*', obj.level) end function suite:testProtectionSemiMove() local obj = Protection.new( {action = 'move'}, makeConfig(), makeTitleObject{page = 'Foo', move = 'autoconfirmed'} ) self:assertEquals('*', obj.level) end function suite:testProtectionTemplate() local obj = Protection.new( {action = 'edit'}, makeConfig(), makeTitleObject{page = 'Template:Foo', edit = 'templateeditor'} ) self:assertEquals('templateeditor', obj.level) end function suite:testProtectionTitleBlacklist() local obj = Protection.new( {action = 'edit'}, makeConfig(), makeTitleObject{page = 'Template:Editnotices/Page/Foo', edit = nil} ) self:assertEquals('templateeditor', obj.level) end -- Reason function suite:testProtectionReason() local obj = Protection.new( {'foo'}, makeConfig() ) self:assertEquals('foo', obj.reason) end function suite:testProtectionReasonLowerCase() local obj = Protection.new( {'fOO'}, makeConfig() ) self:assertEquals('foo', obj.reason) end function suite:testProtectionBadReason() self:assertError( Protection.new, {{'foo|bar'}, makeConfig()}, 'reasons cannot contain the pipe character ("|")' ) end function suite:testProtectionNoReason() local obj = Protection.new( {}, makeConfig() ) self:assertEquals(nil, obj.reason) end -- Protection date function suite:testProtectionProtectionDateIndef() self:assertError( Protection.new, { {date = 'indefinite'}, makeConfig{indefStrings = {indefinite = true}} }, 'invalid protection date: indefinite' ) end function suite:testProtectionProtectionDateTemp() local obj = Protection.new( {date = d.protectionDate}, makeConfig() ) self:assertEquals(d.protectionDateU, obj.protectionDate) end function suite:testProtectionNoProtectionDate() local obj = Protection.new( {}, makeConfig() ) self:assertEquals(nil, obj.protectionDate) end function suite:testProtectionBadProtectionDate() self:assertError( Protection.new, { {date = 'foobar'}, makeConfig{indefStrings = {indefinite = true}} }, 'invalid protection date: foobar' ) end -- bannerConfig function suite:testProtectionMasterBannerConfigPrecedence1() local masterBanner = {text = 'master banner text'} local obj = makeDefaultProtectionObject{masterBanner = masterBanner} self:assertEquals('master banner text', obj.bannerConfig.text) end function suite:testProtectionMasterBannerConfigPrecedence2() local masterBanner = {text = 'master banner text'} local defaultBanners = {[d.action] = {default = {text = 'defaultBanners default text'}}} local obj = makeDefaultProtectionObject(makeConfig{ masterBanner = masterBanner, defaultBanners = defaultBanners }) self:assertEquals('defaultBanners default text', obj.bannerConfig.text) end function suite:testProtectionMasterBannerConfigPrecedence3() local defaultBanners = {[d.action] = { [d.level] = {text = 'defaultBanners level text'}, default = {text = 'defaultBanners default text'} }} local obj = makeDefaultProtectionObject(makeConfig{defaultBanners = defaultBanners}) self:assertEquals('defaultBanners level text', obj.bannerConfig.text) end function suite:testProtectionMasterBannerConfigPrecedence4() local defaultBanners = {[d.action] = { [d.level] = {text = 'defaultBanners level text'} }} local banners = {[d.action] ={ [d.reason] = {text = 'banners text'} }} local obj = makeDefaultProtectionObject(makeConfig{ defaultBanners = defaultBanners, banners = banners }) self:assertEquals('banners text', obj.bannerConfig.text) end function suite:testProtectionMasterBannerConfigFields() local masterBanner = { text = 'master banner text', explanation = 'master banner explanation', tooltip = 'master banner tooltip', alt = 'master banner alt', link = 'master banner link', image = 'master banner image' } local obj = makeDefaultProtectionObject{masterBanner = masterBanner} self:assertEquals('master banner text', obj.bannerConfig.text) self:assertEquals('master banner explanation', obj.bannerConfig.explanation) self:assertEquals('master banner tooltip', obj.bannerConfig.tooltip) self:assertEquals('master banner alt', obj.bannerConfig.alt) self:assertEquals('master banner link', obj.bannerConfig.link) self:assertEquals('master banner image', obj.bannerConfig.image) end -- isUserScript function suite:testProtectionIsUserScriptWithUserCSS() local protection = Protection.new( {}, makeConfig(), mw.title.new('User:Example/common.css') ) self:assertTrue(protection:isUserScript()) end function suite:testProtectionIsUserScriptWithUserJS() local protection = Protection.new( {}, makeConfig(), mw.title.new('User:Example/common.js') ) self:assertTrue(protection:isUserScript()) end function suite:testProtectionIsUserScriptWithUserPage() local protection = Protection.new( {}, makeConfig(), mw.title.new('User:Example') ) self:assertFalse(protection:isUserScript()) end function suite:testProtectionIsUserScriptWithNormalSubpage() local protection = Protection.new( {}, makeConfig(), mw.title.new('User:Example/common') ) self:assertFalse(protection:isUserScript()) end function suite:testProtectionIsUserScriptWithUsernameEndingInCSS() local protection = Protection.new( {}, makeConfig(), mw.title.new('User:My username ends in .css') ) self:assertFalse(protection:isUserScript()) end function suite:testProtectionIsUserScriptWithUsernameEndingInJS() self:assertFalse( Protection.new( {}, makeConfig(), mw.title.new('User:My username ends in .js') ):isUserScript() ) end function suite:testProtectionIsUserScriptWithSubpageContainingCSS() self:assertFalse( Protection.new( {}, makeConfig(), mw.title.new('User:Example/common.css.txt') ):isUserScript() ) end function suite:testProtectionIsUserScriptWithNoSubpagePrefix() self:assertTrue( Protection.new( {}, makeConfig(), mw.title.new('User:Example/.css') ):isUserScript() ) end function suite:testProtectionIsUserScriptWithBlankUsernameAndNoSubpagePrefix() self:assertTrue( Protection.new( {}, makeConfig(), mw.title.new('User:/.css') ):isUserScript() ) end function suite:testProtectionIsUserScriptWhenUsernameIsOnlyCSS() self:assertFalse( Protection.new( {}, makeConfig(), mw.title.new('User:.css') ):isUserScript() ) end function suite:testProtectionIsUserScriptWithNonstandardCSSContentModel() self:assertTrue( Protection.new( {}, makeConfig(), makeTitleObject{page='User:Example/foo', contentModel='css'} ):isUserScript() ) end function suite:testProtectionIsUserScriptWithNonstandardJSContentModel() self:assertTrue( Protection.new( {}, makeConfig(), makeTitleObject{page='User:Example/foo', contentModel='javascript'} ):isUserScript() ) end function suite:testProtectionIsUserScriptWithNonstandardWikitextContentModel() self:assertFalse( Protection.new( {}, makeConfig(), makeTitleObject{page='User:Example/foo.css', contentModel='wikitext'} ):isUserScript() ) end function suite:testProtectionIsUserScriptWithNonUserspacePage() self:assertFalse( Protection.new( {}, makeConfig(), makeTitleObject{page='Wikipedia:Example.css', contentModel='css'} ):isUserScript() ) end -- isProtected function suite:testProtectionIsProtectedTrue() local obj = makeDefaultProtectionObject() obj.level = 'autoconfirmed' self:assertTrue(obj:isProtected()) end function suite:testProtectionIsProtectedFalse() local obj = makeDefaultProtectionObject() obj.level = '*' self:assertFalse(obj:isProtected()) end -- shouldShowLock function suite:testProtectionShouldShowLockWithProtectedPage() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='Foo', edit='sysop'} ) self:assertTrue(obj:shouldShowLock()) end function suite:testProtectionShouldShowLockWithProtectedUserScript() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='User:Example/common.css', contentModel='css', edit='sysop'} ) self:assertFalse(obj:shouldShowLock()) end function suite:testProtectionShouldShowLockWithUnprotectedPage() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='Foo'} ) self:assertFalse(obj:shouldShowLock()) end -- shouldHaveProtectionCategory function suite:testProtectionShouldHaveProtectionCategoryWithProtectedPage() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='Foo', edit='sysop'} ) self:assertTrue(obj:shouldHaveProtectionCategory()) end function suite:testProtectionShouldHaveProtectionCategoryWithProtectedUserScript() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='User:Example/common.css', contentModel='css', edit='sysop'} ) self:assertFalse(obj:shouldHaveProtectionCategory()) end function suite:testProtectionShouldHaveProtectionCategoryWithUnprotectedPage() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='Foo'} ) self:assertFalse(obj:shouldHaveProtectionCategory()) end -- isTemporary function suite:testProtectionIsProtectedTrue() local obj = makeDefaultProtectionObject() obj.expiry = 123456789012 self:assertTrue(obj:isTemporary()) end function suite:testProtectionIsProtectedFalse1() local obj = makeDefaultProtectionObject() obj.expiry = 'indef' self:assertFalse(obj:isTemporary()) end function suite:testProtectionIsProtectedFalse2() local obj = makeDefaultProtectionObject() obj.expiry = nil self:assertFalse(obj:isTemporary()) end -- makeProtectionCategory -- function suite:testProtectionCategoryWithUnprotectedPage() local obj = Protection.new( {}, makeConfig(), makeTitleObject{page='Foo'} ) self:assertEquals(obj:makeProtectionCategory(), '') end function suite:testProtectionCategoryPrecedence1() -- Test that expiry has the lowest priority. local protectionCategories = { [makeDefaultProtectionCategoryKey{expiry = 'all'}] = 'all expiries allowed', [makeDefaultProtectionCategoryKey{namespace = 'all'}] = 'all namespaces allowed', [makeDefaultProtectionCategoryKey{reason = 'all'}] = 'all reasons allowed', [makeDefaultProtectionCategoryKey{level = 'all'}] = 'all levels allowed', [makeDefaultProtectionCategoryKey{action = 'all'}] = 'all actions allowed' } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'all expiries allowed', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence2() -- Test that reason has the highest priority. local protectionCategories = { [makeProtectionCategoryKey{expiry = d.expiryFragment}] = 'expiry only', [makeProtectionCategoryKey{namespace = d.namespaceFragment}] = 'namespace only', [makeProtectionCategoryKey{reason = d.reason}] = 'reason only', [makeProtectionCategoryKey{level = d.level}] = 'level only', [makeProtectionCategoryKey{action = d.action}] = 'action only' } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'reason only', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence3() -- Test that namespace has the highest priority if the reason is set in -- cfg.reasonsWithNamespacePriority. local protectionCategories = { [makeProtectionCategoryKey{expiry = d.expiryFragment}] = 'expiry only', [makeProtectionCategoryKey{namespace = d.namespaceFragment}] = 'namespace only', [makeProtectionCategoryKey{reason = d.reason}] = 'reason only', [makeProtectionCategoryKey{level = d.level}] = 'level only', [makeProtectionCategoryKey{action = d.action}] = 'action only' } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, reasonsWithNamespacePriority = {[d.reason] = true} } self:assertStringContains( 'namespace only', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence4() -- Test that level has a higher priority than namespace. local protectionCategories = { [makeDefaultProtectionCategoryKey{namespace = 'all'}] = 'all namespaces allowed', [makeDefaultProtectionCategoryKey{level = 'all'}] = 'all levels allowed', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'all namespaces allowed', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence5() -- Test that action has a higher priority than level. local protectionCategories = { [makeDefaultProtectionCategoryKey{level = 'all'}] = 'all levels allowed', [makeDefaultProtectionCategoryKey{action = 'all'}] = 'all actions allowed', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'all levels allowed', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence6() -- Test that an exact match will be first. local protectionCategories = { [makeDefaultProtectionCategoryKey()] = 'exact match', [makeDefaultProtectionCategoryKey{action = 'all'}] = 'all actions allowed', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'exact match', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence7() -- Test that matching 4 keys will come before matching 3 keys local protectionCategories = { [makeDefaultProtectionCategoryKey{action = 'all'}] = 'four keys', [makeDefaultProtectionCategoryKey{action = 'all', level = 'all'}] = 'three keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'four keys', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence8() -- Test that matching 3 keys will come before matching 2 keys local protectionCategories = { [makeProtectionCategoryKey{reason = d.reason, action = d.action, level = d.level}] = 'three keys', [makeProtectionCategoryKey{reason = d.reason, action = d.action}] = 'two keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'three keys', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence9() -- Test that matching 2 keys will come before matching 1 key local protectionCategories = { [makeProtectionCategoryKey{action = d.action, level = d.level}] = 'two keys', [makeProtectionCategoryKey{action = d.action}] = 'one key', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'two keys', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryPrecedence10() -- Test that matching 1 keys will come before matching 0 keys local protectionCategories = { [makeProtectionCategoryKey{action = d.action}] = 'one key', [makeProtectionCategoryKey()] = 'no keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'one key', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryAllAlls() -- Test that 'all|all|all|all|all' works local protectionCategories = { [makeProtectionCategoryKey()] = 'no keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'no keys', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryNoFalseMatches() -- Test that we don't match things that we aren't supposed to. local protectionCategories = { [makeProtectionCategoryKey{expiry = 'foo'}] = 'expiry foo', [makeProtectionCategoryKey{namespace = 'foo'}] = 'namespace foo', [makeProtectionCategoryKey{reason = 'foo'}] = 'reason foo', [makeProtectionCategoryKey{level = 'foo'}] = 'level foo', [makeProtectionCategoryKey{action = 'foo'}] = 'action foo', [makeProtectionCategoryKey()] = 'no keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( 'no keys', obj:makeProtectionCategory(), true ) end function suite:testProtectionCategoryProtected() -- Test that protected pages produce some kind of category link. local protectionCategories = { [makeProtectionCategoryKey()] = 'no keys', } local obj = makeDefaultProtectionObject{ protectionCategories = protectionCategories, } self:assertStringContains( '^%[%[Category:.*%]%]$', obj:makeProtectionCategory() ) end function suite:testProtectionCategoryNotProtected() -- Test that unprotected pages produce the blank string. local protectionCategories = { [makeProtectionCategoryKey()] = 'no keys', } local obj = Protection.new( {}, makeConfig{protectionCategories = protectionCategories}, makeTitleObject{page = d.page, 'edit', nil} ) self:assertEquals('', obj:makeProtectionCategory()) end function suite:testProtectionCategoryNoMatch() -- Test that protected pages that don't match any categories -- produce the blank string. local obj = makeDefaultProtectionObject() self:assertEquals('', obj:makeProtectionCategory()) end function suite:testProtectionCategoryExpiryIndef() -- Test that indefinite protection matches the "indef" expiry fragment. local obj = makeDefaultProtectionObject() obj._cfg.protectionCategories = { [makeProtectionCategoryKey{expiry = 'indef', action = 'autoreview'}] = 'indef expiry', } obj.action = 'autoreview' obj.level = 'autoconfirmed' obj.expiry = 'indef' self:assertStringContains('indef expiry', obj:makeProtectionCategory(), true) end function suite:testProtectionCategoryExpiryTemp() -- Test that temporary protection matches the "temp" expiry fragment. local obj = makeDefaultProtectionObject() obj._cfg.protectionCategories = { [makeProtectionCategoryKey{expiry = 'temp', action = 'autoreview'}] = 'temporary expiry', } obj.action = 'autoreview' obj.level = 'autoconfirmed' obj.expiry = d.expiryU self:assertStringContains('temporary expiry', obj:makeProtectionCategory(), true) end function suite:testProtectionCategoryNoExpiry() -- Test that pages with no expiry set don't match "indef" or "temp". local protectionCategories = { [makeProtectionCategoryKey{expiry = 'temp', action = 'autoreview' }] = 'temporary expiry', [makeProtectionCategoryKey{expiry = 'indef', action = 'autoreview' }] = 'indefinite expiry', [makeProtectionCategoryKey()] = 'no matches' } local obj = Protection.new( {}, makeConfig{protectionCategories = protectionCategories}, makeProtectedTitleObject() ) self:assertStringContains('no matches', obj:makeProtectionCategory(), true) end function suite:testProtectionCategoryNamespaceFragment() -- Test that values in cfg.categoryNamespaceKeys will work. local protectionCategories = { [makeProtectionCategoryKey{namespace = 'foobar'}] = 'we found a match', } local obj = Protection.new( {}, makeConfig{ protectionCategories = protectionCategories, categoryNamespaceKeys = {[10] = 'foobar'} -- Template namespace }, makeTitleObject{page = 'Template:Foo', edit = 'autoconfirmed'} ) self:assertStringContains('we found a match', obj:makeProtectionCategory(), true) end function suite:testProtectionCategoryTalk() -- Test that talk pages match the "talk" namespace fragment. local protectionCategories = { [makeProtectionCategoryKey{namespace = 'talk'}] = 'talk namespace', } local obj = Protection.new( {}, makeConfig{protectionCategories = protectionCategories}, makeTitleObject{page = 'Template talk:Example', edit = 'autoconfirmed'} ) self:assertStringContains('talk namespace', obj:makeProtectionCategory(), true) end -- isIncorrect function suite:testProtectionIsIncorrectTrue1() local obj = makeDefaultProtectionObject() function obj:isProtected() return false end self:assertTrue(obj:isIncorrect(), 'Protection:isProtected() returned false') end function suite:testProtectionIsIncorrectTrue2() local obj = makeDefaultProtectionObject() function obj:isProtected() return true end obj.expiry = 0 self:assertTrue(obj:isIncorrect(), 'the page is protected and expiry is in the past') end function suite:testProtectionIsIncorrectFalse1() local obj = makeDefaultProtectionObject() function obj:isProtected() return true end obj.expiry = d.expiryU self:assertFalse(obj:isIncorrect(), 'the page is protected and expiry is in the future') end function suite:testProtectionIsIncorrectFalse2() local obj = makeDefaultProtectionObject() obj.expiry = nil function obj:isProtected() return true end self:assertFalse(obj:isIncorrect(), 'the page is protected and no expiry is set') end -- isTemplateProtectedNonTemplate function suite:testProtectionIsTemplateProtectedNonTemplateFalse1() local obj = makeDefaultProtectionObject() obj.level = 'autoconfirmed' self:assertFalse(obj:isTemplateProtectedNonTemplate(), 'the page is semi-protected') end function suite:testProtectionIsTemplateProtectedNonTemplateFalse2() local obj = makeDefaultProtectionObject() obj.level = 'templateeditor' obj.action = 'edit' rawset(obj.title, 'namespace', 10) -- template space self:assertFalse(obj:isTemplateProtectedNonTemplate(), 'template-protected template') end function suite:testProtectionIsTemplateProtectedNonTemplateFalse3() local obj = makeDefaultProtectionObject() obj.level = 'templateeditor' obj.action = 'edit' rawset(obj.title, 'namespace', 828) -- module space self:assertFalse(obj:isTemplateProtectedNonTemplate(), 'template-protected module') end function suite:testProtectionIsTemplateProtectedNonTemplateFalse4() local obj = makeDefaultProtectionObject() obj.level = 'templatemoveor' obj.action = 'move' rawset(obj.title, 'namespace', 10) -- template space self:assertFalse(obj:isTemplateProtectedNonTemplate(), 'template-move-protected template') end function suite:testProtectionIsTemplateProtectedNonTemplateFalse5() local obj = makeDefaultProtectionObject() obj.level = 'templatemoveor' obj.action = 'move' rawset(obj.title, 'namespace', 828) -- module space self:assertFalse(obj:isTemplateProtectedNonTemplate(), 'template-move-protected module') end function suite:testProtectionIsTemplateProtectedNonTemplateTrue1() local obj = makeDefaultProtectionObject() obj.level = 'templateeditor' obj.action = 'autoreview' self:assertTrue(obj:isTemplateProtectedNonTemplate(), 'the action is not edit or move') end function suite:testProtectionIsTemplateProtectedNonTemplateTrue2() local obj = makeDefaultProtectionObject() obj.level = 'templateeditor' rawset(obj.title, 'namespace', 2) -- user space self:assertTrue(obj:isTemplateProtectedNonTemplate(), 'the action is not in template or module space') end -- makeCategoryLinks function suite:testProtectionMakeCategoryLinksAllPresent() local obj = makeDefaultProtectionObject() obj._cfg.msg = { ['tracking-category-incorrect'] = 'Incorrect category', ['tracking-category-template'] = 'Template category' } function obj:makeProtectionCategory() return '[[Category:Protection category|' .. d.baseText .. ']]' end for _, field in ipairs{'isIncorrect', 'isTemplateProtectedNonTemplate'} do obj[field] = function () return true end end self:assertEquals( '[[Category:Protection category|' .. d.baseText .. ']]' .. '[[Category:Incorrect category|' .. d.baseText .. ']]' .. '[[Category:Template category|' .. d.baseText .. ']]', obj:makeCategoryLinks() ) end function suite:testProtectionMakeCategoryLinksAllAbsent() local obj = makeDefaultProtectionObject() obj._cfg.msg = { ['tracking-category-expiry'] = 'Expiry category', ['tracking-category-incorrect'] = 'Incorrect category', ['tracking-category-template'] = 'Template category' } function obj:makeProtectionCategory() return '' end for _, field in ipairs{'needsExpiry', 'isIncorrect', 'isTemplateProtectedNonTemplate'} do obj[field] = function () return false end end self:assertEquals('', obj:makeCategoryLinks()) end -------------------------------------------------------------------------------- -- Blurb class tests -------------------------------------------------------------------------------- -- initialize function suite:testBlurbNew() local obj = Blurb.new({'foo'}, {'bar'}, {'baz'}) self:assertEquals('foo', obj._protectionObj[1]) self:assertEquals('bar', obj._args[1]) self:assertEquals('baz', obj._cfg[1]) end -- _formatDate function suite:testBlurbFormatDateStandard() local obj = makeDefaultBlurbObject() self:assertEquals('1 January 1970', obj:_formatDate(0)) end function suite:testBlurbFormatDateCustom() local obj = makeDefaultBlurbObject{msg = {['expiry-date-format'] = 'Y Y F F j'}} self:assertEquals('1970 1970 January January 1', obj:_formatDate(0)) end function suite:testBlurbFormatDateError() local obj = makeDefaultBlurbObject() self:assertEquals(nil, obj:_formatDate('foo')) end -- _getExpandedMessage function suite:testBlurbGetExpandedMessage() local obj = makeDefaultBlurbObject() function obj:_substituteParameters(s) return 'testing ' .. s end obj._cfg.msg = {['test-key'] = 'test message'} self:assertEquals('testing test message', obj:_getExpandedMessage('test-key')) end -- _substituteParameters function suite:testBlurbSubstituteParameters() local obj = makeDefaultBlurbObject() obj._makeCurrentVersionParameter = function () return '1' end obj._makeEditRequestParameter = function () return '2' end obj._makeExpiryParameter = function () return '3' end obj._makeExplanationBlurbParameter = function () return '4' end obj._makeImageLinkParameter = function () return '5' end obj._makeIntroBlurbParameter = function () return '6' end obj._makeIntroFragmentParameter = function () return '7' end obj._makePagetypeParameter = function () return '8' end obj._makeProtectionBlurbParameter = function () return '9' end obj._makeProtectionDateParameter = function () return '10' end obj._makeProtectionLevelParameter = function () return '11' end obj._makeProtectionLogParameter = function () return '12' end obj._makeTalkPageParameter = function () return '13' end obj._makeTooltipBlurbParameter = function () return '14' end obj._makeTooltipFragmentParameter = function () return '15' end obj._makeVandalTemplateParameter = function () return '16' end local msg = '${CURRENTVERSION}-' .. '${EDITREQUEST}-' .. '${EXPIRY}-' .. '${EXPLANATIONBLURB}-' .. '${IMAGELINK}-' .. '${INTROBLURB}-' .. '${INTROFRAGMENT}-' .. '${PAGETYPE}-' .. '${PROTECTIONBLURB}-' .. '${PROTECTIONDATE}-' .. '${PROTECTIONLEVEL}-' .. '${PROTECTIONLOG}-' .. '${TALKPAGE}-' .. '${TOOLTIPBLURB}-' .. '${TOOLTIPFRAGMENT}-' .. '${VANDAL}' local expected = '1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16' self:assertEquals(expected, obj:_substituteParameters(msg)) end -- makeCurrentVersionParameter function suite:testBlurbMakeCurrentVersionParameterEdit() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'edit' obj._cfg.msg['current-version-edit-display'] = 'edit display' self:assertEquals( '[//en.wikipedia.org/w/index.php?title=' .. mw.uri.encode(d.page) .. '&action=history edit display]', obj:_makeCurrentVersionParameter() ) end function suite:testBlurbMakeCurrentVersionParameterMove() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'move' obj._cfg.msg['current-version-move-display'] = 'move display' self:assertEquals( '[//en.wikipedia.org/w/index.php?title=' .. mw.uri.encode('Special:Log') .. '&page=' .. mw.uri.encode(d.page) .. '&type=move move display]', obj:_makeCurrentVersionParameter() ) end -- _makeEditRequestParameter function suite:testBlurbMakeEditRequestParameterLevels() -- We can't test the edit requests directly as that is the responsibility of -- [[Module:Submit an edit request]], but we can check that we get different -- outputs for different protection levels. local function makeBlurbObjectWithLevels(action, level) local obj = makeDefaultBlurbObject() obj._protectionObj.action = action obj._protectionObj.level = level obj._cfg.msg['edit-request-display'] = 'display' return obj end local obj1 = makeBlurbObjectWithLevels('edit', 'autoconfirmed') local obj2 = makeBlurbObjectWithLevels('edit', 'templateeditor') local obj3 = makeBlurbObjectWithLevels('edit', 'sysop') local obj4 = makeBlurbObjectWithLevels('move', 'templateeditor') self:assertFalse(obj1:_makeEditRequestParameter() == obj2:_makeEditRequestParameter()) self:assertFalse(obj2:_makeEditRequestParameter() == obj3:_makeEditRequestParameter()) self:assertEquals(obj3:_makeEditRequestParameter(), obj4:_makeEditRequestParameter()) end function suite:testBlurbMakeEditRequestParameterLink() -- Check that the edit request links have features that we can always expect -- to be there. The rest is subject to be changed by [[Module:Submit an edit request]] -- at any time, so we won't test that here. local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'edit' obj._protectionObj.level = 'autoconfirmed' obj._cfg.msg['edit-request-display'] = 'the edit request display' self:assertStringContains( '//en.wikipedia.org/w/index.php?', obj:_makeEditRequestParameter(), true ) self:assertStringContains( 'action=edit', obj:_makeEditRequestParameter(), true ) self:assertStringContains( 'title=[a-zA-Z0-9%%_]*[tT]alk', obj:_makeEditRequestParameter(), false ) self:assertStringContains( 'the edit request display', obj:_makeEditRequestParameter(), true ) end -- _makeExpiryParameter function suite:testBlurbMakeExpiryParameterTemp() local obj = makeDefaultBlurbObject() obj._protectionObj.expiry = 0 function obj:_formatDate(num) return 'unix date is ' .. tostring(num) end self:assertEquals('unix date is 0', obj:_makeExpiryParameter()) end function suite:testBlurbMakeExpiryParameterOther() local obj = makeDefaultBlurbObject() obj._protectionObj.expiry = 'indef' function obj:_formatDate(num) return 'unix date is ' .. tostring(num) end self:assertEquals('indef', obj:_makeExpiryParameter()) end -- _makeExplanationBlurbParameter function suite:testBlurbMakeExplanationBlurbParameter() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'edit' obj._protectionObj.level = 'autoconfirmed' rawset(obj._protectionObj.title, 'isTalkPage', true) obj._cfg.explanationBlurbs = { edit = { autoconfirmed = { talk = 'edit-autoconfirmed-talk', default = 'edit-autoconfirmed-default' }, default = { talk = 'edit-default-talk', default = 'edit-default-default' } } } function obj:_substituteParameters(msg) return msg end self:assertEquals( 'edit-autoconfirmed-talk', obj:_makeExplanationBlurbParameter() ) obj._cfg.explanationBlurbs.edit.autoconfirmed.talk = nil self:assertEquals( 'edit-autoconfirmed-default', obj:_makeExplanationBlurbParameter() ) obj._cfg.explanationBlurbs.edit.autoconfirmed.default = nil self:assertEquals( 'edit-default-talk', obj:_makeExplanationBlurbParameter() ) obj._cfg.explanationBlurbs.edit.default.talk = nil self:assertEquals( 'edit-default-default', obj:_makeExplanationBlurbParameter() ) obj._cfg.explanationBlurbs.edit.default.default = nil self:assertError( obj._makeExplanationBlurbParameter, {obj}, 'could not find explanation blurb for action "edit",' .. ' level "autoconfirmed" and talk key "talk"' ) end function suite:testBlurbMakeExplanationBlurbParameterSpecialCases() local obj = makeDefaultBlurbObject() rawset(obj._protectionObj.title, 'namespace', 8) function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( 'the key is explanation-blurb-nounprotect', obj:_makeExplanationBlurbParameter() ) end -- _makeImageLinkParameter function suite:testBlurbMakeImageLinkParameter() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'move' obj._protectionObj.level = 'sysop' obj._cfg.imageLinks = { edit = { sysop = 'edit-sysop', default = 'edit-default' }, move = { sysop = 'move-sysop', default = 'move-default' } } function obj:_substituteParameters(msg) return msg end self:assertEquals( 'move-sysop', obj:_makeImageLinkParameter() ) obj._cfg.imageLinks.move.sysop = nil self:assertEquals( 'move-default', obj:_makeImageLinkParameter() ) obj._cfg.imageLinks.move.default = nil self:assertEquals( 'edit-default', obj:_makeImageLinkParameter() ) end -- _makeIntroBlurbParameter function suite:testBlurbMakeIntroBlurbParameter() local obj = makeDefaultBlurbObject() function obj._protectionObj:isTemporary() return true end function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( 'the key is intro-blurb-expiry', obj:_makeIntroBlurbParameter() ) function obj._protectionObj:isTemporary() return false end self:assertEquals( 'the key is intro-blurb-noexpiry', obj:_makeIntroBlurbParameter() ) end -- _makeIntroFragmentParameter function suite:testBlurbMakeIntroFragmentParameter() local obj = makeDefaultBlurbObject() function obj._protectionObj:isTemporary() return true end function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( 'the key is intro-fragment-expiry', obj:_makeIntroFragmentParameter() ) function obj._protectionObj:isTemporary() return false end self:assertEquals( 'the key is intro-fragment-noexpiry', obj:_makeIntroFragmentParameter() ) end -- _makePagetypeParameter function suite:testPagetypeParameter() local obj = makeDefaultBlurbObject() rawset(obj._protectionObj.title, 'namespace', 3) obj._cfg.pagetypes = { [3] = 'user talk page', default = 'default page' } self:assertEquals( 'user talk page', obj:_makePagetypeParameter() ) obj._cfg.pagetypes[3] = nil self:assertEquals( 'default page', obj:_makePagetypeParameter() ) obj._cfg.pagetypes.default = nil self:assertError( obj._makePagetypeParameter, {obj}, 'no default pagetype defined' ) end -- _makeProtectionBlurbParameter function suite:testBlurbMakeProtectionBlurbParameter() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'move' obj._protectionObj.level = 'sysop' obj._cfg.protectionBlurbs = { edit = { sysop = 'edit-sysop', default = 'edit-default' }, move = { sysop = 'move-sysop', default = 'move-default' } } function obj:_substituteParameters(msg) return msg end self:assertEquals( 'move-sysop', obj:_makeProtectionBlurbParameter() ) obj._cfg.protectionBlurbs.move.sysop = nil self:assertEquals( 'move-default', obj:_makeProtectionBlurbParameter() ) obj._cfg.protectionBlurbs.move.default = nil self:assertEquals( 'edit-default', obj:_makeProtectionBlurbParameter() ) obj._cfg.protectionBlurbs.edit.default = nil self:assertError( obj._makeProtectionBlurbParameter, {obj}, 'no protection blurb defined for protectionBlurbs.edit.default' ) end -- _makeProtectionDateParameter function suite:testBlurbMakeProtectionDateParameter() local obj = makeDefaultBlurbObject() obj._protectionObj.protectionDate = 0 function obj:_formatDate(num) return 'unix date is ' .. tostring(num) end self:assertEquals('unix date is 0', obj:_makeProtectionDateParameter()) obj._protectionObj.protectionDate = 'indef' self:assertEquals('indef', obj:_makeProtectionDateParameter()) end -- _makeProtectionLevelParameter function suite:testBlurbMakeProtectionLevelParameter() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'move' obj._protectionObj.level = 'sysop' obj._cfg.protectionLevels = { edit = { sysop = 'edit-sysop', default = 'edit-default' }, move = { sysop = 'move-sysop', default = 'move-default' } } function obj:_substituteParameters(msg) return msg end self:assertEquals( 'move-sysop', obj:_makeProtectionLevelParameter() ) obj._cfg.protectionLevels.move.sysop = nil self:assertEquals( 'move-default', obj:_makeProtectionLevelParameter() ) obj._cfg.protectionLevels.move.default = nil self:assertEquals( 'edit-default', obj:_makeProtectionLevelParameter() ) obj._cfg.protectionLevels.edit.default = nil self:assertError( obj._makeProtectionLevelParameter, {obj}, 'no protection level defined for protectionLevels.edit.default' ) end -- _makeProtectionLogParameter function suite:testBlurbMakeProtectionLogParameterPC() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'autoreview' function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertStringContains( '^%[//en%.wikipedia%.org/w/index%.php?', obj:_makeProtectionLogParameter(), false ) self:assertStringContains( 'title=' .. mw.uri.encode('Special:Log'), obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'type=stable', obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'page=' .. mw.uri.encode(d.page), obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'the key is pc%-log%-display%]$', obj:_makeProtectionLogParameter(), false ) end function suite:testBlurbMakeProtectionLogParameterProtection() local obj = makeDefaultBlurbObject() obj._protectionObj.action = 'edit' function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertStringContains( '^%[//en%.wikipedia%.org/w/index%.php?', obj:_makeProtectionLogParameter(), false ) self:assertStringContains( 'title=' .. mw.uri.encode('Special:Log'), obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'type=protect', obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'page=' .. mw.uri.encode(d.page), obj:_makeProtectionLogParameter(), true ) self:assertStringContains( 'the key is protection%-log%-display%]$', obj:_makeProtectionLogParameter(), false ) end -- _makeTalkPageParameter function suite:testBlurbMakeTalkPageParameter() local obj = makeDefaultBlurbObject() function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( '[[' .. d.talkPage .. '#top|' .. 'the key is talk-page-link-display' .. ']]', obj:_makeTalkPageParameter() ) obj._args.section = 'talk section' self:assertEquals( '[[' .. d.talkPage .. '#talk section|' .. 'the key is talk-page-link-display' .. ']]', obj:_makeTalkPageParameter() ) end -- _makeTooltipBlurbParameter function suite:testBlurbMakeTooltipBlurbParameter() local obj = makeDefaultBlurbObject() function obj._protectionObj:isTemporary() return true end function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( 'the key is tooltip-blurb-expiry', obj:_makeTooltipBlurbParameter() ) function obj._protectionObj:isTemporary() return false end self:assertEquals( 'the key is tooltip-blurb-noexpiry', obj:_makeTooltipBlurbParameter() ) end -- _makeTooltipFragmentParameter function suite:testBlurbMakeTooltipFragmentParameter() local obj = makeDefaultBlurbObject() function obj._protectionObj:isTemporary() return true end function obj:_getExpandedMessage(key) return 'the key is ' .. key end self:assertEquals( 'the key is tooltip-fragment-expiry', obj:_makeTooltipFragmentParameter() ) function obj._protectionObj:isTemporary() return false end self:assertEquals( 'the key is tooltip-fragment-noexpiry', obj:_makeTooltipFragmentParameter() ) end -- _makeVandalTemplateParameter function suite:testBlurbMakeVandalTemplateParameter() local obj = makeDefaultBlurbObject() self:assertStringContains( d.baseText, obj:_makeVandalTemplateParameter(), true ) obj._args.user = 'Some user' self:assertStringContains( 'Some user', obj:_makeVandalTemplateParameter(), true ) end -- makeBannerText function suite:testBlurbMakeBannerTextBadInput() local obj = makeDefaultBlurbObject() self:assertError( obj.makeBannerText, {obj, 'foo'}, '"foo" is not a valid banner config field' ) self:assertError( obj.makeBannerText, {obj, nil}, '"nil" is not a valid banner config field' ) end function suite:testBlurbMakeBannerTextGoodInput() local obj = makeDefaultBlurbObject() obj._protectionObj.bannerConfig = { text = 'banner text', explanation = 'banner explanation', tooltip = 'banner tooltip', alt = 'banner alt', link = 'banner link' } self:assertNotError(obj.makeBannerText, {obj, 'text'}) self:assertNotError(obj.makeBannerText, {obj, 'explanation'}) self:assertNotError(obj.makeBannerText, {obj, 'tooltip'}) self:assertNotError(obj.makeBannerText, {obj, 'alt'}) self:assertNotError(obj.makeBannerText, {obj, 'link'}) end function suite:testBlurbMakeBannerTextString() local obj = makeDefaultBlurbObject() function obj:_substituteParameters(msg) return msg end obj._protectionObj.bannerConfig = { text = 'banner text', } self:assertEquals('banner text', obj:makeBannerText('text')) end function suite:testBlurbMakeBannerTextBadFunction() local obj = makeDefaultBlurbObject() function obj:_substituteParameters(msg) return msg end obj._protectionObj.bannerConfig = { text = function () return 9 end, } self:assertError( obj.makeBannerText, {obj, 'text'}, 'bad output from banner config function with key "text"' .. ' (expected string, got number)' ) end function suite:testBlurbMakeBannerTextGoodFunction() local obj = makeDefaultBlurbObject() function obj:_substituteParameters(msg) return msg end obj._protectionObj.bannerConfig = { text = function () return 'some text' end, } self:assertEquals('some text', obj:makeBannerText('text')) end -------------------------------------------------------------------------------- -- BannerTemplate class tests -------------------------------------------------------------------------------- -- BannerTemplate.new function suite:testBannerTemplateNewCfg() local protectionObj = makeDefaultProtectionObject() local obj = BannerTemplate.new(protectionObj, makeConfig{foo = 'bar'}) self:assertEquals('bar', obj._cfg.foo) end function suite:testBannerTemplateNewImageIndefTemplateOrModule() local cfg = { msg = {['image-filename-indef'] = 'red padlock'} } local protectionObj = makeDefaultProtectionObject() protectionObj.action = 'edit' protectionObj.level = 'sysop' function protectionObj:isTemporary() return false end rawset(protectionObj.title, 'namespace', 10) local obj1 = BannerTemplate.new(protectionObj, makeConfig(cfg)) self:assertEquals('red padlock', obj1._imageFilename) rawset(protectionObj.title, 'namespace', 828) local obj2 = BannerTemplate.new(protectionObj, makeConfig(cfg)) self:assertEquals('red padlock', obj2._imageFilename) end function suite:testBannerTemplateNewImageUsesIndefReason() local cfg = { indefImageReasons = {[d.reason] = true}, msg = {['image-filename-indef'] = 'red padlock'} } local protectionObj = makeDefaultProtectionObject() protectionObj.action = 'edit' protectionObj.level = 'sysop' function protectionObj:isTemporary() return false end rawset(protectionObj.title, 'namespace', 2) local obj = BannerTemplate.new(protectionObj, makeConfig(cfg)) self:assertEquals('red padlock', obj._imageFilename) end function suite:testBannerTemplateNewImageDefault() local images = { move = { sysop = 'foo', default = 'bar' } } local protectionObj = makeDefaultProtectionObject() protectionObj.action = 'move' protectionObj.level = 'sysop' local obj = BannerTemplate.new(protectionObj, makeConfig{ images = images }) self:assertEquals('foo', obj._imageFilename) images.move.sysop = nil obj = BannerTemplate.new(protectionObj, makeConfig{ images = images }) self:assertEquals('bar', obj._imageFilename) images.move.default = nil obj = BannerTemplate.new(protectionObj, makeConfig{ images = images }) self:assertEquals(nil, obj._imageFilename) end -- renderImage function suite:testBannerTemplateRenderImageFilename() local obj = makeDefaultBannerTemplateObject() obj._imageFilename = 'ImageFilename.png' self:assertStringContains('ImageFilename.png', obj:renderImage(), true) end function suite:testBannerTemplateRenderImageDefault() local obj = makeDefaultBannerTemplateObject() obj._cfg.msg['image-filename-default'] = 'Defaultfilename.png' self:assertStringContains('Defaultfilename.png', obj:renderImage(), true) end function suite:testBannerTemplateRenderImageDefaultNoConfig() local obj = makeDefaultBannerTemplateObject() self:assertStringContains('Transparent.gif', obj:renderImage(), true) end function suite:testBannerTemplateRenderImageDefaultWidth() local obj = makeDefaultBannerTemplateObject() self:assertStringContains('20px', obj:renderImage(), true) end function suite:testBannerTemplateRenderImageCustomWidth() local obj = makeDefaultBannerTemplateObject() obj.imageWidth = 50 self:assertStringContains('50px', obj:renderImage(), true) end function suite:testBannerTemplateRenderImageAlt() local obj = makeDefaultBannerTemplateObject() obj._imageAlt = 'the alt text' self:assertStringContains('alt%s*=%s*the alt text', obj:renderImage(), false) end function suite:testBannerTemplateRenderImageLink() local obj = makeDefaultBannerTemplateObject() obj._imageLink = 'the link text' self:assertStringContains('link%s*=%s*the link text', obj:renderImage(), false) end function suite:testBannerTemplateRenderImageCaption() local obj = makeDefaultBannerTemplateObject() obj.imageCaption = 'the caption text' self:assertStringContains('the caption text', obj:renderImage(), true) end -------------------------------------------------------------------------------- -- Banner class tests -------------------------------------------------------------------------------- function suite:testBannerNew() local protectionObj = makeDefaultProtectionObject() local blurbObj = makeDefaultBlurbObject() local cfg = makeConfig() function blurbObj:makeBannerText(key) if key == 'alt' then return 'the alt text' elseif key == 'text' then return 'the main text' elseif key == 'explanation' then return 'the explanation text' end end local obj = Banner.new(protectionObj, blurbObj, cfg) self:assertEquals(40, obj.imageWidth) self:assertEquals('the alt text', obj.imageCaption) self:assertEquals('the main text', obj._reasonText) self:assertEquals('the explanation text', obj._explanationText) self:assertEquals(d.page, obj._page) end -- __tostring function suite:testBannerToStringError() local obj = makeDefaultBannerObject() obj._reasonText = nil self:assertError(obj.__tostring, {obj}, 'no reason text set') end function suite:testBannerToString() local obj = makeDefaultBannerObject() obj._reasonText = 'the reason text' obj._explanationText = 'the explanation text' function obj:renderImage() return '[[File:Example.png|30px]]' end self:assertStringContains('[[File:Example.png|30px]]', tostring(obj), true) self:assertStringContains( "'''the reason text'''<br />the explanation text", tostring(obj), true ) obj._explanationText = nil self:assertStringContains("'''the reason text'''", tostring(obj), true) end -------------------------------------------------------------------------------- -- Padlock class tests -------------------------------------------------------------------------------- function suite:testPadlockNew() local protectionObj = makeDefaultProtectionObject() local blurbObj = makeDefaultBlurbObject() local cfg = makeConfig() function blurbObj:makeBannerText(key) if key == 'alt' then return 'the alt text' elseif key == 'tooltip' then return 'the tooltip text' elseif key == 'link' then return 'the link text' end end local obj = Padlock.new(protectionObj, blurbObj, cfg) self:assertEquals(20, obj.imageWidth) self:assertEquals('the tooltip text', obj.imageCaption) self:assertEquals('the alt text', obj._imageAlt) self:assertEquals('the link text', obj._imageLink) end function suite:testPadlockNewIndicators() local protectionObj = makeDefaultProtectionObject() protectionObj.action = 'move' protectionObj.level = 'sysop' local blurbObj = makeDefaultBlurbObject() local cfg = makeConfig{padlockIndicatorNames = { move = 'move-indicator', default = 'default-indicator' }} local obj = Padlock.new(protectionObj, blurbObj, cfg) self:assertEquals(obj._indicatorName, 'move-indicator') cfg.padlockIndicatorNames.move = nil obj = Padlock.new(protectionObj, blurbObj, cfg) self:assertEquals(obj._indicatorName, 'default-indicator') cfg.padlockIndicatorNames.default = nil obj = Padlock.new(protectionObj, blurbObj, cfg) self:assertEquals(obj._indicatorName, 'pp-default') end -- __tostring function suite:testPadlockToString() local obj = makeDefaultPadlockObject() self:assertIsPadlock(tostring(obj)) end -------------------------------------------------------------------------------- -- Export tests -------------------------------------------------------------------------------- -- _main function suite:test_mainError() local args = {action = 'foobar'} local cfg = makeConfig() local title = makeDefaultTitleObject() local success, result = pcall(mProtectionBanner._main, args, cfg, title) self:assertFalse(success) self:assertEquals( 'invalid action: foobar', result, false ) end function suite:testCatOnlyHidesOutput() local args1 = {catonly = 'yes'} local args2 = {catonly = 'yes', small = 'yes'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertNoBanner(mProtectionBanner._main(args1, cfg, title)) self:assertNoPadlock(mProtectionBanner._main(args2, cfg, title)) end function suite:testCatOnlyShowsCategory() local args = {catonly = 'yes'} local cfg = makeConfig() cfg.protectionCategories = { [makeProtectionCategoryKey{expiry = 'indef', action = 'edit'}] = 'indef expiry', } local title = makeDefaultTitleObject() self:assertStringContains("Category:indef expiry", mProtectionBanner._main(args, cfg, title), true) end function suite:testCatOnlyNoGivesOutput() local args = {catonly = 'no'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsBanner(mProtectionBanner._main(args, cfg, title)) end function suite:testCatOnlyNoShowsCategory() local args = {catonly = 'no'} local cfg = makeConfig() cfg.protectionCategories = { [makeProtectionCategoryKey{expiry = 'indef', action = 'edit'}] = 'indef expiry', } local title = makeDefaultTitleObject() self:assertStringContains("Category:indef expiry", mProtectionBanner._main(args, cfg, title), true) end function suite:test_mainSmall1() local args = {small = 'yes'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsPadlock(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainSmall2() local args = {small = 'Yes'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsPadlock(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainSmall3() local args = {small = 'true'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsPadlock(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainLarge1() local args = {} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsBanner(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainLarge2() local args = {small = 'no'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsBanner(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainLarge3() local args = {small = 'No'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsBanner(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainLarge4() local args = {small = 'false'} local cfg = makeConfig() local title = makeDefaultTitleObject() self:assertIsBanner(mProtectionBanner._main(args, cfg, title)) end function suite:test_mainNoBanner() local args = {} local cfg = makeConfig() local title = makeTitleObject{page = d.page, edit = nil} self:assertNoBanner(mProtectionBanner._main(args, cfg, title), 'page unprotected') end function suite:test_mainNoBannerForUserScripts() local args = {} local cfg = makeConfig() local title = makeTitleObject{page = 'User:Example/common.css', contentType = 'css'} self:assertNoBanner(mProtectionBanner._main(args, cfg, title), 'page is a user script') end function suite:test_mainCategories() local args = {} local cfg -- Use main config module local title = makeTitleObject{page = d.page, 'edit', nil} self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner._main(args, cfg, title), false, 'page unprotected' ) end -- p.main function suite:testMainHasOutput() local frame = mw.getCurrentFrame() local parent = frame:newChild{args = {}} local child = parent:newChild{args = {}} local cfg -- Use main config module self:assertStringContains('%S', mProtectionBanner.main(child, cfg), false) end function suite:testMainWrapper() local frame = mw.getCurrentFrame() local parent = frame:newChild{title = 'Template:Pp-example', args = {}} local child = parent:newChild{args = {}} local cfg = makeConfig{ msg = {['tracking-category-incorrect'] = 'Incorrect'}, wrappers = {['Template:Pp-example'] = {category = false}} } self:assertNotStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(child, cfg), false ) self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(parent, cfg), false ) end function suite:testMainWrapperOverride() local frame = mw.getCurrentFrame() local parent = frame:newChild{title = 'Template:Pp-example', args = {category = 'yes'}} local child = parent:newChild{args = {}} local cfg = makeConfig{ msg = {['tracking-category-incorrect'] = 'Incorrect'}, wrappers = {['Template:Pp-example'] = {category = false}} } self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(child, cfg), false ) end function suite:testMainWrapperSandbox() local frame = mw.getCurrentFrame() local parent = frame:newChild{title = 'Template:Pp-example/sandbox', args = {}} local child = parent:newChild{args = {}} local cfg = makeConfig{ msg = {['tracking-category-incorrect'] = 'Incorrect'}, wrappers = {['Template:Pp-example'] = {category = false}} } self:assertNotStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(child, cfg), false ) self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(parent, cfg), false ) end function suite:testMainNoWrapper() local frame = mw.getCurrentFrame() local parent = frame:newChild{title = 'Template:Some template', args = {}} local child = parent:newChild{args = {}} local cfg = makeConfig{ msg = {['tracking-category-incorrect'] = 'Incorrect'}, wrappers = {['Template:Pp-example'] = {category = false}} } self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(child, cfg), false ) self:assertStringContains( '%[%[Category:.-%]%]', mProtectionBanner.main(parent, cfg), false ) end return suite
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Protection banner/testcases/doc
(
edit
)