Skip to content

Commit

Permalink
test: add tests for listing invoices
Browse files Browse the repository at this point in the history
  • Loading branch information
Jooakar committed Feb 8, 2024
1 parent d6d41c0 commit fd55629
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/api/invoices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub struct CreateInvoiceAttachment {
}

/// A populated invoice type that is returned to the user
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PopulatedInvoice {
pub id: i32,
pub status: crate::models::InvoiceStatus,
Expand Down
20 changes: 12 additions & 8 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use serde_derive::{Deserialize, Serialize};
// - Is VAT really necessary to account for? I'm leaving it out for now
// - I'm also leaving InvoiceType out, at least for now

#[derive(diesel_derive_enum::DbEnum, Debug, Clone, Copy, Serialize)]
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, Copy, Serialize, Deserialize)]
#[ExistingTypePath = "crate::schema::sql_types::InvoiceStatus"]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum InvoiceStatus {
Expand All @@ -25,7 +25,7 @@ pub enum InvoiceStatus {
}

/// A party of the invoice
#[derive(Identifiable, Queryable, Selectable, Clone, Debug, Serialize)]
#[derive(Identifiable, Queryable, Selectable, Clone, Debug, Serialize, Deserialize)]
#[diesel(table_name = parties)]
pub struct Party {
pub id: i32,
Expand Down Expand Up @@ -83,13 +83,15 @@ pub struct NewInvoice {
}

/// A single row of an invoice
#[derive(Identifiable, Queryable, Selectable, Associations, Clone, Debug, Serialize)]
#[derive(
Identifiable, Queryable, Selectable, Associations, Clone, Debug, Serialize, Deserialize,
)]
#[diesel(belongs_to(Invoice))]
#[diesel(table_name = invoice_rows)]
pub struct InvoiceRow {
#[serde(skip_serializing)]
#[serde(skip_serializing, skip_deserializing)]
pub id: i32,
#[serde(skip_serializing)]
#[serde(skip_serializing, skip_deserializing)]
pub invoice_id: i32,
/// The product can be at most 128 characters
pub product: String,
Expand All @@ -113,13 +115,15 @@ pub struct NewInvoiceRow {
/// The metadata for an invoice attachment
/// The file itself can be requested using its hash and filename
/// => /somepath/{hash}/{filename}
#[derive(Identifiable, Queryable, Selectable, Associations, Clone, Debug, Serialize)]
#[derive(
Identifiable, Queryable, Selectable, Associations, Clone, Debug, Serialize, Deserialize,
)]
#[diesel(belongs_to(Invoice))]
#[diesel(table_name = invoice_attachments)]
pub struct Attachment {
#[serde(skip_serializing)]
#[serde(skip_serializing, skip_deserializing)]
pub id: i32,
#[serde(skip_serializing)]
#[serde(skip_serializing, skip_deserializing)]
pub invoice_id: i32,
/// The filename can be at most 128 characters
pub filename: String,
Expand Down
60 changes: 59 additions & 1 deletion src/tests/invoices.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::api::app;
use crate::api::invoices::{CreateInvoice, CreateInvoiceRow};
use crate::api::invoices::{CreateInvoice, CreateInvoiceRow, PopulatedInvoice};
use crate::models::NewParty;

use axum::http::StatusCode;
Expand Down Expand Up @@ -49,3 +49,61 @@ async fn create() {

assert_eq!(response.status_code(), StatusCode::CREATED);
}

#[tokio::test]
async fn list_all() {
let app = app().with_state(crate::database::new().await);
let server = TestServer::new(app).unwrap();

let response = server.get("/invoices").await;
assert_eq!(response.status_code(), StatusCode::OK);
}

#[tokio::test]
async fn create_list_all() {
let app = app().with_state(crate::database::new().await);

let body = CreateInvoice {
counter_party: NewParty {
name: String::from("Velkoja"),
street: String::from("Otakaari"),
city: String::from("Espoo"),
zip: String::from("02jotain"),
bank_account: String::from("ei ole"),
},
due_date: chrono::Local::now().date_naive(),
rows: vec![
CreateInvoiceRow {
product: String::from("pleikkari"),
quantity: 69,
unit: String::from("kpl"),
unit_price: 4200,
},
CreateInvoiceRow {
product: String::from("xbox"),
quantity: 1,
unit: String::from("kpl"),
unit_price: 4200,
},
CreateInvoiceRow {
product: String::from("nintendo wii"),
quantity: 2,
unit: String::from("kpl"),
unit_price: 4200,
},
],
attachments: vec![],
};

let server = TestServer::new(app).unwrap();
let body = MultipartForm::new().add_text("data", serde_json::to_string(&body).unwrap());

let create_response = server.post("/invoices").multipart(body).await;
assert_eq!(create_response.status_code(), StatusCode::CREATED);

let list_response = server.get("/invoices").await;
assert_eq!(list_response.status_code(), StatusCode::OK);

let result = std::panic::catch_unwind(|| list_response.json::<Vec<PopulatedInvoice>>());
assert!(result.is_ok_and(|invoices| !invoices.is_empty()));
}

0 comments on commit fd55629

Please sign in to comment.