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