Async/Await with MongoDB Rust Driver not Waiting for Insert

I am attempting to write an integration test for a utility module where my search function returns a new aggregate pipeline. When the database has 0 collections, this fails with an index out-of-bounds error on accounts[0]. It’s acting as if the aggregate pipeline is not waiting for the insert to happen. How do I refactor this to make the aggregate stage wait for the insert?

#[actix_web::test]
async fn test_search_pipeline() {
    let pipeline = vec![doc! { "$match": { "isDeleted": { "$ne": true } } }];

    let mut updated_pipeline = super::search(&pipeline, String::from("foo"));

    let db: Database = connect_to_database().await;
    let accounts_col: Collection<Document> = db.collection("accounts");

    let account_fixture = account::create();

    // Insert a new account in the database
    let new_account = match accounts_col.insert_one(account_fixture, None).await {
        Ok(new_account) => new_account,
        Err(e) => {
            panic!("Unable to insert new account test fixture document: {}", e);
        }
    };

    // Execute the search aggregate pipeline to find the document we just inserted
    let accounts = match accounts_col.aggregate(updated_pipeline, None).await {
        Ok(mut cursor) => {
            let mut accounts: Vec<Document> = Vec::new();

            while let Some(doc) = cursor.next().await {
                match doc {
                    Ok(doc) => accounts.push(doc),
                    Err(e) => panic!("Error iterating through the new account test pipeline cursor : {}", e)
                }
            }

            accounts
        },
        Err(e) => {
            panic!("Unable to execute test search aggregate pipeline: {}", e);
        }
    };

    // Compare the new account id that we inserted with the first search result account id
    let new_account_id: String = new_account.inserted_id.as_object_id().unwrap().to_hex();
    let search_account_id: String = accounts[0].get_object_id("_id").unwrap().to_hex();

    assert_eq!(new_account_id, search_account_id);
}

I have tried removing the actual database calls from the match statements and nesting the aggregate stage inside of the Ok arm of the insert Result. Neither of those changes seem to change the result.

account_fixture:

doc! {
    "name": "ufc0kpu!pgu1QJW3unj",
    "logo": "60e9ca73c500a9001534ad84-logo.png",
    "isActive": true,
    "isDeleted": false,
    "isUnlimited": false,
    "parentAccount": null,
    "credits": 100,
    "isProAccount": true,
    "is360Enabled": true,
    "isResourcesDisabled": false,
    "isEcoPrinting": false,
    "isCoreExtended": false,
    "createdAt": "2021-09-02T12:11:37.995+0000",
}

updated_pipeline:

doc! {
    "$search": {
        "autocomplete": {
            "query": "ufc0kpu!pgu1QJW3unj",
            "path": "name",
            "fuzzy": {
                "maxEdits": 2,
                "prefixLength": 8
            }
        }
    }
}
1 Like