Source code for tests.paraminfo_tests
#!/usr/bin/env python3
"""Test confirming paraminfo contains expected values."""
#
# (C) Pywikibot team, 2015-2023
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
from pywikibot.family import WikimediaFamily
from pywikibot.page import Claim, Property
from pywikibot.site import DataSite
from tests.aspects import (
DefaultSiteTestCase,
DefaultWikibaseClientTestCase,
TestCaseBase,
WikimediaDefaultSiteTestCase,
unittest,
)
from tests.utils import skipping
[docs]
class KnownTypesTestBase(TestCaseBase):
"""Base class for paraminfo checks."""
@staticmethod
def _get_param_values(site, module, parameter):
"""Perform check that a parameter matches the expected list."""
with skipping(
ValueError,
msg=f'Paraminfo for {module} could not be loaded'):
param = site._paraminfo.parameter(module, parameter)
if not param or 'type' not in param:
raise unittest.SkipTest(
f'No defined values for {module}.{parameter}')
return param['type']
def _check_param_values(self, site, module, parameter, expected):
"""Check that a parameter matches the expected list exactly."""
values = self._get_param_values(site, module, parameter)
self.assertCountEqual(expected, values)
def _check_param_subset(self, site, module, parameter, expected):
"""Check that a parameter contains all entries in expected list."""
values = self._get_param_values(site, module, parameter)
self.assertLessEqual(set(expected), set(values))
def _check_param_superset(self, site, module, parameter, expected):
"""Check that a parameter only contains entries in expected list."""
values = self._get_param_values(site, module, parameter)
exp = set(expected)
val = set(values)
if not exp.issuperset(val): # pragma: no cover
diff = val - exp
self.fail('Unexpected param{} {} in values'
.format('s' if len(diff) > 1 else '', diff))
[docs]
class MediaWikiKnownTypesTestCase(KnownTypesTestBase,
DefaultSiteTestCase):
"""Verify MediaWiki types using paraminfo."""
[docs]
def test_api_format(self):
"""Test api format."""
known = ['json', 'xml']
self._check_param_subset(self.site, 'main', 'format', known)
[docs]
def test_assert_user(self):
"""Test assert type."""
known = ['user', 'bot']
self._check_param_subset(self.site, 'main', 'assert', known)
[docs]
def test_feed_format(self):
"""Test feed format."""
known = ['rss', 'atom']
if self.site.has_extension('GoogleNewsSitemap'):
known.append('sitemap')
self._check_param_values(
self.site, 'feedwatchlist', 'feedformat', known)
[docs]
def test_watchlist_show_flags(self):
"""Test watchlist show flags."""
types = ['minor', 'bot', 'anon', 'patrolled', 'unread']
known = types + [f'!{item}' for item in types]
self._check_param_subset(self.site, 'query+watchlist', 'show', known)
[docs]
def test_watchlist_type(self):
"""Test watchlist type."""
known = ['categorize', 'edit', 'external', 'log', 'new']
self._check_param_values(self.site, 'query+watchlist', 'type', known)
[docs]
def test_watchlist_modification_flag(self):
"""Test watchlist modification flag."""
known = ['watch', 'unwatch', 'preferences', 'nochange']
self._check_param_values(self.site, 'edit', 'watchlist', known)
self._check_param_values(self.site, 'delete', 'watchlist', known)
self._check_param_values(self.site, 'move', 'watchlist', known)
self._check_param_values(self.site, 'protect', 'watchlist', known)
self._check_param_values(self.site, 'rollback', 'watchlist', known)
self._check_param_values(self.site, 'undelete', 'watchlist', known)
known = ['watch', 'preferences', 'nochange']
self._check_param_values(self.site, 'upload', 'watchlist', known)
[docs]
def test_content_format(self):
"""Test content format."""
base = [
'application/json',
'text/x-wiki',
'text/javascript',
'text/css',
'text/plain',
]
if self.site.mw_version >= '1.36.0-wmf.2':
base.extend([
'application/octet-stream',
'application/unknown',
'application/x-binary',
'text/unknown',
'unknown/unknown',
])
if isinstance(self.site, DataSite):
# It is not clear when this format has been added, see T129281.
base.append('application/vnd.php.serialized')
extensions = {e['name'] for e in self.site.siteinfo['extensions']}
if 'CollaborationKit' in extensions:
base.append('text/x-collabkit')
for module in ('edit', 'parse'):
args = self.site, module, 'contentformat', base
with self.subTest(module=module):
self._check_param_values(*args)
[docs]
def test_content_model(self):
"""Test content model."""
base = ['css', 'javascript', 'json', 'text', 'wikitext']
wmf = [
'MassMessageListContent',
'SecurePoll',
'Scribunto',
'JsonSchema',
]
self._check_param_subset(self.site, 'edit', 'contentmodel', base)
self._check_param_subset(self.site, 'parse', 'contentmodel', base)
if isinstance(self.site.family, WikimediaFamily):
self._check_param_subset(self.site, 'parse', 'contentmodel', wmf)
[docs]
def test_revision_deletion_type(self):
"""Test revision deletion type."""
known = ['revision', 'archive', 'oldimage', 'filearchive', 'logging']
self._check_param_values(self.site, 'revisiondelete', 'type', known)
[docs]
def test_revision_deletion_what(self):
"""Test revision deletion part."""
known = ['content', 'comment', 'user']
self._check_param_values(self.site, 'revisiondelete', 'hide', known)
[docs]
def test_revision_deletion_level(self):
"""Test revision deletion level."""
known = ['yes', 'no', 'nochange']
self._check_param_values(
self.site, 'revisiondelete', 'suppress', known)
[docs]
class SiteMatrixKnownTypesTestCase(KnownTypesTestBase,
WikimediaDefaultSiteTestCase):
"""Verify Echo types using paraminfo."""
[docs]
def test_site_matrix_type(self):
"""Test site matrix type."""
known = ['special', 'language']
self._check_param_values(self.site, 'sitematrix', 'type', known)
[docs]
def test_site_matrix_state(self):
"""Test site matrix state."""
known = ['closed', 'private', 'fishbowl', 'all', 'nonglobal']
self._check_param_values(self.site, 'sitematrix', 'state', known)
[docs]
class EchoKnownTypesTestCase(KnownTypesTestBase,
WikimediaDefaultSiteTestCase):
"""Verify Echo types using paraminfo."""
[docs]
def test_echo_types(self):
"""Test Echo notification types."""
known = ['alert', 'message']
self._check_param_values(self.site, 'echomarkread', 'sections', known)
known = ['alert', 'message', 'all']
self._check_param_values(self.site, 'echomarkseen', 'type', known)
[docs]
class WikibaseKnownTypesTests(KnownTypesTestBase,
DefaultWikibaseClientTestCase):
"""Verify Wikibase types using paraminfo."""
[docs]
def test_entities(self):
"""Test known entities."""
unsupported = {'form', 'lexeme', 'sense'} # T195435
supported = {'item', 'property'}
known = supported | unsupported
self._check_param_superset(
self.repo, 'wbsearchentities', 'type', known)
# Missing datatypes won't crash pywikibot but should be noted
[docs]
def test_datatypes(self):
"""Test that all encountered datatypes are known."""
unsupported = {
'wikibase-form', 'wikibase-lexeme', 'wikibase-sense', # T194890
'musical-notation', # T218506
'entity-schema', # T245949
}
known = set(Property.types) | unsupported
self._check_param_superset(
self.repo, 'wbformatvalue', 'datatype', known)
[docs]
def test_snaktype(self):
"""Test known snak types."""
known = Claim.SNAK_TYPES
self._check_param_values(self.repo, 'wbcreateclaim', 'snaktype', known)
[docs]
def test_rank(self):
"""Test known ranks."""
known = ['deprecated', 'normal', 'preferred']
self._check_param_values(self.repo, 'wbgetclaims', 'rank', known)
if __name__ == '__main__':
unittest.main()