From b98e986c5ec3c95370baeaf11e74487480f79239 Mon Sep 17 00:00:00 2001 From: Luiz Carvalho Date: Wed, 21 Sep 2022 11:16:53 -0300 Subject: [PATCH] test(mysql): add error tests --- Cargo.toml | 5 +++ tests/mysql/error.rs | 80 ++++++++++++++++++++++++++++++++++++++++ tests/mysql/setup.sql | 16 ++++++++ tests/postgres/error.rs | 2 +- tests/postgres/setup.sql | 2 +- 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 tests/mysql/error.rs diff --git a/Cargo.toml b/Cargo.toml index 625f683f07..e92c64fc93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -266,6 +266,11 @@ name = "mysql-macros" path = "tests/mysql/macros.rs" required-features = ["mysql", "macros"] +[[test]] +name = "mysql-error" +path = "tests/mysql/error.rs" +required-features = ["mysql"] + [[test]] name = "mysql-test-attr" path = "tests/mysql/test-attr.rs" diff --git a/tests/mysql/error.rs b/tests/mysql/error.rs new file mode 100644 index 0000000000..19c8e55a59 --- /dev/null +++ b/tests/mysql/error.rs @@ -0,0 +1,80 @@ +use sqlx::{error::ErrorKind, mysql::MySql, Connection, Executor, Transaction}; +use sqlx_test::new; + +async fn with_test_row(conn: &mut Transaction<'_, MySql>) -> anyhow::Result<()> { + sqlx::query!("INSERT INTO tweet(id, text, owner_id) VALUES (1, 'Foo', 1)") + .execute(conn) + .await?; + Ok(()) +} + +#[sqlx_macros::test] +async fn it_fails_with_unique_violation() -> anyhow::Result<()> { + let mut conn = new::().await?; + let mut tx = conn.begin().await?; + with_test_row(&mut tx).await.unwrap(); + + let res: Result<_, sqlx::Error> = sqlx::query("INSERT INTO tweet VALUES (1, NOW(), 'Foo', 1);") + .execute(&mut tx) + .await; + let err = res.unwrap_err(); + + let err = err.into_database_error().unwrap(); + + assert_eq!(err.kind(), Some(ErrorKind::UniqueViolation)); + + Ok(()) +} + +#[sqlx_macros::test] +async fn it_fails_with_foreign_key_violation() -> anyhow::Result<()> { + let mut conn = new::().await?; + let mut tx = conn.begin().await?; + + let res: Result<_, sqlx::Error> = + sqlx::query("INSERT INTO tweet_reply (tweet_id, text) VALUES (1, 'Reply!');") + .execute(&mut tx) + .await; + let err = res.unwrap_err(); + + let err = err.into_database_error().unwrap(); + + assert_eq!(err.kind(), Some(ErrorKind::ForeignKeyViolation)); + + Ok(()) +} + +#[sqlx_macros::test] +async fn it_fails_with_not_null_violation() -> anyhow::Result<()> { + let mut conn = new::().await?; + let mut tx = conn.begin().await?; + + let res: Result<_, sqlx::Error> = sqlx::query("INSERT INTO tweet (text) VALUES (null);") + .execute(&mut tx) + .await; + let err = res.unwrap_err(); + + let err = err.into_database_error().unwrap(); + + assert_eq!(err.kind(), Some(ErrorKind::NotNullViolation)); + + Ok(()) +} + +#[sqlx_macros::test] +async fn it_fails_with_check_violation() -> anyhow::Result<()> { + let mut conn = new::().await?; + let mut tx = conn.begin().await?; + + let res: Result<_, sqlx::Error> = + sqlx::query("INSERT INTO products VALUES (1, 'Product 1', 0);") + .execute(&mut tx) + .await; + let err = res.unwrap_err(); + + let err = err.into_database_error().unwrap(); + + assert_eq!(err.kind(), Some(ErrorKind::CheckViolation)); + + Ok(()) +} diff --git a/tests/mysql/setup.sql b/tests/mysql/setup.sql index 17b351432c..733d90c12e 100644 --- a/tests/mysql/setup.sql +++ b/tests/mysql/setup.sql @@ -6,3 +6,19 @@ CREATE TABLE tweet text TEXT NOT NULL, owner_id BIGINT ); + +CREATE TABLE tweet_reply +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tweet_id BIGINT NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW(), + text TEXT NOT NULL, + owner_id BIGINT, + CONSTRAINT tweet_id_fk FOREIGN KEY (tweet_id) REFERENCES tweet(id) +); + +CREATE TABLE products ( + product_no INTEGER, + name TEXT, + price NUMERIC CHECK (price > 0) +); diff --git a/tests/postgres/error.rs b/tests/postgres/error.rs index 53625b4e96..9adc57bd9a 100644 --- a/tests/postgres/error.rs +++ b/tests/postgres/error.rs @@ -32,7 +32,7 @@ async fn it_fails_with_foreign_key_violation() -> anyhow::Result<()> { let mut tx = conn.begin().await?; let res: Result<_, sqlx::Error> = - sqlx::query("INSERT INTO tweet_reply (tweet, text) VALUES (1, 'Reply!');") + sqlx::query("INSERT INTO tweet_reply (tweet_id, text) VALUES (1, 'Reply!');") .execute(&mut tx) .await; let err = res.unwrap_err(); diff --git a/tests/postgres/setup.sql b/tests/postgres/setup.sql index 535a004fe7..56edaf99fd 100644 --- a/tests/postgres/setup.sql +++ b/tests/postgres/setup.sql @@ -24,7 +24,7 @@ CREATE TABLE tweet CREATE TABLE tweet_reply ( id BIGSERIAL PRIMARY KEY, - tweet BIGINT REFERENCES tweet(id), + tweet_id BIGINT NOT NULL REFERENCES tweet(id), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), text TEXT NOT NULL, owner_id BIGINT