Files
nextsnap/tests/test_webdav_proxy.py
kamaji cad4118f72 Add NextSnap PWA with photo gallery viewer and continuous capture
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>
2026-02-07 04:53:13 -06:00

196 lines
6.4 KiB
Python

import pytest
from app import create_app
from unittest.mock import patch, MagicMock
import base64
@pytest.fixture
def app():
"""Create application for testing."""
app = create_app('development')
app.config['TESTING'] = True
app.config['SECRET_KEY'] = 'test-secret-key'
app.config['SESSION_TYPE'] = 'null'
return app
@pytest.fixture
def client(app):
"""Create test client with authenticated session."""
with app.test_client() as client:
# Set up authenticated session
with client.session_transaction() as sess:
sess['username'] = 'testuser'
sess['password'] = base64.b64encode(b'testpass').decode()
sess['is_admin'] = False
yield client
def test_list_files_not_authenticated(app):
"""Test list files without authentication."""
with app.test_client() as client:
response = client.get('/api/files/list?path=/')
assert response.status_code == 401
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_list_files_success(mock_nc_client, client):
"""Test successful file listing."""
mock_instance = MagicMock()
mock_instance.propfind.return_value = {
'items': [
{'name': 'Documents', 'path': '/Documents', 'type': 'directory', 'size': 0},
{'name': 'photo.jpg', 'path': '/photo.jpg', 'type': 'file', 'size': 12345}
],
'path': '/',
'count': 2
}
mock_nc_client.return_value = mock_instance
response = client.get('/api/files/list?path=/')
assert response.status_code == 200
data = response.get_json()
assert 'items' in data
assert len(data['items']) == 2
assert data['items'][0]['name'] == 'Documents'
assert data['items'][1]['name'] == 'photo.jpg'
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_upload_file_success(mock_nc_client, client):
"""Test successful file upload."""
mock_instance = MagicMock()
mock_instance.put_file.return_value = {
'success': True,
'url': 'http://nextcloud/remote.php/dav/files/testuser/photo.jpg'
}
mock_nc_client.return_value = mock_instance
# Test with form data
response = client.post(
'/api/files/upload?path=/uploads',
data={
'path': '/uploads',
'file': (BytesIO(b'fake image data'), 'photo.jpg')
},
content_type='multipart/form-data'
)
assert response.status_code == 200
data = response.get_json()
assert data['success'] is True
assert 'photo.jpg' in data['path']
def test_upload_file_no_path(client):
"""Test upload without target path."""
response = client.post('/api/files/upload')
assert response.status_code == 400
data = response.get_json()
assert 'error' in data
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_verify_file_exists(mock_nc_client, client):
"""Test file verification - file exists."""
mock_instance = MagicMock()
mock_instance.head.return_value = True
mock_nc_client.return_value = mock_instance
response = client.get('/api/files/verify?path=/photo.jpg')
assert response.status_code == 200
data = response.get_json()
assert data['exists'] is True
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_verify_file_not_exists(mock_nc_client, client):
"""Test file verification - file does not exist."""
mock_instance = MagicMock()
mock_instance.head.return_value = False
mock_nc_client.return_value = mock_instance
response = client.get('/api/files/verify?path=/nonexistent.jpg')
assert response.status_code == 404
data = response.get_json()
assert data['exists'] is False
def test_verify_file_no_path(client):
"""Test verification without path."""
response = client.get('/api/files/verify')
assert response.status_code == 400
data = response.get_json()
assert 'error' in data
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_mkdir_success(mock_nc_client, client):
"""Test successful directory creation."""
mock_instance = MagicMock()
mock_instance.mkcol.return_value = True
mock_nc_client.return_value = mock_instance
response = client.post(
'/api/files/mkdir',
json={'path': '/NewFolder'}
)
assert response.status_code == 201
data = response.get_json()
assert data['success'] is True
assert data['path'] == '/NewFolder'
def test_mkdir_no_path(client):
"""Test mkdir without path."""
response = client.post('/api/files/mkdir', json={})
assert response.status_code == 400
data = response.get_json()
assert 'error' in data
@patch('app.routes.webdav_proxy.NextcloudClient')
def test_rename_file_success(mock_nc_client, client):
"""Test successful file rename."""
mock_instance = MagicMock()
mock_instance.move.return_value = True
mock_nc_client.return_value = mock_instance
response = client.post(
'/api/files/rename',
json={
'source': '/old_name.jpg',
'destination': '/new_name.jpg'
}
)
assert response.status_code == 200
data = response.get_json()
assert data['success'] is True
assert data['source'] == '/old_name.jpg'
assert data['destination'] == '/new_name.jpg'
def test_rename_file_missing_params(client):
"""Test rename without required parameters."""
response = client.post(
'/api/files/rename',
json={'source': '/old_name.jpg'}
)
assert response.status_code == 400
data = response.get_json()
assert 'error' in data
@patch('app.routes.webdav_proxy.NextcloudClient')
@patch('app.routes.webdav_proxy.Image')
def test_thumbnail_success(mock_image, mock_nc_client, client):
"""Test successful thumbnail generation."""
# Mock Nextcloud client
mock_instance = MagicMock()
mock_instance.get_file.return_value = b'fake image data'
mock_nc_client.return_value = mock_instance
# Mock PIL Image
mock_img = MagicMock()
mock_img.mode = 'RGB'
mock_image.open.return_value = mock_img
response = client.get('/api/files/thumbnail?path=/photo.jpg&size=256')
assert response.status_code == 200
assert response.content_type == 'image/jpeg'
def test_thumbnail_no_path(client):
"""Test thumbnail without path."""
response = client.get('/api/files/thumbnail')
assert response.status_code == 400
data = response.get_json()
assert 'error' in data
# Import BytesIO for upload test
from io import BytesIO