Spaces:
Running
Running
File size: 8,734 Bytes
7f6ef8f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
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
@pytest.fixture
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")
@patch('backend.app.pd.read_csv')
@patch('backend.app.get_dataset_config')
@patch('backend.app.get_leaderboard')
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"
@patch('backend.app.pd.read_csv')
@patch('backend.app.get_dataset_config')
@patch('backend.app.get_chart')
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
@patch('backend.app.pd.read_csv')
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
@patch('backend.app.image_examples_tab')
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()
@patch('backend.app.audio_examples_tab')
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()
@patch('backend.app.video_examples_tab')
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
@patch('backend.app.requests.get')
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()
@patch('backend.app.requests.get')
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()
@patch('backend.app.requests.get')
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
@patch('backend.app.get_old_format_dataframe')
@patch('backend.app.get_leaderboard_filters')
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'])
@patch('backend.app.mk_variations')
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)
|