| 1 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|