예제 #1
0
async def test_upload_image(cli, url, factory: Factory, login, db_conn,
                            dummy_server):
    await factory.create_company()
    await factory.create_user()
    await login()
    assert 'https://www.example.org/main.png' == await db_conn.fetchval(
        'SELECT image FROM companies')
    data = FormData()
    data.add_field('image',
                   create_image(),
                   filename='testing.png',
                   content_type='application/octet-stream')
    r = await cli.post(url('company-upload', field='image'),
                       data=data,
                       headers={
                           'Referer':
                           f'http://127.0.0.1:{cli.server.port}/foobar/',
                           'Origin': f'http://127.0.0.1:{cli.server.port}',
                       })
    assert r.status == 200, await r.text()
    # debug(dummy_server.app['log'])
    assert sorted(dummy_server.app['log']) == [
        'DELETE aws_endpoint_url/testingbucket.example.org/main.png',
        'DELETE aws_endpoint_url/testingbucket.example.org/thumb.png',
        RegexStr(
            r'PUT aws_endpoint_url/testingbucket.example.org/tests/testing/co/image/\w+/main.png'
        ),
        RegexStr(
            r'PUT aws_endpoint_url/testingbucket.example.org/tests/testing/co/image/\w+/thumb.png'
        ),
    ]
    logo = await db_conn.fetchval('SELECT image FROM companies')
    assert logo.startswith(
        'https://testingbucket.example.org/tests/testing/co/image/')
예제 #2
0
파일: test_cats.py 프로젝트: bakasa/nosht
async def test_upload_image(cli, url, factory: Factory, login, dummy_server):
    await factory.create_company()
    await factory.create_user()
    await factory.create_cat()
    await login()
    data = FormData()
    data.add_field('image',
                   create_image(),
                   filename='testing.png',
                   content_type='application/octet-stream')
    r = await cli.post(url('categories-add-image', cat_id=factory.category_id),
                       data=data,
                       headers={
                           'Referer':
                           f'http://127.0.0.1:{cli.server.port}/foobar/',
                           'Origin': f'http://127.0.0.1:{cli.server.port}',
                       })
    assert r.status == 200, await r.text()
    assert sorted(dummy_server.app['log']) == [
        RegexStr(
            r'PUT aws_endpoint_url/testingbucket.example.org/tests/testing/supper-clubs/option/\w+/main.png'
        ),
        RegexStr(
            r'PUT aws_endpoint_url/testingbucket.example.org/tests/testing/supper-clubs/option/\w+/thumb.png'
        ),
    ]
예제 #3
0
def test_inline_css_dev(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.html': '{{inline_css("theme/main.css")}}',
                'bar.html': "{{ url('theme/main.css') }}",
            },
            'theme': {
                'sass/main.scss': 'body {width: 10px + 10px;}',
            },
        })
    build(tmpdir, mode=Mode.development)
    assert gettree(tmpdir.join('dist')) == {
        'foo': {
            'index.html': ('body {\n'
                           '  width: 20px; }\n'
                           '\n'
                           '/*# sourceMappingURL=/theme/main.css.map */\n'),
        },
        'bar': {
            'index.html': RegexStr(r'/theme/main.css\?t=\d+\n'),
        },
        'theme': {
            'main.css.map':
            RegexStr('{.*'),
            'main.css': ('body {\n'
                         '  width: 20px; }\n'
                         '\n'
                         '/*# sourceMappingURL=main.css.map */'),
            '.src': {
                'main.scss': 'body {width: 10px + 10px;}',
            },
        },
    }
예제 #4
0
async def test_real_intent(cli, url, login, db_conn, factory: Factory):
    await factory.create_company(stripe_public_key=stripe_public_key,
                                 stripe_secret_key=stripe_secret_key)
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(status='published', price=123.45)

    await login()
    data = {
        'tickets': [
            {
                't': True,
                'first_name': 'Ticket',
                'last_name': 'Buyer',
                'email': '*****@*****.**'
            },
            {
                't': True,
                'email': '*****@*****.**'
            },
        ],
        'ticket_type':
        factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id),
                            data=data)
    assert r.status == 200, await r.text()
    response_data = await r.json()
    assert response_data == {
        'booking_token': RegexStr(r'.+'),
        'ticket_count': 2,
        'extra_donated': None,
        'item_price': 123.45,
        'total_price': 246.90,
        'timeout': AnyInt(),
        'client_secret': RegexStr(r'pi_.*'),
        'action_id': AnyInt(),
    }
    customer_id = await db_conn.fetchval(
        'SELECT stripe_customer_id FROM users WHERE id=$1', factory.user_id)
    assert customer_id is not None
    assert customer_id.startswith('cus_')

    app = cli.app['main_app']
    r = await StripeClient(app, stripe_secret_key).get(
        f'payment_intents?limit=3&customer={customer_id}')

    assert len(r['data']) == 1
    payment_intent = r['data'][0]
    assert payment_intent['amount'] == 246_90
    assert payment_intent[
        'description'] == f'2 tickets for The Event Name ({factory.event_id})'
    assert payment_intent['metadata'] == {
        'purpose': 'buy-tickets',
        'event_id': str(factory.event_id),
        'tickets_bought': '2',
        'reserve_action_id': str(response_data['action_id']),
        'user_id': str(factory.user_id),
    }
