Skip to content

Commit

Permalink
Restructured API tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-k committed Apr 27, 2022
1 parent 6ef0baa commit defe135
Show file tree
Hide file tree
Showing 8 changed files with 577 additions and 560 deletions.
153 changes: 153 additions & 0 deletions tests/api/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use crate::helpers::spawn_app;
use auditor::domain::{Component, Record, RecordTest};
use fake::{Fake, Faker};

#[tokio::test]
async fn add_returns_a_200_for_valid_json_data() {
// Arange
let app = spawn_app().await;
let client = reqwest::Client::new();

// Act
for _ in 0..100 {
let body: RecordTest = Faker.fake();

let response = client
.post(&format!("{}/add", &app.address))
.header("Content-Type", "application/json")
.json(&body)
.send()
.await
.expect("Failed to execute request.");

assert_eq!(200, response.status().as_u16());

let saved = sqlx::query_as!(
Record,
r#"SELECT
record_id, site_id, user_id, group_id, components as "components: Vec<Component>",
start_time, stop_time, runtime
FROM accounting
WHERE record_id = $1
"#,
body.record_id.as_ref().unwrap(),
)
.fetch_one(&app.db_pool)
.await
.expect("Failed to fetch data.");

assert_eq!(body, saved);
}
}

#[tokio::test]
async fn add_returns_a_400_for_invalid_json_data() {
// Arange
let app = spawn_app().await;
let client = reqwest::Client::new();

let forbidden_strings: Vec<String> = ['/', '(', ')', '"', '<', '>', '\\', '{', '}']
.into_iter()
.map(|s| format!("test{}test", s))
.collect();

for field in ["record_id", "site_id", "group_id", "user_id"] {
for fs in forbidden_strings.iter() {
// Act
let mut body: RecordTest = Faker.fake();
match field {
"record_id" => body.record_id = Some(fs.clone()),
"site_id" => body.site_id = Some(fs.clone()),
"group_id" => body.group_id = Some(fs.clone()),
"user_id" => body.user_id = Some(fs.clone()),
_ => (),
}

let response = client
.post(&format!("{}/add", &app.address))
.header("Content-Type", "application/json")
.json(&body)
.send()
.await
.expect("Failed to execute request.");

assert_eq!(400, response.status().as_u16());

let saved = sqlx::query!(
r#"SELECT
record_id, site_id, user_id, group_id,
components as "components: Vec<Component>",
start_time, stop_time, runtime
FROM accounting
WHERE record_id = $1
"#,
body.record_id.as_ref().unwrap(),
)
.fetch_all(&app.db_pool)
.await
.expect("Failed to fetch data.");

assert_eq!(saved.len(), 0);
}
}
}

#[tokio::test]
async fn add_returns_a_400_when_data_is_missing() {
// Arrange
let app = spawn_app().await;
let client = reqwest::Client::new();

let record: RecordTest = Faker.fake();

let test_cases = vec![
("record_id is missing", {
let mut r = record.clone();
r.record_id = None;
r
}),
("site_id is missing", {
let mut r = record.clone();
r.site_id = None;
r
}),
("user_id is missing", {
let mut r = record.clone();
r.user_id = None;
r
}),
("group_id is missing", {
let mut r = record.clone();
r.group_id = None;
r
}),
("components is missing", {
let mut r = record.clone();
r.components = None;
r
}),
("start_time is missing", {
let mut r = record.clone();
r.start_time = None;
r
}),
];

for (error_message, invalid_body) in test_cases {
// Act
let response = client
.post(&format!("{}/add", &app.address))
.header("Content-Type", "application/json")
.json(&invalid_body)
.send()
.await
.expect("Failed to execute request.");

assert_eq!(
400,
response.status().as_u16(),
"The API did not fail with 400 Bad Request when the payload was {}.",
error_message
);
}
}
74 changes: 74 additions & 0 deletions tests/api/get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::helpers::spawn_app;
use auditor::domain::{Record, RecordTest};
use fake::{Fake, Faker};

#[tokio::test]
async fn get_returns_a_200_and_list_of_records() {
// Arange
let app = spawn_app().await;
let client = reqwest::Client::new();

// First send a couple of records
let mut test_cases: Vec<RecordTest> = (0..100)
.into_iter()
.map(|_| Faker.fake::<RecordTest>())
.collect();

for case in test_cases.iter() {
let response = client
.post(&format!("{}/add", &app.address))
.header("Content-Type", "application/json")
.json(&case)
.send()
.await
.expect("Failed to execute request.");

assert_eq!(200, response.status().as_u16());
}

let response = client
.get(&format!("{}/get", &app.address))
.send()
.await
.expect("Failed to execute request.");
assert_eq!(200, response.status().as_u16());

let mut received_records = response.json::<Vec<Record>>().await.unwrap();

// make sure they are both sorted
test_cases.sort_by(|a, b| {
a.record_id
.as_ref()
.unwrap()
.cmp(b.record_id.as_ref().unwrap())
});
received_records.sort_by(|a, b| a.record_id.cmp(&b.record_id));

for (i, (record, received)) in test_cases.iter().zip(received_records.iter()).enumerate() {
assert_eq!(
record,
received,
"Check {}: Record {} and {} did not match.",
i,
record.record_id.as_ref().unwrap(),
received.record_id
);
}
}

#[tokio::test]
async fn get_returns_a_200_and_no_records() {
let app = spawn_app().await;
let client = reqwest::Client::new();

let response = client
.get(&format!("{}/get", &app.address))
.send()
.await
.expect("Failed to execute request.");
assert_eq!(200, response.status().as_u16());

let received_records = response.json::<Vec<Record>>().await.unwrap();

assert!(received_records.is_empty());
}
Loading

0 comments on commit defe135

Please sign in to comment.