def it_returns_approved_emails(self, client, db, db_session): event = create_event(title='Event 1') event_2 = create_event(title='Event 2') event_date = create_event_date(event_id=str(event.id), event_datetime='2019-07-20 19:00') event_date_2 = create_event_date(event_id=str(event_2.id), event_datetime='2019-07-13 19:00') approved_email = create_email(event_id=str(event.id), created_at='2019-07-01 11:00', send_starts_at='2019-07-10', send_after='2019-07-01 11:00', expires='2019-07-20', email_state='approved') create_email(event_id=str(event_2.id), created_at='2019-07-02 11:00', send_starts_at='2019-07-01', expires='2019-07-12') response = client.get(url_for('emails.get_approved_emails'), headers=[('Content-Type', 'application/json'), create_authorization_header()]) json_latest_emails = json.loads(response.get_data(as_text=True)) assert len(json_latest_emails) == 1 assert json_latest_emails[0] == approved_email.serialize()
def it_creates_emails_for_imported_emails(self, client, db_session, sample_old_emails, sample_event_with_dates): response = client.post(url_for('emails.import_emails'), data=json.dumps(sample_old_emails), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_emails = json.loads(response.get_data(as_text=True))['emails'] email_types = [MAGAZINE, EVENT, ANNOUNCEMENT, ANON_REMINDER] assert len(json_emails) == len(sample_old_emails) for i in range(0, len(sample_old_emails)): if json_emails[i]['email_type'] == EVENT: assert json_emails[i]['event_id'] == str( sample_event_with_dates.id) assert json_emails[i]['email_type'] == email_types[i] assert json_emails[i]['created_at'] == sample_old_emails[i][ 'timestamp'][:-3] assert json_emails[i]['extra_txt'] == sample_old_emails[i][ 'extratxt'] assert json_emails[i]['details'] == sample_old_emails[i][ 'eventdetails'] assert str(json_emails[i]['old_id']) == sample_old_emails[i]['id'] assert str(json_emails[i] ['old_event_id']) == sample_old_emails[i]['eventid'] assert json_emails[i]['replace_all'] == ( True if sample_old_emails[i]['replaceAll'] == 'y' else False) assert json_emails[i]['send_starts_at'] == sample_old_emails[i][ 'timestamp'].split(' ')[0] expiry = (datetime.strptime(sample_old_emails[i]['timestamp'].split(' ')[0], "%Y-%m-%d") + timedelta(weeks=2)).strftime("%Y-%m-%d") \ if email_types[i] != EVENT else sample_event_with_dates.get_last_event_date() assert json_emails[i]['expires'] == expiry
def it_unsubscribes_member(self, mocker, app, client, db_session, sample_member): mock_send_email = mocker.patch('app.routes.members.rest.send_email') mock_ga_event = mocker.patch('app.routes.members.rest.send_ga_event') unsubcode = encrypt( "{}={}".format(app.config['EMAIL_TOKENS']['member_id'], str(sample_member.id)), app.config['EMAIL_UNSUB_SALT']) response = client.post(url_for('members.unsubscribe_member', unsubcode=unsubcode), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert not sample_member.active assert response.json == { 'message': '{} unsubscribed'.format(sample_member.name) } assert mock_ga_event.called assert mock_send_email.called assert mock_send_email.call_args[0][0] == sample_member.email assert mock_send_email.call_args[0][ 1] == 'New Acropolis unsubscription' assert '{}, you have successfully unsubscribed from New Acropolis events and magazines'.format( sample_member.name) in mock_send_email.call_args[0][2]
def it_updates_a_magazine(self, mocker, client, db_session): magazine = create_magazine(title='title', filename='new filename') mocker_upload = mocker.patch( 'app.routes.magazines.rest.upload_tasks.upload_magazine.apply_async' ) data = { 'title': 'new title', 'filename': 'Magazine Issue 1.pdf', 'pdf_data': 'test data', 'topics': '', 'tags': 'update tag' } response = client.post(url_for('magazines.update_magazine', id=magazine.id), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 200 assert response.json['title'] == data['title'] assert data['pdf_data'] in mocker_upload.call_args[0][0] magazines = dao_get_magazines() assert len(magazines) == 1 magazines[0].tags == 'update tag'
def it_raises_error_if_email_not_updated(self, mocker, client, db_session, sample_email): data = { "event_id": str(sample_email.event_id), "details": sample_email.details, "extra_txt": '<div>New extra text</div>', "replace_all": sample_email.replace_all, "email_type": EVENT, "email_state": READY } mocker.patch('app.routes.emails.rest.dao_update_email', return_value=False) response = client.post(url_for('emails.update_email', email_id=sample_email.id), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 400 json_resp = json.loads(response.get_data(as_text=True)) assert json_resp['message'] == '{} did not update email'.format( sample_email.id)
def it_doesnt_import_members_with_invalid_marketing( self, client, db_session, sample_marketing, sample_member): data = [ { "id": "2", "Name": "Test member 2", "EmailAdd": "*****@*****.**", "Active": "y", "CreationDate": "2019-08-02", "Marketing": "2", "IsMember": "n", "LastUpdated": "2019-08-11 10:00:00" }, { "id": "3", "Name": "Test member 3", "EmailAdd": "*****@*****.**", "Active": "y", "CreationDate": "2019-08-02", "Marketing": "1", "IsMember": "n", "LastUpdated": "2019-08-11 10:00:00" }, ] response = client.post(url_for('members.import_members'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 assert response.json.get('errors') == ['Cannot find marketing: 2'] members = Member.query.all() assert len(members) == 2
def it_imports_marketings(self, client, db_session): data = [ { "id": "1", "marketingtxt": 'Poster', "ordernum": "0", "visible": "1" }, { "id": "2", "marketingtxt": 'Leaflet', "ordernum": "1", "visible": "1" }, ] response = client.post(url_for('marketings.import_marketings'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 marketings = Marketing.query.all() assert len(marketings) == 2 assert marketings[0].old_id == int(data[0]['id']) assert marketings[0].description == data[0]['marketingtxt'] assert marketings[0].order_number == int(data[0]['ordernum']) assert marketings[0].active == (data[0]['visible'] == '1')
def it_updates_a_magazine_email_to_ready(self, mocker, client, db, db_session, sample_admin_user, sample_magazine_email): mock_send_email = mocker.patch( 'app.routes.emails.rest.send_smtp_email', return_value=200) data = { "magazine_id": str(sample_magazine_email.magazine_id), "details": sample_magazine_email.details, "extra_txt": '<div>New extra text</div>', "replace_all": sample_magazine_email.replace_all, "email_type": MAGAZINE, "email_state": READY } response = client.post(url_for('emails.update_email', email_id=str(sample_magazine_email.id)), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.json['extra_txt'] == data['extra_txt'] emails = Email.query.all() assert len(emails) == 1 assert emails[0].extra_txt == data['extra_txt'] assert mock_send_email.call_args[0][0] == [TEST_ADMIN_USER]
def it_creates_event_types_for_imported_event_types(self, client, db_session): data = [ { "id": "1", "EventType": "Talk", "Fees": "5", "ConcFees": "3", "EventDesc": "", "EventFilename": None }, { "id": "2", "EventType": "Introductory Course", "Fees": "0", "ConcFees": None, "EventDesc": "", "EventFilename": None } ] response = client.post( url_for('event_types.import_event_types'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()] ) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp) == len(data) for i in range(0, len(data) - 1): assert json_resp[i]["old_id"] == int(data[i]["id"]) assert json_resp[i]["event_type"] == data[i]["EventType"]
def it_ignores_existing_event_types_for_imported_event_types(self, client, db_session, sample_event_type): data = [ { "id": "1", "EventType": sample_event_type.event_type, "Fees": "5", "ConcFees": "3", "EventDesc": "", "EventFilename": None }, { "id": "2", "EventType": "Introductory Course", "Fees": "0", "ConcFees": None, "EventDesc": "", "EventFilename": None } ] response = client.post( url_for('event_types.import_event_types'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()] ) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) # should ignore the first data element but create the second one assert len(json_resp) == 1 assert json_resp[0]["old_id"] == int(data[1]["id"]) assert json_resp[0]["event_type"] == data[1]["EventType"]
def it_returns_all_venues(self, client, sample_venue, db_session): response = client.get(url_for('venues.get_venues'), headers=[create_authorization_header()]) assert response.status_code == 200 data = json.loads(response.get_data(as_text=True)) assert len(data) == 1
def it_creates_venues_for_imported_venues(self, client, db_session): data = [{ "id": "1", "name": "", "address": "19 Compton Terrace N1 2UN, next door to Union Chapel.", "tube": "Highbury & Islington (Victoria Line), 2 minutes walk", "bus": "Bus routes 4, 19, 30, 43 & 277 stop nearby" }, { "id": "2", "name": "Bristol", "address": "Caf\u00e9 Revival, 56 Corn Street, Bristol, BS1 1JG", "tube": "", "bus": "" }] response = client.post(url_for('venues.import_venues'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp) == len(data) for i in range(0, len(data) - 1): assert json_resp[i]["old_id"] == int(data[i]["id"]) assert json_resp[i]["name"] == data[i]["name"] if data[i][ "name"] else 'Head branch' assert json_resp[i]["address"] == data[i]["address"] assert json_resp[i][ "directions"] == "<div>Bus: {bus}</div><div>Train: {train}</div>".format( bus=data[i]["bus"], train=data[i]["tube"])
def it_creates_venues(self, client, db_session): data = [ { 'name': 'London branch', 'address': '19 Compton Terrace', 'directions': 'Nearest station: Highbury & Islington', 'default': True }, { 'name': 'Test branch', 'address': '1 Test Street', 'directions': 'Nearest station: Teston', 'default': False }, ] response = client.post(url_for('venues.create_venues'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp) == len(data) # python 3 udpate code? assert sorted(data, key=lambda k: k['name']) == sorted( [{ 'name': j['name'], 'address': j['address'], 'directions': j['directions'], 'default': j['default'] } for j in json_resp], key=lambda k: k['name'])
def it_creates_venues_only_first_default(self, client, db_session): data = [ { 'name': 'London branch', 'address': '19 Compton Terrace', 'directions': 'Nearest station: Highbury & Islington', 'default': True }, { 'name': 'Test branch', 'address': '1 Test Street', 'directions': 'Nearest station: Teston', 'default': True }, ] response = client.post(url_for('venues.create_venues'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp) == len(data) assert Venue.query.filter_by(name=data[0]['name']).one().default assert not Venue.query.filter_by(name=data[1]['name']).one().default assert json_resp[0]['default'] assert not json_resp[1]['default']
def it_doesnt_import_exising_marketings(self, client, db_session, sample_marketing): data = [ { "id": "1", "marketingtxt": 'Leaflet', "ordernum": "0", "visible": "1" }, { "id": "2", "marketingtxt": 'Poster', "ordernum": "1", "visible": "1" }, ] response = client.post(url_for('marketings.import_marketings'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 assert response.json.get('errors') == ['marketing already exists: 1'] marketings = Marketing.query.all() assert len(marketings) == 2
def it_creates_an_event_email(self, mocker, client, db_session, sample_event_with_dates): data = { "event_id": str(sample_event_with_dates.id), "details": "<div>Some additional details</div>", "extra_txt": "<div>Some more information about the event</div>", "replace_all": False, "email_type": "event" } response = client.post(url_for('emails.create_email'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) json_resp = json.loads(response.get_data(as_text=True)) assert json_resp['email_type'] == 'event' assert not json_resp['old_id'] assert json_resp['event_id'] == str(sample_event_with_dates.id) assert not json_resp['old_event_id'] assert json_resp[ 'extra_txt'] == '<div>Some more information about the event</div>' assert json_resp['details'] == '<div>Some additional details</div>' assert not json_resp['replace_all'] emails = Email.query.all() assert len(emails) == 1 assert emails[0].email_type == 'event' assert emails[0].event_id == sample_event_with_dates.id
def it_gets_the_marketings(self, client, db_session, sample_marketing): response = client.get(url_for('marketings.get_marketings'), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 200 assert len(response.json) == 1 assert response.json[0]['id'] == str(sample_marketing.id)
def it_updates_an_event_email_to_approved(self, mocker, app, client, db, db_session, sample_admin_user, sample_email, now, delay): mock_send_email = mocker.patch( 'app.routes.emails.rest.send_smtp_email', return_value=200) with freeze_time(now): data = { "event_id": str(sample_email.event_id), "details": sample_email.details, "extra_txt": '<div>New extra text</div>', "replace_all": sample_email.replace_all, "email_type": EVENT, "email_state": APPROVED, "send_starts_at": "2019-08-08", "reject_reason": 'test reason' } response = client.post(url_for('emails.update_email', email_id=str(sample_email.id)), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.json['extra_txt'] == data['extra_txt'] emails = Email.query.all() assert len(emails) == 1 assert emails[0].email_state == data['email_state'] assert emails[0].extra_txt == data['extra_txt'] assert emails[0].send_after == delay assert mock_send_email.call_args[0][0] == [TEST_ADMIN_USER] assert mock_send_email.call_args[0][ 1] == "{} has been approved".format(emails[0].get_subject())
def it_gets_email_providers_in_order(self, client, db, db_session, sample_email_provider): next_email_provider = create_email_provider( name='Next email provider', pos=2, smtp_server='http://smtp.test', smtp_user='******', smtp_password='******') response = client.get(url_for('email_provider.get_email_providers'), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 200 assert len(response.json) == 2 assert response.json[0]['id'] == str(sample_email_provider.id) assert 'api_key' not in response.json[0] assert response.json[0][ 'shortened_api_key'] == sample_email_provider.api_key[-10:] assert response.json[1]['id'] == str(next_email_provider.id) assert 'api_key' not in response.json[1] assert response.json[1][ 'shortened_api_key'] == next_email_provider.api_key[-10:] assert response.json[1][ 'shortened_smtp_password'] == next_email_provider.smtp_password[ -5:]
def it_imports_members(self, client, db_session, sample_marketing): data = [ { "id": "1", "Name": "Test member", "EmailAdd": "*****@*****.**", "Active": "y", "CreationDate": "2019-08-01", "Marketing": "1", "IsMember": "n", "LastUpdated": "2019-08-10 10:00:00" }, { "id": "2", "Name": "Test member 2", "EmailAdd": "*****@*****.**", "Active": "y", "CreationDate": "2019-08-02", "Marketing": "1", "IsMember": "n", "LastUpdated": "2019-08-11 10:00:00" }, ] response = client.post(url_for('members.import_members'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 members = Member.query.all() assert len(members) == 2 assert members[0].old_id in [int(i['id']) for i in data] assert members[0].name in [n['Name'] for n in data]
def it_creates_an_email_provider(self, client, db_session): data_map = { "to": "to", "from": "from", "subject": "subject", "message": "message" } data = { "name": "Test provider", "daily_limit": 100, "api_key": "api-key", "api_url": "http://api-url.com", "data_map": json.dumps(data_map), "pos": 0, } response = client.post(url_for('email_provider.create_email_provider'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) for key in data.keys(): if key == 'data_map': assert json.loads(data[key]) == json_resp[key] else: assert data[key] == json_resp[key]
def it_subscribes_member(self, mocker, app, client, db_session, sample_marketing): mock_send_email = mocker.patch('app.routes.members.rest.send_email') mock_ga_event = mocker.patch('app.routes.members.rest.send_ga_event') data = { 'name': 'Test member', 'email': '*****@*****.**', 'marketing_id': sample_marketing.id } response = client.post(url_for('members.subscribe_member'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) members = Member.query.all() assert len(members) == 1 assert members[0].name == data['name'] assert members[0].email == data['email'] assert members[0].active is True assert members[0].marketing_id == sample_marketing.id assert mock_ga_event.called assert mock_send_email.called assert mock_send_email.call_args[0][0] == data['email'] assert mock_send_email.call_args[0][1] == 'New Acropolis subscription' assert 'Thank you {} for subscribing to New Acropolis events and magazines'.format(data['name']) \ in mock_send_email.call_args[0][2]
def it_updates_an_email_provider_on_valid_post_data( self, client, db_session, sample_email_provider): data_map = { "to": "to", "from": "from", "subject": "subject", "message": "text" } data = { "daily_limit": 200, "api_key": "new-api-key", "api_url": "http://new-api-url.com", "pos": 1, "data_map": json.dumps(data_map), } response = client.post(url_for( 'email_provider.update_email_provider', email_provider_id=sample_email_provider.id), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 200 json_resp = json.loads(response.get_data(as_text=True)) for key in data.keys(): if key == 'data_map': assert json.loads(data[key]) == json_resp[key] else: assert data[key] == json_resp[key]
def it_creates_a_magazine_and_uploads_it_to_storage( self, mocker, client, db_session): mocker_upload = mocker.patch( 'app.routes.magazines.rest.upload_tasks.upload_magazine.apply_async' ) with open(os.path.join('tests', 'test_files', 'test_magazine.pdf'), encoding='mac_roman', newline='') as f: pdf_data = base64.b64encode( f.read().encode('utf-8')).decode('utf-8') data = { 'title': 'title', 'filename': 'Magazine Issue 1.pdf', 'pdf_data': pdf_data, 'tags': 'new tag' } response = client.post(url_for('magazines.create_magazine'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 assert pdf_data in mocker_upload.call_args[0][0] magazines = dao_get_magazines() assert len(magazines) == 1 magazines[0].tags == 'new tag'
def it_doesnt_create_email_for_imported_emails_already_imported( self, client, db_session, sample_old_emails, sample_event): create_email() # email with old_id=1 response = client.post(url_for('emails.import_emails'), data=json.dumps(sample_old_emails), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) json_emails = json_resp['emails'] email_types = [EVENT, ANNOUNCEMENT, ANON_REMINDER] assert len(json_emails) == len(sample_old_emails) - 1 for i in range(0, len(sample_old_emails) - 1): assert json_emails[i]['email_type'] == email_types[i] assert json_emails[i]['created_at'] == sample_old_emails[ i + 1]['timestamp'][:-3] assert json_emails[i]['extra_txt'] == sample_old_emails[ i + 1]['extratxt'] assert json_emails[i]['details'] == sample_old_emails[ i + 1]['eventdetails'] assert str(json_emails[i]['old_id']) == sample_old_emails[i + 1]['id'] assert str(json_emails[i]['old_event_id']) == sample_old_emails[ i + 1]['eventid'] assert json_emails[i]['replace_all'] == ( True if sample_old_emails[i + 1]['replaceAll'] == 'y' else False) json_errors = json_resp['errors'] assert json_errors == ['email already exists: 1']
def it_does_not_create_book_for_imported_books_with_duplicates( self, client, db_session): duplicate_book = { "id": "1", "FormatId": "1", "Title": "The Alchemist", "Author": "Jorge A Livraga", "ImageFilename": "BookAlchemist.png", "WebLink": "", "Price": "7.00", "BuyCode": "XXYXXYXXYYXYY", "Active": "y" }, sample_books_for_import.extend(duplicate_book) response = client.post(url_for('books.import_books'), data=json.dumps(sample_books_for_import), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 201 json_books = json.loads(response.get_data(as_text=True))['books'] assert len(json_books) == len( sample_books_for_import) - 1 # don't add in duplicate book for i in range(0, len(sample_books_for_import) - 1): assert json_books[i]["old_id"] == int( sample_books_for_import[i]["id"]) assert json_books[i]["title"] == sample_books_for_import[i][ "Title"] assert json_books[i]["author"] == sample_books_for_import[i][ "Author"]
def it_does_not_create_article_for_imported_articles_with_duplicates(self, client, db_session): duplicate_article = { "id": "1", "title": "Forty Years Fighting Racism and Intolerance", "author": "John Gilbert", "content": """<h2>A century with no solidarity</h2>\r\n One of the worst plagues that the twentieth century has had to \r\n bear is racial discrimination.""", "entrydate": "2015-11-01" }, sample_articles.extend(duplicate_article) response = client.post( url_for('articles.import_articles'), data=json.dumps(sample_articles), headers=[('Content-Type', 'application/json'), create_authorization_header()] ) assert response.status_code == 201 json_articles = json.loads(response.get_data(as_text=True))['articles'] assert len(json_articles) == len(sample_articles) - 1 # don't add in duplicate article for i in range(0, len(sample_articles) - 1): assert json_articles[i]["old_id"] == int(sample_articles[i]["id"]) assert json_articles[i]["title"] == sample_articles[i]["title"] assert json_articles[i]["author"] == sample_articles[i]["author"] assert json_articles[i]["content"] == sample_articles[i]["content"] assert json_articles[i]["created_at"] == sample_articles[i]["entrydate"]
def it_returns_all_books(self, client, db_session, sample_book): response = client.get(url_for('books.get_books'), headers=[create_authorization_header()]) assert response.status_code == 200 assert len(response.json) == 1 assert response.json[0]['id'] == str(sample_book.id)
def it_returns_correct_book(self, client, sample_book, db_session): response = client.get(url_for('book.get_book_by_id', book_id=str(sample_book.id)), headers=[create_authorization_header()]) assert response.status_code == 200 assert response.json['id'] == str(sample_book.id)
def it_raises_401_if_token_expires(self, auth_app): auth_header = create_authorization_header() with freeze_time('2017-10-20T13:00:00'): response = auth_app.get(path='/protected', headers=[auth_header]) assert response.status_code == 401 json_resp = json.loads(response.get_data(as_text=True)) assert json_resp['message'] == 'Signature expired'