예제 #5
0
async def test_event_export(cli, url, login, factory: Factory):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(
        price=12.34,
        status='published',
        location_name='Testing Location',
        location_lat=51.5,
        location_lng=-0.5,
        start_ts=datetime(2032, 6, 1, 1, 13, 12, tzinfo=timezone.utc),
        duration=timedelta(hours=2, minutes=45),
        youtube_video_id='abcxyz',
    )

    # two tickets
    await factory.buy_tickets(await factory.create_reservation())
    await factory.buy_tickets(await factory.create_reservation())

    await login()

    r = await cli.get(url('export', type='events'))
    assert r.status == 200
    assert r.headers['Content-Disposition'] == RegexStr(
        r'attachment;filename=nosht_events_\d{4}-\d\d-\d\dT.+\.csv')
    text = await r.text()
    data = [dict(r) for r in DictReader(StringIO(text))]
    assert data == [
        {
            'id': str(factory.event_id),
            'name': 'The Event Name',
            'slug': 'the-event-name',
            'status': 'published',
            'start_time': '2032-06-01T02:13:12+01',
            'timezone': 'Europe/London',
            'duration_hours': '2.75',
            'youtube_video_id': 'abcxyz',
            'short_description': RegexStr(r'.*'),
            'long_description': RegexStr(r'.*'),
            'description_intro': RegexStr(r'.*'),
            'description_image': '',
            'is_public': 'true',
            'location_name': 'Testing Location',
            'location_lat': '51.5000000',
            'location_lng': '-0.5000000',
            'ticket_limit': '',
            'image': '',
            'ticket_price': '12.34,12.34',
            'tickets_booked': '2',
            'total_raised': '24.68',
            'category_id': str(factory.category_id),
            'category_slug': 'supper-clubs',
        },
    ]
예제 #6
0
async def test_reserve_tickets(cli, url, db_conn, factory: Factory, login):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user(first_name=None, last_name=None, email='*****@*****.**')
    await factory.create_event(status='published', price=10)
    await login(email='*****@*****.**')

    data = {
        'tickets': [
            {
                't': True,
                'first_name': 'Ticket',
                'last_name': 'Buyer',
                'email': '*****@*****.**',
                'allow_marketing': True,
            },
            {
                't': True,
                'first_name': 'Other',
                'last_name': 'Person',
                'email': '*****@*****.**',
                'extra_info': 'I love to party',
                'cover_costs': None,
                'allow_marketing': None,
            },
        ],
        'ticket_type': factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id), data=data)
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'booking_token': RegexStr(r'.+'),
        'ticket_count': 2,
        'extra_donated': None,
        'item_price': 10.0,
        'total_price': 20.0,
        'timeout': AnyInt(),
        'client_secret': RegexStr(r'payment_intent_secret_\d+'),
        'action_id': AnyInt(),
    }
    booking_token = decrypt_json(cli.app['main_app'], data['booking_token'].encode())
    reserve_action_id = await db_conn.fetchval("SELECT id FROM actions WHERE type='reserve-tickets'")
    assert booking_token == {
        'user_id': factory.user_id,
        'action_id': reserve_action_id,
        'event_id': factory.event_id,
        'price_cent': 20_00,
        'ticket_count': 2,
        'event_name': 'The Event Name',
    }
예제 #7
0
async def test_cat_event_list(cli, url, db_conn, factory: Factory):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(status='published')

    slug = await db_conn.fetchval('SELECT slug FROM categories WHERE id=$1', factory.category_id)
    r = await cli.get(url('category', category=slug))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'events': [
            {
                'id': factory.event_id,
                'name': 'The Event Name',
                'cat_slug': 'supper-clubs',
                'slug': 'the-event-name',
                'image': 'https://www.example.org/main.png',
                'short_description': RegexStr(r'.*'),
                'start_ts': '2032-06-28T19:00:00',
                'duration': 3600,
                'sold_out': False,
                'allow_donations': False,
                'allow_tickets': True,
            },
        ],
    }
    await db_conn.execute("update events set secondary_image='second-image', location_name='loc-name'")
    r = await cli.get(url('category', category=slug))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'events': [
            {
                'id': factory.event_id,
                'name': 'The Event Name',
                'cat_slug': 'supper-clubs',
                'slug': 'the-event-name',
                'image': 'https://www.example.org/main.png',
                'secondary_image': 'second-image',
                'short_description': RegexStr(r'.*'),
                'location_name': 'loc-name',
                'start_ts': '2032-06-28T19:00:00',
                'duration': 3600,
                'sold_out': False,
                'allow_donations': False,
                'allow_tickets': True,
            },
        ],
    }
