launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #12645
[Merge] lp:~sinzui/launchpad/merge-non-active-person into lp:launchpad
Curtis Hovey has proposed merging lp:~sinzui/launchpad/merge-non-active-person into lp:launchpad.
Commit message:
Allow users to merge non-active accounts.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1057947 in Launchpad itself: "LocationError: (None, 'name') when merging an account with a NEW email address"
https://bugs.launchpad.net/launchpad/+bug/1057947
For more details, see:
https://code.launchpad.net/~sinzui/launchpad/merge-non-active-person/+merge/127041
MergePeopleView.initialize() uses PersonSet.getByEmail() in a way that
won't find people by a NEW email address, causing merges of unactivated
accounts to fail like OOPS-e2f5d3b6769c012de049daf4a60c0941.
This is basically the same as bug #1019975, just at a later stage.
The fix was to pass filter_status=False to the method so that NEW
addresses can be used to look up the IPerson.
--------------------------------------------------------------------
RULES
Pre-implementation: no one
* Add a test for the current case with active accounts and validated
email addresses.
* Setup the same test with a NEW email address and non-active account.
Expect the LocationError: (None, 'name') result.
* Add filter_status=False to the view's call to PersonSet.getByEmail()
and verify the test passes.
QA
* Visit https://qastaging.launchpad.net/~ddw
* Follow the "Are you Ddw" link and Continue to send an confirmation email.
* Look in qastaging db for the token associated with your address:
select * from logintoken where created > '2012-09-28';
* Visit https://qastaging.launchpad.net/token/<TOKEN/+accountmerge
* Verify the page loads.
* Confirm
* Verify the page loads and you see that the merge is queued.
LINT
lib/lp/services/verification/browser/logintoken.py
lib/lp/services/verification/browser/tests/test_logintoken.py
LoC
I have a 3000 line credit at the moment.
TEST
./bin/test -vvc -t MergePeopleView lp.services.verification.browser.tests
IMPLEMENTATION
This is a rare case where the implementation plan was exactly as expected.
lib/lp/services/verification/browser/logintoken.py
lib/lp/services/verification/browser/tests/test_logintoken.py
--
https://code.launchpad.net/~sinzui/launchpad/merge-non-active-person/+merge/127041
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/merge-non-active-person into lp:launchpad.
=== modified file 'lib/lp/services/verification/browser/logintoken.py'
--- lib/lp/services/verification/browser/logintoken.py 2012-08-14 23:19:36 +0000
+++ lib/lp/services/verification/browser/logintoken.py 2012-09-28 18:09:24 +0000
@@ -535,7 +535,8 @@
def initialize(self):
self.redirectIfInvalidOrConsumedToken()
- self.dupe = getUtility(IPersonSet).getByEmail(self.context.email)
+ self.dupe = getUtility(IPersonSet).getByEmail(
+ self.context.email, filter_status=False)
def success(self, message):
# We're not a GeneralFormView, so we need to do the redirect
=== modified file 'lib/lp/services/verification/browser/tests/test_logintoken.py'
--- lib/lp/services/verification/browser/tests/test_logintoken.py 2012-06-14 05:18:22 +0000
+++ lib/lp/services/verification/browser/tests/test_logintoken.py 2012-09-28 18:09:24 +0000
@@ -4,6 +4,7 @@
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
+from lp.services.identity.interfaces.account import AccountStatus
from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
from lp.services.verification.browser.logintoken import (
ClaimTeamView,
@@ -18,6 +19,7 @@
)
from lp.testing.deprecated import LaunchpadFormHarness
from lp.testing.layers import DatabaseFunctionalLayer
+from lp.testing.views import create_initialized_view
class TestCancelActionOnLoginTokenViews(TestCaseWithFactory):
@@ -100,3 +102,46 @@
msgs = self._claimToken(token2)
self.assertEquals(
[u'claimee has already been converted to a team.'], msgs)
+
+
+class MergePeopleViewTestCase(TestCaseWithFactory):
+ """Test the view for confirming a merge via login token."""
+
+ layer = DatabaseFunctionalLayer
+
+ def assertWorkflow(self, claimer, dupe):
+ token = getUtility(ILoginTokenSet).new(
+ requester=claimer, requesteremail='me@xxxxxx',
+ email="him@xxxxxx", tokentype=LoginTokenType.ACCOUNTMERGE)
+ view = create_initialized_view(token, name="+accountmerge")
+ self.assertIs(False, view.mergeCompleted)
+ self.assertTextMatchesExpressionIgnoreWhitespace(
+ '.*to merge the Launchpad account named.*claimer', view.render())
+ view = create_initialized_view(
+ token, name="+accountmerge", principal=claimer,
+ form={'VALIDATE': 'Confirm'}, method='POST')
+ with person_logged_in(claimer):
+ view.render()
+ self.assertIs(True, view.mergeCompleted)
+ notifications = view.request.notifications
+ self.assertEqual(2, len(notifications))
+ text = notifications[0].message
+ self.assertTextMatchesExpressionIgnoreWhitespace(
+ "A merge is queued.*", text)
+
+ def test_confirm_email_for_active_account(self):
+ # Users can confirm they control an email address to merge a duplicate
+ # profile.
+ claimer = self.factory.makePerson(email='me@xxxxxx', name='claimer')
+ dupe = self.factory.makePerson(email='him@xxxxxx', name='dupe')
+ self.assertWorkflow(claimer, dupe)
+
+ def test_confirm_email_for_non_active_account(self):
+ # Users can confirm they control an email address to merge a
+ # non-active duplicate profile.
+ claimer = self.factory.makePerson(email='me@xxxxxx', name='claimer')
+ dupe = self.factory.makePerson(
+ email='him@xxxxxx', name='dupe',
+ email_address_status=EmailAddressStatus.NEW,
+ account_status=AccountStatus.NOACCOUNT)
+ self.assertWorkflow(claimer, dupe)
Follow ups