Querying postgres using sqlx

Hello, Rustaceans. I'm building a CRUD app where users can join by just submitting a username or a referral code from a previously registered user(don't worry about auth security). The backend service is in Axum, Postgres and sqlx. I have written a username signup handler that looks like so:

#[debug_handler]
pub async fn signup_username(
    ctx: Extension<ApiContext>, 
    Form(input): Form<UserBody<UsernameInput>>
) -> Result<Json<UserBody<User>>, ApiError> {
    debug!("Received signup request for username: {}", input.user.username);


    let referral_code = generate_referral_code(input.user.username.clone())?;

    if input.user.username.is_empty(){
        return Err(ApiError::MissingCredential);
    } else {
        debug!("Inserting user: {} with referral code: {}", input.user.username, referral_code);
        let user = sqlx::query_as!(
            User,
            r#"
                insert into users(username, referral_code)
                values($1, $2)
                returning username, id, referral_code, referred_by, invited_users_count, created_at, updated_at
            "#,
            input.user.username,
            referral_code
        )
        .fetch_one(&ctx.0.db)
        .await
        .map_err(| err | {
            error!("error trying to insert into db: {err}");
            ApiError::InternalServerError
        })?;
        debug!("Successfully inserted user: {:?}", user);

        Ok(Json(UserBody {
           user,
        }))
    }
}

The handler takes an input of the type Form extractor and returns Json, or ApiError as output. I have the database table created and I try to insert the form input into the table to create a new user. The code compiles successfully. So I test it by trying to insert a new username to find out if the insertion works:


#[tokio::test]
async fn signup_returns_a_200_for_valid_form_data() {
    let config: Config = Config::new();

    let db_connection = PgPoolOptions::new()
        .max_connections(5)
        .connect(&config.database_url)
        .await
        .expect("Failed to connect to db");

    let client = hyper::Client::new();

    let body = hyper::Body::from("username=brook");

    let request = hyper::Request::builder()
        .method(hyper::Method::POST)
        .uri("http://127.0.0.1:8080/users/signup-username")
        .header("Content-Type", "application/x-www-form-urlencoded")
        .body(body)
        .expect("Failed to create request");

    let response = client
        .request(request)
        .await
        .expect("Failed to send request");

    assert_eq!(response.status(), hyper::StatusCode::OK);

    let saved = sqlx::query!(
        "select username, referral_code from users where username = 'brook' ",
        )
        .fetch_one(&db_connection)
        .await
        .expect("Failed to fetch saved data");

    assert_eq!(saved.username, "brook");
    assert!(!saved.referral_code.is_empty());

}

But the first assert_eq:

assert_eq!(response.status(), hyper::StatusCode::OK);

Fails with a 422 error code:

--- signup_returns_a_200_for_valid_form_data stdout ----
thread 'signup_returns_a_200_for_valid_form_data' panicked at 'assertion failed: `(left == right)`
  left: `422`,
 right: `200`', tests/signup.rs:35:5

I've added a couple of debug logs to the code to try and smoke out the bug, but I've had no success. What am I doing wrong?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.