Offline-first photo capture app for Nextcloud with: - Camera capture with continuous mode (auto-reopens after each photo) - File browser with fullscreen image gallery, swipe navigation, and rename - Upload queue with background sync engine - Admin panel for Nextcloud user management - Service worker for offline-first caching (v13) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
134 lines
4.7 KiB
Python
134 lines
4.7 KiB
Python
import pytest
|
|
from app import create_app
|
|
from unittest.mock import patch, MagicMock
|
|
import tempfile
|
|
import os
|
|
|
|
@pytest.fixture
|
|
def app():
|
|
"""Create application for testing."""
|
|
app = create_app('development')
|
|
app.config['TESTING'] = True
|
|
# Use simple session for testing
|
|
app.config['SECRET_KEY'] = 'test-secret-key'
|
|
app.config['SESSION_TYPE'] = 'null' # Disable server-side sessions for testing
|
|
return app
|
|
|
|
@pytest.fixture
|
|
def client(app):
|
|
"""Create test client with session support."""
|
|
with app.test_client() as client:
|
|
with client.session_transaction() as sess:
|
|
# Initialize session
|
|
pass
|
|
yield client
|
|
|
|
def test_login_missing_credentials(client):
|
|
"""Test login with missing credentials."""
|
|
response = client.post('/api/auth/login', json={})
|
|
assert response.status_code == 400
|
|
data = response.get_json()
|
|
assert 'error' in data
|
|
|
|
def test_login_empty_credentials(client):
|
|
"""Test login with empty credentials."""
|
|
response = client.post('/api/auth/login', json={'username': '', 'password': ''})
|
|
assert response.status_code == 400
|
|
data = response.get_json()
|
|
assert 'error' in data
|
|
|
|
@patch('app.routes.auth.NextcloudClient')
|
|
def test_login_invalid_credentials(mock_nc_client, client):
|
|
"""Test login with invalid credentials."""
|
|
# Mock NextcloudClient to return False for verify_credentials
|
|
mock_instance = MagicMock()
|
|
mock_instance.verify_credentials.return_value = False
|
|
mock_nc_client.return_value = mock_instance
|
|
|
|
response = client.post('/api/auth/login', json={'username': 'testuser', 'password': 'wrongpass'})
|
|
assert response.status_code == 401
|
|
data = response.get_json()
|
|
assert 'error' in data
|
|
|
|
@patch('app.routes.auth.NextcloudClient')
|
|
def test_login_success(mock_nc_client, client):
|
|
"""Test successful login."""
|
|
# Mock NextcloudClient to return True for verify_credentials
|
|
mock_instance = MagicMock()
|
|
mock_instance.verify_credentials.return_value = True
|
|
mock_instance.check_admin.return_value = False
|
|
mock_nc_client.return_value = mock_instance
|
|
|
|
response = client.post('/api/auth/login', json={'username': 'testuser', 'password': 'testpass'})
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['success'] is True
|
|
assert data['username'] == 'testuser'
|
|
assert data['is_admin'] is False
|
|
|
|
@patch('app.routes.auth.NextcloudClient')
|
|
def test_login_admin_user(mock_nc_client, client):
|
|
"""Test login with admin user."""
|
|
mock_instance = MagicMock()
|
|
mock_instance.verify_credentials.return_value = True
|
|
mock_instance.check_admin.return_value = True
|
|
mock_nc_client.return_value = mock_instance
|
|
|
|
response = client.post('/api/auth/login', json={'username': 'admin', 'password': 'adminpass'})
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['success'] is True
|
|
assert data['is_admin'] is True
|
|
|
|
def test_status_not_authenticated(client):
|
|
"""Test status endpoint when not authenticated."""
|
|
response = client.get('/api/auth/status')
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['authenticated'] is False
|
|
|
|
@patch('app.routes.auth.NextcloudClient')
|
|
def test_status_authenticated(mock_nc_client, client):
|
|
"""Test status endpoint when authenticated."""
|
|
# First login
|
|
mock_instance = MagicMock()
|
|
mock_instance.verify_credentials.return_value = True
|
|
mock_instance.check_admin.return_value = False
|
|
mock_nc_client.return_value = mock_instance
|
|
|
|
client.post('/api/auth/login', json={'username': 'testuser', 'password': 'testpass'})
|
|
|
|
# Check status
|
|
response = client.get('/api/auth/status')
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['authenticated'] is True
|
|
assert data['username'] == 'testuser'
|
|
|
|
@patch('app.routes.auth.NextcloudClient')
|
|
def test_logout(mock_nc_client, client):
|
|
"""Test logout functionality."""
|
|
# First login
|
|
mock_instance = MagicMock()
|
|
mock_instance.verify_credentials.return_value = True
|
|
mock_instance.check_admin.return_value = False
|
|
mock_nc_client.return_value = mock_instance
|
|
|
|
client.post('/api/auth/login', json={'username': 'testuser', 'password': 'testpass'})
|
|
|
|
# Verify logged in
|
|
response = client.get('/api/auth/status')
|
|
data = response.get_json()
|
|
assert data['authenticated'] is True
|
|
|
|
# Logout
|
|
response = client.post('/api/auth/logout')
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['success'] is True
|
|
|
|
# Verify logged out
|
|
response = client.get('/api/auth/status')
|
|
data = response.get_json()
|
|
assert data['authenticated'] is False
|