예제 #8
0
def test_resolve_sass_path_dev(tmpdir):
    mktree(
        tmpdir, {
            'pages/foobar.md': '# hello',
            'theme': {
                'assets/assets/image.png':
                '*',
                'sass/main.scss':
                'body {content: resolve_path("/assets/image.png")}',
            },
        })

    config = get_config(str(tmpdir))
    config.mode = Mode.development
    assets_grablib(config)
    mtime = tmpdir.join('theme/sass/main.scss').stat().mtime
    assert gettree(tmpdir.join('dist')) == {
        'assets': {
            'image.png': '*',
        },
        'theme': {
            'main.css.map':
            RegexStr('{.*'),
            'main.css': ("body {\n"
                         "  content: '/assets/image.png?t=%0.0f'; }\n"
                         "\n"
                         "/*# sourceMappingURL=main.css.map */") % mtime,
            '.src': {
                'main.scss':
                'body {content: resolve_path("/assets/image.png")}',
            },
        },
    }
예제 #9
0
async def test_event_ticket_export_host(cli, url, login, factory: Factory,
                                        db_conn):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user(role='host')
    await factory.create_event(status='published')
    await factory.book_free(await factory.create_reservation())
    await db_conn.execute(
        "UPDATE tickets SET first_name='foo', last_name='bar'")

    await login()

    r = await cli.get(url('event-tickets-export', id=factory.event_id))
    assert r.status == 200
    text = await r.text()
    data = [dict(r) for r in DictReader(StringIO(text))]
    assert data == [
        {
            'ticket_id': RegexStr(r'.{7}-\d+'),
            'ticket_status': 'booked',
            'booking_type': 'book-free-tickets',
            'booked_at': CloseToNow(delta=3),
            'price': '',
            'extra_donated': '',
            'extra_info': '',
            'guest_name': 'foo bar',
            'buyer_name': 'foo bar',
            'ticket_type_name': 'Standard',
        },
    ]
예제 #10
0
async def test_event_donations_export(cli, url, login, factory: Factory,
                                      db_conn):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_donation_option()
    await factory.create_event(status='published')
    await factory.create_donation(gift_aid=True)
    await login()

    r = await cli.get(url('event-donations-export', id=factory.event_id))
    assert r.status == 200
    text = await r.text()
    data = [dict(r) for r in DictReader(StringIO(text))]

    assert len(data) == 1
    assert data[0] == {
        'donation_id': RegexStr(r'.{7}-\d+'),
        'amount': '20.0',
        'user_id': str(factory.user_id),
        'user_email': '*****@*****.**',
        'donation_option': str(factory.donation_option_id),
        'gift_aid': 'True',
        'name': 'Frank Spencer',
        'timestamp': CloseToNow(delta=3),
    }
예제 #11
0
async def test_send(client: AsyncClient, aws: DummyServer):
    ses = SesClient(client, SesConfig('test_access_key', 'test_secret_key', 'testing-region-1'))

    message_id = await ses.send_email(
        '*****@*****.**',
        'test email',
        ['*****@*****.**'],
        'this is a test email',
        html_body='This is a <b>test</b> email.',
    )
    assert message_id == '123-message-id'

    assert len(aws.app['emails']) == 1
    eml = aws.app['emails'][0]
    assert eml['body'] == {
        'Action': 'SendRawEmail',
        'Source': '*****@*****.**',
        'RawMessage.Data': RegexStr('.+'),
        'Destination.ToAddresses.member.1': '*****@*****.**',
    }
    assert eml['email'] == {
        'Subject': 'test email',
        'From': '*****@*****.**',
        'MIME-Version': '1.0',
        'To': '*****@*****.**',
        'payload': [
            {'Content-Type': 'text/plain', 'payload': 'this is a test email\n'},
            {'Content-Type': 'text/html', 'payload': 'This is a <b>test</b> email.\n'},
        ],
    }
