jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/543107 )

Change subject: [bugfix] Fix generate_family_file.py for private wikis
......................................................................

[bugfix] Fix generate_family_file.py for private wikis

In site_detect.py, MWSite._parse_post_117 attempts to create a
temporary pywikibot.Family when generate_family_file.py is run
on private wikis, but this fails as pywikibot.Family was made
abstract in commit 5c5292e87cf318f67ad295239766cfc991319bcf.
This commit fixes.

Bug: T235768
Change-Id: I0ce0f596fd50a61d373a1c0e7089ab480b2899c1
---
M pywikibot/site_detect.py
M tests/site_detect_tests.py
2 files changed, 110 insertions(+), 8 deletions(-)

Approvals:
  Zhuyifei1999: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/site_detect.py b/pywikibot/site_detect.py
index 09b3be4..c85d984 100644
--- a/pywikibot/site_detect.py
+++ b/pywikibot/site_detect.py
@@ -15,7 +15,6 @@
 import pywikibot

 from pywikibot.comms.http import fetch
-from pywikibot import config
 from pywikibot.exceptions import ServerError
 from pywikibot.tools import MediaWikiVersion, PY2

@@ -177,13 +176,11 @@
             username = pywikibot.input(
                 'Private wiki detected. Login is required.\n'
                 'Please enter your username?')
-            config.usernames['temporary_family'] = {'temporary_code': username}
             # Setup a dummy family so that we can create a site object
-            fam = pywikibot.Family()
-            fam.name = 'temporary_family'
-            fam.scriptpath = lambda code: self.api[:-8]  # without /api.php
-            fam.langs = {'temporary_code': self.server}
-            site = pywikibot.Site('temporary_code', fam)
+            fam = pywikibot.family.AutoFamily(
+                'temporary_family',
+                self.api[:-8])
+            site = pywikibot.Site(fam.code, fam, username)
             site.version = lambda: str(self.version)
             # Now the site object is able to login
             info = site.siteinfo
diff --git a/tests/site_detect_tests.py b/tests/site_detect_tests.py
index f8cd7a7..0b7048a 100644
--- a/tests/site_detect_tests.py
+++ b/tests/site_detect_tests.py
@@ -10,10 +10,18 @@

 from requests.exceptions import ConnectionError, Timeout

+import pywikibot
 from pywikibot.exceptions import ServerError
 from pywikibot.site_detect import MWSite
+from pywikibot.tools import PY2

-from tests.aspects import unittest, TestCase
+from tests.aspects import unittest, TestCase, PatchingTestCase
+from tests.utils import DrySite
+
+if not PY2:
+    from urllib.parse import urlparse
+else:
+    from urlparse import urlparse


 class SiteDetectionTestCase(TestCase):
@@ -267,6 +275,103 @@
         self.assertNoSite('http://musicbrainz.org/doc/$1')


+class PrivateWikiTestCase(PatchingTestCase):
+
+    """Test generate_family_file works for private wikis."""
+
+    net = False
+
+    SCHEME = 'https'
+    NETLOC = 'privatewiki.example.com'
+    WEBPATH = '/wiki/'
+    SCRIPTPATH = '/w'
+    APIPATH = SCRIPTPATH + '/api.php'
+    USERNAME = 'Private Wiki User'
+    VERSION = '1.33.0'
+    LANG = 'ike-cans'
+
+    _server = SCHEME + '://' + NETLOC
+    _weburl = _server + WEBPATH
+    _apiurl = _server + APIPATH
+    _generator = 'MediaWiki ' + VERSION
+
+    _responses = {
+        # site_detect.MWSite.__init__ first fetches whatever is at
+        # the user-supplied URL. We need to return enough data for
+        # site_detect.WikiHTMLPageParser to determine the server
+        # version and the API URL.
+        WEBPATH: ''.join((
+            '<meta name="generator" content="', _generator,
+            '"/>\n<link rel="EditURI" type="application/rsd+xml" '
+            'href="', _apiurl, '?action=rsd"/>')),
+        APIPATH: '{"error":{"code":"readapidenied"}}',
+    }
+
+    _siteinfo = {
+        'generator': _generator,
+        'server': _server,
+        'scriptpath': SCRIPTPATH,
+        'articlepath': WEBPATH.rstrip('/') + '/$1',
+        'lang': LANG,
+    }
+
+    @PatchingTestCase.patched(pywikibot.site_detect, 'fetch')
+    def fetch(self, url, *args, **kwargs):
+        """Patched version of pywikibot.site_detect.fetch."""
+        parsed_url = urlparse(url)
+        self.assertEqual(parsed_url.scheme, self.SCHEME)
+        self.assertEqual(parsed_url.netloc, self.NETLOC)
+        self.assertIn(parsed_url.path, self._responses)
+
+        return type(str('Response'),
+                    (object,),
+                    {'status': 200,
+                     'text': self._responses[parsed_url.path],
+                     'data': type(str('ResponseData'),
+                                  (object,),
+                                  {'url': url})})
+
+    @PatchingTestCase.patched(pywikibot, 'input')
+    def input(self, question, *args, **kwargs):
+        """Patched version of pywikibot.input."""
+        self.assertTrue(question.endswith('username?'))
+        return self.USERNAME
+
+    @PatchingTestCase.patched(pywikibot, 'Site')
+    def Site(self, code=None, fam=None, user=None, *args, **kwargs):
+        """Patched version of pywikibot.Site."""
+        self.assertEqual(code, fam.code)
+        self.assertEqual(fam.domain, self.NETLOC)
+        self.assertEqual(user, self.USERNAME)
+        if not args and 'sysop' not in kwargs:
+            kwargs['sysop'] = None
+        site = DrySite(code, fam, user, *args, **kwargs)
+        site._siteinfo._cache.update(
+            (key, (value, True))
+            for key, value in self._siteinfo.items())
+        return site
+
+    def test_T235768_failure(self):
+        """Test generate_family_file works for private wikis.
+
+        generate_family_file.FamilyFileGenerator.run() does:
+          w = self.Wiki(self.base_url)
+          self.wikis[w.lang] = w
+
+        where self.Wiki is pywikibot.site_detect.MWSite.__init__.
+        That calls MWSite._parse_post_117() which sets lang, but
+        that call's wrapped to log exceptions and then continue
+        past them.  In T235768, the code that handles private
+        wikis raises an exception that's consumed in that way.
+        The value returned to FamilyFileGenerator.run() does not
+        have lang set, causing generate_family_file to bomb.
+        """
+        site = MWSite(self._weburl)
+        self.assertIsInstance(site, MWSite)
+        self.assertTrue(hasattr(site, 'lang'))
+        self.assertEqual(site.lang, self.LANG)
+
+
 if __name__ == '__main__':  # pragma: no cover
     try:
         unittest.main()

--
To view, visit https://gerrit.wikimedia.org/r/543107
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I0ce0f596fd50a61d373a1c0e7089ab480b2899c1
Gerrit-Change-Number: 543107
Gerrit-PatchSet: 5
Gerrit-Owner: Gary Benson <[email protected]>
Gerrit-Reviewer: Gary Benson <[email protected]>
Gerrit-Reviewer: Zhuyifei1999 <[email protected]>
Gerrit-Reviewer: jenkins-bot (75)
Gerrit-CC: Framawiki <[email protected]>
Gerrit-CC: Xqt <[email protected]>
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to