Skip to content

Commit

Permalink
fix(graphQL): fix wrong read status when list notifications (#3555)
Browse files Browse the repository at this point in the history
Signed-off-by: Wei Zhang <[email protected]>
  • Loading branch information
zwpaper authored Dec 13, 2024
1 parent c90db2f commit 3e157e5
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 11 deletions.
7 changes: 4 additions & 3 deletions ee/tabby-db/src/notifications.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ SELECT
notifications.id,
notifications.created_at,
notifications.updated_at,
recipient,
content,
notifications.recipient,
notifications.content,
CASE
WHEN read_notifications.user_id IS NOT NULL THEN 1
WHEN read_notifications.user_id = '{user_id}' THEN 1
ELSE 0
END AS read
FROM
Expand All @@ -121,6 +121,7 @@ LEFT JOIN
read_notifications
ON
notifications.id = read_notifications.notification_id
AND read_notifications.user_id = '{user_id}'
WHERE
({recipient_clause})
AND notifications.created_at > '{date_7days_ago}'
Expand Down
163 changes: 155 additions & 8 deletions ee/tabby-webserver/src/service/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod tests {
use super::*;

#[tokio::test]
async fn test_notification_admin_list() {
async fn test_admin_list() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -70,7 +70,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_list_read() {
async fn test_admin_list_read() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -94,7 +94,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_list_all() {
async fn test_admin_list_all() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -121,7 +121,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_mark_all_read_admin() {
async fn test_admin_mark_all_read_admin() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -139,7 +139,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_mark_read_twice() {
async fn test_admin_mark_read_twice() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand Down Expand Up @@ -169,7 +169,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_mark_all_read_twice() {
async fn test_admin_mark_all_read_twice() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -196,7 +196,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_admin_mark_all_read_admin_and_all_user() {
async fn test_admin_mark_all_read_admin_and_all_user() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -218,7 +218,7 @@ mod tests {
}

#[tokio::test]
async fn test_notification_user_mark_all_read_admin_and_all_user() {
async fn test_user_mark_all_read_admin_and_all_user() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

Expand All @@ -237,4 +237,151 @@ mod tests {
assert_eq!(notifications.len(), 1);
assert!(notifications[0].read);
}

#[tokio::test]
async fn test_multi_user_list() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

let user1 = db
.create_user("test1".into(), None, false, None)
.await
.unwrap()
.as_id();
let user2 = db
.create_user("test2".into(), None, false, None)
.await
.unwrap()
.as_id();
db.create_notification("admin", "admin_list").await.unwrap();
db.create_notification("all_user", "all_user")
.await
.unwrap();

let notifications = service.list(&user1).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(!notifications[0].read);

let notifications = service.list(&user2).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(!notifications[0].read);
}

#[tokio::test]
async fn test_multi_user_mark_read() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

let user1 = db
.create_user("test1".into(), None, false, None)
.await
.unwrap()
.as_id();
let user2 = db
.create_user("test2".into(), None, false, None)
.await
.unwrap()
.as_id();
db.create_notification("admin", "admin_list").await.unwrap();
db.create_notification("all_user", "all_user")
.await
.unwrap();

// user1 mark read
service.mark_read(&user1, None).await.unwrap();
let notifications = service.list(&user1).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(notifications[0].read);

// user2 should still have unread notification
let notifications = service.list(&user2).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(!notifications[0].read);

// user2 mark read
service.mark_read(&user2, None).await.unwrap();
let notifications = service.list(&user2).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(notifications[0].read);
}

#[tokio::test]
async fn test_multi_admin_mark_read() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

let user1 = db
.create_user("test1".into(), None, true, None)
.await
.unwrap()
.as_id();
let user2 = db
.create_user("test2".into(), None, true, None)
.await
.unwrap()
.as_id();
db.create_notification("admin", "admin_list").await.unwrap();
db.create_notification("all_user", "all_user")
.await
.unwrap();

// user1 mark read
service.mark_read(&user1, None).await.unwrap();
let notifications = service.list(&user1).await.unwrap();
assert_eq!(notifications.len(), 2);
assert!(notifications[0].read);
assert!(notifications[1].read);

// user2 should still have unread notification
let notifications = service.list(&user2).await.unwrap();
assert_eq!(notifications.len(), 2);
assert!(!notifications[0].read);
assert!(!notifications[1].read);

// user2 mark read
service.mark_read(&user2, None).await.unwrap();
let notifications = service.list(&user2).await.unwrap();
assert_eq!(notifications.len(), 2);
assert!(notifications[0].read);
assert!(notifications[1].read);
}

#[tokio::test]
async fn test_multi_admin_user_mark_read() {
let db = DbConn::new_in_memory().await.unwrap();
let service = create(db.clone());

let admin = db
.create_user("test1".into(), None, true, None)
.await
.unwrap()
.as_id();
let user = db
.create_user("test2".into(), None, false, None)
.await
.unwrap()
.as_id();
db.create_notification("admin", "admin_list").await.unwrap();
db.create_notification("all_user", "all_user")
.await
.unwrap();

// admin mark read
service.mark_read(&admin, None).await.unwrap();
let notifications = service.list(&admin).await.unwrap();
assert_eq!(notifications.len(), 2);
assert!(notifications[0].read);
assert!(notifications[1].read);

// user should still have unread notification
let notifications = service.list(&user).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(!notifications[0].read);

// user mark read
service.mark_read(&user, None).await.unwrap();
let notifications = service.list(&user).await.unwrap();
assert_eq!(notifications.len(), 1);
assert!(notifications[0].read);
}
}

0 comments on commit 3e157e5

Please sign in to comment.