예제 #12
0
async def test_with_def(email_actor: EmailActor, factory: Factory, dummy_server, db_conn):
    await factory.create_company()
    await factory.create_user(email='*****@*****.**')

    await db_conn.execute_b(
        'INSERT INTO email_definitions (:values__names) VALUES :values',
        values=Values(
            company=factory.company_id,
            trigger=Triggers.password_reset.value,
            subject='{{{ company_name}}} xxx',
            body='DEBUG:\n{{{ __debug_context__ }}}',
        )
    )

    await email_actor.send_emails(factory.company_id, Triggers.password_reset, [UserEmail(id=factory.user_id)])

    assert dummy_server.app['log'] == [
        ('email_send_endpoint', 'Subject: "Testing xxx", To: "Frank Spencer <*****@*****.**>"'),
    ]
    assert len(dummy_server.app['emails']) == 1
    email = dummy_server.app['emails'][0]
    # debug(email)
    email_context = json.loads(re.search('```(.*?)```', email['part:text/plain'], flags=re.S).group(1))
    assert email_context == {
        'company_name': 'Testing',
        'company_logo': None,
        'base_url': 'https://127.0.0.1',
        'first_name': 'Frank',
        'full_name': 'Frank Spencer',
        'unsubscribe_link': RegexStr(r'https://127\.0\.0\.1/api/unsubscribe/\d+/\?sig=[0-9a-f]+'),
    }
예제 #13
0
async def test_cat_event_list(cli, url, db_conn, factory: Factory):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(status='published')

    slug = await db_conn.fetchval('SELECT slug FROM categories WHERE id=$1', factory.category_id)
    r = await cli.get(url('category', category=slug))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'events': [
            {
                'id': factory.event_id,
                'name': 'The Event Name',
                'cat_slug': 'supper-clubs',
                'slug': 'the-event-name',
                'image': None,
                'short_description': RegexStr('.*'),
                'location_name': None,
                'start_ts': '2020-01-28T19:00:00',
                'duration': None,
            },
        ],
    }
예제 #14
0
async def test_set_password(cli, url, factory: Factory, db_conn, login):
    await factory.create_company()
    await factory.create_user()

    pw_before = await db_conn.fetchval('SELECT password_hash FROM users WHERE id=$1', factory.user_id)

    with pytest.raises(AssertionError):
        await login(password='******')

    data = {
        'password1': 'testing-new-password',
        'password2': 'testing-new-password',
        'token': encrypt_json(cli.app['main_app'], factory.user_id),
    }
    r = await cli.json_post(url('set-password'), data=data, origin_null=True)
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'status': 'success',
        'auth_token': RegexStr(r'.+'),
        'user': {
            'id': factory.user_id,
            'first_name': 'Frank',
            'last_name': 'Spencer',
            'email': '*****@*****.**',
            'role': 'admin',
            'status': 'active',
        },
    }
    pw_after = await db_conn.fetchval('SELECT password_hash FROM users WHERE id=$1', factory.user_id)
    assert pw_after != pw_before
    await login(password='******', captcha=True)
예제 #15
0
async def test_reserve_tickets_free(cli, url, factory: Factory, login):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(status='published')
    await login()

    data = {
        'tickets': [{'t': True, 'first_name': 'Ticket', 'last_name': 'Buyer', 'email': '*****@*****.**'}],
        'ticket_type': factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id), data=data)
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'booking_token': RegexStr(r'.+'),
        'ticket_count': 1,
        'extra_donated': None,
        'item_price': None,
        'total_price': None,
        'timeout': AnyInt(),
        'client_secret': None,
        'action_id': AnyInt(),
    }
    assert decrypt_json(cli.app['main_app'], data['booking_token'].encode()) == {
        'user_id': factory.user_id,
        'action_id': AnyInt(),
        'event_id': factory.event_id,
        'price_cent': None,
        'ticket_count': 1,
        'event_name': 'The Event Name',
    }
예제 #16
0
async def test_upload_logo(cli, url, factory: Factory, db_conn, login,
                           dummy_server):
    await factory.create_company()
    await factory.create_user()
    await login()
    assert None is await db_conn.fetchval('SELECT logo FROM companies')
    data = FormData()
    data.add_field('image',
                   create_image(400, 300),
                   filename='testing.png',
                   content_type='application/octet-stream')
    r = await cli.post(url('company-upload', field='logo'),
                       data=data,
                       headers={
                           'Referer':
                           f'http://127.0.0.1:{cli.server.port}/foobar/',
                           'Origin': f'http://127.0.0.1:{cli.server.port}',
                       })
    assert r.status == 200, await r.text()
    assert dummy_server.app['images'] == [
        (
            RegexStr(
                r'/aws_endpoint_url/testingbucket.example.org/tests/testing/co/logo/\w+/main.png'
            ),
            341,
            256,
        ),
    ]
    assert None is not await db_conn.fetchval('SELECT logo FROM companies')
