improvements on tests
This commit is contained in:
2
QWEN.md
2
QWEN.md
@@ -17,3 +17,5 @@ Here are special rules you must follow:
|
|||||||
3. modals can be closed by triggering a close-modal event anywhere in the dom.
|
3. modals can be closed by triggering a close-modal event anywhere in the dom.
|
||||||
4. validation is done server-side. On modals, an error should cause the button to shake, and the invalid fields to be highlighted in red using normal daisyui paradigms. When relevant, there should be a notification banner inside the dialog-box to show the details of the error.
|
4. validation is done server-side. On modals, an error should cause the button to shake, and the invalid fields to be highlighted in red using normal daisyui paradigms. When relevant, there should be a notification banner inside the dialog-box to show the details of the error.
|
||||||
5. When validation is done outside of a modal, it should cause a notification banner with the details.
|
5. When validation is done outside of a modal, it should cause a notification banner with the details.
|
||||||
|
6. Testing is done with pytest.
|
||||||
|
7. Testing is done with beautifulsoup4
|
||||||
|
|||||||
@@ -200,5 +200,4 @@ def update_folder(folder_id):
|
|||||||
response = make_response(render_template('partials/folder_modal.html', folder=folder, errors=errors, name=name, rule_text=rule_text, priority=priority))
|
response = make_response(render_template('partials/folder_modal.html', folder=folder, errors=errors, name=name, rule_text=rule_text, priority=priority))
|
||||||
response.headers['HX-Retarget'] = '#folder-modal'
|
response.headers['HX-Retarget'] = '#folder-modal'
|
||||||
response.headers['HX-Reswap'] = 'outerHTML'
|
response.headers['HX-Reswap'] = 'outerHTML'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
Flask==2.3.2
|
Flask==2.3.2
|
||||||
Flask-SQLAlchemy==3.0.5
|
Flask-SQLAlchemy==3.0.5
|
||||||
psycopg2-binary==2.9.7
|
psycopg2-binary==2.9.7
|
||||||
pytest==7.4.0
|
pytest==7.4.0
|
||||||
|
beautifulsoup4==4.13.4
|
||||||
|
Flask-Migrate==4.1.0
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from app.models import User, Folder
|
from app.models import User, Folder
|
||||||
|
from app.routes import MOCK_USER_ID
|
||||||
import uuid
|
import uuid
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
def test_index_route(client, app, mock_user):
|
def test_index_route(client, app, mock_user):
|
||||||
response = client.get('/')
|
response = client.get('/')
|
||||||
@@ -25,4 +27,242 @@ def test_add_folder_route(client, mock_user):
|
|||||||
|
|
||||||
# Verify that the number of folders has increased
|
# Verify that the number of folders has increased
|
||||||
final_folder_count = Folder.query.count()
|
final_folder_count = Folder.query.count()
|
||||||
assert final_folder_count > initial_folder_count
|
assert final_folder_count > initial_folder_count
|
||||||
|
|
||||||
|
# Validation failure tests
|
||||||
|
def test_add_folder_validation_failure_empty_name(client, mock_user):
|
||||||
|
"""Test validation failure when folder name is empty."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': '', 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
# Check that the specific error message is present
|
||||||
|
assert b'Folder name is required' in response.data
|
||||||
|
# Check that the input field has the error class
|
||||||
|
assert b'input-error' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_failure_short_name(client, mock_user):
|
||||||
|
"""Test validation failure when folder name is too short."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'ab', 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be at least 3 characters' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_failure_long_name(client, mock_user):
|
||||||
|
"""Test validation failure when folder name is too long."""
|
||||||
|
long_name = 'a' * 51
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': long_name, 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be less than 50 characters' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_failure_empty_rule(client, mock_user):
|
||||||
|
"""Test validation failure when rule text is empty."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': ''},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text is required' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_failure_short_rule(client, mock_user):
|
||||||
|
"""Test validation failure when rule text is too short."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': 'short'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text must be at least 10 characters' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_failure_long_rule(client, mock_user):
|
||||||
|
"""Test validation failure when rule text is too long."""
|
||||||
|
long_rule = 'a' * 201
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': long_rule},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text must be less than 200 characters' in response.data
|
||||||
|
|
||||||
|
def test_add_folder_validation_multiple_errors(client, mock_user):
|
||||||
|
"""Test validation failure with multiple errors."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'ab', 'rule_text': 'short'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be at least 3 characters' in response.data
|
||||||
|
assert b'Rule text must be at least 10 characters' in response.data
|
||||||
|
|
||||||
|
# Edit folder validation failure tests
|
||||||
|
def test_edit_folder_validation_failure_empty_name(client, mock_folder):
|
||||||
|
"""Test validation failure when folder name is empty during edit."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': '', 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name is required' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_failure_short_name(client, mock_folder):
|
||||||
|
"""Test validation failure when folder name is too short during edit."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'ab', 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be at least 3 characters' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_failure_long_name(client, mock_folder):
|
||||||
|
"""Test validation failure when folder name is too long during edit."""
|
||||||
|
long_name = 'a' * 51
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': long_name, 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be less than 50 characters' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_failure_empty_rule(client, mock_folder):
|
||||||
|
"""Test validation failure when rule text is empty during edit."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': ''},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text is required' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_failure_short_rule(client, mock_folder):
|
||||||
|
"""Test validation failure when rule text is too short during edit."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': 'short'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text must be at least 10 characters' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_failure_long_rule(client, mock_folder):
|
||||||
|
"""Test validation failure when rule text is too long during edit."""
|
||||||
|
long_rule = 'a' * 201
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': long_rule},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Rule text must be less than 200 characters' in response.data
|
||||||
|
|
||||||
|
def test_edit_folder_validation_multiple_errors(client, mock_folder):
|
||||||
|
"""Test validation failure with multiple errors during edit."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'ab', 'rule_text': 'short'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert b'Folder name must be at least 3 characters' in response.data
|
||||||
|
assert b'Rule text must be at least 10 characters' in response.data
|
||||||
|
|
||||||
|
# Dialog close tests
|
||||||
|
def test_add_folder_success_closes_dialog(client, mock_user):
|
||||||
|
"""Test that successful folder creation triggers dialog close."""
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': 'Test Folder', 'rule_text': 'Test rule something ok yes'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
# Check for close-modal trigger in response headers
|
||||||
|
assert 'HX-Trigger' in response.headers
|
||||||
|
assert 'close-modal' in response.headers['HX-Trigger']
|
||||||
|
|
||||||
|
def test_edit_folder_success_closes_dialog(client, mock_folder):
|
||||||
|
"""Test that successful folder update triggers dialog close."""
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': 'Updated Folder', 'rule_text': 'Updated rule text'},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
# Check for close-modal trigger in response headers
|
||||||
|
assert 'HX-Trigger' in response.headers
|
||||||
|
assert 'close-modal' in response.headers['HX-Trigger']
|
||||||
|
|
||||||
|
# Content matching tests
|
||||||
|
def test_add_folder_content_matches_submission(client, mock_user):
|
||||||
|
"""Test that submitted folder content matches what was sent."""
|
||||||
|
test_name = 'Test Folder Content'
|
||||||
|
test_rule = 'Test rule content matching submission'
|
||||||
|
test_priority = '1'
|
||||||
|
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': test_name, 'rule_text': test_rule, 'priority': test_priority},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
|
||||||
|
# Verify the folder was created with correct content
|
||||||
|
created_folder = Folder.query.filter_by(name=test_name).first()
|
||||||
|
assert created_folder is not None
|
||||||
|
assert created_folder.name == test_name.strip()
|
||||||
|
assert created_folder.rule_text == test_rule.strip()
|
||||||
|
assert created_folder.priority == int(test_priority)
|
||||||
|
assert created_folder.user_id == MOCK_USER_ID
|
||||||
|
|
||||||
|
def test_edit_folder_content_matches_submission(client, mock_folder):
|
||||||
|
"""Test that updated folder content matches what was sent."""
|
||||||
|
test_name = 'Updated Folder Content'
|
||||||
|
test_rule = 'Updated rule content matching submission'
|
||||||
|
test_priority = '-1'
|
||||||
|
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': test_name, 'rule_text': test_rule, 'priority': test_priority},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
# Verify the folder was updated with correct content
|
||||||
|
updated_folder = Folder.query.filter_by(id=mock_folder.id).first()
|
||||||
|
assert updated_folder is not None
|
||||||
|
assert updated_folder.name == test_name.strip()
|
||||||
|
assert updated_folder.rule_text == test_rule.strip()
|
||||||
|
assert updated_folder.priority == int(test_priority)
|
||||||
|
|
||||||
|
def test_add_folder_content_whitespace_handling(client, mock_user):
|
||||||
|
"""Test that whitespace is properly handled in submitted content."""
|
||||||
|
test_name = ' Test Folder With Whitespace '
|
||||||
|
test_rule = ' Test rule with whitespace around it '
|
||||||
|
test_priority = '0'
|
||||||
|
|
||||||
|
response = client.post('/api/folders',
|
||||||
|
data={'name': test_name, 'rule_text': test_rule, 'priority': test_priority},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
|
||||||
|
# Verify the folder was created with properly trimmed content
|
||||||
|
created_folder = Folder.query.filter_by(name='Test Folder With Whitespace').first()
|
||||||
|
assert created_folder is not None
|
||||||
|
assert created_folder.name == 'Test Folder With Whitespace' # Should be trimmed
|
||||||
|
assert created_folder.rule_text == 'Test rule with whitespace around it' # Should be trimmed
|
||||||
|
assert created_folder.priority == int(test_priority)
|
||||||
|
|
||||||
|
def test_edit_folder_content_whitespace_handling(client, mock_folder):
|
||||||
|
"""Test that whitespace is properly handled in updated content."""
|
||||||
|
test_name = ' Updated Folder With Whitespace '
|
||||||
|
test_rule = ' Updated rule with whitespace around it '
|
||||||
|
test_priority = '1'
|
||||||
|
|
||||||
|
response = client.put(f'/api/folders/{mock_folder.id}',
|
||||||
|
data={'name': test_name, 'rule_text': test_rule, 'priority': test_priority},
|
||||||
|
content_type='application/x-www-form-urlencoded')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
# Verify the folder was updated with properly trimmed content
|
||||||
|
updated_folder = Folder.query.filter_by(id=mock_folder.id).first()
|
||||||
|
assert updated_folder is not None
|
||||||
|
assert updated_folder.name == 'Updated Folder With Whitespace' # Should be trimmed
|
||||||
|
assert updated_folder.rule_text == 'Updated rule with whitespace around it' # Should be trimmed
|
||||||
|
assert updated_folder.priority == int(test_priority)
|
||||||
Reference in New Issue
Block a user