Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(graphQL): fix wrong read status when list notifications #3555

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
Loading