예제 #17
0
async def test_user_list(cli, settings, send_email, db_conn):
    expected_msg_ids = []
    for i in range(4):
        uid = str(uuid.uuid4())
        await send_email(uid=uid, company_code='whoever', recipients=[{'address': f'{i}@t.com'}])
        expected_msg_ids.append(f'{uid}-{i}tcom')

    await send_email(uid=str(uuid.uuid4()), company_code='different1')
    await send_email(uid=str(uuid.uuid4()), company_code='different2')
    r = await cli.get(modify_url('/user/email-test/messages.json', settings, 'whoever'))
    assert r.status == 200, await r.text()
    assert r.headers['Access-Control-Allow-Origin'] == '*'
    data = await r.json()
    # debug(data)
    assert data['count'] == 4
    msg_ids = [h['external_id'] for h in data['items']]
    assert msg_ids == list(reversed(expected_msg_ids))
    first_item = data['items'][0]
    assert first_item == {
        'id': await db_conn.fetchval('select id from messages where external_id=$1', expected_msg_ids[3]),
        'external_id': expected_msg_ids[3],
        'send_ts': RegexStr(r'\d{4}-\d{2}-\d{2}.*'),
        'update_ts': RegexStr(r'\d{4}-\d{2}-\d{2}.*'),
        'status': 'send',
        'to_first_name': None,
        'to_last_name': None,
        'to_user_link': None,
        'to_address': '*****@*****.**',
        'company_id': await db_conn.fetchval('select id from companies where code=$1', 'whoever'),
        'method': 'email-test',
        'subject': 'test message',
        'tags': [expected_msg_ids[3][:-6]],
        'from_name': 'Sender Name',
        'cost': None,
        'extra': None,
    }

    r = await cli.get(modify_url('/user/email-test/messages.json', settings, '__all__'))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data['count'] == 6

    r = await cli.get(modify_url('/user/email-test/messages.html', settings, '__all__'))
    assert r.status == 200, await r.text()
    text = await r.text()
    assert '<caption>Results: <b>6</b></caption>' in text
    assert text.count('.com</a>') == 6
예제 #18
0
async def test_event_host_updates(email_actor: EmailActor, factory: Factory,
                                  dummy_server):
    await factory.create_company()
    await factory.create_cat()

    await factory.create_user()
    await factory.create_event(
        start_ts=offset_from_now(days=5),
        price=10,
        status='published',
    )

    anne = await factory.create_user(first_name='anne',
                                     email='*****@*****.**')
    await factory.buy_tickets(await factory.create_reservation(anne))

    assert len(dummy_server.app['emails']) == 1
    assert 1 == await email_actor.send_event_host_updates.direct()
    assert len(dummy_server.app['emails']) == 2
    email = dummy_server.app['emails'][1]
    # debug(email)
    # from pathlib import Path
    # Path('email.html').write_text(email['part:text/html'])
    assert email['Subject'] == 'The Event Name Update from Testing'
    assert email['To'] == 'Frank Spencer <*****@*****.**>'

    html = email['part:text/html']
    assert 'The Event Name is coming up in <strong>5</strong>' in html
    assert (
        '<div class="stat-label">Tickets Booked in the last day</div>\n'
        '<div class="stat-value">\n'
        '  <span class="large">1</span>\n'
        '</div>\n'
        '\n'
        '<div class="stat-label">Tickets Booked Total</div>\n'
        '<div class="stat-value">\n'
        '  <span class="large">1</span>\n'
        '</div>\n'
        '\n'
        '<div class="stat-label">Total made from ticket sales</div>\n'
        '<div class="stat-value">\n'
        '  <span class="large">£10.00</span>\n'
        '</div>\n'
        '\n'
        '<p>Guests can book your event by going to</p>\n'
        '\n'
        '<div class="text-center highlighted">https://127.0.0.1/supper-clubs/the-event-name/</div>\n'
    ) in html
    assert '<strong>Congratulations, all tickets have been booked - your event is full.</strong>' not in html

    assert (
        f'<a href="https://127.0.0.1/dashboard/events/{factory.event_id}/"><span>Event Dashboard</span></a>'
    ) in html

    assert RegexStr(
        '.*The Event Name is coming up in <strong>5</strong> days on <strong>.*'
    ) == html
예제 #19
0
async def test_osm_error(cli, dummy_server, caplog):
    r = await cli.get('/map.jpg?lat=45&lng=0&zoom=6&width=200&height=100')
    content = await r.read()
    assert r.status == 200, content
    image = Image.open(BytesIO(content))
    assert image.size == (200, 100)
    assert len(caplog.records) == 4
    r = caplog.records[0]
    assert r.getMessage() == RegexStr(r"unexpected status 429 from 'http://localhost:\d+/osm/6/\d\d/\d\d\.png'")
