db_tests.rs

   1use super::*;
   2use crate::test_both_dbs;
   3use gpui::executor::{Background, Deterministic};
   4use pretty_assertions::{assert_eq, assert_ne};
   5use std::sync::Arc;
   6use tests::TestDb;
   7
   8test_both_dbs!(
   9    test_get_users,
  10    test_get_users_by_ids_postgres,
  11    test_get_users_by_ids_sqlite
  12);
  13
  14async fn test_get_users(db: &Arc<Database>) {
  15    let mut user_ids = Vec::new();
  16    let mut user_metric_ids = Vec::new();
  17    for i in 1..=4 {
  18        let user = db
  19            .create_user(
  20                &format!("user{i}@example.com"),
  21                false,
  22                NewUserParams {
  23                    github_login: format!("user{i}"),
  24                    github_user_id: i,
  25                    invite_count: 0,
  26                },
  27            )
  28            .await
  29            .unwrap();
  30        user_ids.push(user.user_id);
  31        user_metric_ids.push(user.metrics_id);
  32    }
  33
  34    assert_eq!(
  35        db.get_users_by_ids(user_ids.clone()).await.unwrap(),
  36        vec![
  37            User {
  38                id: user_ids[0],
  39                github_login: "user1".to_string(),
  40                github_user_id: Some(1),
  41                email_address: Some("user1@example.com".to_string()),
  42                admin: false,
  43                metrics_id: user_metric_ids[0].parse().unwrap(),
  44                ..Default::default()
  45            },
  46            User {
  47                id: user_ids[1],
  48                github_login: "user2".to_string(),
  49                github_user_id: Some(2),
  50                email_address: Some("user2@example.com".to_string()),
  51                admin: false,
  52                metrics_id: user_metric_ids[1].parse().unwrap(),
  53                ..Default::default()
  54            },
  55            User {
  56                id: user_ids[2],
  57                github_login: "user3".to_string(),
  58                github_user_id: Some(3),
  59                email_address: Some("user3@example.com".to_string()),
  60                admin: false,
  61                metrics_id: user_metric_ids[2].parse().unwrap(),
  62                ..Default::default()
  63            },
  64            User {
  65                id: user_ids[3],
  66                github_login: "user4".to_string(),
  67                github_user_id: Some(4),
  68                email_address: Some("user4@example.com".to_string()),
  69                admin: false,
  70                metrics_id: user_metric_ids[3].parse().unwrap(),
  71                ..Default::default()
  72            }
  73        ]
  74    );
  75}
  76
  77test_both_dbs!(
  78    test_get_or_create_user_by_github_account,
  79    test_get_or_create_user_by_github_account_postgres,
  80    test_get_or_create_user_by_github_account_sqlite
  81);
  82
  83async fn test_get_or_create_user_by_github_account(db: &Arc<Database>) {
  84    let user_id1 = db
  85        .create_user(
  86            "user1@example.com",
  87            false,
  88            NewUserParams {
  89                github_login: "login1".into(),
  90                github_user_id: 101,
  91                invite_count: 0,
  92            },
  93        )
  94        .await
  95        .unwrap()
  96        .user_id;
  97    let user_id2 = db
  98        .create_user(
  99            "user2@example.com",
 100            false,
 101            NewUserParams {
 102                github_login: "login2".into(),
 103                github_user_id: 102,
 104                invite_count: 0,
 105            },
 106        )
 107        .await
 108        .unwrap()
 109        .user_id;
 110
 111    let user = db
 112        .get_or_create_user_by_github_account("login1", None, None)
 113        .await
 114        .unwrap()
 115        .unwrap();
 116    assert_eq!(user.id, user_id1);
 117    assert_eq!(&user.github_login, "login1");
 118    assert_eq!(user.github_user_id, Some(101));
 119
 120    assert!(db
 121        .get_or_create_user_by_github_account("non-existent-login", None, None)
 122        .await
 123        .unwrap()
 124        .is_none());
 125
 126    let user = db
 127        .get_or_create_user_by_github_account("the-new-login2", Some(102), None)
 128        .await
 129        .unwrap()
 130        .unwrap();
 131    assert_eq!(user.id, user_id2);
 132    assert_eq!(&user.github_login, "the-new-login2");
 133    assert_eq!(user.github_user_id, Some(102));
 134
 135    let user = db
 136        .get_or_create_user_by_github_account("login3", Some(103), Some("user3@example.com"))
 137        .await
 138        .unwrap()
 139        .unwrap();
 140    assert_eq!(&user.github_login, "login3");
 141    assert_eq!(user.github_user_id, Some(103));
 142    assert_eq!(user.email_address, Some("user3@example.com".into()));
 143}
 144
 145test_both_dbs!(
 146    test_create_access_tokens,
 147    test_create_access_tokens_postgres,
 148    test_create_access_tokens_sqlite
 149);
 150
 151async fn test_create_access_tokens(db: &Arc<Database>) {
 152    let user = db
 153        .create_user(
 154            "u1@example.com",
 155            false,
 156            NewUserParams {
 157                github_login: "u1".into(),
 158                github_user_id: 1,
 159                invite_count: 0,
 160            },
 161        )
 162        .await
 163        .unwrap()
 164        .user_id;
 165
 166    let token_1 = db.create_access_token(user, "h1", 2).await.unwrap();
 167    let token_2 = db.create_access_token(user, "h2", 2).await.unwrap();
 168    assert_eq!(
 169        db.get_access_token(token_1).await.unwrap(),
 170        access_token::Model {
 171            id: token_1,
 172            user_id: user,
 173            hash: "h1".into(),
 174        }
 175    );
 176    assert_eq!(
 177        db.get_access_token(token_2).await.unwrap(),
 178        access_token::Model {
 179            id: token_2,
 180            user_id: user,
 181            hash: "h2".into()
 182        }
 183    );
 184
 185    let token_3 = db.create_access_token(user, "h3", 2).await.unwrap();
 186    assert_eq!(
 187        db.get_access_token(token_3).await.unwrap(),
 188        access_token::Model {
 189            id: token_3,
 190            user_id: user,
 191            hash: "h3".into()
 192        }
 193    );
 194    assert_eq!(
 195        db.get_access_token(token_2).await.unwrap(),
 196        access_token::Model {
 197            id: token_2,
 198            user_id: user,
 199            hash: "h2".into()
 200        }
 201    );
 202    assert!(db.get_access_token(token_1).await.is_err());
 203
 204    let token_4 = db.create_access_token(user, "h4", 2).await.unwrap();
 205    assert_eq!(
 206        db.get_access_token(token_4).await.unwrap(),
 207        access_token::Model {
 208            id: token_4,
 209            user_id: user,
 210            hash: "h4".into()
 211        }
 212    );
 213    assert_eq!(
 214        db.get_access_token(token_3).await.unwrap(),
 215        access_token::Model {
 216            id: token_3,
 217            user_id: user,
 218            hash: "h3".into()
 219        }
 220    );
 221    assert!(db.get_access_token(token_2).await.is_err());
 222    assert!(db.get_access_token(token_1).await.is_err());
 223}
 224
 225test_both_dbs!(
 226    test_add_contacts,
 227    test_add_contacts_postgres,
 228    test_add_contacts_sqlite
 229);
 230
 231async fn test_add_contacts(db: &Arc<Database>) {
 232    let mut user_ids = Vec::new();
 233    for i in 0..3 {
 234        user_ids.push(
 235            db.create_user(
 236                &format!("user{i}@example.com"),
 237                false,
 238                NewUserParams {
 239                    github_login: format!("user{i}"),
 240                    github_user_id: i,
 241                    invite_count: 0,
 242                },
 243            )
 244            .await
 245            .unwrap()
 246            .user_id,
 247        );
 248    }
 249
 250    let user_1 = user_ids[0];
 251    let user_2 = user_ids[1];
 252    let user_3 = user_ids[2];
 253
 254    // User starts with no contacts
 255    assert_eq!(db.get_contacts(user_1).await.unwrap(), &[]);
 256
 257    // User requests a contact. Both users see the pending request.
 258    db.send_contact_request(user_1, user_2).await.unwrap();
 259    assert!(!db.has_contact(user_1, user_2).await.unwrap());
 260    assert!(!db.has_contact(user_2, user_1).await.unwrap());
 261    assert_eq!(
 262        db.get_contacts(user_1).await.unwrap(),
 263        &[Contact::Outgoing { user_id: user_2 }],
 264    );
 265    assert_eq!(
 266        db.get_contacts(user_2).await.unwrap(),
 267        &[Contact::Incoming {
 268            user_id: user_1,
 269            should_notify: true
 270        }]
 271    );
 272
 273    // User 2 dismisses the contact request notification without accepting or rejecting.
 274    // We shouldn't notify them again.
 275    db.dismiss_contact_notification(user_1, user_2)
 276        .await
 277        .unwrap_err();
 278    db.dismiss_contact_notification(user_2, user_1)
 279        .await
 280        .unwrap();
 281    assert_eq!(
 282        db.get_contacts(user_2).await.unwrap(),
 283        &[Contact::Incoming {
 284            user_id: user_1,
 285            should_notify: false
 286        }]
 287    );
 288
 289    // User can't accept their own contact request
 290    db.respond_to_contact_request(user_1, user_2, true)
 291        .await
 292        .unwrap_err();
 293
 294    // User accepts a contact request. Both users see the contact.
 295    db.respond_to_contact_request(user_2, user_1, true)
 296        .await
 297        .unwrap();
 298    assert_eq!(
 299        db.get_contacts(user_1).await.unwrap(),
 300        &[Contact::Accepted {
 301            user_id: user_2,
 302            should_notify: true,
 303            busy: false,
 304        }],
 305    );
 306    assert!(db.has_contact(user_1, user_2).await.unwrap());
 307    assert!(db.has_contact(user_2, user_1).await.unwrap());
 308    assert_eq!(
 309        db.get_contacts(user_2).await.unwrap(),
 310        &[Contact::Accepted {
 311            user_id: user_1,
 312            should_notify: false,
 313            busy: false,
 314        }]
 315    );
 316
 317    // Users cannot re-request existing contacts.
 318    db.send_contact_request(user_1, user_2).await.unwrap_err();
 319    db.send_contact_request(user_2, user_1).await.unwrap_err();
 320
 321    // Users can't dismiss notifications of them accepting other users' requests.
 322    db.dismiss_contact_notification(user_2, user_1)
 323        .await
 324        .unwrap_err();
 325    assert_eq!(
 326        db.get_contacts(user_1).await.unwrap(),
 327        &[Contact::Accepted {
 328            user_id: user_2,
 329            should_notify: true,
 330            busy: false,
 331        }]
 332    );
 333
 334    // Users can dismiss notifications of other users accepting their requests.
 335    db.dismiss_contact_notification(user_1, user_2)
 336        .await
 337        .unwrap();
 338    assert_eq!(
 339        db.get_contacts(user_1).await.unwrap(),
 340        &[Contact::Accepted {
 341            user_id: user_2,
 342            should_notify: false,
 343            busy: false,
 344        }]
 345    );
 346
 347    // Users send each other concurrent contact requests and
 348    // see that they are immediately accepted.
 349    db.send_contact_request(user_1, user_3).await.unwrap();
 350    db.send_contact_request(user_3, user_1).await.unwrap();
 351    assert_eq!(
 352        db.get_contacts(user_1).await.unwrap(),
 353        &[
 354            Contact::Accepted {
 355                user_id: user_2,
 356                should_notify: false,
 357                busy: false,
 358            },
 359            Contact::Accepted {
 360                user_id: user_3,
 361                should_notify: false,
 362                busy: false,
 363            }
 364        ]
 365    );
 366    assert_eq!(
 367        db.get_contacts(user_3).await.unwrap(),
 368        &[Contact::Accepted {
 369            user_id: user_1,
 370            should_notify: false,
 371            busy: false,
 372        }],
 373    );
 374
 375    // User declines a contact request. Both users see that it is gone.
 376    db.send_contact_request(user_2, user_3).await.unwrap();
 377    db.respond_to_contact_request(user_3, user_2, false)
 378        .await
 379        .unwrap();
 380    assert!(!db.has_contact(user_2, user_3).await.unwrap());
 381    assert!(!db.has_contact(user_3, user_2).await.unwrap());
 382    assert_eq!(
 383        db.get_contacts(user_2).await.unwrap(),
 384        &[Contact::Accepted {
 385            user_id: user_1,
 386            should_notify: false,
 387            busy: false,
 388        }]
 389    );
 390    assert_eq!(
 391        db.get_contacts(user_3).await.unwrap(),
 392        &[Contact::Accepted {
 393            user_id: user_1,
 394            should_notify: false,
 395            busy: false,
 396        }],
 397    );
 398}
 399
 400test_both_dbs!(
 401    test_metrics_id,
 402    test_metrics_id_postgres,
 403    test_metrics_id_sqlite
 404);
 405
 406async fn test_metrics_id(db: &Arc<Database>) {
 407    let NewUserResult {
 408        user_id: user1,
 409        metrics_id: metrics_id1,
 410        ..
 411    } = db
 412        .create_user(
 413            "person1@example.com",
 414            false,
 415            NewUserParams {
 416                github_login: "person1".into(),
 417                github_user_id: 101,
 418                invite_count: 5,
 419            },
 420        )
 421        .await
 422        .unwrap();
 423    let NewUserResult {
 424        user_id: user2,
 425        metrics_id: metrics_id2,
 426        ..
 427    } = db
 428        .create_user(
 429            "person2@example.com",
 430            false,
 431            NewUserParams {
 432                github_login: "person2".into(),
 433                github_user_id: 102,
 434                invite_count: 5,
 435            },
 436        )
 437        .await
 438        .unwrap();
 439
 440    assert_eq!(db.get_user_metrics_id(user1).await.unwrap(), metrics_id1);
 441    assert_eq!(db.get_user_metrics_id(user2).await.unwrap(), metrics_id2);
 442    assert_eq!(metrics_id1.len(), 36);
 443    assert_eq!(metrics_id2.len(), 36);
 444    assert_ne!(metrics_id1, metrics_id2);
 445}
 446
 447test_both_dbs!(
 448    test_project_count,
 449    test_project_count_postgres,
 450    test_project_count_sqlite
 451);
 452
 453async fn test_project_count(db: &Arc<Database>) {
 454    let owner_id = db.create_server("test").await.unwrap().0 as u32;
 455
 456    let user1 = db
 457        .create_user(
 458            &format!("admin@example.com"),
 459            true,
 460            NewUserParams {
 461                github_login: "admin".into(),
 462                github_user_id: 0,
 463                invite_count: 0,
 464            },
 465        )
 466        .await
 467        .unwrap();
 468    let user2 = db
 469        .create_user(
 470            &format!("user@example.com"),
 471            false,
 472            NewUserParams {
 473                github_login: "user".into(),
 474                github_user_id: 1,
 475                invite_count: 0,
 476            },
 477        )
 478        .await
 479        .unwrap();
 480
 481    let room_id = RoomId::from_proto(
 482        db.create_room(user1.user_id, ConnectionId { owner_id, id: 0 }, "")
 483            .await
 484            .unwrap()
 485            .id,
 486    );
 487    db.call(
 488        room_id,
 489        user1.user_id,
 490        ConnectionId { owner_id, id: 0 },
 491        user2.user_id,
 492        None,
 493    )
 494    .await
 495    .unwrap();
 496    db.join_room(room_id, user2.user_id, ConnectionId { owner_id, id: 1 })
 497        .await
 498        .unwrap();
 499    assert_eq!(db.project_count_excluding_admins().await.unwrap(), 0);
 500
 501    db.share_project(room_id, ConnectionId { owner_id, id: 1 }, &[])
 502        .await
 503        .unwrap();
 504    assert_eq!(db.project_count_excluding_admins().await.unwrap(), 1);
 505
 506    db.share_project(room_id, ConnectionId { owner_id, id: 1 }, &[])
 507        .await
 508        .unwrap();
 509    assert_eq!(db.project_count_excluding_admins().await.unwrap(), 2);
 510
 511    // Projects shared by admins aren't counted.
 512    db.share_project(room_id, ConnectionId { owner_id, id: 0 }, &[])
 513        .await
 514        .unwrap();
 515    assert_eq!(db.project_count_excluding_admins().await.unwrap(), 2);
 516
 517    db.leave_room(ConnectionId { owner_id, id: 1 })
 518        .await
 519        .unwrap();
 520    assert_eq!(db.project_count_excluding_admins().await.unwrap(), 0);
 521}
 522
 523#[test]
 524fn test_fuzzy_like_string() {
 525    assert_eq!(Database::fuzzy_like_string("abcd"), "%a%b%c%d%");
 526    assert_eq!(Database::fuzzy_like_string("x y"), "%x%y%");
 527    assert_eq!(Database::fuzzy_like_string(" z  "), "%z%");
 528}
 529
 530#[gpui::test]
 531async fn test_fuzzy_search_users() {
 532    let test_db = TestDb::postgres(build_background_executor());
 533    let db = test_db.db();
 534    for (i, github_login) in [
 535        "California",
 536        "colorado",
 537        "oregon",
 538        "washington",
 539        "florida",
 540        "delaware",
 541        "rhode-island",
 542    ]
 543    .into_iter()
 544    .enumerate()
 545    {
 546        db.create_user(
 547            &format!("{github_login}@example.com"),
 548            false,
 549            NewUserParams {
 550                github_login: github_login.into(),
 551                github_user_id: i as i32,
 552                invite_count: 0,
 553            },
 554        )
 555        .await
 556        .unwrap();
 557    }
 558
 559    assert_eq!(
 560        fuzzy_search_user_names(db, "clr").await,
 561        &["colorado", "California"]
 562    );
 563    assert_eq!(
 564        fuzzy_search_user_names(db, "ro").await,
 565        &["rhode-island", "colorado", "oregon"],
 566    );
 567
 568    async fn fuzzy_search_user_names(db: &Database, query: &str) -> Vec<String> {
 569        db.fuzzy_search_users(query, 10)
 570            .await
 571            .unwrap()
 572            .into_iter()
 573            .map(|user| user.github_login)
 574            .collect::<Vec<_>>()
 575    }
 576}
 577
 578test_both_dbs!(test_channels, test_channels_postgres, test_channels_sqlite);
 579
 580async fn test_channels(db: &Arc<Database>) {
 581    let a_id = db
 582        .create_user(
 583            "user1@example.com",
 584            false,
 585            NewUserParams {
 586                github_login: "user1".into(),
 587                github_user_id: 5,
 588                invite_count: 0,
 589            },
 590        )
 591        .await
 592        .unwrap()
 593        .user_id;
 594
 595    let b_id = db
 596        .create_user(
 597            "user2@example.com",
 598            false,
 599            NewUserParams {
 600                github_login: "user2".into(),
 601                github_user_id: 6,
 602                invite_count: 0,
 603            },
 604        )
 605        .await
 606        .unwrap()
 607        .user_id;
 608
 609    let zed_id = db.create_root_channel("zed", "1", a_id).await.unwrap();
 610
 611    // Make sure that people cannot read channels they haven't been invited to
 612    assert!(db.get_channel(zed_id, b_id).await.unwrap().is_none());
 613
 614    db.invite_channel_member(zed_id, b_id, a_id, false)
 615        .await
 616        .unwrap();
 617
 618    db.respond_to_channel_invite(zed_id, b_id, true)
 619        .await
 620        .unwrap();
 621
 622    let crdb_id = db
 623        .create_channel("crdb", Some(zed_id), "2", a_id)
 624        .await
 625        .unwrap();
 626    let livestreaming_id = db
 627        .create_channel("livestreaming", Some(zed_id), "3", a_id)
 628        .await
 629        .unwrap();
 630    let replace_id = db
 631        .create_channel("replace", Some(zed_id), "4", a_id)
 632        .await
 633        .unwrap();
 634
 635    let mut members = db.get_channel_members(replace_id).await.unwrap();
 636    members.sort();
 637    assert_eq!(members, &[a_id, b_id]);
 638
 639    let rust_id = db.create_root_channel("rust", "5", a_id).await.unwrap();
 640    let cargo_id = db
 641        .create_channel("cargo", Some(rust_id), "6", a_id)
 642        .await
 643        .unwrap();
 644
 645    let cargo_ra_id = db
 646        .create_channel("cargo-ra", Some(cargo_id), "7", a_id)
 647        .await
 648        .unwrap();
 649
 650    let result = db.get_channels_for_user(a_id).await.unwrap();
 651    assert_eq!(
 652        result.channels,
 653        vec![
 654            Channel {
 655                id: zed_id,
 656                name: "zed".to_string(),
 657                parent_id: None,
 658            },
 659            Channel {
 660                id: crdb_id,
 661                name: "crdb".to_string(),
 662                parent_id: Some(zed_id),
 663            },
 664            Channel {
 665                id: livestreaming_id,
 666                name: "livestreaming".to_string(),
 667                parent_id: Some(zed_id),
 668            },
 669            Channel {
 670                id: replace_id,
 671                name: "replace".to_string(),
 672                parent_id: Some(zed_id),
 673            },
 674            Channel {
 675                id: rust_id,
 676                name: "rust".to_string(),
 677                parent_id: None,
 678            },
 679            Channel {
 680                id: cargo_id,
 681                name: "cargo".to_string(),
 682                parent_id: Some(rust_id),
 683            },
 684            Channel {
 685                id: cargo_ra_id,
 686                name: "cargo-ra".to_string(),
 687                parent_id: Some(cargo_id),
 688            }
 689        ]
 690    );
 691
 692    let result = db.get_channels_for_user(b_id).await.unwrap();
 693    assert_eq!(
 694        result.channels,
 695        vec![
 696            Channel {
 697                id: zed_id,
 698                name: "zed".to_string(),
 699                parent_id: None,
 700            },
 701            Channel {
 702                id: crdb_id,
 703                name: "crdb".to_string(),
 704                parent_id: Some(zed_id),
 705            },
 706            Channel {
 707                id: livestreaming_id,
 708                name: "livestreaming".to_string(),
 709                parent_id: Some(zed_id),
 710            },
 711            Channel {
 712                id: replace_id,
 713                name: "replace".to_string(),
 714                parent_id: Some(zed_id),
 715            },
 716        ]
 717    );
 718
 719    // Update member permissions
 720    let set_subchannel_admin = db.set_channel_member_admin(crdb_id, a_id, b_id, true).await;
 721    assert!(set_subchannel_admin.is_err());
 722    let set_channel_admin = db.set_channel_member_admin(zed_id, a_id, b_id, true).await;
 723    assert!(set_channel_admin.is_ok());
 724
 725    let result = db.get_channels_for_user(b_id).await.unwrap();
 726    assert_eq!(
 727        result.channels,
 728        vec![
 729            Channel {
 730                id: zed_id,
 731                name: "zed".to_string(),
 732                parent_id: None,
 733            },
 734            Channel {
 735                id: crdb_id,
 736                name: "crdb".to_string(),
 737                parent_id: Some(zed_id),
 738            },
 739            Channel {
 740                id: livestreaming_id,
 741                name: "livestreaming".to_string(),
 742                parent_id: Some(zed_id),
 743            },
 744            Channel {
 745                id: replace_id,
 746                name: "replace".to_string(),
 747                parent_id: Some(zed_id),
 748            },
 749        ]
 750    );
 751
 752    // Remove a single channel
 753    db.remove_channel(crdb_id, a_id).await.unwrap();
 754    assert!(db.get_channel(crdb_id, a_id).await.unwrap().is_none());
 755
 756    // Remove a channel tree
 757    let (mut channel_ids, user_ids) = db.remove_channel(rust_id, a_id).await.unwrap();
 758    channel_ids.sort();
 759    assert_eq!(channel_ids, &[rust_id, cargo_id, cargo_ra_id]);
 760    assert_eq!(user_ids, &[a_id]);
 761
 762    assert!(db.get_channel(rust_id, a_id).await.unwrap().is_none());
 763    assert!(db.get_channel(cargo_id, a_id).await.unwrap().is_none());
 764    assert!(db.get_channel(cargo_ra_id, a_id).await.unwrap().is_none());
 765}
 766
 767test_both_dbs!(
 768    test_joining_channels,
 769    test_joining_channels_postgres,
 770    test_joining_channels_sqlite
 771);
 772
 773async fn test_joining_channels(db: &Arc<Database>) {
 774    let owner_id = db.create_server("test").await.unwrap().0 as u32;
 775
 776    let user_1 = db
 777        .create_user(
 778            "user1@example.com",
 779            false,
 780            NewUserParams {
 781                github_login: "user1".into(),
 782                github_user_id: 5,
 783                invite_count: 0,
 784            },
 785        )
 786        .await
 787        .unwrap()
 788        .user_id;
 789    let user_2 = db
 790        .create_user(
 791            "user2@example.com",
 792            false,
 793            NewUserParams {
 794                github_login: "user2".into(),
 795                github_user_id: 6,
 796                invite_count: 0,
 797
 798            },
 799        )
 800        .await
 801        .unwrap()        .user_id;
 802
 803    let channel_1 = db
 804        .create_root_channel("channel_1", "1", user_1)
 805        .await
 806        .unwrap();
 807    let room_1 = db.room_id_for_channel(channel_1).await.unwrap();
 808
 809    // can join a room with membership to its channel
 810    let joined_room = db
 811        .join_room(room_1, user_1, ConnectionId { owner_id, id: 1 })
 812        .await
 813        .unwrap();
 814    assert_eq!(joined_room.room.participants.len(), 1);
 815
 816    drop(joined_room);
 817    // cannot join a room without membership to its channel
 818    assert!(db
 819        .join_room(room_1, user_2, ConnectionId { owner_id, id: 1 })
 820        .await
 821        .is_err());
 822}
 823
 824test_both_dbs!(
 825    test_channel_invites,
 826    test_channel_invites_postgres,
 827    test_channel_invites_sqlite
 828);
 829
 830async fn test_channel_invites(db: &Arc<Database>) {
 831    db.create_server("test").await.unwrap();
 832
 833    let user_1 = db
 834        .create_user(
 835            "user1@example.com",
 836            false,
 837            NewUserParams {
 838                github_login: "user1".into(),
 839                github_user_id: 5,
 840                invite_count: 0,
 841            },
 842        )
 843        .await
 844        .unwrap()
 845        .user_id;
 846    let user_2 = db
 847        .create_user(
 848            "user2@example.com",
 849            false,
 850            NewUserParams {
 851                github_login: "user2".into(),
 852                github_user_id: 6,
 853                invite_count: 0,
 854            },
 855        )
 856        .await
 857        .unwrap()
 858        .user_id;
 859
 860    let user_3 = db
 861        .create_user(
 862            "user3@example.com",
 863            false,
 864            NewUserParams {
 865                github_login: "user3".into(),
 866                github_user_id: 7,
 867                invite_count: 0,
 868            },
 869        )
 870        .await
 871        .unwrap()
 872        .user_id;
 873
 874    let channel_1_1 = db
 875        .create_root_channel("channel_1", "1", user_1)
 876        .await
 877        .unwrap();
 878
 879    let channel_1_2 = db
 880        .create_root_channel("channel_2", "2", user_1)
 881        .await
 882        .unwrap();
 883
 884    db.invite_channel_member(channel_1_1, user_2, user_1, false)
 885        .await
 886        .unwrap();
 887    db.invite_channel_member(channel_1_2, user_2, user_1, false)
 888        .await
 889        .unwrap();
 890    db.invite_channel_member(channel_1_1, user_3, user_1, true)
 891        .await
 892        .unwrap();
 893
 894    let user_2_invites = db
 895        .get_channel_invites_for_user(user_2) // -> [channel_1_1, channel_1_2]
 896        .await
 897        .unwrap()
 898        .into_iter()
 899        .map(|channel| channel.id)
 900        .collect::<Vec<_>>();
 901
 902    assert_eq!(user_2_invites, &[channel_1_1, channel_1_2]);
 903
 904    let user_3_invites = db
 905        .get_channel_invites_for_user(user_3) // -> [channel_1_1]
 906        .await
 907        .unwrap()
 908        .into_iter()
 909        .map(|channel| channel.id)
 910        .collect::<Vec<_>>();
 911
 912    assert_eq!(user_3_invites, &[channel_1_1]);
 913
 914    let members = db
 915        .get_channel_member_details(channel_1_1, user_1)
 916        .await
 917        .unwrap();
 918    assert_eq!(
 919        members,
 920        &[
 921            proto::ChannelMember {
 922                user_id: user_1.to_proto(),
 923                kind: proto::channel_member::Kind::Member.into(),
 924                admin: true,
 925            },
 926            proto::ChannelMember {
 927                user_id: user_2.to_proto(),
 928                kind: proto::channel_member::Kind::Invitee.into(),
 929                admin: false,
 930            },
 931            proto::ChannelMember {
 932                user_id: user_3.to_proto(),
 933                kind: proto::channel_member::Kind::Invitee.into(),
 934                admin: true,
 935            },
 936        ]
 937    );
 938
 939    db.respond_to_channel_invite(channel_1_1, user_2, true)
 940        .await
 941        .unwrap();
 942
 943    let channel_1_3 = db
 944        .create_channel("channel_3", Some(channel_1_1), "1", user_1)
 945        .await
 946        .unwrap();
 947
 948    let members = db
 949        .get_channel_member_details(channel_1_3, user_1)
 950        .await
 951        .unwrap();
 952    assert_eq!(
 953        members,
 954        &[
 955            proto::ChannelMember {
 956                user_id: user_1.to_proto(),
 957                kind: proto::channel_member::Kind::Member.into(),
 958                admin: true,
 959            },
 960            proto::ChannelMember {
 961                user_id: user_2.to_proto(),
 962                kind: proto::channel_member::Kind::AncestorMember.into(),
 963                admin: false,
 964            },
 965        ]
 966    );
 967}
 968
 969test_both_dbs!(
 970    test_channel_renames,
 971    test_channel_renames_postgres,
 972    test_channel_renames_sqlite
 973);
 974
 975async fn test_channel_renames(db: &Arc<Database>) {
 976    db.create_server("test").await.unwrap();
 977
 978    let user_1 = db
 979        .create_user(
 980            "user1@example.com",
 981            false,
 982            NewUserParams {
 983                github_login: "user1".into(),
 984                github_user_id: 5,
 985                invite_count: 0,
 986            },
 987        )
 988        .await
 989        .unwrap()
 990        .user_id;
 991
 992    let user_2 = db
 993        .create_user(
 994            "user2@example.com",
 995            false,
 996            NewUserParams {
 997                github_login: "user2".into(),
 998                github_user_id: 6,
 999                invite_count: 0,
1000            },
1001        )
1002        .await
1003        .unwrap()
1004        .user_id;
1005
1006    let zed_id = db.create_root_channel("zed", "1", user_1).await.unwrap();
1007
1008    db.rename_channel(zed_id, user_1, "#zed-archive")
1009        .await
1010        .unwrap();
1011
1012    let zed_archive_id = zed_id;
1013
1014    let (channel, _) = db
1015        .get_channel(zed_archive_id, user_1)
1016        .await
1017        .unwrap()
1018        .unwrap();
1019    assert_eq!(channel.name, "zed-archive");
1020
1021    let non_permissioned_rename = db
1022        .rename_channel(zed_archive_id, user_2, "hacked-lol")
1023        .await;
1024    assert!(non_permissioned_rename.is_err());
1025
1026    let bad_name_rename = db.rename_channel(zed_id, user_1, "#").await;
1027    assert!(bad_name_rename.is_err())
1028}
1029
1030fn build_background_executor() -> Arc<Background> {
1031    Deterministic::new(0).build_background()
1032}