Spaces:
Running
Running
Mark Duppenthaler
Updated table. No more individual rows, separate tabs for leaderboard type, export tables
7f6ef8f
import json | |
import os | |
import pytest | |
from unittest.mock import patch, MagicMock, mock_open | |
import pandas as pd | |
from io import StringIO | |
from flask import Flask | |
# Import the Flask app and other necessary modules | |
from backend.app import app, get_leaderboard, get_chart | |
def client(): | |
"""Create a test client for the Flask app.""" | |
app.config['TESTING'] = True | |
with app.test_client() as client: | |
yield client | |
def test_index_route(client): | |
"""Test the index route returns the index.html file.""" | |
with patch('backend.app.send_from_directory') as mock_send: | |
mock_send.return_value = "index content" | |
response = client.get('/') | |
assert response.status_code == 200 | |
mock_send.assert_called_once_with(app.static_folder, "index.html") | |
def test_data_files_benchmark(mock_get_leaderboard, mock_get_config, mock_read_csv, client): | |
"""Test the data_files route with benchmark dataset type.""" | |
# Mock the DataFrame and config | |
mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]}) | |
mock_read_csv.return_value = mock_df | |
mock_config = {'name': 'test_dataset'} | |
mock_get_config.return_value = mock_config | |
mock_get_leaderboard.return_value = "leaderboard data" | |
# Make the request | |
response = client.get('/data/test_dataset?dataset_type=benchmark') | |
# Assertions | |
mock_read_csv.assert_called_once() | |
mock_get_config.assert_called_once_with('test_dataset') | |
mock_get_leaderboard.assert_called_once_with(mock_config, mock_df) | |
assert response == "leaderboard data" | |
def test_data_files_attacks_variations(mock_get_chart, mock_get_config, mock_read_csv, client): | |
"""Test the data_files route with attacks_variations dataset type.""" | |
# Mock the DataFrame and config | |
mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']}) | |
mock_read_csv.return_value = mock_df | |
mock_config = {'name': 'test_dataset'} | |
mock_get_config.return_value = mock_config | |
mock_get_chart.return_value = "chart data" | |
# Make the request | |
response = client.get('/data/test_dataset?dataset_type=attacks_variations') | |
# Assertions | |
mock_read_csv.assert_called_once() | |
mock_get_config.assert_called_once_with('test_dataset') | |
mock_get_chart.assert_called_once_with(mock_config, mock_df) | |
assert response == "chart data" | |
def test_data_files_missing_dataset_type(client): | |
"""Test the data_files route with missing dataset_type.""" | |
response = client.get('/data/test_dataset') | |
assert response.status_code == 400 | |
assert b"Dataset type not specified" in response.data | |
def test_data_files_file_not_found(mock_read_csv, client): | |
"""Test the data_files route when file is not found.""" | |
mock_read_csv.side_effect = FileNotFoundError() | |
response = client.get('/data/test_dataset?dataset_type=benchmark') | |
assert response.status_code == 404 | |
assert b"File not found" in response.data | |
def test_example_files_image(mock_image_examples, client): | |
"""Test the example_files route with image type.""" | |
mock_image_examples.return_value = {"examples": ["image1", "image2"]} | |
response = client.get('/examples/image') | |
assert response.status_code == 200 | |
data = json.loads(response.data) | |
assert "examples" in data | |
mock_image_examples.assert_called_once() | |
def test_example_files_audio(mock_audio_examples, client): | |
"""Test the example_files route with audio type.""" | |
mock_audio_examples.return_value = {"examples": ["audio1", "audio2"]} | |
response = client.get('/examples/audio') | |
assert response.status_code == 200 | |
data = json.loads(response.data) | |
assert "examples" in data | |
mock_audio_examples.assert_called_once() | |
def test_example_files_video(mock_video_examples, client): | |
"""Test the example_files route with video type.""" | |
mock_video_examples.return_value = {"examples": ["video1", "video2"]} | |
response = client.get('/examples/video') | |
assert response.status_code == 200 | |
data = json.loads(response.data) | |
assert "examples" in data | |
mock_video_examples.assert_called_once() | |
def test_example_files_invalid_type(client): | |
"""Test the example_files route with invalid type.""" | |
response = client.get('/examples/invalid') | |
assert response.status_code == 400 | |
assert b"Invalid example type" in response.data | |
def test_proxy_valid_url(mock_requests_get, client): | |
"""Test the proxy route with a valid URL.""" | |
# Create a mock response | |
mock_response = MagicMock() | |
mock_response.status_code = 200 | |
mock_response.content = b"test content" | |
mock_response.headers = {"Content-Type": "text/plain"} | |
mock_requests_get.return_value = mock_response | |
# Mock the ABS_DATASET_DOMAIN constant | |
with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt') | |
assert response.status_code == 200 | |
assert response.data == b"test content" | |
mock_requests_get.assert_called_once() | |
def test_proxy_invalid_domain(mock_requests_get, client): | |
"""Test the proxy route with an invalid domain.""" | |
# Mock the ABS_DATASET_DOMAIN constant | |
with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
response = client.get('/proxy/https%3A%2F%2Fmalicious.com%2Ftest.txt') | |
assert response.status_code == 403 | |
data = json.loads(response.data) | |
assert "error" in data | |
mock_requests_get.assert_not_called() | |
def test_proxy_request_error(mock_requests_get, client): | |
"""Test the proxy route when the request fails.""" | |
mock_requests_get.side_effect = Exception("Connection error") | |
# Mock the ABS_DATASET_DOMAIN constant | |
with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt') | |
assert response.status_code == 500 | |
data = json.loads(response.data) | |
assert "error" in data | |
def test_get_leaderboard(mock_get_filters, mock_get_old_format): | |
"""Test the get_leaderboard function.""" | |
# Mock the input data | |
df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]}) | |
config = { | |
'first_cols': ['model'], | |
'attack_scores': ['score'], | |
'categories': ['category1'] | |
} | |
# Mock the function returns | |
mock_get_old_format.return_value = df | |
mock_get_filters.return_value = ( | |
{'group1': ['metric1', 'metric2']}, | |
['metric1'] | |
) | |
# Call the function | |
response = get_leaderboard(config, df) | |
# Assertions | |
assert response.status_code == 200 | |
data = json.loads(response.data) | |
assert 'groups' in data | |
assert 'default_selected_metrics' in data | |
assert 'rows' in data | |
mock_get_old_format.assert_called_once_with(df, config['first_cols'], config['attack_scores']) | |
mock_get_filters.assert_called_once_with(df, config['categories']) | |
def test_get_chart(mock_mk_variations): | |
"""Test the get_chart function.""" | |
# Mock the input data | |
df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']}) | |
config = { | |
'attacks_with_variations': ['attack1', 'attack2'] | |
} | |
# Mock the function return | |
mock_chart_data = {'chart': 'data'} | |
mock_mk_variations.return_value = mock_chart_data | |
# Call the function | |
response = get_chart(config, df) | |
# Assertions | |
assert response.status_code == 200 | |
data = json.loads(response.data) | |
assert data == mock_chart_data | |
mock_mk_variations.assert_called_once_with(df, config['attacks_with_variations']) | |
# Add a test for the main function | |
def test_main(): | |
"""Test the main function.""" | |
with patch('backend.app.app.run') as mock_run: | |
# We can't directly test __main__ block, but we can test the app.run call | |
# by importing and calling it in a test context | |
import backend.app | |
if hasattr(backend.app, 'main'): # If main function exists | |
backend.app.main() | |
mock_run.assert_called_once_with(host="0.0.0.0", port=7860, debug=True, use_reloader=True) | |