From 006b59be0f53eff748543b659a4091cecd0f487a Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Tue, 22 Aug 2017 15:31:41 -0400 Subject: [PATCH] Start working on limiting verifications in UI --- gratipay/models/participant/email.py | 11 ++++++ scss/components/emails.scss | 33 ------------------ scss/pages/emails.scss | 3 ++ tests/ttw/test_email_verification.py | 38 +++++++++++++++++++-- www/assets/gratipay.css.spt | 2 +- www/~/%username/emails/index.spt | 50 +++++++++++++++++----------- 6 files changed, 81 insertions(+), 56 deletions(-) delete mode 100644 scss/components/emails.scss create mode 100644 scss/pages/emails.scss diff --git a/gratipay/models/participant/email.py b/gratipay/models/participant/email.py index c5da38de8a..029fe337ee 100644 --- a/gratipay/models/participant/email.py +++ b/gratipay/models/participant/email.py @@ -54,6 +54,17 @@ class Email(object): """ + @property + def has_pending_email_address_verifications(self): + """A boolean indicating whether there are email address verifications + outstanding for this participant. Makes a db call. + """ + for email in self.get_emails(): + if not email.verified: + return True + return False + + def start_email_verification(self, email, *packages): """Add an email address for a participant. diff --git a/scss/components/emails.scss b/scss/components/emails.scss deleted file mode 100644 index 33efbc1ea5..0000000000 --- a/scss/components/emails.scss +++ /dev/null @@ -1,33 +0,0 @@ -.emails { - .label-primary, .set-primary { display: none; } - .verified { - .label-unverified, .resend { display: none; } - .set-primary { display: inline-block; } - } - .primary { - .set-primary, .remove { display: none; } - .label-primary { display: inline; } - } - li { - list-style: square inside; - margin: 0 0 0.5em 0.5em; - clear: both; - } - .label-primary, .label-unverified { - font-size: 90%; - margin-left: 0.5em; - } - .label-primary { - color: #164a9a; - } - .label-unverified { - color: #aaa; - } - li button { - float: right; - margin-left: 5px; - } - .add-email { - clear: both; - } -} diff --git a/scss/pages/emails.scss b/scss/pages/emails.scss new file mode 100644 index 0000000000..0375ea407c --- /dev/null +++ b/scss/pages/emails.scss @@ -0,0 +1,3 @@ +#emails #content { + +} diff --git a/tests/ttw/test_email_verification.py b/tests/ttw/test_email_verification.py index 7730994744..fa1ae43b5a 100644 --- a/tests/ttw/test_email_verification.py +++ b/tests/ttw/test_email_verification.py @@ -7,9 +7,13 @@ class Tests(BrowserHarness, QueuedEmailHarness): - def test_can_verify_email(self): + def setUp(self): + BrowserHarness.setUp(self) + QueuedEmailHarness.setUp(self) self.make_participant('alice', claimed_time='now') self.sign_in('alice') + + def start_verification(self, email_address): self.visit('/~alice/emails/') self.css('#content input').fill('alice@example.com') self.css('#content button').click() @@ -20,6 +24,36 @@ def test_can_verify_email(self): , verification_email['body_text'] , re.DOTALL | re.MULTILINE ).groups()[0] + return verification_link + def attempt_verification(self, email_address): + verification_link = self.start_verification(email_address) self.visit(verification_link) - assert self.css('#content h1').text == 'Success!' + return self.css('#content h1').text + + + def test_can_verify_email_address(self): + assert self.attempt_verification('alice@example.com') == 'Success!' + + def test_can_resend_when_pending(self): + self.start_verification('alice@example.com') + assert self.attempt_verification('alice@example.com') == 'Success!' + + def test_can_reverify_when_already_verified(self): + raise NotImplementedError + + + def test_cannot_start_a_second_verification_while_one_open(self): + raise NotImplementedError + + + def test_can_start_a_second_verification_when_first_completed(self): + raise NotImplementedError + + + def test_verification_constraint_survives_remove_and_readd(self): + raise NotImplementedError + + + def test_verification_constraint_survives_close_and_reopen(self): + raise NotImplementedError diff --git a/www/assets/gratipay.css.spt b/www/assets/gratipay.css.spt index 7cc741a052..b54726e531 100644 --- a/www/assets/gratipay.css.spt +++ b/www/assets/gratipay.css.spt @@ -33,7 +33,6 @@ @import "scss/components/cta"; @import "scss/components/danger-zone"; @import "scss/components/dropdown"; -@import "scss/components/emails"; @import "scss/components/github-ribbon"; @import "scss/components/js-edit"; @import "scss/components/linear_gradient"; @@ -65,6 +64,7 @@ @import "scss/layouts/layout"; @import "scss/layouts/responsiveness"; +@import "scss/pages/emails"; @import "scss/pages/homepage"; @import "scss/pages/history"; @import "scss/pages/identities"; diff --git a/www/~/%username/emails/index.spt b/www/~/%username/emails/index.spt index d3fde7a684..2a62b89818 100644 --- a/www/~/%username/emails/index.spt +++ b/www/~/%username/emails/index.spt @@ -7,6 +7,7 @@ banner = '~' + participant.username title = _("Emails") emails = participant.get_emails() +page_id = 'emails' [-----------------------------------------------------------------------------] text/html {% extends "templates/profile.html" %} @@ -17,26 +18,35 @@ emails = participant.get_emails() {% endblock %} {% block content %} -
- -
- - -
-
+ +{% for i, email in enumerate(emails) %} + {% set is_primary = email.address == participant.email_address %} + + + +{% endfor %} +
+ +
+ {{ email.address }} + {{ i }} · + {% if email.verified %} + {% if is_primary %} + {{ _("Primary") }} + {% else %} + + {% endif %} · + + {% else %} + {{ _("Unverified") }} · + + {% endif %} +
+
+
+ + +

{{ _("Notifications") }}