예제 #20
0
async def test_reserve_tickets_cover_costs(cli, url, factory: Factory, login):
    await factory.create_company()
    await factory.create_cat(cover_costs_message='Help!', cover_costs_percentage=12.5)
    await factory.create_user(first_name=None, last_name=None, email='*****@*****.**')
    await factory.create_event(status='published', price=10)
    await login(email='*****@*****.**')

    data = {
        'tickets': [
            {
                't': True,
                'first_name': 'Ticket',
                'last_name': 'Buyer',
                'email': '*****@*****.**',
                'cover_costs': True,
            },
            {
                't': True,
            },
        ],
        'ticket_type': factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id), data=data)
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'booking_token': RegexStr(r'.+'),
        'ticket_count': 2,
        'extra_donated': 2.5,
        'item_price': 10.0,
        'total_price': 22.50,
        'timeout': AnyInt(),
        'client_secret': RegexStr(r'payment_intent_secret_\d+'),
        'action_id': AnyInt(),
    }
    assert decrypt_json(cli.app['main_app'], data['booking_token'].encode()) == {
        'user_id': factory.user_id,
        'action_id': AnyInt(),
        'event_id': factory.event_id,
        'price_cent': 22_50,
        'ticket_count': 2,
        'event_name': 'The Event Name',
    }
예제 #21
0
async def test_event_public(cli, url, factory: Factory, db_conn):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(status='published',
                               location_name='Testing Location',
                               location_lat=51.5,
                               location_lng=-0.5)
    cat_slug, event_slug = await db_conn.fetchrow(
        """
        SELECT cat.slug, e.slug
        FROM events AS e
        JOIN categories cat on e.category = cat.id
        WHERE e.id=$1
        """, factory.event_id)
    r = await cli.get(url('event-get', category=cat_slug, event=event_slug))
    assert r.status == 200, await r.text()
    data = await r.json()
    # debug(data)
    assert data == {
        'event': {
            'id': factory.event_id,
            'name': 'The Event Name',
            'image': None,
            'short_description': RegexStr('.*'),
            'long_description': RegexStr('.*'),
            'category_content': None,
            'location': {
                'name': 'Testing Location',
                'lat': 51.5,
                'lng': -0.5,
            },
            'price': None,
            'start_ts': '2020-01-28T19:00:00',
            'duration': None,
            'tickets_available': None,
            'host_id': factory.user_id,
            'host_name': 'Frank Spencer',
            'stripe_key': None,
            'currency': 'gbp',
        },
    }
예제 #22
0
async def test_add_image(cli, url, factory: Factory, db_conn, login,
                         dummy_server):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_donation_option()
    await login()
    assert None is await db_conn.fetchval('SELECT image FROM donation_options')
    data = FormData()
    data.add_field('image',
                   create_image(700, 500),
                   filename='testing.png',
                   content_type='application/octet-stream')
    r = await cli.post(url('donation-image-upload',
                           pk=factory.donation_option_id),
                       data=data,
                       headers={
                           'Referer':
                           f'http://127.0.0.1:{cli.server.port}/foobar/',
                           'Origin': f'http://127.0.0.1:{cli.server.port}',
                       })
    assert r.status == 200, await r.text()
    assert sorted(dummy_server.app['images']) == [
        (
            RegexStr(
                r'/aws_endpoint_url/testingbucket.example.org/tests/testing/supper-clubs/\d+/\w+/main.png'
            ),
            672,
            480,
        ),
        (
            RegexStr(
                r'/aws_endpoint_url/testingbucket.example.org/tests/testing/supper-clubs/\d+/\w+/thumb.png'
            ),
            400,
            200,
        ),
    ]
    assert None is not await db_conn.fetchval(
        'SELECT image FROM donation_options')
    assert sum('DELETE aws_endpoint_url/' in e
               for e in dummy_server.app['log']) == 0
예제 #23
0
async def test_book_multiple(donorfy: DonorfyActor, factory: Factory,
                             dummy_server, cli, url, login):
    await factory.create_company()
    await factory.create_user()
    await factory.create_cat()
    await factory.create_user(first_name='T',
                              last_name='B',
                              email='*****@*****.**')
    await factory.create_event(status='published', price=10)
    await login(email='*****@*****.**')

    data = {
        'tickets': [
            {
                't': True,
                'email': '*****@*****.**'
            },
            {
                't': True,
                'email': '*****@*****.**'
            },
        ],
        'ticket_type':
        factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id),
                            data=data)
    assert r.status == 200, await r.text()
    action_id = (await r.json())['action_id']
    await factory.fire_stripe_webhook(action_id)

    trans_data = dummy_server.app['post_data'][
        'POST donorfy_api_root/standard/transactions']
    assert len(trans_data) == 1
    assert trans_data[0] == {
        'ExistingConstituentId': '123456',
        'Channel': 'nosht-supper-clubs',
        'Currency': 'gbp',
        'Campaign': 'supper-clubs:the-event-name',
        'PaymentMethod': 'Payment Card via Stripe',
        'Product': 'Event Ticket(s)',
        'Fund': 'Unrestricted General',
        'Department': '220 Ticket Sales',
        'BankAccount': 'Unrestricted Account',
        'DatePaid': CloseToNow(),
        'Amount': 20.0,
        'ProcessingCostsAmount': 0.5,
        'Quantity': 2,
        'Acknowledgement': 'supper-clubs-thanks',
        'AcknowledgementText': RegexStr('Ticket ID: .*'),
        'Reference': 'Events.HUF:supper-clubs the-event-name',
        'AddGiftAidDeclaration': False,
        'GiftAidClaimed': False,
    }
