1- import pandas as pd
2- from pandas .testing import assert_frame_equal
31import pytest
4- from unittest import mock
52
63from genie import dashboard_table_updater as dash_update
74
85
9- @pytest .fixture
10- def mock_syn (tmp_path ):
11- """Fixture for a fake synapse client and test file."""
12- syn = mock .MagicMock ()
13-
14- # Create a fake clinical file
15- clinical_path = tmp_path / "clinical.txt"
16- clinical_path .write_text ("SAMPLE_ID\n S1\n S2\n S3\n " )
17-
18- # Entity returned by syn.get for the clinical file
19- clinical_entity = mock .MagicMock ()
20- clinical_entity .path = str (clinical_path )
21-
22- # syn.get() will return this entity when given file_mapping["sample"]
23- syn .get .return_value = clinical_entity
24-
25- # Default columns of existing table
26- syn .getTableColumns .return_value = [{"name" : "SAMPLE_ID" }]
27-
28- return syn
29-
30-
316@pytest .mark .parametrize (
327 "input_string_time, expected_output_time" ,
338 [
@@ -42,118 +17,3 @@ def test_that_string_to_unix_epoch_time_milliseconds_gives_expected_time(
4217):
4318 output = dash_update .string_to_unix_epoch_time_milliseconds (input_string_time )
4419 assert output == expected_output_time
45-
46-
47- def test_that_update_samples_in_release_table_adds_column_and_calls_update (
48- tmp_path , mock_syn
49- ):
50- """Test that a new release column is added and load._update_table gets correct data."""
51- file_mapping = {"sample" : "syn123" }
52- release = "5.3-consortium"
53- samples_in_release_synid = "syn999"
54-
55- # Fake DataFrames for clinical and existing table
56- clinical_df = pd .DataFrame ({"SAMPLE_ID" : ["S1" , "S2" , "S3" ]})
57- existing_df = pd .DataFrame ({"SAMPLE_ID" : ["S1" ], release : [1 ]})
58-
59- with (
60- mock .patch .object (pd , "read_csv" , return_value = clinical_df ) as mock_read ,
61- mock .patch .object (
62- dash_update .extract , "get_syntabledf" , return_value = existing_df
63- ) as mock_extract ,
64- mock .patch .object (dash_update .load , "_update_table" ) as mock_update ,
65- ):
66- dash_update .update_samples_in_release_table (
67- syn = mock_syn ,
68- file_mapping = file_mapping ,
69- release = release ,
70- samples_in_release_synid = samples_in_release_synid ,
71- )
72-
73- # --- Assertions on Synapse calls ---
74- mock_syn .get .assert_has_calls (
75- [
76- mock .call (file_mapping ["sample" ], followLink = True ),
77- mock .call (samples_in_release_synid ),
78- ]
79- )
80- mock_syn .getTableColumns .assert_called_once_with (samples_in_release_synid )
81-
82- # --- Assertions on pd.read_csv ---
83- mock_read .assert_called_once ()
84- assert list (mock_read .return_value .columns ) == ["SAMPLE_ID" ]
85-
86- # --- Assertions on extract.get_syntabledf ---
87- mock_extract .assert_called_once_with (
88- syn = mock_syn ,
89- query_string = f'SELECT SAMPLE_ID, "{ release } " FROM { samples_in_release_synid } ' ,
90- )
91-
92- # --- Assertions on load._update_table inputs ---
93- mock_update .assert_called_once ()
94- args , kwargs = mock_update .call_args
95-
96- # Extract arguments
97- _ , _ , samples_in_releasedf , synid_arg , key_cols = args
98-
99- # Ensure correct Synapse ID and key columns
100- assert synid_arg == samples_in_release_synid
101- assert key_cols == ["SAMPLE_ID" ]
102-
103- # Check that new samples and old samples are in expected order
104- assert_frame_equal (
105- samples_in_releasedf .reset_index (drop = True ),
106- pd .DataFrame (
107- {"SAMPLE_ID" : ["S2" , "S3" , "S1" ], "5.3-consortium" : [1 , 1 , 1 ]}
108- ),
109- )
110-
111-
112- def test_that_update_samples_in_release_table_existing_column_calls_update_directly (
113- mock_syn ,
114- ):
115- """If the release column already exists, we skip creating new column but still call _update_table."""
116- release = "5.3-consortium"
117- file_mapping = {"sample" : "syn123" }
118- samples_in_release_synid = "syn999"
119-
120- # Pretend the release column already exists
121- mock_syn .getTableColumns .return_value = [{"name" : "SAMPLE_ID" }, {"name" : release }]
122-
123- clinical_df = pd .DataFrame ({"SAMPLE_ID" : ["S1" , "S2" ]})
124- existing_df = pd .DataFrame ({"SAMPLE_ID" : ["S2" , "S1" ], release : [1 , 1 ]})
125-
126- with (
127- mock .patch .object (pd , "read_csv" , return_value = clinical_df ) as mock_read ,
128- mock .patch .object (
129- dash_update .extract , "get_syntabledf" , return_value = existing_df
130- ) as mock_extract ,
131- mock .patch .object (dash_update .load , "_update_table" ) as mock_update ,
132- ):
133-
134- dash_update .update_samples_in_release_table (
135- syn = mock_syn ,
136- file_mapping = file_mapping ,
137- release = release ,
138- samples_in_release_synid = samples_in_release_synid ,
139- )
140- # --- Assertions on Synapse calls ---
141- mock_syn .get .assert_has_calls (
142- [
143- mock .call (file_mapping ["sample" ], followLink = True ),
144- ]
145- )
146- args , kwargs = mock_update .call_args
147-
148- # Extract arguments
149- _ , _ , samples_in_releasedf , synid_arg , key_cols = args
150-
151- # Ensure correct Synapse ID and key columns
152- assert synid_arg == samples_in_release_synid
153- assert key_cols == ["SAMPLE_ID" ]
154-
155- # Check that new samples and old samples are in expected order
156- assert_frame_equal (
157- samples_in_releasedf .reset_index (drop = True ),
158- pd .DataFrame ({"SAMPLE_ID" : ["S1" , "S2" ], "5.3-consortium" : [1 , 1 ]}),
159- )
0 commit comments