def test_admin_can_ban_email_domain(client, user_info): register_user(client, user_info) promote_user_to_admin(client, user_info) rv = client.get(url_for('admin.domains', domain_type='email')) rv = client.post(url_for('do.ban_domain', domain_type='email'), data=dict(csrf_token=csrf_token(rv.data), domain='spam4u.com'), follow_redirects=True) reply = json.loads(rv.data.decode('utf-8')) assert reply['status'] == 'ok' log_out_current_user(client) rv = client.get(url_for('auth.register')) with mail.record_messages() as outbox: data = dict(csrf_token=csrf_token(rv.data), username='******', password='******', confirm='Safe123#$@lolnot', email_required='*****@*****.**', invitecode='', accept_tos=True, captcha='xyzzy') rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) assert len(outbox) == 0 assert b'do not accept emails' in rv.data assert b'Register' in rv.data assert b'Log out' not in rv.data
def test_reset_password(client, user_info): """A user can reset their password using a link sent to their email.""" new_password = '******' assert new_password != user_info['password'] register_user(client, user_info) log_out_current_user(client) with mail.record_messages() as outbox: rv = client.get(url_for('user.password_recovery')) rv = client.post(url_for('user.password_recovery'), data=dict(csrf_token=csrf_token(rv.data), email=user_info['email'], captcha='xyzzy')) message = outbox.pop() assert message.send_to == {user_info['email']} soup = BeautifulSoup(message.html, 'html.parser') token = soup.a['href'].split('/')[-1] rv = client.get(url_for('user.password_reset', token=token), follow_redirects=True) rv = client.post(url_for('do.reset'), data=dict(csrf_token=csrf_token(rv.data), user=get_value(rv.data, 'user'), key=get_value(rv.data, 'key'), password=new_password, confirm=new_password)) log_out_current_user(client) user_info['password'] = new_password log_in_user(client, user_info, expect_success=True)
def test_registration_login(client): """The registration page logs a user in if they register correctly.""" rv = client.get(url_for('auth.register')) with mail.record_messages() as outbox: data = dict(csrf_token=csrf_token(rv.data), username='******', password='******', confirm='Safe123#$@lolnot', invitecode='', accept_tos=True, captcha='xyzzy') if email_validation_is_required(): data['email_required'] = '*****@*****.**' else: data['email_optional'] = '*****@*****.**' rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) if email_validation_is_required(): assert b'spam' in rv.data # Telling user to go check it. message = outbox[-1] soup = BeautifulSoup(message.html, 'html.parser') token = soup.a['href'].split('/')[-1] rv = client.get(url_for('auth.login_with_token', token=token), follow_redirects=True) assert auth_provider.get_user_by_email( '*****@*****.**').name == 'supertester' assert b'Log out' in rv.data
def test_delete(self, client, profile): profile_dict = profile for status in list(ProfileStatus): profile = Profile(**profile_dict) profile.status = status cdatabase.db_session.add(profile) cdatabase.db_session.commit() profile_id = profile.id res = client.delete(url_for('api_app.profileresource', id=profile_id)) res = client.get(url_for('api_app.profileresource', id=profile_id)) assert self.assert_json(res.headers) deleted = False if status == ProfileStatus.ACTIVE: assert self.assert_success(res) assert profile.status == ProfileStatus.PENDING_DELETION elif status == ProfileStatus.INACTIVE: assert res.status_code == 404 deleted = True else: assert profile.status == status if not deleted: cdatabase.db_session.delete(profile) cdatabase.db_session.commit()
def test_export_collection(client): """Can we export a collection of resources properly?""" response = client.get('/genre/?export=True') assert response.status_code == 200 data = response.get_data(as_text=True) assert len(data) == 354 assert response.headers['Content-type'] == 'text/csv; charset=utf-8'
def test_search_collection(client): """Can we GET a collection of resources properly?""" response = client.get('/artist/?Name=Calexico') assert response.status_code == 200 json_response = json.loads(response.get_data(as_text=True))['resources'] assert len(json_response) == 1 assert response.headers['Content-type'] == 'application/json'
def test_reregister(client, user_info, user2_info): "A user account which is unconfirmed after two days can be re-registered." rv = client.get(url_for('auth.register')) data = dict(csrf_token=csrf_token(rv.data), username=user_info['username'], password=user_info['password'], confirm=user_info['password'], invitecode='', accept_tos=True, email_required=user_info['email'], captcha='xyzzy') rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) new_user = User.get(User.name == user_info['username']) assert new_user.status == UserStatus.PROBATION new_user.joindate -= timedelta(days=3) new_user.save() rv = client.get(url_for('auth.register')) with mail.record_messages() as outbox: data = dict( csrf_token=csrf_token(rv.data), username=user_info['username'], password=user_info['password'], confirm=user_info['password'], invitecode='', email_required=user2_info['email'], accept_tos=True, ) rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) assert b'spam' in rv.data # Telling user to go check it. message = outbox[-1] assert message.send_to == {user2_info['email']} soup = BeautifulSoup(message.html, 'html.parser') token = soup.a['href'].split('/')[-1] rv = client.get(url_for('auth.login_with_token', token=token), follow_redirects=True) assert b'Log out' in rv.data assert auth_provider.get_user_by_email(user_info['email']) == None assert (auth_provider.get_user_by_email( user2_info['email']).name == user_info['username'])
def test_search_collection(client): """Can we GET a collection of resources properly?""" response = client.get('/artist/?Name=Calexico') assert response.status_code == 200 json_response = json.loads( response.get_data(as_text=True))['resources'] assert len(json_response) == 1 assert response.headers['Content-type'] == 'application/json'
def test_etag_mismatch(client): """Do we get a 412 if we don't provide a matching ETag in an If-Match header?""" response = client.get( '/track/1', headers={'If-Match': '000,111'} ) assert response.status_code == 412
def test_get_resource(client): """Can we GET a resource properly?""" response = client.get('/track/1') assert response.status_code == 200 assert '</track/1>; rel=self' in response.headers['Link'] assert json.loads(response.get_data(as_text=True)) == TRACK_ONE assert response.headers['Content-type'] == 'application/json' assert response.headers['ETag'] in RESOURCE_ETAGS
def test_get_collection(client): """Can we GET a collection of resources properly?""" response = client.get('/artist/') assert response.status_code == 200 json_response = json.loads(response.get_data(as_text=True))['resources'] assert len(json_response) == 276 assert response.headers['Content-type'] == 'application/json' assert response.headers['ETag'] in COLLECTION_ETAGS
def test_delete(self, client, device): res = client.put(url_for('api_app.deviceresource'), data=device) data = json.loads(res.data) res = client.delete(url_for('api_app.deviceresource', id=data['id'])) res = client.get(url_for('api_app.deviceresource', id=data['id'])) assert res.status_code == 404
def test_get_collection(client): """Can we GET a collection of resources properly?""" response = client.get('/artist/') assert response.status_code == 200 json_response = json.loads( response.get_data(as_text=True))['resources'] assert len(json_response) == 275 assert response.headers['Content-type'] == 'application/json' assert response.headers['ETag'] in COLLECTION_ETAGS
def test_delete(self, client, mdm_group): res = client.put(url_for('api_app.mdmgroupresource'), data=mdm_group) data = json.loads(res.data) res = client.delete(url_for('api_app.mdmgroupresource', id=data['id'])) res = client.get(url_for('api_app.mdmgroupresource', id=data['id'])) assert res.status_code == 404
def test_put_new(client): """Can we PUT a resource at *new* ID?""" response = client.get('/artist/277') assert response.status_code == 404 response = client.put('/artist/277', data=json.dumps(NEW_ARTIST), headers={'Content-type': 'application/json'}) assert response.status_code == 201 assert json.loads(response.get_data(as_text=True)) == NEW_ARTIST
def test_etag_not_modified(client): """Do we get a 304 if we provide a valid If-None-Match header value?""" response = client.get( '/track/1', headers={ 'If-None-Match': '"7bcefa90a6faacf8460b00f0bb217388",' '"8a4a9037a1eb0a50ed7f8d523e05cfcb"' }, ) assert response.status_code == 304
def test_put_new(client): """Can we PUT a resource at *new* ID?""" response = client.get('/artist/276') assert response.status_code == 404 response = client.put( '/artist/276', data=json.dumps(NEW_ARTIST), headers={'Content-type': 'application/json'} ) assert response.status_code == 201 assert json.loads(response.get_data(as_text=True)) == NEW_ARTIST
def test_delete_account(client, user_info): """A user can delete their account.""" register_user(client, user_info) # The password has to be right. rv = client.get(url_for('user.delete_account')) rv = client.post(url_for('do.delete_user'), data=dict(csrf_token=csrf_token(rv.data), password='******', consent='YES'), follow_redirects=True) reply = json.loads(rv.data.decode('utf-8')) assert reply['status'] == 'error' # The consent must be given. rv = client.get(url_for('user.delete_account')) rv = client.post(url_for('do.delete_user'), data=dict(csrf_token=csrf_token(rv.data), password='******', consent='NO'), follow_redirects=True) reply = json.loads(rv.data.decode('utf-8')) assert reply['status'] == 'error' rv = client.get(url_for('user.delete_account')) rv = client.post(url_for('do.delete_user'), data=dict(csrf_token=csrf_token(rv.data), password=user_info['password'], consent='YES'), follow_redirects=True) reply = json.loads(rv.data.decode('utf-8')) assert reply['status'] == 'ok' # Deleting your account should log you out. rv = client.get(url_for('home.index')) assert b'Log in' in rv.data # Try to log in to the deleted account. log_in_user(client, user_info, expect_success=False)
def test_etag_not_modified(client): """Do we get a 304 if we provide a valid If-None-Match header value?""" response = client.get( '/track/1', headers={ 'If-None-Match': '"7bcefa90a6faacf8460b00f0bb217388",' '"8a4a9037a1eb0a50ed7f8d523e05cfcb",' '"8527642c9c0fbbd6807e49c30d93a2c6",' '"d7078e022cb3398329a4254468c80fad",' }, ) assert response.status_code == 304
def test_get_by_name_returns_empty_if_missing(self, client, mdm_group): mdm_group = MDMGroup(**mdm_group) cdatabase.db_session.add(mdm_group) cdatabase.db_session.commit() res = client.get(url_for('api_app.mdmgroupresource'), data={'group_name': 'carrots'}) assert self.assert_json(res.headers) assert self.assert_success(res) data = json.loads(res.data) assert len(data) == 0
def test_login_before_confirming_email(client, user_info): """Registered users with unconfirmed emails can't log in.""" rv = client.get(url_for('auth.register')) with mail.record_messages() as outbox: data = dict(csrf_token=csrf_token(rv.data), username=user_info['username'], password=user_info['password'], confirm=user_info['password'], email_required=user_info['email'], invitecode='', accept_tos=True, captcha='xyzzy') rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) assert b'spam' in rv.data # Telling user to go check it. message = outbox.pop() rv = client.get(url_for('auth.login')) rv = client.post(url_for('auth.login'), data=dict(csrf_token=csrf_token(rv.data), username=user_info['username'], password=user_info['password']), follow_redirects=True) assert b'Resend account confirmation instructions' in rv.data rv = client.post(url_for('auth.resend_confirmation_email'), data=dict(csrf_token=csrf_token(rv.data), email=user_info['email']), follow_redirects=True) assert b'spam' in rv.data # Telling user to go check it. message = outbox.pop() soup = BeautifulSoup(message.html, 'html.parser') token = soup.a['href'].split('/')[-1] rv = client.get(url_for('auth.login_with_token', token=token), follow_redirects=True) assert b'Log out' in rv.data
def test_password_required_to_change_recovery_email(client, user_info): """Changing the password recovery requires the correct password.""" register_user(client, user_info) wrong_password = '******' new_email = '*****@*****.**' assert wrong_password != user_info['password'] assert new_email != user_info['email'] rv = client.get(url_for('user.edit_account')) data = dict(csrf_token=csrf_token(rv.data), email_required=new_email, oldpassword=wrong_password, password='', confirm='') # No confirmation email should be sent. with mail.record_messages() as outbox: rv = client.post(url_for('do.edit_account'), data=data, follow_redirects=True) assert len(outbox) == 0 log_out_current_user(client) # Verify password recovery email goes to the right place. with mail.record_messages() as outbox: rv = client.get(url_for('user.password_recovery')) rv = client.post(url_for('user.password_recovery'), data=dict(csrf_token=csrf_token(rv.data), email=new_email, captcha='xyzzy')) assert len(outbox) == 0 rv = client.get(url_for('user.password_recovery')) rv = client.post(url_for('user.password_recovery'), data=dict(csrf_token=csrf_token(rv.data), email=user_info['email'], captcha='xyzzy')) assert len(outbox) == 1
def test_get_by_name_retrieves_group_if_found(self, client, mdm_group): mdm_group = MDMGroup(**mdm_group) cdatabase.db_session.add(mdm_group) cdatabase.db_session.commit() res = client.get(url_for('api_app.mdmgroupresource'), data={'group_name': mdm_group.group_name}) assert self.assert_json(res.headers) assert self.assert_success(res) data = json.loads(res.data) assert len(data) == 1 assert data[0]['id'] == mdm_group.id
def test_get(self, client, mdm_group): res = client.put(url_for('api_app.mdmgroupresource'), data=mdm_group) data = json.loads(res.data) res = client.get(url_for('api_app.mdmgroupresource', id=data['id'])) data = json.loads(res.data) assert 'id' in data assert isinstance(data['id'], int) assert data['id'] > 0 mdm_group['id'] = data['id'] assert mdm_group == data
def test_get(self, client, device): res = client.put(url_for('api_app.deviceresource'), data=device) data = json.loads(res.data) res = client.get(url_for('api_app.deviceresource', id=data['id'])) data = json.loads(res.data) assert 'id' in data assert isinstance(data['id'], int) assert data['id'] > 0 device['id'] = data['id'] assert device == data
def test_admin_can_ban_and_unban_user(client, user_info, user2_info): register_user(client, user_info) register_user(client, user2_info) promote_user_to_admin(client, user2_info) username = user_info['username'] rv = client.get(url_for('user.view', user=username)) rv = client.post(url_for('do.ban_user', username=username), data=dict(csrf_token=csrf_token(rv.data)), follow_redirects=True) # For now, banning makes you unable to log in. log_out_current_user(client) log_in_user(client, user_info, expect_success=False) log_in_user(client, user2_info, expect_success=True) rv = client.get(url_for('user.view', user=username)) rv = client.post(url_for('do.unban_user', username=username), data=dict(csrf_token=csrf_token(rv.data)), follow_redirects=True) log_out_current_user(client) log_in_user(client, user_info, expect_success=True)
def test_get(self, client, profile): res = client.put(url_for('api_app.profileresource'), data=profile) data = json.loads(res.data) res = client.get(url_for('api_app.profileresource', id=data['id'])) data = json.loads(res.data) assert 'id' in data assert isinstance(data['id'], int) assert data['id'] > 0 assert data['identifier'] == profile['identifier'] assert data['uuid'] == profile['uuid'] assert data['status'] == profile['status'].value
def test_post(self, client, mdm_group): res = client.put(url_for('api_app.mdmgroupresource'), data=mdm_group) data = json.loads(res.data) mdm_group['group_name'] = 'something else' res = client.post(url_for('api_app.mdmgroupresource', id=data['id']), data=mdm_group) assert self.assert_success(res) res = client.get(url_for('api_app.mdmgroupresource', id=data['id'])) assert self.assert_json(res.headers) assert self.assert_success(res) data = json.loads(res.data) mdm_group['id'] = data['id'] assert data == mdm_group
def test_post(self, client, device): res = client.put(url_for('api_app.deviceresource'), data=device) data = json.loads(res.data) device['udid'] = str(uuid.uuid4()) device['serial_number'] = '12131415' res = client.post(url_for('api_app.deviceresource', id=data['id']), data=device) assert self.assert_success(res) res = client.get(url_for('api_app.deviceresource', id=data['id'])) assert self.assert_json(res.headers) assert self.assert_success(res) data = json.loads(res.data) device['id'] = data['id'] assert data == device
def test_post(self, client, profile): res = client.put(url_for('api_app.profileresource'), data=profile) data = json.loads(res.data) profile['profile_data'] = 'something else' res = client.post(url_for('api_app.profileresource', id=data['id']), data=profile) assert self.assert_success(res) res = client.get(url_for('api_app.profileresource', id=data['id'])) assert self.assert_json(res.headers) assert self.assert_success(res) data = json.loads(res.data) assert data['identifier'] == profile['identifier'] assert data['uuid'] == profile['uuid'] assert data['status'] == profile['status'].value
def test_email_required_for_registration(client, user_info): "If emails are required, trying to register without one will fail." rv = client.get(url_for('auth.register')) with mail.record_messages() as outbox: data = dict(csrf_token=csrf_token(rv.data), username='******', password='******', confirm='Safe123#$@lolnot', email_required='', invitecode='', accept_tos=True, captcha='xyzzy') rv = client.post(url_for('auth.register'), data=data, follow_redirects=True) assert len(outbox) == 0 assert b'Error' in rv.data assert b'Register' in rv.data assert b'Log out' not in rv.data
def test_flask_app(client): """Does Emily run successfully as a Flask web server?""" response = client.get('/get_session') assert response.status_code == 200 session_id = response.get_data(as_text=True) response = client.post('/chat', data={ 'message': 'hello', 'session_id': session_id }) assert response.status_code == 200 json_response = json.loads(response.get_data(as_text=True)) assert json_response['response'] == 'world' response = client.post('/chat', data={ 'message': 'quit', 'session_id': session_id }) # The Emily thread closes if no more sessions are left, but pytest runs through these tests too quickly for Emily to make that check in time. time.sleep(0.1)
def test_change_password(client, user_info): """A user can change their password and log in with the new password.""" register_user(client, user_info) new_password = '******' + '\N{PARTIAL DIFFERENTIAL}' assert new_password != user_info['password'] rv = client.get(url_for('user.edit_account')) rv = client.post(url_for('do.edit_account'), data=dict(csrf_token=csrf_token(rv.data), oldpassword=user_info['password'], password=new_password, confirm=new_password), follow_redirects=True) reply = json.loads(rv.data.decode('utf-8')) assert reply['status'] == 'ok' log_out_current_user(client) # Try to log in with the old password log_in_user(client, user_info, expect_success=False) new_info = dict(user_info) new_info.update(password=new_password) log_in_user(client, new_info, expect_success=True)
def test_delete(client): """Can we DELETE a resource?""" response = client.delete('/album/1') assert response.status_code == 204 response = client.get('/album/1') assert response.status_code == 404
def test_meta_endpoint(client): """Can we retrieve a description of the resource from its 'meta' endpoint?""" response = client.get('/artist/meta') assert json.loads(response.get_data(as_text=True)) == ARTIST_META
def test_index(client): """Test that the index works.""" assert client.get(url_for('index')).status_code == 200
def test_get_datetime(client): """Do we get back a properly formatted datetime on a model that defines one?""" response = client.get('/post/1.0') assert response.status_code == 200 assert response.json['posted_at'] is not None
def test_wildcard_filtering(client): """Do we return filtered results when a wildcarded URL parameter is provided?""" response = client.get('/artist?Name=%25%25DC') assert response.status_code == 200 assert len(response.json['resources']) == 1 assert response.json['resources'][0]['ArtistId'] == 1
def test_get_automap_collection(client): """Do we see a model's __unicode__ definition being used in the admin?""" response = client.get(url_for('blog.index_view')) assert response.status_code == 200 assert 'Jeff Knupp' in response.get_data(as_text=True)
def test_limit(client): """Do we return sorted results when a 'limit' URL parameter is provided?""" response = client.get('/artist?limit=5') assert response.status_code == 200 assert len(response.json['resources']) == 5 assert response.json['resources'][0]['ArtistId'] == 1
def test_sorting(client): """Do we return sorted results when a 'sort' URL parameter is provided?""" response = client.get('/artist?sort=Name') assert response.status_code == 200 assert len(response.json['resources']) == 275 assert response.json['resources'][0]['ArtistId'] == 43
def test_pagination(client): """Do we return paginated results when a 'page' parameter is provided?""" response = client.get('/artist?page=2') assert response.status_code == 200 assert len(response.json['resources']) == 20 assert response.json['resources'][0]['ArtistId'] == 21
def test_get_automap_collection(client): """Do we see a model's __unicode__ definition being used in the admin?""" response = client.get('/admin/blogview/') assert response.status_code == 200 assert 'Jeff Knupp' in response.data
def test_validate_get_single_resource(client): """Do we get back an error message when making a GET request for a single resource which fails validation ?""" response = client.get('/user/1') assert response.status_code == 400 assert response.json['message'] == INVALID_ACTION_MESSAGE
def test_validate_get(client): """Do we get back an error message when making a GET request that fails validation?""" response = client.get('/user') assert response.status_code == 400 assert response.json['message'] == INVALID_ACTION_MESSAGE
def test_get_root(client): """Can we GET a list of resources from `/`""" response = client.get('/') assert response.status_code == 200 assert response.headers['Content-type'] == 'application/json'