예제 #24
0
async def test_user_export(cli, url, login, factory: Factory):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user(receive_emails=False)
    await factory.create_event(status='published', price=10)
    await login()

    data = {
        'tickets': [{
            't': True,
            'email': '*****@*****.**'
        }],
        'ticket_type': factory.ticket_type_id,
    }
    r = await cli.json_post(url('event-reserve-tickets', id=factory.event_id),
                            data=data)
    assert r.status == 200, await r.text()
    await factory.buy_tickets(await factory.create_reservation())

    r = await cli.get(url('export', type='users'))
    assert r.status == 200
    text = await r.text()
    data = [dict(r) for r in DictReader(StringIO(text))]
    assert data == [
        {
            'id': str(factory.user_id),
            'role': 'admin',
            'status': 'active',
            'first_name': 'Frank',
            'last_name': 'Spencer',
            'email': '*****@*****.**',
            'phone_number': '',
            'stripe_customer_id': 'customer-id',
            'receive_emails': 'false',
            'allow_marketing': 'false',
            'created_ts': RegexStr(r'\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\+00'),
            'active_ts': RegexStr(r'\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\+00'),
            'tickets': '2',
        },
    ]
예제 #25
0
async def test_host_signup_email(cli, url, factory: Factory, db_conn,
                                 dummy_server, settings):
    await factory.create_company()
    assert 0 == await db_conn.fetchval('SELECT COUNT(*) FROM users')
    data = {
        'email': '*****@*****.**',
        'name': 'Jane Doe',
        'grecaptcha_token': '__ok__',
    }
    r = await cli.post(url('signup-host', site='email'), data=json.dumps(data))
    assert r.status == 200, await r.text()
    response_data = await r.json()

    assert 1 == await db_conn.fetchval('SELECT COUNT(*) FROM users')
    user = await db_conn.fetchrow(
        'SELECT id, company, first_name, last_name, email, role, status FROM users'
    )

    assert response_data == {
        'user': {
            'id': user['id'],
            'name': 'Jane Doe',
            'email': '*****@*****.**',
            'role': 'host',
        },
    }
    assert dict(user) == {
        'id': AnyInt(),
        'company': factory.company_id,
        'first_name': 'Jane',
        'last_name': 'Doe',
        'email': '*****@*****.**',
        'role': 'host',
        'status': 'pending',
    }
    assert dummy_server.app['log'] == [
        ('grecaptcha', '__ok__'),
        (
            'email_send_endpoint',
            'Subject: "Testing Account Created (Action required)", To: "Jane Doe <*****@*****.**>"',
        ),
    ]
    email = dummy_server.app['emails'][0]['part:text/plain']
    assert 'Confirm Email' in email
    assert 'Create &amp; Publish Events' not in email
    token = re.search('/set-password/\?sig=([^"]+)', email).group(1)
    token_data = json.loads(
        fernet.Fernet(settings.auth_key).decrypt(token.encode()).decode())
    assert token_data == {
        'user_id': user['id'],
        'nonce': RegexStr('.{20}'),
    }
예제 #26
0
파일: test_users.py 프로젝트: bakasa/nosht
async def test_user_actions(cli, url, login, factory: Factory, db_conn):
    await factory.create_company()
    await factory.create_user()
    await login()

    r = await cli.get(url('user-actions', pk=factory.user_id))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'actions': [
            {
                'id': await db_conn.fetchval('SELECT id FROM actions'),
                'ts': CloseToNow(),
                'type': 'login',
                'extra': {
                    'ip': '127.0.0.1',
                    'ua': RegexStr(r'Python.*'),
                    'url': RegexStr(r'http://127.0.0.1:\d+/api/auth-token/'),
                },
            },
        ],
    }
