Passed
Push — master ( 97b1b2...a0bd49 )
by Jochen
02:14
created

tests.blueprints.user.test_views_create.UserCreateTestCase.setup_newsletter_list()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
"""
2
:Copyright: 2006-2019 Jochen Kupperschmidt
3
:License: Modified BSD, see LICENSE for details.
4
"""
5
6
from unittest.mock import patch
7
8
from byceps.services.authentication.password.models import Credential
9
from byceps.services.authentication.session import service as session_service
10
from byceps.services.authorization.models import Role, UserRole
11
from byceps.services.brand import settings_service as brand_settings_service
12
from byceps.services.consent import consent_service, \
13
    subject_service as consent_subject_service
14
from byceps.services.email import service as email_service
15
from byceps.services.newsletter import \
16
    command_service as newsletter_command_service, service as newsletter_service
17
from byceps.services.snippet import service as snippet_service
18
from byceps.services.snippet.transfer.models import Scope
19
from byceps.services.terms import version_service as terms_version_service
20
from byceps.services.user import event_service, service as user_service
21
from byceps.services.user.models.user import User
22
from byceps.services.verification_token import service as \
23
    verification_token_service
24
25
from tests.base import AbstractAppTestCase
26
from tests.helpers import create_brand, create_party, create_site, \
27
    create_user, http_client
28
29
from testfixtures.authorization import create_role
30
31
32
class UserCreateTestCase(AbstractAppTestCase):
33
34
    def setUp(self):
35
        super().setUp()
36
37
        self.admin = create_user('Admin')
38
39
        self.brand = create_brand()
40
        email_service.set_sender_address_for_brand(self.brand.id,
41
                                                   '[email protected]')
42
        self.brand_id = self.brand.id
43
44
        party = create_party(brand_id=self.brand.id)
45
        create_site(party.id)
46
47
        self.setup_terms()
48
        self.setup_privacy_policy()
49
        self.setup_newsletter_list()
50
        self.setup_roles()
51
52
    def setup_terms(self):
53
        scope = Scope.for_brand(self.brand_id)
54
55
        snippet = snippet_service.create_fragment(
56
            scope, 'terms_of_service', self.admin.id,
57
            'Don\'t do anything stupid!')
58
59
        consent_subject = consent_subject_service.create_subject(
60
                '{}_terms-of-service_v1'.format(self.brand_id),
61
                'Terms of service for {} / v1'.format(self.brand.title),
62
                'terms_of_service')
63
64
        terms_version = terms_version_service.create_version(
65
            self.brand_id, '01-Jan-2016', snippet.id, consent_subject.id)
66
67
        terms_version_service.set_current_version(self.brand.id,
68
                                                  terms_version.id)
69
70
        self.terms_version_id = terms_version.id
71
        self.terms_consent_subject_id = terms_version.consent_subject_id
72
73
    def setup_privacy_policy(self):
74
        consent_subject = consent_subject_service.create_subject(
75
                '{}_privacy_policy_v1'.format(self.brand_id),
76
                'Privacy policy for {} / v1'.format(self.brand.title),
77
                'privacy_policy')
78
79
        brand_settings_service.create_setting(self.brand.id,
80
            'privacy_policy_consent_subject_id', str(consent_subject.id))
81
82
        self.privacy_policy_consent_subject_id = consent_subject.id
83
84
    def setup_newsletter_list(self):
85
        newsletter_command_service.create_list(self.brand.id, self.brand.title)
86
87
    def setup_roles(self):
88
        self.board_user_role = create_role('board_user')
89
        self.db.session.add(self.board_user_role)
90
        self.db.session.commit()
91
92
    @patch('byceps.email.send')
93
    def test_create(self, send_email_mock):
94
        screen_name = 'Hiro'
95
96
        user_count_before = get_user_count()
97
        assert find_user(screen_name) is None
98
99
        form_data = {
100
            'screen_name': screen_name,
101
            'first_names': 'Hiroaki',
102
            'last_name': 'Protagonist',
103
            'email_address': '[email protected]',
104
            'password': 'Snow_Crash',
105
            'terms_version_id': self.terms_version_id,
106
            'consent_to_terms': 'y',
107
            'consent_to_privacy_policy': 'y',
108
            'subscribe_to_newsletter': 'y',
109
        }
110
111
        response = self.send_request(form_data)
112
        assert response.status_code == 302
