from unittest.mock import patch, MagicMock import pytest import requests from tcga_downloader.interactive import ( fetch_data_types, fetch_projects, interactive_select, select_data_type, select_project, ) @patch("tcga_downloader.interactive.requests.get") def test_fetch_projects(mock_get): mock_response = mock_get.return_value mock_response.status_code = 200 mock_response.json.return_value = { "data": { "hits": [ { "project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma", "primary_site": ["Breast"], }, { "project_id": "TCGA-LUAD", "name": "Lung Adenocarcinoma", "primary_site": ["Lung"], }, ] } } projects = fetch_projects() assert len(projects) == 2 assert projects[0]["project_id"] == "TCGA-BRCA" assert projects[1]["project_id"] == "TCGA-LUAD" @patch("tcga_downloader.interactive.requests.post") def test_fetch_data_types(mock_post): mock_response = mock_post.return_value mock_response.status_code = 200 mock_response.json.return_value = { "data": { "aggregations": { "data_type": { "buckets": [ {"key": "Gene Expression", "doc_count": 100}, {"key": "Copy Number Variation", "doc_count": 50}, {"key": "DNA Methylation", "doc_count": 30}, ] } } } } data_types = fetch_data_types("TCGA-BRCA") assert len(data_types) == 3 assert data_types[0] == "Gene Expression" assert data_types[1] == "Copy Number Variation" assert data_types[2] == "DNA Methylation" @patch("tcga_downloader.interactive.requests.post") def test_fetch_data_types_empty(mock_post): mock_response = mock_post.return_value mock_response.status_code = 200 mock_response.json.return_value = {"data": {"aggregations": {"data_type": {"buckets": []}}}} data_types = fetch_data_types("TCGA-BRCA") assert len(data_types) == 0 @patch("tcga_downloader.interactive.requests.post") def test_fetch_data_types_api_error(mock_post): mock_post.side_effect = requests.exceptions.HTTPError("API Error") with pytest.raises(requests.exceptions.HTTPError): fetch_data_types("TCGA-BRCA") @patch("tcga_downloader.interactive.requests.get") def test_fetch_projects_network_error(mock_get): mock_get.side_effect = requests.exceptions.ConnectionError("Network error") with pytest.raises(requests.exceptions.ConnectionError): fetch_projects() @patch("tcga_downloader.interactive.questionary.select") def test_select_project(mock_select): mock_question = MagicMock() mock_select.return_value = mock_question mock_question.ask.return_value = "TCGA-BRCA - Breast Invasive Carcinoma" projects = [ {"project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma"}, {"project_id": "TCGA-LUAD", "name": "Lung Adenocarcinoma"}, ] selected = select_project(projects) assert selected["project_id"] == "TCGA-BRCA" assert selected["name"] == "Breast Invasive Carcinoma" @patch("tcga_downloader.interactive.questionary.select") def test_select_project_no_selection(mock_select): mock_question = MagicMock() mock_select.return_value = mock_question mock_question.ask.return_value = None projects = [ {"project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma"}, {"project_id": "TCGA-LUAD", "name": "Lung Adenocarcinoma"}, ] with pytest.raises(SystemExit) as exc_info: select_project(projects) assert exc_info.value.code == 0 @patch("tcga_downloader.interactive.questionary.select") def test_select_data_type(mock_select): mock_question = MagicMock() mock_select.return_value = mock_question mock_question.ask.return_value = "Gene Expression" data_types = ["Gene Expression", "Copy Number Variation", "DNA Methylation"] selected = select_data_type(data_types) assert selected == "Gene Expression" @patch("tcga_downloader.interactive.questionary.select") def test_select_data_type_no_selection(mock_select): mock_question = MagicMock() mock_select.return_value = mock_question mock_question.ask.return_value = None data_types = ["Gene Expression", "Copy Number Variation", "DNA Methylation"] with pytest.raises(SystemExit) as exc_info: select_data_type(data_types) assert exc_info.value.code == 0 @patch("tcga_downloader.interactive.questionary.select") def test_select_data_type_empty_list(mock_select): data_types = [] with pytest.raises(SystemExit) as exc_info: select_data_type(data_types) assert exc_info.value.code == 1 mock_select.assert_not_called() @patch("tcga_downloader.interactive.fetch_projects") @patch("tcga_downloader.interactive.fetch_data_types") @patch("tcga_downloader.interactive.select_project") @patch("tcga_downloader.interactive.select_data_type") def test_interactive_select_success( mock_select_dt, mock_select_proj, mock_fetch_dt, mock_fetch_proj ): mock_fetch_proj.return_value = [ {"project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma"} ] mock_select_proj.return_value = {"project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma"} mock_fetch_dt.return_value = ["Gene Expression", "Copy Number Variation"] mock_select_dt.return_value = "Gene Expression" project_id, data_type = interactive_select() assert project_id == "TCGA-BRCA" assert data_type == "Gene Expression" mock_fetch_proj.assert_called_once() mock_fetch_dt.assert_called_once_with("TCGA-BRCA") mock_select_proj.assert_called_once() mock_select_dt.assert_called_once() @patch("tcga_downloader.interactive.fetch_projects") @patch("tcga_downloader.interactive.fetch_data_types") @patch("tcga_downloader.interactive.select_project") @patch("tcga_downloader.interactive.select_data_type") def test_interactive_select_no_project( mock_select_dt, mock_select_proj, mock_fetch_dt, mock_fetch_proj ): mock_fetch_proj.return_value = [ {"project_id": "TCGA-BRCA", "name": "Breast Invasive Carcinoma"} ] mock_select_proj.side_effect = SystemExit(0) with pytest.raises(SystemExit) as exc_info: interactive_select() assert exc_info.value.code == 0 mock_fetch_proj.assert_called_once() mock_select_proj.assert_called_once() mock_fetch_dt.assert_not_called() mock_select_dt.assert_not_called()