diff --git a/kibicara/platforms/email/bot.py b/kibicara/platforms/email/bot.py index e62e6ed..a0aa306 100644 --- a/kibicara/platforms/email/bot.py +++ b/kibicara/platforms/email/bot.py @@ -4,8 +4,8 @@ # # SPDX-License-Identifier: 0BSD +from kibicara import email from kibicara.config import config -from kibicara.email import send_email from kibicara.model import Hood from kibicara.platformapi import Censor, Spawner from kibicara.platforms.email.model import EmailSubscribers @@ -40,7 +40,7 @@ class EmailBot(Censor): ) % (message.text, config['root_url'], self.hood.id, token) try: logger.debug('Trying to send: \n%s' % body) - send_email( + email.send_email( subscriber.email, "Kibicara " + self.hood.name, body=body, ) except (ConnectionRefusedError, SMTPException): diff --git a/kibicara/platforms/email/webapi.py b/kibicara/platforms/email/webapi.py index f018f3a..1e38a4a 100644 --- a/kibicara/platforms/email/webapi.py +++ b/kibicara/platforms/email/webapi.py @@ -5,11 +5,11 @@ # SPDX-License-Identifier: 0BSD from fastapi import APIRouter, Depends, HTTPException, Response, status +from kibicara import email from kibicara.platforms.email.bot import spawner from kibicara.platforms.email.model import Email, EmailSubscribers from kibicara.platformapi import Message from kibicara.config import config -from kibicara.email import send_email from kibicara.webapi.admin import from_token, to_token from kibicara.webapi.hoods import get_hood, get_hood_unauthorized from logging import getLogger @@ -99,7 +99,7 @@ async def email_read(email=Depends(get_email)): @router.put('/{email_id}', status_code=status.HTTP_204_NO_CONTENT) async def email_update(email=Depends(get_email)): - await email.update() + await email.update() # TODO @router.delete('/{email_id}', status_code=status.HTTP_204_NO_CONTENT) @@ -123,13 +123,13 @@ async def email_subscribe( :return: Returns status code 200 after sending confirmation email. """ token = to_token(hood=hood.id, email=subscriber.email) - confirm_link = '%s/api/%d/email/subscribe/confirm/%s' % ( + confirm_link = '%s/api/hoods/%d/email/subscribe/confirm/%s' % ( config['root_url'], hood.id, token, ) try: - send_email( + email.send_email( subscriber.email, "Subscribe to Kibicara " + hood.name, sender=hood.name, @@ -177,7 +177,10 @@ async def email_unsubscribe(token, hood=Depends(get_hood_unauthorized)): # If token.hood and url.hood are different, raise an error: if hood.id is not payload['hood']: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST) - await EmailSubscribers.objects.delete(hood=payload['hood'], email=payload['email']) + subscriber = await EmailSubscribers.objects.filter( + hood=payload['hood'], email=payload['email'] + ).get() + await subscriber.delete() @router.get('/subscribers/') diff --git a/tests/conftest.py b/tests/conftest.py index d23d740..b180119 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -122,11 +122,12 @@ def test_id(client, hood_id, auth_header): @fixture(scope="function") def email_row(client, hood_id, auth_header): - response = client.post('/api/hoods/%d/email/' % hood_id, headers=auth_header) + response = client.post( + '/api/hoods/%d/email/' % hood_id, + json={'name': 'kibicara-test'}, + headers=auth_header, + ) assert response.status_code == status.HTTP_201_CREATED - assert response.json()["hood"]["id"] == hood_id - email_row = response.json() - response = client.post('/api/hoods/%d/email/' % hood_id, headers=auth_header) - assert response.status_code == status.HTTP_409_CONFLICT - yield email_row - client.delete('/api/hoods/%d/email/' % hood_id, headers=auth_header) + email_id = int(response.headers['Location']) + yield response.json() + client.delete('/api/hoods/%d/email/%d' % (hood_id, email_id), headers=auth_header) diff --git a/tests/test_api_email_happy_path.py b/tests/test_api_email_happy_path.py index 984a14e..97db38f 100644 --- a/tests/test_api_email_happy_path.py +++ b/tests/test_api_email_happy_path.py @@ -3,39 +3,32 @@ # SPDX-License-Identifier: 0BSD from fastapi import status -from logging import getLogger, INFO, WARNING, Handler from kibicara.webapi.admin import to_token import subprocess from pytest import skip +from re import findall +from urllib.parse import urlparse -class CaptureHandler(Handler): - def __init__(self): - super().__init__() - self.records = [] - - def emit(self, record): - self.records.append(record) - - -def test_email_subscribe(client, hood_id, email_row): - logger = getLogger() - capture = CaptureHandler() - logger.setLevel(INFO) - logger.addHandler(capture) +def test_email_subscribe_unsubscribe(client, hood_id, receive_email): response = client.post( '/api/hoods/%d/email/subscribe/' % hood_id, json={'email': 'test@localhost'} ) - logger.setLevel(WARNING) - logger.removeHandler(capture) - assert response.status_code == status.HTTP_502_BAD_GATEWAY - token = capture.records[0].message - response = client.post( - '/api/hoods/%d/email/subscribe/confirm/%s' % (hood_id, token) - ) + assert response.status_code == status.HTTP_202_ACCEPTED + mail = receive_email() + body = mail['body'] + confirm_url = findall( + 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', + body, + )[0] + print(urlparse(confirm_url).path) + response = client.post(urlparse(confirm_url).path) assert response.status_code == status.HTTP_201_CREATED - # response = client.get('/api/hoods/%d/email/subscribe/confirm/%s' % (hood_id, token)) - # assert response.status_code == status.HTTP_409_CONFLICT + response = client.post(urlparse(confirm_url).path) + assert response.status_code == status.HTTP_409_CONFLICT + token = to_token(email=mail['to'], hood=hood_id) + response = client.delete('/api/hoods/%d/email/unsubscribe/%s' % (hood_id, token)) + assert response.status_code == status.HTTP_204_NO_CONTENT def test_email_message(client, hood_id, trigger_id, email_row): @@ -48,13 +41,6 @@ def test_email_message(client, hood_id, trigger_id, email_row): assert response.status_code == status.HTTP_201_CREATED -def test_email_unsubscribe(client, hood_id, email_row): - test_email_subscribe(client, hood_id, email_row) - token = to_token(email="user@localhost", hood=hood_id) - response = client.delete('/api/hoods/%d/email/unsubscribe/%s' % (hood_id, token)) - assert response.status_code == status.HTTP_204_NO_CONTENT - - def test_email_send_mda(trigger_id, email_row): skip('Only works if kibicara is listening on port 8000, and only sometimes') mail = """From test@example.com Tue Jun 16 15:33:19 2020