Skip to main content

max / goingson

4.6 KB · 162 lines History Blame Raw
1 //! Unit tests for snooze options command.
2
3 use crate::commands::*;
4 use chrono::{Datelike, Local, Timelike, Utc, Weekday};
5
6 #[test]
7 fn returns_expected_option_keys() {
8 let response = get_snooze_options();
9
10 // Should have 3-4 options (laterToday may be omitted if too late)
11 assert!(
12 response.options.len() >= 3,
13 "Should have at least 3 options"
14 );
15 assert!(
16 response.options.len() <= 4,
17 "Should have at most 4 options"
18 );
19
20 // Check that expected keys are present
21 let keys: Vec<&str> = response.options.iter().map(|o| o.key.as_str()).collect();
22 assert!(keys.contains(&"tomorrow"), "Should have tomorrow option");
23 assert!(keys.contains(&"weekend"), "Should have weekend option");
24 assert!(keys.contains(&"nextWeek"), "Should have nextWeek option");
25 }
26
27 #[test]
28 fn all_times_are_in_the_future() {
29 let response = get_snooze_options();
30 let now = Local::now().with_timezone(&Utc);
31
32 for option in &response.options {
33 assert!(
34 option.time > now,
35 "Option '{}' time should be in the future: {:?}",
36 option.key,
37 option.time
38 );
39 }
40 }
41
42 #[test]
43 fn min_custom_is_current_time() {
44 let before = Local::now().with_timezone(&Utc);
45 let response = get_snooze_options();
46 let after = Local::now().with_timezone(&Utc);
47
48 assert!(
49 response.min_custom >= before && response.min_custom <= after,
50 "min_custom should be approximately current time"
51 );
52 }
53
54 #[test]
55 fn options_have_valid_labels() {
56 let response = get_snooze_options();
57
58 for option in &response.options {
59 assert!(!option.label.is_empty(), "Label should not be empty");
60 assert!(
61 !option.formatted.is_empty(),
62 "Formatted time should not be empty"
63 );
64 }
65
66 // Check specific labels
67 let labels: Vec<&str> = response.options.iter().map(|o| o.label.as_str()).collect();
68 assert!(labels.contains(&"Tomorrow"));
69 assert!(labels.contains(&"This Weekend"));
70 assert!(labels.contains(&"Next Week"));
71 }
72
73 #[test]
74 fn formatted_time_contains_expected_components() {
75 let response = get_snooze_options();
76
77 for option in &response.options {
78 // Should contain day abbreviation (Mon, Tue, etc.)
79 let has_day = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
80 .iter()
81 .any(|d| option.formatted.contains(d));
82 assert!(
83 has_day,
84 "Formatted time should contain day: {}",
85 option.formatted
86 );
87
88 // Should contain AM or PM
89 assert!(
90 option.formatted.contains("AM") || option.formatted.contains("PM"),
91 "Formatted time should contain AM/PM: {}",
92 option.formatted
93 );
94 }
95 }
96
97 #[test]
98 fn tomorrow_is_next_day_at_9am() {
99 let response = get_snooze_options();
100 let tomorrow_option = response
101 .options
102 .iter()
103 .find(|o| o.key == "tomorrow")
104 .expect("Should have tomorrow option");
105
106 let local_time = tomorrow_option.time.with_timezone(&Local);
107 assert_eq!(local_time.hour(), 9, "Tomorrow should be at 9am");
108 assert_eq!(local_time.minute(), 0, "Tomorrow should be at exactly :00");
109 }
110
111 #[test]
112 fn weekend_is_saturday_at_10am() {
113 let response = get_snooze_options();
114 let weekend_option = response
115 .options
116 .iter()
117 .find(|o| o.key == "weekend")
118 .expect("Should have weekend option");
119
120 let local_time = weekend_option.time.with_timezone(&Local);
121 assert_eq!(
122 local_time.weekday(),
123 Weekday::Sat,
124 "Weekend should be Saturday"
125 );
126 assert_eq!(local_time.hour(), 10, "Weekend should be at 10am");
127 assert_eq!(local_time.minute(), 0, "Weekend should be at exactly :00");
128 }
129
130 #[test]
131 fn next_week_is_monday_at_9am() {
132 let response = get_snooze_options();
133 let next_week_option = response
134 .options
135 .iter()
136 .find(|o| o.key == "nextWeek")
137 .expect("Should have nextWeek option");
138
139 let local_time = next_week_option.time.with_timezone(&Local);
140 assert_eq!(
141 local_time.weekday(),
142 Weekday::Mon,
143 "Next week should be Monday"
144 );
145 assert_eq!(local_time.hour(), 9, "Next week should be at 9am");
146 assert_eq!(local_time.minute(), 0, "Next week should be at exactly :00");
147 }
148
149 #[test]
150 fn options_are_ordered_chronologically() {
151 let response = get_snooze_options();
152
153 for window in response.options.windows(2) {
154 assert!(
155 window[0].time < window[1].time,
156 "Options should be in chronological order: {:?} should be before {:?}",
157 window[0].key,
158 window[1].key
159 );
160 }
161 }
162