feat: add PendingRewardDialog, RewardConfirmDialog, and TaskConfirmDialog components
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 25s
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 25s
- Implemented PendingRewardDialog for handling pending reward requests. - Created RewardConfirmDialog for confirming reward redemption. - Developed TaskConfirmDialog for task confirmation with child name display. test: add unit tests for ChildView and ParentView components - Added comprehensive tests for ChildView including task triggering and SSE event handling. - Implemented tests for ParentView focusing on override modal and SSE event management. test: add ScrollingList component tests - Created tests for ScrollingList to verify item fetching, loading states, and custom item classes. - Included tests for two-step click interactions and edit button display logic. - Moved toward hashed passwords.
This commit is contained in:
142
backend/tests/test_auth_api.py
Normal file
142
backend/tests/test_auth_api.py
Normal file
@@ -0,0 +1,142 @@
|
||||
import pytest
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from flask import Flask
|
||||
from api.auth_api import auth_api
|
||||
from db.db import users_db
|
||||
from tinydb import Query
|
||||
from models.user import User
|
||||
from datetime import datetime
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Setup Flask test client with auth blueprint."""
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(auth_api, url_prefix='/auth')
|
||||
app.config['TESTING'] = True
|
||||
app.config['SECRET_KEY'] = 'supersecretkey'
|
||||
app.config['FRONTEND_URL'] = 'http://localhost:5173'
|
||||
with app.test_client() as client:
|
||||
yield client
|
||||
|
||||
def test_signup_hashes_password(client):
|
||||
"""Test that signup hashes the password."""
|
||||
# Clean up any existing user
|
||||
users_db.remove(Query().email == 'test@example.com')
|
||||
|
||||
data = {
|
||||
'first_name': 'Test',
|
||||
'last_name': 'User',
|
||||
'email': 'test@example.com',
|
||||
'password': 'password123'
|
||||
}
|
||||
response = client.post('/auth/signup', json=data)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Check that password is hashed in DB
|
||||
user_dict = users_db.get(Query().email == 'test@example.com')
|
||||
assert user_dict is not None
|
||||
assert user_dict['password'].startswith('scrypt:')
|
||||
|
||||
def test_login_with_correct_password(client):
|
||||
"""Test login succeeds with correct password."""
|
||||
# Clean up and create a user with hashed password
|
||||
users_db.remove(Query().email == 'test@example.com')
|
||||
hashed_pw = generate_password_hash('password123')
|
||||
user = User(
|
||||
first_name='Test',
|
||||
last_name='User',
|
||||
email='test@example.com',
|
||||
password=hashed_pw,
|
||||
verified=True
|
||||
)
|
||||
users_db.insert(user.to_dict())
|
||||
|
||||
data = {'email': 'test@example.com', 'password': 'password123'}
|
||||
response = client.post('/auth/login', json=data)
|
||||
assert response.status_code == 200
|
||||
assert 'token' in response.headers.get('Set-Cookie', '')
|
||||
|
||||
def test_login_with_incorrect_password(client):
|
||||
"""Test login fails with incorrect password."""
|
||||
# Clean up and create a user with hashed password
|
||||
users_db.remove(Query().email == 'test@example.com')
|
||||
hashed_pw = generate_password_hash('password123')
|
||||
user = User(
|
||||
first_name='Test',
|
||||
last_name='User',
|
||||
email='test@example.com',
|
||||
password=hashed_pw,
|
||||
verified=True
|
||||
)
|
||||
users_db.insert(user.to_dict())
|
||||
|
||||
data = {'email': 'test@example.com', 'password': 'wrongpassword'}
|
||||
response = client.post('/auth/login', json=data)
|
||||
assert response.status_code == 401
|
||||
assert response.json['code'] == 'INVALID_CREDENTIALS'
|
||||
|
||||
def test_reset_password_hashes_new_password(client):
|
||||
"""Test that reset-password hashes the new password."""
|
||||
# Clean up and create a user with reset token
|
||||
users_db.remove(Query().email == 'test@example.com')
|
||||
user = User(
|
||||
first_name='Test',
|
||||
last_name='User',
|
||||
email='test@example.com',
|
||||
password=generate_password_hash('oldpassword'),
|
||||
verified=True,
|
||||
reset_token='validtoken',
|
||||
reset_token_created=datetime.utcnow().isoformat()
|
||||
)
|
||||
users_db.insert(user.to_dict())
|
||||
|
||||
data = {'token': 'validtoken', 'password': 'newpassword123'}
|
||||
response = client.post('/auth/reset-password', json=data)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Check that password is hashed in DB
|
||||
user_dict = users_db.get(Query().email == 'test@example.com')
|
||||
assert user_dict is not None
|
||||
assert user_dict['password'].startswith('scrypt:')
|
||||
assert check_password_hash(user_dict['password'], 'newpassword123')
|
||||
|
||||
def test_migration_script_hashes_plain_text_passwords():
|
||||
"""Test the migration script hashes plain text passwords."""
|
||||
# Clean up
|
||||
users_db.remove(Query().email == 'test1@example.com')
|
||||
users_db.remove(Query().email == 'test2@example.com')
|
||||
|
||||
# Create users with plain text passwords
|
||||
user1 = User(
|
||||
first_name='Test1',
|
||||
last_name='User',
|
||||
email='test1@example.com',
|
||||
password='plaintext1',
|
||||
verified=True
|
||||
)
|
||||
already_hashed = generate_password_hash('alreadyhashed')
|
||||
user2 = User(
|
||||
first_name='Test2',
|
||||
last_name='User',
|
||||
email='test2@example.com',
|
||||
password=already_hashed, # Already hashed
|
||||
verified=True
|
||||
)
|
||||
users_db.insert(user1.to_dict())
|
||||
users_db.insert(user2.to_dict())
|
||||
|
||||
# Run migration script
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
from scripts.hash_passwords import main
|
||||
main()
|
||||
|
||||
# Check user1 password is now hashed
|
||||
user1_dict = users_db.get(Query().email == 'test1@example.com')
|
||||
assert user1_dict['password'].startswith('scrypt:')
|
||||
assert check_password_hash(user1_dict['password'], 'plaintext1')
|
||||
|
||||
# Check user2 password unchanged
|
||||
user2_dict = users_db.get(Query().email == 'test2@example.com')
|
||||
assert user2_dict['password'] == already_hashed
|
||||
Reference in New Issue
Block a user