Completed
Push — main ( 254773...79af2c )
by Jochen
03:19
created

terms_version()   A

Complexity

Conditions 1

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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