예제 #27
0
async def test_send_names(client: AsyncClient, aws: DummyServer):
    ses = SesClient(
        client,
        SesConfig('test_access_key', 'test_secret_key', 'testing-region-1'))

    await ses.send_email(
        '*****@*****.**',
        'test email',
        [SesRecipient('*****@*****.**', 'John', 'Doe')],
        'this is a test email',
        cc=[
            SesRecipient('*****@*****.**'),
            SesRecipient('*****@*****.**', 'CC2'),
            SesRecipient('*****@*****.**', None, 'CC3'),
            SesRecipient('*****@*****.**', 'Anna, Bob', 'CC4'),
        ],
        bcc=['*****@*****.**'],
    )
    assert len(aws.app['emails']) == 1
    eml = aws.app['emails'][0]
    assert eml['body'] == {
        'Action': 'SendRawEmail',
        'Source': '*****@*****.**',
        'RawMessage.Data': RegexStr('.+'),
        'Destination.ToAddresses.member.1': '*****@*****.**',
        'Destination.CcAddresses.member.1': '*****@*****.**',
        'Destination.CcAddresses.member.2': '*****@*****.**',
        'Destination.CcAddresses.member.3': '*****@*****.**',
        'Destination.CcAddresses.member.4': '*****@*****.**',
        'Destination.BccAddresses.member.1': '*****@*****.**',
    }
    assert eml['email'] == {
        'Subject':
        'test email',
        'From':
        '*****@*****.**',
        'Content-Transfer-Encoding':
        '7bit',
        'MIME-Version':
        '1.0',
        'To':
        'John Doe <*****@*****.**>',
        'Cc':
        '[email protected], CC2 <*****@*****.**>, CC3 <*****@*****.**>,\n "Anna, Bob CC4" <*****@*****.**>',
        'Bcc':
        '*****@*****.**',
        'payload': [{
            'Content-Type': 'text/plain',
            'payload': 'this is a test email\n'
        }],
    }
예제 #28
0
async def test_stripe_existing_customer_card(cli, db_conn, stripe_factory: Factory):
    await stripe_factory.create_company(stripe_public_key=stripe_public_key, stripe_secret_key=stripe_secret_key)
    await stripe_factory.create_cat()
    await stripe_factory.create_user()
    await stripe_factory.create_event(ticket_limit=10)

    res: Reservation = await stripe_factory.create_reservation()
    app = cli.app['main_app']

    customers = await stripe_request(app, BasicAuth(stripe_secret_key), 'get', 'customers?limit=1')
    customer = customers['data'][0]
    customer_id = customer['id']
    await db_conn.execute('UPDATE users SET stripe_customer_id=$1 WHERE id=$2', customer_id, stripe_factory.user_id)

    m = StripePayModel(
        stripe_token='tok_visa',
        stripe_client_ip='0.0.0.0',
        stripe_card_ref='{last4}-{exp_year}-{exp_month}'.format(**customer['sources']['data'][0]),
        booking_token=encrypt_json(app, res.dict()),
    )

    await stripe_pay(m, stripe_factory.company_id, stripe_factory.user_id, app, db_conn)

    new_customer_id = await db_conn.fetchval('SELECT stripe_customer_id FROM users WHERE id=$1', stripe_factory.user_id)
    assert new_customer_id == customer_id

    extra = await db_conn.fetchval("SELECT extra FROM actions WHERE type='buy-tickets'")

    extra = json.loads(extra)
    assert extra == {
        'new_card': False,
        'new_customer': False,
        'charge_id': RegexStr('ch_.+'),
        'card_expiry': RegexStr('\d+/\d+'),
        'card_last4': '4242',
    }
예제 #29
0
async def test_root(cli, url, factory: Factory):
    await factory.create_company()
    await factory.create_cat()
    await factory.create_user()
    await factory.create_event(highlight=True,
                               status='published',
                               location_name='Testing Location')
    r = await cli.get(url('index'))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'categories': [
            {
                'id': factory.category_id,
                'name': 'Supper Clubs',
                'slug': 'supper-clubs',
                'image': 'https://www.example.org/main.png',
                'description': None,
            },
        ],
        'highlight_events': [
            {
                'id': factory.event_id,
                'name': 'The Event Name',
                'cat_slug': 'supper-clubs',
                'slug': 'the-event-name',
                'image': 'https://www.example.org/main.png',
                'secondary_image': None,
                'short_description': RegexStr(r'.*'),
                'location_name': 'Testing Location',
                'start_ts': '2032-06-28T19:00:00',
                'duration': 3600,
                'sold_out': False,
                'allow_donations': False,
                'allow_tickets': True,
            },
        ],
        'company': {
            'id': factory.company_id,
            'name': 'Testing',
            'image': 'https://www.example.org/main.png',
            'currency': 'gbp',
            'stripe_public_key': 'stripe_key_xxx',
            'footer_links': None,
        },
        'user':
        None,
    }
예제 #30
0
async def test_retrieve_missing_email_defs(cli, url, login, factory: Factory):
    await factory.create_company()
    await factory.create_user()

    await login()

    r = await cli.get(url('email-defs-retrieve', trigger=Triggers.event_reminder.value))
    assert r.status == 200, await r.text()
    data = await r.json()
    assert data == {
        'trigger': 'event-reminder',
        'customised': False,
        'active': True,
        'subject': '{{{ event_name }}} Upcoming',
        'title': '{{ company_name }}',
        'body': RegexStr(r'.*'),
    }