2323from dash import html
2424import dash_bootstrap_components as dbc
2525import study_smart .app as app
26+ import plotly .graph_objects as go
2627from study_smart .app import (
2728 get_subject_color_map ,
2829 build_chart ,
@@ -68,7 +69,6 @@ def make_exam(name, exam_date, hours, topics=None):
6869
6970def test_generate_schedule_returns_figure_and_schedule ():
7071 """Test that generate_schedule returns figure and schedule with valid exams."""
71- import plotly .graph_objects as go
7272 app .exams .append ({
7373 "name" : "Stats" ,
7474 "date" : "2026-06-10" ,
@@ -99,10 +99,6 @@ def test_generate_schedule_returns_figure_and_schedule():
9999def test_get_subject_color_map_topics_share_exam_color ():
100100 """Test that all topics of one exam share the same color."""
101101 exam_list = [make_exam ("Stats" , date (2026 , 6 , 5 ), 10 , ["Ch1" , "Ch2" ])]
102- schedule = make_schedule (
103- {"date" : date (2026 , 6 , 1 ), "subject" : "Ch1" , "hours" : 2.0 , "type" : "initial" },
104- {"date" : date (2026 , 6 , 1 ), "subject" : "Ch2" , "hours" : 2.0 , "type" : "initial" },
105- )
106102 color_map , exam_colors = get_subject_color_map (exam_list )
107103 assert color_map ["Ch1" ] == color_map ["Ch2" ]
108104 assert color_map ["Ch1" ] == exam_colors ["Stats" ]
@@ -111,9 +107,6 @@ def test_get_subject_color_map_topics_share_exam_color():
111107def test_get_subject_color_map_exam_name_in_color_map ():
112108 """Test that the exam name itself is included in color_map."""
113109 exam_list = [make_exam ("Stats" , date (2026 , 6 , 5 ), 10 , ["Ch1" ])]
114- schedule = make_schedule (
115- {"date" : date (2026 , 6 , 1 ), "subject" : "Ch1" , "hours" : 2.0 , "type" : "initial" }
116- )
117110 color_map , _ = get_subject_color_map (exam_list )
118111 assert "Stats" in color_map
119112
@@ -124,30 +117,20 @@ def test_get_subject_color_map_two_exams_different_colors():
124117 make_exam ("Stats" , date (2026 , 6 , 5 ), 10 , ["Ch1" ]),
125118 make_exam ("Math" , date (2026 , 6 , 7 ), 8 , ["Algebra" ]),
126119 ]
127- schedule = make_schedule (
128- {"date" : date (2026 , 6 , 1 ), "subject" : "Ch1" , "hours" : 2.0 , "type" : "initial" },
129- {"date" : date (2026 , 6 , 2 ), "subject" : "Algebra" , "hours" : 2.0 , "type" : "initial" },
130- )
131120 _ , exam_colors = get_subject_color_map (exam_list )
132121 assert exam_colors ["Stats" ] != exam_colors ["Math" ]
133122
134123
135124def test_get_subject_color_map_hsl_format ():
136125 """Test that exam colors are returned in hsl(...) string format."""
137126 exam_list = [make_exam ("Stats" , date (2026 , 6 , 5 ), 10 , [])]
138- schedule = make_schedule (
139- {"date" : date (2026 , 6 , 1 ), "subject" : "Stats" , "hours" : 2.0 , "type" : "initial" }
140- )
141127 _ , exam_colors = get_subject_color_map (exam_list )
142128 assert exam_colors ["Stats" ].startswith ("hsl(" )
143129
144130
145131def test_get_subject_color_map_single_exam_hue_is_zero ():
146132 """Test that single exam gets hue 0 (first color in the cycle)."""
147133 exam_list = [make_exam ("Stats" , date (2026 , 6 , 5 ), 10 , [])]
148- schedule = make_schedule (
149- {"date" : date (2026 , 6 , 1 ), "subject" : "Stats" , "hours" : 2.0 , "type" : "initial" }
150- )
151134 _ , exam_colors = get_subject_color_map (exam_list )
152135 assert exam_colors ["Stats" ] == "hsl(0, 70%, 50%)"
153136
@@ -156,7 +139,6 @@ def test_get_subject_color_map_single_exam_hue_is_zero():
156139
157140def test_build_chart_returns_figure ():
158141 """Test that build_chart returns a Plotly Figure object."""
159- import plotly .graph_objects as go
160142 schedule = make_schedule (
161143 {"date" : date (2026 , 6 , 1 ), "subject" : "Stats" , "hours" : 3.0 , "type" : "initial" }
162144 )
@@ -544,7 +526,19 @@ def test_load_exams_splits_topics_correctly():
544526 with patch ("study_smart.app.pd.read_excel" , return_value = mock_df ):
545527 load_exams (1 )
546528 assert app .exams [0 ]["topics" ] == ["Ch1" , "Ch2" , "Ch3" ]
547-
529+
530+ def test_load_exams_does_not_duplicate_on_second_load ():
531+ """Test that loading the same file twice does not duplicate exams."""
532+ mock_df = pd .DataFrame ({
533+ "name" : ["Stats" ],
534+ "date" : [date (2026 , 6 , 1 )],
535+ "hours" : [10 ],
536+ "topics" : ["Ch1" ],
537+ })
538+ with patch ("study_smart.app.pd.read_excel" , return_value = mock_df ):
539+ load_exams (1 )
540+ load_exams (1 )
541+ assert len (app .exams ) == 1
548542
549543# Tests for delete_commitment callback
550544
0 commit comments