// rocie - An enterprise grocery management system // // Copyright (C) 2026 Benedikt Peetz // SPDX-License-Identifier: GPL-3.0-or-later // // This file is part of Rocie. // // You should have received a copy of the License along with this program. // If not, see . use rocie_client::{ apis::{ api_get_auth_inventory_api::amount_by_id, api_set_auth_barcode_api::{buy_barcode, consume_barcode}, api_set_auth_product_api::{associate_barcode, register_product}, api_set_auth_unit_api::register_unit, api_set_auth_unit_property_api::register_unit_property, }, models::{Barcode, BarcodeId, ProductStub, UnitAmount, UnitPropertyStub, UnitStub}, }; use crate::{ _testenv::init::function_name, products::create_associated_barcode, testenv::{TestEnv, log::request}, }; #[tokio::test] async fn test_barcode_buy() { let env = TestEnv::new(function_name!()).await; let barcode_id = 23; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode(&env, "Liter", "Milk", "Volume", unit_value, barcode_id).await; request!(env, buy_barcode(BarcodeId { value: barcode_id }, 1)); let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, unit_value); } #[tokio::test] async fn test_barcode_buy_multiple() { let env = TestEnv::new(function_name!()).await; let barcode_id = 23; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode(&env, "Liter", "Milk", "Volume", unit_value, barcode_id).await; request!(env, buy_barcode(BarcodeId { value: barcode_id }, 5)); let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, unit_value * 5); } #[tokio::test] async fn test_barcode_consume() { let env = TestEnv::new(function_name!()).await; let barcode_id = BarcodeId { value: 23 }; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode( &env, "Liter", "Milk", "Volume", unit_value, barcode_id.value, ) .await; request!(env, buy_barcode(barcode_id, 1)); request!( env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: 1, }, ) ); let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, 0); } #[tokio::test] async fn test_barcode_consume_error() { let env = TestEnv::new(function_name!()).await; let barcode_id = BarcodeId { value: 23 }; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode( &env, "Liter", "Milk", "Volume", unit_value, barcode_id.value, ) .await; request!(env, buy_barcode(barcode_id, 1)); request!( @expect_error "We should not be able to consume more than available." env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: unit_value + 1, }, ) ); // Test, that the error does not actually go into the db. let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, unit_value); } #[tokio::test] async fn test_barcode_consume_error_other() { let env = TestEnv::new(function_name!()).await; let barcode_id = BarcodeId { value: 23 }; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode( &env, "Liter", "Milk", "Volume", unit_value, barcode_id.value, ) .await; request!(env, buy_barcode(barcode_id, 1)); request!( env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: 1, }, ) ); request!( @expect_error "We already consumed everything, we bought" env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: 1, }, ) ); // Test, that the error does not actually go into the db. let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, 0); } #[tokio::test] async fn test_barcode_multiple_buy_and_consume() { let env = TestEnv::new(function_name!()).await; let barcode_id = BarcodeId { value: 23 }; let unit_value = 1; let (unit_id, product_id) = create_associated_barcode( &env, "Liter", "Milk", "Volume", unit_value, barcode_id.value, ) .await; request!(env, buy_barcode(barcode_id, 1)); request!(env, buy_barcode(barcode_id, 1)); env.log("Bought both barcodes"); request!( env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: 1, }, ) ); env.log("Consumed first barcode"); request!( env, consume_barcode( barcode_id, UnitAmount { unit: unit_id, value: 1, }, ) ); env.log("Consumed second barcode"); let product_amount = request!(env, amount_by_id(product_id)); assert_eq!(product_amount.product_id, product_id); assert_eq!(product_amount.amount.unit, unit_id); assert_eq!(product_amount.amount.value, 0); } #[tokio::test] async fn test_barcode_fill_up() { let env = TestEnv::new(function_name!()).await; let milk_id = BarcodeId { value: 23 }; let bread_id = BarcodeId { value: 24 }; let nuts_id = BarcodeId { value: 25 }; let _ = create_associated_barcode(&env, "Liter", "Milk", "Volume", 2, milk_id.value).await; let _ = create_associated_barcode(&env, "Kilogram", "Bread", "Mass", 2, bread_id.value).await; let _ = create_associated_barcode(&env, "Piece", "Nut", "Quantity", 2, nuts_id.value).await; request!(env, buy_barcode(milk_id, 1)); request!(env, buy_barcode(bread_id, 1)); request!(env, buy_barcode(nuts_id, 1)); } #[tokio::test] async fn test_barcode_associate_false_unit() { let env = TestEnv::new(function_name!()).await; let unit_property_mass = request!( env, register_unit_property(UnitPropertyStub { description: None, name: "Mass".to_owned() }) ); let unit_property_volume = request!( env, register_unit_property(UnitPropertyStub { description: None, name: "Volume".to_owned() }) ); let product = request!( env, register_product(ProductStub { description: None, name: "Milk".to_owned(), parent: None, unit_property: unit_property_mass, }) ); let unit_mass = request!( env, register_unit(UnitStub { description: None, full_name_plural: "Grams".to_owned(), full_name_singular: "Gram".to_owned(), short_name: "g".to_owned(), unit_property: unit_property_mass }) ); let unit_volume = request!( env, register_unit(UnitStub { description: None, full_name_plural: "Liters".to_owned(), full_name_singular: "Liter".to_owned(), short_name: "L".to_owned(), unit_property: unit_property_volume }) ); let barcode_id_1 = BarcodeId { value: 23 }; let barcode_id_2 = BarcodeId { value: 24 }; let value = 1; request!( env, associate_barcode( product, Barcode { amount: UnitAmount { unit: unit_mass, value, }, id: barcode_id_1, }, ) ); request!(@expect_error "Should not work, as we registered the base product with unit_property_mass" env, associate_barcode( product, Barcode { amount: UnitAmount { unit: unit_volume, value, }, id: barcode_id_2, }, ) ); }