Example #1
0
 def task(self):
     the_bot_it_user = User(self.wiki, "Benutzer:THEbotIT")
     page: Optional[Page] = None
     for idx, (page, revision_id, ts, _) in enumerate(
             the_bot_it_user.contributions(total=10000,
                                           start=Timestamp(year=2022,
                                                           month=3,
                                                           day=26),
                                           end=Timestamp(year=2022,
                                                         month=3,
                                                         day=22))):
         if idx % 100 == 0:
             self.logger.info(f"index is {idx}")
         if idx < 700:
             continue
         last_two_reivisions: List[Revision] = list(page.revisions())[:2]
         # make sure the last edit is the potential dangerous one
         if last_two_reivisions[0]["revid"] == revision_id:
             if last_two_reivisions[0]["size"] - last_two_reivisions[1][
                     "size"] < 0:
                 if "RE:" in page.title():
                     self.logger.info(f"bad edit on {page.title()}")
                     page.text = page.getOldVersion(
                         oldid=last_two_reivisions[1]["revid"])
                     page.save(
                         f"Änderung {last_two_reivisions[0]['revid']} von [[Benutzer:THEbotIT|THEbotIT]] ([[Benutzer Diskussion:THEbotIT|Diskussion]]) rückgängig gemacht."
                     )
     self.logger.info("THE END")
Example #2
0
 def isEligibleAsGreeter(self, greeter: pywikibot.User) -> bool:
     if not greeter.isRegistered():
         pywikibot.warning(f"Greeter '{greeter.username}' does not exist.")
         return False
     if greeter.isBlocked():
         pywikibot.warning(
             f"'{greeter.username}' is blocked and thus not eligible as greeter."
         )
         return False
     if self.isUserGloballyLocked(greeter):
         pywikibot.warning(
             f"'{greeter.username}' is globally locked and thus not eligible as greeter."
         )
         return False
     if not "review" in greeter.getprops()["rights"]:
         pywikibot.warning(
             f"'{greeter.username}' does not have review rights and is thus not eligible as greeter."
         )
         return False
     if greeter.getUserTalkPage().protection():
         # Talk page is protected, thus not eligible as greeter
         return False
     if not inProduction and greeter.username != "Count Count":
         return False
     cutoffTime = datetime.now() - timedelta(hours=24)
     lastActivityTimestamp = greeter.last_event.timestamp()
     if lastActivityTimestamp < cutoffTime:
         # not active in the last 24 hours and is thus not eligible as greeter
         return False
     return True
