Skip to content

Commit

Permalink
Merge pull request #191 from Divyesh000/testoder-product
Browse files Browse the repository at this point in the history
write tests for Order and OrderProduct models
  • Loading branch information
creme332 authored May 21, 2024
2 parents cec9a2a + bc11eea commit db062cc
Show file tree
Hide file tree
Showing 4 changed files with 434 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/models/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function save(): bool
$update_stock_stm = $conn->prepare($query);

foreach ($this->line_items as $line_item) {
if (!$line_item->validate()) {
if (!empty($line_item->validate())) {
// line item contains invalid attributes
$conn->rollBack();
$conn = null;
Expand Down Expand Up @@ -192,9 +192,14 @@ public function save(): bool
*
* @param OrderProduct $orderProduct
* @return void
* @throws Exception
*/
public function addLineItem(OrderProduct $orderProduct): void
{
$errors = $orderProduct->validate();
if (!empty($errors)) {
throw new Exception("Invalid line item: " . json_encode($errors));
}
$this->line_items[] = $orderProduct;
}

Expand Down
27 changes: 27 additions & 0 deletions src/models/Store.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,30 @@ public function validate(): array
return $errors;
}

/**
* Increments stock of a product
* @param int $product_id ID of product whose stock will increase
* @param int $quantity Amount by which stock increases
* @return bool Success or not
*/
public function addProductStock(int $product_id, int $quantity): bool
{
$conn = self::connect();
$query = "INSERT INTO store_product (store_id, product_id, stock_level) VALUES (:store_id, :product_id, :quantity)
ON DUPLICATE KEY UPDATE stock_level = stock_level + :quantity";
$params = ['store_id' => $this->store_id, 'product_id' => $product_id, 'quantity' => $quantity];
$stm = $conn->prepare($query);
$stm->execute($params);

$rows_affected = $stm->rowCount();
$conn = null;
return $rows_affected === 1;
}

/**
* @param int $product_id
* @return int Stock level of product. Defaults to 0.
*/
public function getProductStock(int $product_id): int
{
$query = "SELECT stock_level FROM store_product WHERE store_id = :store_id AND product_id = :product_id;";
Expand All @@ -159,6 +183,9 @@ public function getProductStock(int $product_id): int
}
}

/**
* @return Product[] Array of products which store sells.
*/
public function getProducts(): array
{
$query = "SELECT p.* FROM product p JOIN store_product sp ON p.product_id = sp.product_id WHERE sp.store_id = :store_id;";
Expand Down
160 changes: 160 additions & 0 deletions tests/OrderProductTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use Steamy\Model\Order;
use Steamy\Model\OrderProduct;
use Steamy\Model\Store;
use Steamy\Model\Client;
use Steamy\Model\Product;
use Steamy\Core\Database;
use Steamy\Model\Location;

class OrderProductTest extends TestCase
{
use Database;

private ?Order $dummy_order;
private ?Client $client;
private ?Store $dummy_store;
private ?Product $dummy_product;
private array $line_items = [];

/**
* @throws Exception
*/
public function setUp(): void
{
parent::setUp();

// Initialize a dummy store object for testing
$this->dummy_store = new Store(
phone_no: "987654321", // Phone number
address: new Location(
street: "Augus",
city: "Flacq",
district_id: 2,
latitude: 60,
longitude: 60
)
);

$success = $this->dummy_store->save();
if (!$success) {
$errors = $this->dummy_store->validate();
$error_msg = "Unable to save store to database. ";
if (!empty($errors)) {
$error_msg .= "Errors: " . implode(',', $errors);
} else {
$error_msg .= "Attributes seem to be ok as per validate().";
}

throw new Exception($error_msg);
}

// Create a dummy client
$this->client = new Client(
"[email protected]",
"John",
"Doe",
"john_doe",
"password",
new Location("Royal", "Curepipe", 1, 50, 50)
);
$success = $this->client->save();
if (!$success) {
throw new Exception('Unable to save client');
}

// Create a dummy product
$this->dummy_product = new Product(
"Latte",
50,
"latte.jpeg",
"A delicious latte",
"Beverage",
5.0,
"A cup of latte",
new DateTime()
);
$success = $this->dummy_product->save();
if (!$success) {
throw new Exception('Unable to save product');
}

// Update stock level for the product
$this->dummy_store->addProductStock($this->dummy_product->getProductID(), 10);

// Create dummy order line items
$this->line_items = [
new OrderProduct($this->dummy_product->getProductID(), "medium", "oat", 2, 5.0)
];

// Create a dummy order
$this->dummy_order = new Order(
$this->dummy_store->getStoreID(),
$this->client->getUserID()
);

// Add line items to the order
foreach ($this->line_items as $line_item) {
$this->dummy_order->addLineItem($line_item);
}

$success = $this->dummy_order->save();
if (!$success) {
throw new Exception('Unable to save order');
}
}

public function tearDown(): void
{
$this->dummy_order = null;
$this->client = null;
$this->dummy_store = null;
$this->dummy_product = null;
$this->line_items = [];

// Clear all data from relevant tables
self::query(
'DELETE FROM order_product; DELETE FROM `order`; DELETE FROM client; DELETE FROM user; DELETE FROM store_product; DELETE FROM product; DELETE FROM store;'
);
}

public function testValidate(): void
{
$invalidOrderProduct = new OrderProduct(
product_id: $this->dummy_product->getProductID(),
cup_size: "extra large", // Invalid cup size
milk_type: "invalid milk", // Invalid milk type
quantity: -1, // Invalid quantity
unit_price: -2.99, // Invalid unit price
order_id: $this->dummy_order->getOrderID()
);

$errors = $invalidOrderProduct->validate();

$this->assertArrayHasKey('quantity', $errors);
$this->assertArrayHasKey('cup_size', $errors);
$this->assertArrayHasKey('milk_type', $errors);
$this->assertArrayHasKey('unit_price', $errors);
}

public function testGetByID(): void
{
// Assuming getByID is a method that retrieves an OrderProduct by order ID and product ID
$retrievedOrderProduct = OrderProduct::getByID(
$this->dummy_order->getOrderID(),
$this->dummy_product->getProductID()
);

$this->assertNotNull($retrievedOrderProduct);
$this->assertEquals($this->dummy_order->getOrderID(), $retrievedOrderProduct->getOrderID());
$this->assertEquals($this->dummy_product->getProductID(), $retrievedOrderProduct->getProductID());
$this->assertEquals("medium", $retrievedOrderProduct->getCupSize());
$this->assertEquals("oat", $retrievedOrderProduct->getMilkType());
$this->assertEquals(2, $retrievedOrderProduct->getQuantity());
$this->assertEquals(5.0, $retrievedOrderProduct->getUnitPrice());
}
}
Loading

0 comments on commit db062cc

Please sign in to comment.