113
114
        user_count_afterwards = get_user_count()
115
        assert user_count_afterwards == user_count_before + 1
116
117
        user = find_user(screen_name)
118
        assert user is not None
119
120
        assert user.created_at is not None
121
        assert user.screen_name == 'Hiro'
122
        assert user.email_address == '[email protected]'
123
        assert not user.enabled
124
        assert not user.deleted
125
126
        # events
127
        assert_creation_event_created(user.id)
128
129
        # password
130
        assert_password_credentials_created(user.id)
131
132
        # Session token should not have been created at this point.
133
        session_token = session_service.find_session_token_for_user(user.id)
134
        assert session_token is None
135
136
        # avatar
137
        assert user.avatar is None
138
139
        # details
140
        assert user.detail.first_names == 'Hiroaki'
141
        assert user.detail.last_name == 'Protagonist'
142
143
        # authorization
144
        board_user_role = Role.query.get('board_user')
145
        actual_roles = get_user_roles(user.id)
146
        assert board_user_role in actual_roles
147
148
        # consents
149
        assert_consent(user.id, self.terms_consent_subject_id)
150
        assert_consent(user.id, self.privacy_policy_consent_subject_id)
151
152
        # newsletter subscription
153
        assert is_subscribed_to_newsletter(user.id, self.brand_id)
154
155
        # confirmation e-mail
156
157
        verification_token = find_verification_token(user.id)
158
        assert verification_token is not None
159
160
        expected_sender = '[email protected]'
161
        expected_recipients = ['[email protected]']
162
        expected_subject = 'Hiro, bitte bestätige deine E-Mail-Adresse'
163
        expected_body = '''
164
Hallo Hiro,
165
166
bitte bestätige deine E-Mail-Adresse, indem du diese URL abrufst: https://www.example.com/users/email_address/confirmation/{}
167
        '''.strip().format(verification_token.token)
168
169
        send_email_mock.assert_called_once_with(
170
            expected_sender,
171
            expected_recipients,
172
            expected_subject,
173
            expected_body)
174
175
    @patch('byceps.email.send')
176
    def test_create_without_newsletter_subscription(self, send_email_mock):
177
        screen_name = 'Hiro'
178
179
        form_data = {
180
            'screen_name': screen_name,
181
            'first_names': 'Hiroaki',
182
            'last_name': 'Protagonist',
183
            'email_address': '[email protected]',
184
            'password': 'Snow_Crash',
185
            'terms_version_id': self.terms_version_id,
186
            'consent_to_terms': 'y',
187
            'consent_to_privacy_policy': 'y',
188
            'subscribe_to_newsletter': '',
189
        }
190
191
        response = self.send_request(form_data)
192
        assert response.status_code == 302
193
194
        user = find_user(screen_name)
195
        assert user is not None
196
197
        # newsletter subscription
198
        assert not is_subscribed_to_newsletter(user.id, self.brand_id)
199
200
    # helpers
201
202
    def send_request(self, form_data):
203
        url = '/users/'
204
205
        with http_client(self.app) as client:
206
            return client.post(url, data=form_data)
207
208
209
def find_user(screen_name):
210
    return user_service.find_user_by_screen_name(screen_name)
211
212
213
def get_user_count():
214
    return User.query.count()
215
216
217
def get_user_roles(user_id):
218
    return Role.query \
219
        .join(UserRole) \
220
        .filter_by(user_id=user_id) \
221
        .all()
222
223
224
def find_verification_token(user_id):
225
    return verification_token_service \
226
        .find_for_email_address_confirmation_by_user(user_id)
227
228
229
def is_subscribed_to_newsletter(user_id, brand_id):
230
    return newsletter_service.is_subscribed(user_id, brand_id)
231
232
233
def assert_creation_event_created(user_id):
234
    events = event_service.get_events_of_type_for_user('user-created', user_id)
235
    assert len(events) == 1
236
237
    first_event = events[0]
238
    assert first_event.event_type == 'user-created'
239
    assert first_event.data == {}
240
241
242
def assert_password_credentials_created(user_id):
243
    credential = Credential.query.get(user_id)
244
245
    assert credential is not None
246
    assert credential.password_hash.startswith('pbkdf2:sha256:150000$')
247
    assert credential.updated_at is not None
248
249
250
def assert_consent(user_id, subject_id):
251
    assert consent_service.has_user_consented_to_subject(user_id, subject_id)
252