Example #3
0
 def test_anonymous_user(self):
     """Test registered user."""
     user = User(self.site, '123.45.67.89')
     with suppress_warnings('pywikibot.page.User.name', DeprecationWarning):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertTrue(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('invalid', user.getprops())
Example #4
0
 def test_invalid_user(self):
     """Test invalid user."""
     user = User(self.site, 'Invalid char\x9f in Name')
     with suppress_warnings():
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('invalid', user.getprops())
 def test_registered_user(self):
     """Test registered user."""
     user = User(self.site, 'Xqt')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsInstance(user.registration(), pywikibot.Timestamp)
     self.assertGreater(user.editCount(), 0)
     self.assertFalse(user.isBlocked())
     self.assertTrue(user.isEmailable())
     self.assertIn('userid', user.getprops())
Example #6
0
 def test_unregistered_user(self):
     """Test unregistered user."""
     user = User(self.site, 'This user name is not registered yet')
     with suppress_warnings():
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('missing', user.getprops())
 def test_logevents(self):
     """Test the User.logevents() method."""
     mysite = self.get_site()
     user = User(mysite, mysite.user())
     le = list(user.logevents(total=10))
     if not le:
         self.skipTest('User {0} has no logevents on site {1}.'.format(
             mysite.user(), mysite))
     self.assertLessEqual(len(le), 10)
     last = le[0]
     self.assertTrue(all(event.user() == user.username for event in le))
     self.assertEqual(last, user.last_event)
Example #8
0
 def test_anonymous_user(self):
     """Test registered user."""
     user = User(self.site, '123.45.67.89')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertTrue(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
Example #9
0
 def test_registered_user_without_timestamp(self):
     """Test registered user when registration timestamp is None."""
     user = User(self.site, 'Ulfb')
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertIsNone(user.getprops()['registration'])
     self.assertGreater(user.editCount(), 0)
     self.assertEqual(user.gender(), 'male')
     self.assertIn('userid', user.getprops())
Example #10
0
 def getUserData(self, user: pywikibot.User, endTime: datetime,
                 exactResults: bool) -> UserData:
     contribs = list(user.contributions(total=5000, start=endTime))
     articleContribs = list(
         user.contributions(total=5000, start=endTime, namespace=""))
     flaggedEditCount = self.getFlaggedEditCount(user, exactResults)
     return UserData(
         user,
         user.editCount,
         contribs,
         articleContribs,
         flaggedEditCount,
         self.site.logevents(page=f"User:{user.username}"),
         self.getUserRegistrationTimeSafe(user),
         self.getFlaggedRevsUserParams(user),
     )
Example #11
0
    def isUserSigned(self, user: pywikibot.User, tosignstr: str) -> bool:
        for wikilink in pywikibot.link_regex.finditer(pywikibot.textlib.removeDisabledParts(tosignstr)):
            if not wikilink.group("title").strip():
                continue
            try:
                link = pywikibot.Link(wikilink.group("title"), source=self.site)
                link.parse()
            except pywikibot.Error:
                continue
            #            if link.site != self.site: continue
            if user.isAnonymous():
                if link.namespace != -1:
                    continue
                if link.title != "Beiträge/" + user.username and link.title != "Contributions/" + user.username:
                    continue
            else:
                if link.namespace == -1 and link.title == "Beiträge/" + user.username:
                    return True
                if link.namespace not in [2, 3]:
                    continue
                if link.title != user.username:
                    continue
            return True

        return False
Example #12
0
 def test_unregistered_user(self):
     """Test unregistered user."""
     user = User(self.site, 'This user name is not registered yet')
     with suppress_warnings('pywikibot.page.User.name', DeprecationWarning):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('missing', user.getprops())
     self.assertFalse(user.is_thankable)
Example #13
0
 def test_anonymous_user(self):
     """Test registered user."""
     user = User(self.site, '123.45.67.89')
     with suppress_warnings('pywikibot.page.User.name', DeprecationWarning):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertTrue(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('invalid', user.getprops())
     self.assertFalse(user.is_thankable)
Example #14
0
 def hasUnsignedTemplateForUser(user: pywikibot.User, line: str) -> bool:
     match = re.search(r"{{(?:Vorlage:)?(?:unsigniert|unsigned)\|([^|}]+)", line)
     if match:
         if user.isAnonymous():
             return match.group(1).strip().lower() == user.username.lower()
         else:
             return match.group(1).strip() == user.username
     return False
 def test_anonymous_user(self):
     """Test registered user."""
     user = User(self.site, '123.45.67.89')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertTrue(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
 def test_unregistered_user(self):
     """Test unregistered user."""
     user = User(self.site, 'This user name is not registered yet')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('missing', user.getprops())
 def test_invalid_user(self):
     """Test invalid user."""
     user = User(self.site, 'Invalid char\x9f in Name')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
Example #18
0
 def clearnotify(self, user: pywikibot.User) -> None:
     if not Controller.doNotify:
         return
     if user.isAnonymous():
         return
     key = self.getKey(user)
     p = self.redis.pipeline()  # type: ignore
     p.delete(key)
     p.execute()
Example #19
0
 def test_registered_user_without_timestamp(self):
     """Test registered user when registration timestamp is None."""
     user = User(self.site, 'Ulfb')
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertIsNone(user.getprops()['registration'])
     self.assertGreater(user.editCount(), 0)
     self.assertEqual(user.gender(), 'male')
     self.assertIn('userid', user.getprops())
     self.assertTrue(user.is_thankable)
Example #20
0
 def test_female_user(self):
     """Test female user."""
     user = User(self.site, 'Alraunenstern')
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertGreater(user.editCount(), 0)
     self.assertEqual(user.gender(), 'female')
     self.assertIn('userid', user.getprops())
 def test_contribution(self):
     """Test the User.usercontribs() method."""
     mysite = self.get_site()
     user = User(mysite, mysite.user())
     uc = list(user.contributions(total=10))
     if not uc:
         self.skipTest('User {0} has no contributions on site {1}.'.format(
             mysite.user(), mysite))
     self.assertLessEqual(len(uc), 10)
     last = uc[0]
     for contrib in uc:
         self.assertIsInstance(contrib, tuple)
         self.assertLength(contrib, 4)
         p, i, t, c = contrib
         self.assertIsInstance(p, Page)
         self.assertIsInstance(i, int)
         self.assertIsInstance(t, Timestamp)
         self.assertIsInstance(c, StringTypes)
     self.assertEqual(last, user.last_edit)
Example #22
0
 def test_autoblocked_user_with_namespace(self):
     """Test autoblocked user."""
     user = User(self.site, 'User:#1242976')
     self.assertEqual('#1242976', user.username)
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username[1:])
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
     self.assertTrue(user._isAutoblock)
     self.assertRaisesRegex(AutoblockUser, 'This is an autoblock ID',
                            user.getUserPage)
     self.assertRaisesRegex(AutoblockUser, 'This is an autoblock ID',
                            user.getUserTalkPage)
Example #23
0
    def getUserRegistrationTimeSafe(
            self, user: pywikibot.User) -> pywikibot.Timestamp:
        registrationTime = user.registration()
        if registrationTime:
            return registrationTime

        events = self.site.logevents(user=user.username, logtype="newusers")
        for ev in events:
            if ev.type() == "newusers":
                if ev.action() == "newusers" or ev.action(
                ) == "autocreate" or ev.action() == "create2":
                    return ev.timestamp()
                else:
                    raise NotImplementedError

        # Happens for old accounts
        oldestContribList = list(user.contributions(reverse=True, total=1))
        if len(oldestContribList) == 1:
            return oldestContribList[0][2]
        else:
            raise NotImplementedError
 def test_autoblocked_user_with_namespace(self):
     """Test autoblocked user."""
     # Suppress output: This is an autoblock ID, you can only use to unblock
     with patch.object(pywikibot, 'output'):
         user = User(self.site, 'User:#1242976')
     self.assertEqual('#1242976', user.username)
     with suppress_warnings('pywikibot.page.User.name is deprecated'):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(with_ns=False), user.username[1:])
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
     self.assertTrue(user._isAutoblock)
     self.assertRaisesRegex(AutoblockUser, 'This is an autoblock ID',
                            user.getUserPage)
     self.assertRaisesRegex(AutoblockUser, 'This is an autoblock ID',
                            user.getUserTalkPage)
Example #25
0
 def test_female_user(self):
     """Test female user."""
     user = User(self.site, 'Alraunenstern')
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertGreater(user.editCount(), 0)
     self.assertEqual(user.gender(), 'female')
     self.assertIn('userid', user.getprops())
     self.assertTrue(user.is_thankable)
Example #26
0
 def _thanks_for_month(self, year, month, good_data, min_actions=1):
     """Test the thanks report for a given month."""
     bot = ThanksReportBot(year=year,
                           month=month,
                           minimum_actions=min_actions)
     bot.site = pywikibot.Site(fam=self.family, code=self.code)
     (good_thankers, good_thankees_with_strings) = good_data
     good_thankees = {}
     for k, v in good_thankees_with_strings.items():
         good_thankees[User(bot.site, k)] = v
     (pulled_thankers, pulled_thankees) = bot.gather()
     self.assertDictContainsSubset(good_thankers, pulled_thankers,
                                   'Bad thankers report')
     self.assertDictContainsSubset(good_thankees, pulled_thankees,
                                   'Bad thankees report')
Example #27
0
 def checkGeneralEligibilityForPromotion(
         self, user: pywikibot.User) -> List[CriteriaCheck]:
     criteriaChecks = []
     if user.isBlocked():
         criteriaChecks.append(
             CriteriaCheck(False, "Benutzer ist gesperrt."))
     else:
         criteriaChecks.append(
             CriteriaCheck(True, "Benutzer ist nicht gesperrt."))
     if self.site.isBot(user.username):
         criteriaChecks.append(CriteriaCheck(False,
                                             "Benutzer ist ein Bot."))
     else:
         criteriaChecks.append(CriteriaCheck(True,
                                             "Benutzer ist kein Bot."))
     return criteriaChecks
Example #28
0
 def greet(self, greeter: Greeter, user: pywikibot.User) -> None:
     pywikibot.output(
         f"Greeting '{user.username}' as '{greeter.user.username}'")
     userTalkPage = user.getUserTalkPage()
     if userTalkPage.exists():
         pywikibot.warning(
             f"User talk page of {user.username} was created suddenly")
         raise TalkPageExistsException()
     greeterTalkPagePrefix = ("Benutzerin Diskussion:"
                              if greeter.user.gender() == "female" else
                              "Benutzer Diskussion:")
     greeterTalkPage = greeterTalkPagePrefix + greeter.user.username
     userTalkPage.text = (
         f"{{{{subst:Wikipedia:WikiProjekt Begrüßung von Neulingen/Vorlage:Willkommen|1="
         f"{greeter.signatureWithoutTimestamp}|2={greeter.user.username}|3={greeterTalkPage}}}}}"
     )
     userTalkPage.save(summary="Bot: Herzlich Willkommen bei Wikipedia!",
                       watch=False)
     self.redisDb.addGreetedUser(greeter.user.username, user.username)
Example #29
0
 def checknotify(self, user: pywikibot.User) -> bool:
     if not Controller.doNotify:
         return False
     if user.isAnonymous():
         return False
     if self.isExperiencedUser(user):
         return False
     reset = int(time.time()) + 60 * 60 * 24 * 30
     key = self.getKey(user)
     p = self.redis.pipeline()  # type: ignore
     p.incr(key)
     p.expireat(key, reset + 10)
     limitReached = p.execute()[0] >= 3
     if limitReached:
         p.delete(key)
         p.execute()
         return True
     else:
         return False
 def test_unregistered_user(self):
     """Test unregistered user."""
     user = User(self.site, 'This user name is not registered yet')
     self._tests_unregistered_user(user, prop='missing')
     self.assertFalse(user.isAnonymous())
 def test_anonymous_user(self):
     """Test registered user."""
     user = User(self.site, '123.45.67.89')
     self._tests_unregistered_user(user)
     self.assertTrue(user.isAnonymous())
Example #32
0
 def test_bot_user(self):
     """Test bot user."""
     user = User(self.site, 'Xqbot')
     self.assertIn('bot', user.groups())
     self.assertFalse(user.is_thankable)
 def _is_user_blocked(self, user):
     try:
         return self._user_blocks[user]
     except KeyError:
         self._user_blocks[user] = User(self._site, user).is_blocked()
         return self._user_blocks[user]
Example #34
0
 def test_registered_user(self):
     """Test registered user."""
     user = User(self.site, 'Xqt')
     self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsInstance(user.registration(), pywikibot.Timestamp)
     self.assertGreater(user.editCount(), 0)
     self.assertFalse(user.isBlocked())
     self.assertTrue(user.isEmailable())
     self.assertIn('userid', user.getprops())
 def test_bot_user(self):
     """Test bot user."""
     user = User(self.site, 'Xqbot')
     self.assertIn('bot', user.groups())
     self.assertFalse(user.is_thankable)
Example #36
0
import datetime

import pywikibot
from dateutil.relativedelta import relativedelta
from pywikibot import User


site = pywikibot.Site('ja')
sysops = []
no_edit_sysops = []
no_event_sysops = []
three_month_ago: datetime.datetime = datetime.datetime.utcnow() - relativedelta(months=3)

for s in site.allusers(group='sysop'):
    sysops.append(User(site, s['name']))

for s in sysops:
    last_edit = s.last_edit
    if last_edit and last_edit[2] < three_month_ago:
        no_edit_sysops.append(s)

for s in no_edit_sysops:
    last_event = s.last_event
    if last_event and last_event.timestamp() < three_month_ago:
        no_event_sysops.append(s)

print(no_event_sysops)
input()
Example #37
0
 def test_autoblocked_user(self):
     """Test autoblocked user."""
     with patch.object(pywikibot, 'output') as p:
         user = User(self.site, '#1242976')
     p.assert_called_once_with(
         'This is an autoblock ID, you can only use to unblock it.')
     self.assertEqual('#1242976', user.username)
     self.assertEqual(user.title(with_ns=False), user.username[1:])
     self.assertFalse(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsNone(user.registration())
     self.assertFalse(user.isEmailable())
     self.assertIn('invalid', user.getprops())
     self.assertTrue(user._isAutoblock)
     with self.assertRaisesRegex(AutoblockUserError,
                                 'This is an autoblock ID'):
         user.getUserPage()
     with self.assertRaisesRegex(AutoblockUserError,
                                 'This is an autoblock ID'):
         user.getUserTalkPage()
 def test_invalid_user(self):
     """Test invalid user."""
     user = User(self.site, 'Invalid char\x9f in Name')
     self._tests_unregistered_user(user)
     self.assertFalse(user.isAnonymous())
 def test_registered_user(self):
     """Test registered user."""
     user = User(self.site, 'Xqt')
     with suppress_warnings('pywikibot.page.User.name', DeprecationWarning):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(with_ns=False), user.username)
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsInstance(user.registration(), pywikibot.Timestamp)
     self.assertGreater(user.editCount(), 0)
     self.assertFalse(user.isBlocked())
     self.assertTrue(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('userid', user.getprops())
     self.assertEqual(user.getprops()['userid'], 287832)
     self.assertEqual(user.pageid, 6927779)
     self.assertEqual(user.getUserPage(),
                      pywikibot.Page(self.site, 'Benutzer:Xqt'))
     self.assertEqual(user.getUserPage(subpage='pwb'),
                      pywikibot.Page(self.site, 'Benutzer:Xqt/pwb'))
     self.assertEqual(user.getUserTalkPage(),
                      pywikibot.Page(self.site, 'Benutzer Diskussion:Xqt'))
     self.assertEqual(
         user.getUserTalkPage(subpage='pwb'),
         pywikibot.Page(self.site, 'Benutzer Diskussion:Xqt/pwb'))
     self.assertTrue(user.is_thankable)
     contribs = user.contributions(total=10)
     self.assertLength(list(contribs), 10)
     self.assertTrue(all(
         isinstance(contrib, tuple) for contrib in contribs))
     self.assertTrue(
         all('user' in contrib and contrib['user'] == user.username
             for contrib in contribs))
     self.assertIn('user', user.groups())
     self.assertIn('edit', user.rights())
Example #40
0
 def test_registered_user(self):
     """Test registered user."""
     user = User(self.site, 'Xqt')
     with suppress_warnings('pywikibot.page.User.name', DeprecationWarning):
         self.assertEqual(user.name(), user.username)
     self.assertEqual(user.title(withNamespace=False), user.username)
     self.assertTrue(user.isRegistered())
     self.assertFalse(user.isAnonymous())
     self.assertIsInstance(user.registration(), pywikibot.Timestamp)
     self.assertGreater(user.editCount(), 0)
     self.assertFalse(user.isBlocked())
     self.assertTrue(user.isEmailable())
     self.assertEqual(user.gender(), 'unknown')
     self.assertIn('userid', user.getprops())
     self.assertEqual(user.getprops()['userid'], 287832)
     self.assertEqual(user.pageid, 6927779)
     self.assertEqual(user.getUserPage(),
                      pywikibot.Page(self.site, 'Benutzer:Xqt'))
     self.assertEqual(user.getUserPage(subpage='pwb'),
                      pywikibot.Page(self.site, 'Benutzer:Xqt/pwb'))
     self.assertEqual(user.getUserTalkPage(),
                      pywikibot.Page(self.site, 'Benutzer Diskussion:Xqt'))
     self.assertEqual(user.getUserTalkPage(subpage='pwb'),
                      pywikibot.Page(self.site,
                                     'Benutzer Diskussion:Xqt/pwb'))
     self.assertTrue(user.is_thankable)
     contribs = user.contributions(total=10)
     self.assertEqual(len(list(contribs)), 10)
     self.assertTrue(all(isinstance(contrib, tuple)
                         for contrib in contribs))
     self.assertTrue(all('user' in contrib
                         and contrib['user'] == user.username
                         for contrib in contribs))
     self.assertIn('user', user.groups())
     self.assertIn('edit', user.rights())