Added email functionality
Build LinkLog Development Image / development-image (push) Successful in 10s
Build LinkLog Development Image / development-image (push) Successful in 10s
This commit is contained in:
@@ -9,6 +9,7 @@ from uuid import uuid4
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from backend.app.main import app
|
||||
from backend.app.services.token_service import issue_token
|
||||
|
||||
|
||||
client = TestClient(app)
|
||||
@@ -74,6 +75,41 @@ def test_admin_can_add_list_and_remove_users():
|
||||
assert client.put('/api/admin/users/user-1', headers=headers, json={'is_admin': False}).status_code == 400
|
||||
|
||||
|
||||
def test_new_user_must_verify_email_before_login():
|
||||
headers = login_headers()
|
||||
username = f'unverified-{uuid4().hex}'
|
||||
created = client.post('/api/admin/users', headers=headers, json={
|
||||
'username': username,
|
||||
'email': f'{username}@example.com',
|
||||
'password': 'secret123',
|
||||
})
|
||||
assert created.status_code == 201
|
||||
assert created.json()['email_verified'] is False
|
||||
|
||||
login = client.post('/api/auth/login', json={'username': username, 'password': 'secret123'})
|
||||
assert login.status_code == 403
|
||||
assert login.json()['detail'] == 'Email address is not verified'
|
||||
|
||||
|
||||
def test_email_verification_link_enables_login():
|
||||
headers = login_headers()
|
||||
username = f'verifiable-{uuid4().hex}'
|
||||
created = client.post('/api/admin/users', headers=headers, json={
|
||||
'username': username,
|
||||
'email': f'{username}@example.com',
|
||||
'password': 'secret123',
|
||||
})
|
||||
assert created.status_code == 201
|
||||
user_id = created.json()['id']
|
||||
from backend.app.services.email_verification import create_verification_token
|
||||
verification_token = create_verification_token(user_id)
|
||||
|
||||
verified = client.get('/api/auth/verify-email', params={'token': verification_token})
|
||||
assert verified.status_code == 200
|
||||
assert client.post('/api/auth/login', json={'username': username, 'password': 'secret123'}).status_code == 200
|
||||
assert client.get('/api/auth/verify-email', params={'token': verification_token}).status_code == 400
|
||||
|
||||
|
||||
def test_admin_can_remove_user_with_owned_data():
|
||||
headers = login_headers()
|
||||
username = f'data-owner-{uuid4().hex}'
|
||||
@@ -84,7 +120,8 @@ def test_admin_can_remove_user_with_owned_data():
|
||||
})
|
||||
assert create_response.status_code == 201
|
||||
user_id = create_response.json()['id']
|
||||
user_headers = login_headers(username)
|
||||
user_token = issue_token(user_id, username)['access_token']
|
||||
user_headers = {'Authorization': f'Bearer {user_token}'}
|
||||
|
||||
link_response = client.post('/api/links', headers=user_headers, json={
|
||||
'title': 'Owned link',
|
||||
|
||||
@@ -10,7 +10,7 @@ def test_database_migrations_are_versioned_and_idempotent():
|
||||
connection = sqlite3.connect(':memory:')
|
||||
|
||||
apply_migrations(connection)
|
||||
assert get_schema_version(connection) == 4
|
||||
assert get_schema_version(connection) == 5
|
||||
tables = {
|
||||
row[0]
|
||||
for row in connection.execute(
|
||||
@@ -27,6 +27,6 @@ def test_database_migrations_are_versioned_and_idempotent():
|
||||
assert set(DEFAULT_TAGS) <= seeded_tags
|
||||
|
||||
apply_migrations(connection)
|
||||
assert get_schema_version(connection) == 4
|
||||
assert get_schema_version(connection) == 5
|
||||
|
||||
connection.close()
|
||||
@@ -0,0 +1,28 @@
|
||||
## Copyright © 2026 Olaf Kolkman
|
||||
## SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from backend.app.services.email_service import send_verification_email
|
||||
|
||||
|
||||
def test_send_verification_email_uses_smtp_settings(monkeypatch):
|
||||
from backend.app.core.config import settings
|
||||
|
||||
monkeypatch.setattr(settings, 'smtp_host', 'smtp.example.com')
|
||||
monkeypatch.setattr(settings, 'smtp_port', 587)
|
||||
monkeypatch.setattr(settings, 'smtp_from', 'LinkLog <no-reply@example.com>')
|
||||
monkeypatch.setattr(settings, 'smtp_username', 'mailer')
|
||||
monkeypatch.setattr(settings, 'smtp_password', 'secret')
|
||||
monkeypatch.setattr(settings, 'smtp_use_tls', True)
|
||||
|
||||
with patch('backend.app.services.email_service.SMTP') as smtp_class:
|
||||
smtp = smtp_class.return_value.__enter__.return_value
|
||||
send_verification_email('user@example.com', 'user', 'https://linklog.example/verify')
|
||||
|
||||
smtp_class.assert_called_once_with('smtp.example.com', 587, timeout=10)
|
||||
smtp.starttls.assert_called_once_with()
|
||||
smtp.login.assert_called_once_with('mailer', 'secret')
|
||||
message = smtp.send_message.call_args.args[0]
|
||||
assert message['To'] == 'user@example.com'
|
||||
assert 'https://linklog.example/verify' in message.get_content()
|
||||
Reference in New Issue
Block a user