diff --git a/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation.yaml b/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation.yaml deleted file mode 100644 index 2746eb2..0000000 --- a/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation.yaml +++ /dev/null @@ -1,161 +0,0 @@ -interactions: -- request: - body: email=subscribed%40example.org&password=password - headers: - accept-encoding: ['gzip, deflate'] - !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] - method: !!python/unicode POST - uri: http://localhost:9001/3.0/users - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - location: ['http://localhost:9001/3.0/users/1881'] - status: {code: 201, message: Created} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode DELETE - uri: http://localhost:9001/3.0/users/1881 - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - status: {code: 204, message: No Content} -- request: - body: email=subscribed%40example.org&password=password - headers: - accept-encoding: ['gzip, deflate'] - !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] - method: !!python/unicode POST - uri: http://localhost:9001/3.0/users - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - location: ['http://localhost:9001/3.0/users/1882'] - status: {code: 201, message: Created} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode GET - uri: http://localhost:9001/3.0/users/expired@example.org - response: - body: {string: !!python/unicode 404 Not Found} - headers: - content-length: ['13'] - content-type: [application/json; charset=utf-8] - status: {code: 404, message: Not Found} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode DELETE - uri: http://localhost:9001/3.0/users/1882 - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - status: {code: 204, message: No Content} -- request: - body: email=subscribed%40example.org&password=password - headers: - accept-encoding: ['gzip, deflate'] - !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] - method: !!python/unicode POST - uri: http://localhost:9001/3.0/users - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - location: ['http://localhost:9001/3.0/users/1883'] - status: {code: 201, message: Created} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode GET - uri: http://localhost:9001/3.0/users/subscribed@example.org - response: - body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": - "\"aef2be6373d039f3c26769f3eb033b21185c8817\"", "is_server_owner": false, - "password": "$6$rounds=631015$2Z59WghziNfKCrWC$JuV8ayS7XVdOnPzYOKn4qTxm8XlpL.aDYHhcHDo3.mvkC473gjLEpEObyzt4g51oPp0M/BiZ2k.vyY8DWX9U01", - "self_link": "http://localhost:9001/3.0/users/1883", "user_id": 1883}'} - headers: - content-length: ['330'] - content-type: [application/json; charset=utf-8] - status: {code: 200, message: OK} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode DELETE - uri: http://localhost:9001/3.0/users/1883 - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - status: {code: 204, message: No Content} -- request: - body: email=subscribed%40example.org&password=password - headers: - accept-encoding: ['gzip, deflate'] - !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] - method: !!python/unicode POST - uri: http://localhost:9001/3.0/users - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - location: ['http://localhost:9001/3.0/users/1884'] - status: {code: 201, message: Created} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode DELETE - uri: http://localhost:9001/3.0/users/1884 - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - status: {code: 204, message: No Content} -- request: - body: email=subscribed%40example.org&password=password - headers: - accept-encoding: ['gzip, deflate'] - !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] - method: !!python/unicode POST - uri: http://localhost:9001/3.0/users - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - location: ['http://localhost:9001/3.0/users/1885'] - status: {code: 201, message: Created} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode GET - uri: http://localhost:9001/3.0/users/very_new_email@example.org - response: - body: {string: !!python/unicode 404 Not Found} - headers: - content-length: ['13'] - content-type: [application/json; charset=utf-8] - status: {code: 404, message: Not Found} -- request: - body: null - headers: - accept-encoding: ['gzip, deflate'] - method: !!python/unicode DELETE - uri: http://localhost:9001/3.0/users/1885 - response: - body: {string: !!python/unicode ''} - headers: - content-length: ['0'] - status: {code: 204, message: No Content} -version: 1 diff --git a/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_form.yaml b/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_form.yaml new file mode 100644 index 0000000..1370438 --- /dev/null +++ b/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_form.yaml @@ -0,0 +1,161 @@ +interactions: +- request: + body: email=subscribed%40example.org&password=password + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/28'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/28 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +- request: + body: email=subscribed%40example.org&password=password + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/29'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/expired@example.org + response: + body: {string: !!python/unicode 404 Not Found} + headers: + content-length: ['13'] + content-type: [application/json; charset=utf-8] + status: {code: 404, message: Not Found} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/29 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +- request: + body: email=subscribed%40example.org&password=password + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/30'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/subscribed@example.org + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"5b903167d2b50d956863bbfd5880dd0eceb3d596\"", "is_server_owner": false, + "password": "$6$rounds=599452$C.hyM3Ay.J8.D9H7$aL0NS6O8j3giGbeSo96vI3m9QO1JzbOlOaOsQyE3PR5MTfx7xpjuKrcEaBZdHy1uC5.4ZvfG6rKMopv7jJs740", + "self_link": "http://localhost:9001/3.0/users/30", "user_id": 30}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/30 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +- request: + body: email=subscribed%40example.org&password=password + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/31'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/31 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +- request: + body: email=subscribed%40example.org&password=password + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/32'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/very_new_email@example.org + response: + body: {string: !!python/unicode 404 Not Found} + headers: + content-length: ['13'] + content-type: [application/json; charset=utf-8] + status: {code: 404, message: Not Found} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/32 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +version: 1 diff --git a/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_link.yaml b/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_link.yaml new file mode 100644 index 0000000..4cf838a --- /dev/null +++ b/src/postorius/tests/fixtures/vcr_cassettes/test_address_activation_link.yaml @@ -0,0 +1,185 @@ +interactions: +- request: + body: email=ler%40example.org&password=None + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/users/33'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/ler@example.org + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"e2ca8e584502a0ba3030303596ee22524dc088e0\"", "is_server_owner": false, + "password": "$6$rounds=703870$7pXnb3SN9d5cV4.q$It.9gbzLZ6ObJGacUh..Dk84oiyEmWvQrAUCssSBnCaXIAG0TJtTRkpzxR1iF9MFccK7qbJiWL..7w49ys.nt1", + "self_link": "http://localhost:9001/3.0/users/33", "user_id": 33}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: email=les%40example.org + headers: + accept-encoding: ['gzip, deflate'] + !!python/unicode content-type: [!!python/unicode application/x-www-form-urlencoded] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/users/33/addresses + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + location: ['http://localhost:9001/3.0/addresses/les@example.org'] + status: {code: 201, message: Created} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode POST + uri: http://localhost:9001/3.0/addresses/les@example.org/verify + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/ler@example.org + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"e2ca8e584502a0ba3030303596ee22524dc088e0\"", "is_server_owner": false, + "password": "$6$rounds=703870$7pXnb3SN9d5cV4.q$It.9gbzLZ6ObJGacUh..Dk84oiyEmWvQrAUCssSBnCaXIAG0TJtTRkpzxR1iF9MFccK7qbJiWL..7w49ys.nt1", + "self_link": "http://localhost:9001/3.0/users/33", "user_id": 33}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/33/addresses + response: + body: {string: !!python/unicode '{"entries": [{"email": "ler@example.org", "http_etag": + "\"89527e98048f08fde2847021cef02a192ac27fc7\"", "original_email": "ler@example.org", + "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/ler@example.org", + "user": "http://localhost:9001/3.0/users/33"}, {"email": "les@example.org", + "http_etag": "\"337a980ce38a749fe9f7f1d8bc725686ab5f58ed\"", "original_email": + "les@example.org", "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/les@example.org", + "user": "http://localhost:9001/3.0/users/33", "verified_on": "2005-08-01T07:49:23"}], + "http_etag": "\"9552706b1b24fd14f46274af34f88e3a2855526c\"", "start": 0, "total_size": + 2}'} + headers: + content-length: ['705'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/ler@example.org + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"e2ca8e584502a0ba3030303596ee22524dc088e0\"", "is_server_owner": false, + "password": "$6$rounds=703870$7pXnb3SN9d5cV4.q$It.9gbzLZ6ObJGacUh..Dk84oiyEmWvQrAUCssSBnCaXIAG0TJtTRkpzxR1iF9MFccK7qbJiWL..7w49ys.nt1", + "self_link": "http://localhost:9001/3.0/users/33", "user_id": 33}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/33/addresses + response: + body: {string: !!python/unicode '{"entries": [{"email": "ler@example.org", "http_etag": + "\"89527e98048f08fde2847021cef02a192ac27fc7\"", "original_email": "ler@example.org", + "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/ler@example.org", + "user": "http://localhost:9001/3.0/users/33"}, {"email": "les@example.org", + "http_etag": "\"337a980ce38a749fe9f7f1d8bc725686ab5f58ed\"", "original_email": + "les@example.org", "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/les@example.org", + "user": "http://localhost:9001/3.0/users/33", "verified_on": "2005-08-01T07:49:23"}], + "http_etag": "\"9552706b1b24fd14f46274af34f88e3a2855526c\"", "start": 0, "total_size": + 2}'} + headers: + content-length: ['705'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/ler@example.org + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"e2ca8e584502a0ba3030303596ee22524dc088e0\"", "is_server_owner": false, + "password": "$6$rounds=703870$7pXnb3SN9d5cV4.q$It.9gbzLZ6ObJGacUh..Dk84oiyEmWvQrAUCssSBnCaXIAG0TJtTRkpzxR1iF9MFccK7qbJiWL..7w49ys.nt1", + "self_link": "http://localhost:9001/3.0/users/33", "user_id": 33}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/33 + response: + body: {string: !!python/unicode '{"created_on": "2005-08-01T07:49:23", "http_etag": + "\"e2ca8e584502a0ba3030303596ee22524dc088e0\"", "is_server_owner": false, + "password": "$6$rounds=703870$7pXnb3SN9d5cV4.q$It.9gbzLZ6ObJGacUh..Dk84oiyEmWvQrAUCssSBnCaXIAG0TJtTRkpzxR1iF9MFccK7qbJiWL..7w49ys.nt1", + "self_link": "http://localhost:9001/3.0/users/33", "user_id": 33}'} + headers: + content-length: ['326'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode GET + uri: http://localhost:9001/3.0/users/33/addresses + response: + body: {string: !!python/unicode '{"entries": [{"email": "ler@example.org", "http_etag": + "\"89527e98048f08fde2847021cef02a192ac27fc7\"", "original_email": "ler@example.org", + "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/ler@example.org", + "user": "http://localhost:9001/3.0/users/33"}, {"email": "les@example.org", + "http_etag": "\"337a980ce38a749fe9f7f1d8bc725686ab5f58ed\"", "original_email": + "les@example.org", "registered_on": "2005-08-01T07:49:23", "self_link": "http://localhost:9001/3.0/addresses/les@example.org", + "user": "http://localhost:9001/3.0/users/33", "verified_on": "2005-08-01T07:49:23"}], + "http_etag": "\"9552706b1b24fd14f46274af34f88e3a2855526c\"", "start": 0, "total_size": + 2}'} + headers: + content-length: ['705'] + content-type: [application/json; charset=utf-8] + status: {code: 200, message: OK} +- request: + body: null + headers: + accept-encoding: ['gzip, deflate'] + method: !!python/unicode DELETE + uri: http://localhost:9001/3.0/users/33 + response: + body: {string: !!python/unicode ''} + headers: + content-length: ['0'] + status: {code: 204, message: No Content} +version: 1 diff --git a/src/postorius/tests/mailman_api_tests/test_address_activation.py b/src/postorius/tests/mailman_api_tests/test_address_activation.py index 601899f..47e12d8 100644 --- a/src/postorius/tests/mailman_api_tests/test_address_activation.py +++ b/src/postorius/tests/mailman_api_tests/test_address_activation.py @@ -1,22 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016 by the Free Software Foundation, Inc. +# +# This file is part of Postorius. +# +# Postorius is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# Postorius is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# Postorius. If not, see . + from __future__ import (absolute_import, division, print_function, unicode_literals) import logging from datetime import datetime, timedelta +from django.contrib import messages from django.contrib.auth.models import User -from django.contrib.messages.storage.fallback import FallbackStorage from django.core.urlresolvers import reverse from django.core import mail from django.test.client import Client, RequestFactory from django.test.utils import override_settings from django.test import TestCase -from mock import patch, call, Mock from postorius.forms import AddressActivationForm from postorius.models import AddressConfirmationProfile -from postorius import views -from postorius.views.user import address_activation_link from postorius.tests import MM_VCR +from postorius.tests.utils import get_flash_messages from postorius.utils import get_client @@ -28,7 +43,7 @@ Test the activation form. """ - @MM_VCR.use_cassette('test_address_activation.yaml') + @MM_VCR.use_cassette('test_address_activation_form.yaml') def setUp(self): # Create a user and profile. self.user = User.objects.create_user('testuser', 'les@example.org', 'testpass') @@ -40,34 +55,34 @@ self.expired.save() self.mm_user = get_client().create_user('subscribed@example.org', 'password') - @MM_VCR.use_cassette('test_address_activation.yaml') + @MM_VCR.use_cassette('test_address_activation_form.yaml') def tearDown(self): self.profile.delete() self.expired.delete() self.user.delete() self.mm_user.delete() - @MM_VCR.use_cassette('test_address_activation.yaml') + @MM_VCR.use_cassette('test_address_activation_form.yaml') def test_valid_email_is_valid(self): form = AddressActivationForm({'email': 'very_new_email@example.org',}) self.assertTrue(form.is_valid()) def test_email_used_by_django_auth_is_invalid(self): - # No need for cassette becuase we should check mailman last since it's the most expensive + # No need for cassette because we should check mailman last since it's the most expensive form = AddressActivationForm({'email': 'les@example.org',}) self.assertFalse(form.is_valid()) def test_invalid_email_is_not_valid(self): - # No need for cassette becuase we should check mailman last since it's the most expensive + # No need for cassette because we should check mailman last since it's the most expensive form = AddressActivationForm({'email': 'les@example',}) self.assertFalse(form.is_valid()) - @MM_VCR.use_cassette('test_address_activation.yaml') + @MM_VCR.use_cassette('test_address_activation_form.yaml') def test_email_used_by_expired_confirmation_profile_is_valid(self): form = AddressActivationForm({'email': 'expired@example.org',}) self.assertTrue(form.is_valid()) - @MM_VCR.use_cassette('test_address_activation.yaml') + @MM_VCR.use_cassette('test_address_activation_form.yaml') def test_email_used_by_mailman_is_invalid(self): form = AddressActivationForm({'email': 'subscribed@example.org',}) self.assertFalse(form.is_valid()) @@ -157,30 +172,35 @@ not expired. """ + @MM_VCR.use_cassette('test_address_activation_link.yaml') def setUp(self): - # Set up a profile with a predictable key self.user = User.objects.create_user( username='ler', email=u'ler@example.org', password='pwd') + self.mm_user = get_client().create_user('ler@example.org', None) self.profile = AddressConfirmationProfile.objects.create(email=u'les@example.org', user=self.user) self.profile.save() + @MM_VCR.use_cassette('test_address_activation_link.yaml') def tearDown(self): self.profile.delete() self.user.delete() + self.mm_user.delete() - @patch.object(views.user, '_add_address') - def test_mailman(self, _add_address_mock): + @MM_VCR.use_cassette('test_address_activation_link.yaml') + def test_add_address(self): # An activation key pointing to a valid profile adds the address # to the user. - request = RequestFactory().get(reverse( - 'address_activation_link', kwargs={ - 'activation_key': self.profile.activation_key})) - setattr(request, 'session', 'session') - messages = FallbackStorage(request) - setattr(request, '_messages', messages) - address_activation_link( - request, self.profile.activation_key) - expected_calls = [call(request, u'ler@example.org', - u'les@example.org')] - self.assertEqual(_add_address_mock.mock_calls, expected_calls) + self.client.login(username='ler', password='pwd') + url = reverse('address_activation_link', + args=[self.profile.activation_key]) + response = self.client.get(url) + self.assertRedirects(response, reverse('user_profile')) + msgs = get_flash_messages(response) + self.assertEqual(len(msgs), 1) + self.assertEqual(msgs[0].level, messages.SUCCESS, msgs[0].message) + self.assertEqual( + set([a.email for a in self.mm_user.addresses]), + set(['ler@example.org', 'les@example.org'])) + logged_in_user = response.wsgi_request.user + self.assertEqual(logged_in_user.other_emails, ['les@example.org']) diff --git a/src/postorius/utils.py b/src/postorius/utils.py index 14ef1b9..53a641a 100644 --- a/src/postorius/utils.py +++ b/src/postorius/utils.py @@ -106,10 +106,12 @@ mm_user = MailmanUser.objects.get(address=user.email) user.other_emails = [str(address) for address in mm_user.addresses if address.verified_on is not None] - except (MailmanApiError, Mailman404Error, AttributeError): + except (MailmanApiError, Mailman404Error, AttributeError) as e: # MailmanApiError: No connection to Mailman # Mailman404Error: The user does not have a mailman user associated with it. # AttributeError: Anonymous user + logger.warning("Mailman error while setting other emails for %s: %r", + user.email, e) return if user.email in user.other_emails: user.other_emails.remove(user.email) diff --git a/src/postorius/views/user.py b/src/postorius/views/user.py index 745af2c..eef78f4 100644 --- a/src/postorius/views/user.py +++ b/src/postorius/views/user.py @@ -17,9 +17,12 @@ # Postorius. If not, see . +import logging + from django.forms.formsets import formset_factory from django.contrib import messages from django.contrib.auth.decorators import (login_required,user_passes_test) +from django.core.urlresolvers import reverse from django.shortcuts import redirect, render from django.template import RequestContext from django.utils.decorators import method_decorator @@ -44,6 +47,9 @@ import datetime +logger = logging.getLogger(__name__) + + class UserMailmanSettingsView(MailmanUserView): """The logged-in user's global Mailman Preferences.""" @@ -263,18 +269,8 @@ {'mm_user': mm_user, 'form': form}, context_instance=RequestContext(request)) -def _add_address(request, user_email, address): - # Add an address to a user record in mailman. - try: - try: - mailman_user = MailmanUser.objects.get(address=user_email) - except Mailman404Error: - mailman_user = MailmanUser.objects.create(user_email, '') - mailman_user.add_address(address) - except (MailmanApiError, MailmanConnectionError): - messages.error(request, _('The address could not be added.')) - +@login_required() def address_activation_link(request, activation_key): """ Checks the given activation_key. If it is valid, the saved address will be @@ -284,14 +280,31 @@ try: profile = AddressConfirmationProfile.objects.get( activation_key=activation_key) + if request.user != profile.user: + return redirect('{}?next={}'.format( + reverse(settings.LOGIN_URL), request.path)) if not profile.is_expired: - _add_address(request, profile.user.email, profile.email) - profile.delete() + # Add the address to the user record in Mailman. + logger.info("Adding address %s to %s", profile.email, request.user.email) + try: + try: + mailman_user = MailmanUser.objects.get(address=request.user.email) + except Mailman404Error: + mailman_user = MailmanUser.objects.create(request.user.email, '') + mm_address = mailman_user.add_address(profile.email) + # The address has just been verified. + mm_address.verify() + except (MailmanApiError, MailmanConnectionError): + messages.error(request, _('The address could not be added.')) + return + # Reset the other_emails cache + if hasattr(request.user, 'other_emails'): + del request.user.other_emails + utils.set_other_emails(request.user) messages.success(request, _('The email address has been activated!')) else: - profile.delete() messages.error(request, _('The activation link has expired, please add the email again!')) - return redirect('address_activation') + profile.delete() except AddressConfirmationProfile.DoesNotExist: messages.error(request, _('The activation link is invalid')) - return redirect('list_index') + return redirect('user_profile')