Skip to content

Commit 7bc6f65

Browse files
committed
Merge remote-tracking branch 'origin/levkk-cookie-test' into dan-notificatioins-backwards-compatible
2 parents 23fb688 + 3bfee36 commit 7bc6f65

File tree

2 files changed

+44
-36
lines changed

2 files changed

+44
-36
lines changed

pgml-dashboard/src/components/layouts/head/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ mod default_head_template_test {
134134

135135
#[test]
136136
fn set_head() {
137-
let mut head = Head::new()
137+
let head = Head::new()
138138
.title("test title")
139139
.description("test description")
140140
.image("image/test_image.jpg");

pgml-dashboard/src/utils/cookies.rs

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
11
use chrono;
22
use rocket::http::{Cookie, CookieJar};
33
use rocket::serde::{Deserialize, Serialize};
4+
use time::Duration;
45

6+
/// Session data.
7+
#[derive(Serialize, Deserialize, Debug, Clone)]
8+
pub struct Notifications {
9+
/// App-wide notifications.
10+
notifications: Vec<NotificationCookie>,
11+
}
12+
13+
/// App-wide notifications.
514
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
615
pub struct NotificationCookie {
16+
/// Unique ID of the notification.
717
pub id: String,
18+
/// Time the notification was viewed. Used for reshowing the notification.
819
pub time_viewed: Option<chrono::DateTime<chrono::Utc>>,
20+
/// Time the notification modal was viewed. Used for reshowing the notification modal.
921
pub time_modal_viewed: Option<chrono::DateTime<chrono::Utc>>,
1022
}
1123

12-
pub struct Notifications {}
24+
#[derive(Serialize, Deserialize, Debug, Clone)]
25+
pub struct NotificationsCookieOld {
26+
pub notifications: Vec<String>,
27+
}
28+
29+
impl From<NotificationsCookieOld> for NotificationCookie {
30+
fn from(old: NotificationsCookieOld) -> Self {
31+
NotificationCookie {
32+
id: old.notifications[0].clone(),
33+
time_viewed: None,
34+
time_modal_viewed: None,
35+
}
36+
}
37+
}
1338

1439
impl Notifications {
15-
pub fn update_viewed(all_desired_notifications: &Vec<NotificationCookie>, cookies: &CookieJar<'_>) {
16-
let session = Notifications::safe_serialize_session(all_desired_notifications);
40+
/// Update the viewed notifications in the session.
41+
pub fn update_viewed(notifications: &[NotificationCookie], cookies: &CookieJar<'_>) {
42+
let session = Notifications::safe_serialize_session(notifications);
1743

1844
let mut cookie = Cookie::new("session", session);
19-
cookie.set_max_age(::time::Duration::weeks(4));
45+
cookie.set_max_age(Duration::weeks(52 * 100)); // Keep the cookie "forever"
2046
cookies.add_private(cookie);
2147
}
2248

49+
/// Get viewed notifications from the session.
2350
pub fn get_viewed(cookies: &CookieJar<'_>) -> Vec<NotificationCookie> {
2451
match cookies.get_private("session") {
2552
Some(session) => Notifications::safe_deserialize_session(session.value()),
@@ -28,40 +55,21 @@ impl Notifications {
2855
}
2956

3057
pub fn safe_deserialize_session(session: &str) -> Vec<NotificationCookie> {
31-
match serde_json::from_str::<serde_json::Value>(session).unwrap_or_else(|_| {
32-
serde_json::from_str::<serde_json::Value>(&Notifications::safe_serialize_session(&vec![])).unwrap()
33-
})["notifications"]
34-
.as_array()
35-
{
36-
Some(items) => items
37-
.into_iter()
38-
.map(|notification| {
39-
serde_json::from_str::<NotificationCookie>(&notification.to_string()).unwrap_or_else(|_| {
40-
serde_json::from_str::<String>(&notification.to_string())
41-
.and_then(|id| {
42-
Ok(NotificationCookie {
43-
id,
44-
time_viewed: None,
45-
time_modal_viewed: None,
46-
})
47-
})
48-
.unwrap_or_else(|_| NotificationCookie::default())
49-
})
50-
})
51-
.collect::<Vec<NotificationCookie>>(),
52-
_ => vec![],
58+
match serde_json::from_str::<Notifications>(session) {
59+
Ok(notifications) => notifications.notifications,
60+
Err(_) => match serde_json::from_str::<NotificationsCookieOld>(session) {
61+
Ok(notifications) => vec![NotificationCookie::from(notifications)],
62+
Err(_) => vec![],
63+
},
5364
}
5465
}
5566

56-
pub fn safe_serialize_session(cookies: &Vec<NotificationCookie>) -> String {
57-
let serialized = cookies
58-
.iter()
59-
.map(|x| serde_json::to_string(x))
60-
.filter(|x| x.is_ok())
61-
.map(|x| x.unwrap())
62-
.collect::<Vec<String>>();
67+
pub fn safe_serialize_session(notifications: &[NotificationCookie]) -> String {
68+
let notifications = Notifications {
69+
notifications: notifications.to_vec(),
70+
};
6371

64-
format!(r#"{{"notifications": [{}]}}"#, serialized.join(","))
72+
serde_json::to_string(&notifications).unwrap()
6573
}
6674
}
6775

@@ -118,7 +126,7 @@ mod test {
118126
time_viewed: None,
119127
time_modal_viewed: None,
120128
}];
121-
let expected = r#"{"notifications": [{"id":"1","time_viewed":null,"time_modal_viewed":null}]}"#;
129+
let expected = r#"{"notifications":[{"id":"1","time_viewed":null,"time_modal_viewed":null}]}"#;
122130
assert_eq!(Notifications::safe_serialize_session(&cookies), expected);
123131
}
124132
}

0 commit comments

Comments
 (0)