fbpx
วิกิพีเดีย

มอดูล:Protection banner/testcases

-- 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(page, action, level)  local levels = {  edit = {},  move = {},  autoreview = {}  }  levels[action][1] = level  local title = mw.title.new(page)  return rawset(title, 'protectionLevels', levels) end  local function makeDefaultTitleObject()  return makeTitleObject(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 = {},  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  function suite:assertIsPadlock(s, msg)  self:assertStringContains(  '^%cUNIQ.-QINU%c$',  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('Foo', 'edit', 'autoconfirmed')  )  self:assertEquals('autoconfirmed', obj.level) end  function suite:testProtectionFull()  local obj = Protection.new(  {action = 'edit'},  makeConfig(),  makeTitleObject('Foo', 'edit', 'sysop')  )  self:assertEquals('sysop', obj.level) end  function suite:testProtectionUnprotected()  local obj = Protection.new(  {action = 'edit'},  makeConfig(),  makeTitleObject('Foo', 'edit', nil)  )  self:assertEquals('*', obj.level) end  function suite:testProtectionSemiMove()  local obj = Protection.new(  {action = 'move'},  makeConfig(),  makeTitleObject('Foo', 'move', 'autoconfirmed')  )  self:assertEquals('*', obj.level) end  function suite:testProtectionTemplate()  local obj = Protection.new(  {action = 'edit'},  makeConfig(),  makeTitleObject('Template:Foo', 'edit', 'templateeditor')  )  self:assertEquals('templateeditor', obj.level) end  function suite:testProtectionTitleBlacklist()  local obj = Protection.new(  {action = 'edit'},  makeConfig(),  makeTitleObject('Template:Editnotices/Page/Foo', 'edit', nil)  )  self:assertEquals('templateeditor', obj.level) end  -- Expiry  function suite:testProtectionExpiryIndef()  local obj = Protection.new(  {expiry = 'indefinite'},  makeConfig{indefStrings = {indefinite = true}}  )  self:assertEquals('indef', obj.expiry) end  function suite:testProtectionExpiryTemp()  local obj = Protection.new(  {expiry = d.expiry, action = 'autoreview' },  makeConfig()  )  self:assertEquals(d.expiryU, obj.expiry) end  function suite:testProtectionNoExpiry()  local obj = Protection.new(  { action = 'autoreview' },  makeConfig()  )  self:assertEquals(nil, obj.expiry) end  function suite:testProtectionBadExpiry()  self:assertError(  Protection.new,  {{expiry = 'foobar', action = 'autoreview' }, makeConfig()},  'invalid expiry date: foobar'  ) end  function suite:testProtectionPastExpiry()  local obj = Protection.new(  {expiry = d.protectionDate, action = 'autoreview' },  makeConfig()  )  self:assertEquals(d.protectionDateU, obj.expiry) 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  -- 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  -- 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: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(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('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('Template talk:Example', 'edit', 'autoconfirmed')  )  self:assertStringContains('talk namespace', obj:makeProtectionCategory(), true) end  -- needsExpiry  function suite:testProtectionNeedsExpiryFalse1()  local obj = makeDefaultProtectionObject()  obj.expiry = d.expiryU  self:assertFalse(  obj:needsExpiry(),  'expiry is already set'  ) end  function suite:testProtectionNeedsExpiryFalse2()  local obj = makeDefaultProtectionObject()  obj.expiry = nil  obj.action = 'move'  obj._cfg.expiryCheckActions.move = false  self:assertFalse(  obj:needsExpiry(),  'action is blacklisted in cfg.expiryCheckActions'  ) end  function suite:testProtectionNeedsExpiryFalse3()  local obj = makeDefaultProtectionObject()  obj.expiry = nil  obj.action = 'move'  obj._cfg.expiryCheckActions.move = nil  obj.reason = nil  self:assertFalse(  obj:needsExpiry(),  'cfg.expiryCheckActions is nil, and no reason is set'  ) end  function suite:testProtectionNeedsExpiryFalse4()  local obj = makeDefaultProtectionObject()  obj.expiry = nil  obj.action = 'move'  obj._cfg.expiryCheckActions.move = nil  obj.reason = 'vandalism'  obj._cfg.reasonsWithoutExpiryCheck.vandalism = true  self:assertFalse(  obj:needsExpiry(),  'cfg.expiryCheckActions is nil, and the reason is blacklisted'  ) end  function suite:testProtectionNeedsExpiryTrue1()  local obj = makeDefaultProtectionObject()  obj.expiry = nil  obj.action = 'move'  obj._cfg.expiryCheckActions.move = true  self:assertTrue(  obj:needsExpiry(),  'expiry is nil and action is whitelisted in cfg.expiryCheckActions'  ) end  function suite:testProtectionNeedsExpiryTrue2()  local obj = makeDefaultProtectionObject()  obj.expiry = nil  obj.action = 'move'  obj._cfg.expiryCheckActions.move = nil  obj.reason = 'vandalism'  obj._cfg.reasonsWithoutExpiryCheck.vandalism = nil  self:assertTrue(  obj:needsExpiry(),  'expiry and expiryCheckActions are nil, and the reason is present and'  .. ' not blacklisted.'  ) 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-expiry'] = 'Expiry category',  ['tracking-category-incorrect'] = 'Incorrect category',  ['tracking-category-template'] = 'Template category'  }  function obj:makeProtectionCategory()  return '[[Category:Protection category|' .. d.baseText .. ']]'  end  for _, field in ipairs{'needsExpiry', 'isIncorrect', 'isTemplateProtectedNonTemplate'} do  obj[field] = function () return true end  end  self:assertEquals(  '[[Category:Protection category|' .. d.baseText .. ']]' ..  '[[Category:Expiry 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 = {expiry = 'foo', action = 'autoreview' }  local cfg = makeConfig()  local title  local success, result = pcall(mProtectionBanner._main, args, cfg, title)  self:assertFalse(success)  self:assertEquals(  'invalid expiry date: foo',  result,  false  ) 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(d.page, 'edit', nil)  self:assertNoBanner(mProtectionBanner._main(args, cfg, title), 'page unprotected') end  function suite:test_mainCategories()  local args = {}  local cfg -- Use main config module  local title = makeTitleObject(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 

มอด, protection, banner, testcases, อหน, าช, ดทดสอบของมอด, มอด, protection, banner, ผลล, พธ, ของช, ดทดสอบ, load, necessary, modules, local, mprotectionbanner, require, module, protection, banner, sandbox, local, scribuntounit, require, module, scribuntounit, c. nikhuxhnachudthdsxbkhxngmxdul mxdul Protection banner phllphthkhxngchudthdsxb 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 page action level local levels edit move autoreview levels action 1 level local title mw title new page return rawset title protectionLevels levels end local function makeDefaultTitleObject return makeTitleObject 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 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 function suite assertIsPadlock s msg self assertStringContains cUNIQ QINU c 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 Foo edit autoconfirmed self assertEquals autoconfirmed obj level end function suite testProtectionFull local obj Protection new action edit makeConfig makeTitleObject Foo edit sysop self assertEquals sysop obj level end function suite testProtectionUnprotected local obj Protection new action edit makeConfig makeTitleObject Foo edit nil self assertEquals obj level end function suite testProtectionSemiMove local obj Protection new action move makeConfig makeTitleObject Foo move autoconfirmed self assertEquals obj level end function suite testProtectionTemplate local obj Protection new action edit makeConfig makeTitleObject Template Foo edit templateeditor self assertEquals templateeditor obj level end function suite testProtectionTitleBlacklist local obj Protection new action edit makeConfig makeTitleObject Template Editnotices Page Foo edit nil self assertEquals templateeditor obj level end Expiry function suite testProtectionExpiryIndef local obj Protection new expiry indefinite makeConfig indefStrings indefinite true self assertEquals indef obj expiry end function suite testProtectionExpiryTemp local obj Protection new expiry d expiry action autoreview makeConfig self assertEquals d expiryU obj expiry end function suite testProtectionNoExpiry local obj Protection new action autoreview makeConfig self assertEquals nil obj expiry end function suite testProtectionBadExpiry self assertError Protection new expiry foobar action autoreview makeConfig invalid expiry date foobar end function suite testProtectionPastExpiry local obj Protection new expiry d protectionDate action autoreview makeConfig self assertEquals d protectionDateU obj expiry 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 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 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 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 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 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 Template talk Example edit autoconfirmed self assertStringContains talk namespace obj makeProtectionCategory true end needsExpiry function suite testProtectionNeedsExpiryFalse1 local obj makeDefaultProtectionObject obj expiry d expiryU self assertFalse obj needsExpiry expiry is already set end function suite testProtectionNeedsExpiryFalse2 local obj makeDefaultProtectionObject obj expiry nil obj action move obj cfg expiryCheckActions move false self assertFalse obj needsExpiry action is blacklisted in cfg expiryCheckActions end function suite testProtectionNeedsExpiryFalse3 local obj makeDefaultProtectionObject obj expiry nil obj action move obj cfg expiryCheckActions move nil obj reason nil self assertFalse obj needsExpiry cfg expiryCheckActions is nil and no reason is set end function suite testProtectionNeedsExpiryFalse4 local obj makeDefaultProtectionObject obj expiry nil obj action move obj cfg expiryCheckActions move nil obj reason vandalism obj cfg reasonsWithoutExpiryCheck vandalism true self assertFalse obj needsExpiry cfg expiryCheckActions is nil and the reason is blacklisted end function suite testProtectionNeedsExpiryTrue1 local obj makeDefaultProtectionObject obj expiry nil obj action move obj cfg expiryCheckActions move true self assertTrue obj needsExpiry expiry is nil and action is whitelisted in cfg expiryCheckActions end function suite testProtectionNeedsExpiryTrue2 local obj makeDefaultProtectionObject obj expiry nil obj action move obj cfg expiryCheckActions move nil obj reason vandalism obj cfg reasonsWithoutExpiryCheck vandalism nil self assertTrue obj needsExpiry expiry and expiryCheckActions are nil and the reason is present and not blacklisted 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 expiry Expiry category tracking category incorrect Incorrect category tracking category template Template category function obj makeProtectionCategory return Category Protection category d baseText end for field in ipairs needsExpiry isIncorrect isTemplateProtectedNonTemplate do obj field function return true end end self assertEquals Category Protection category d baseText Category Expiry 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 amp 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 amp page mw uri encode d page amp 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 lt br gt 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 expiry foo action autoreview local cfg makeConfig local title local success result pcall mProtectionBanner main args cfg title self assertFalse success self assertEquals invalid expiry date foo result false 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 d page edit nil self assertNoBanner mProtectionBanner main args cfg title page unprotected end function suite test mainCategories local args local cfg Use main config module local title makeTitleObject 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 ekhathungcak https th wikipedia org w index php title mxdul Protection banner testcases amp oldid 8348118, wikipedia, วิกิ หนังสือ, หนังสือ, ห้องสมุด,

บทความ

, อ่าน, ดาวน์โหลด, ฟรี, ดาวน์โหลดฟรี, mp3, วิดีโอ, mp4, 3gp, jpg, jpeg, gif, png, รูปภาพ, เพลง, เพลง, หนัง, หนังสือ, เกม, เกม