< Summary - Backend C Tests - Coverage Report

Information
Class: inventory_service_c
Assembly: src.backend.database
File(s): C:\Users\yagiz\Desktop\Project\smart-maintenance-suite\src\backend\database\inventory_service.c
Line coverage
70%
Covered lines: 72
Uncovered lines: 30
Coverable lines: 102
Total lines: 186
Line coverage: 70.5%
Branch coverage
52%
Covered branches: 18
Total branches: 34
Branch coverage: 52.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_all_inventory71.43%0087.8%
update_inventory_quantity50%0071.43%
get_low_stock_items42.86%0066.67%
add_inventory_item0%0018.18%

File(s)

C:\Users\yagiz\Desktop\Project\smart-maintenance-suite\src\backend\database\inventory_service.c

#LineLine coverage
 1#include "inventory_service.h"
 2#include "db_connection.h"
 3#include "logger.h"
 4#include <stdio.h>
 5#include <stdlib.h>
 6#include <string.h>
 7
 8#ifndef TEST_MODE
 9
 310int get_all_inventory(InventoryItem *out_items, int max_items) {
 311  if (!out_items || max_items <= 0)
 112    return 0;
 13
 214  DBConnection *conn_wrapper = db_pool_acquire();
 15
 216  if (!conn_wrapper)
 117    return 0;
 18
 119  const char *query =
 20    "SELECT id, part_name, sku, quantity, min_stock_level, unit_cost, "
 21    "to_char(last_restocked_at, 'YYYY-MM-DD HH24:MI:SS') "
 22    "FROM inventory ORDER BY id ASC;";
 123  PGresult *res = PQexec(conn_wrapper->pg_conn, query);
 24
 125  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
 026    LOG_ERROR("Failed to fetch inventory: %s",
 27              PQerrorMessage(conn_wrapper->pg_conn));
 028    PQclear(res);
 029    db_pool_release(conn_wrapper);
 030    return 0;
 31  }
 32
 133  int rows = PQntuples(res);
 134  int count = (rows < max_items) ? rows : max_items;
 35
 336  for (int i = 0; i < count; i++) {
 237    out_items[i].id = atoi(PQgetvalue(res, i, 0));
 238    strncpy(out_items[i].part_name, PQgetvalue(res, i, 1), 99);
 239    out_items[i].part_name[99] = '\0';
 240    strncpy(out_items[i].sku, PQgetvalue(res, i, 2), 49);
 241    out_items[i].sku[49] = '\0';
 242    out_items[i].quantity = atoi(PQgetvalue(res, i, 3));
 243    out_items[i].min_stock_level = atoi(PQgetvalue(res, i, 4));
 244    out_items[i].unit_cost = atof(PQgetvalue(res, i, 5));
 245    strncpy(out_items[i].last_restocked_at,
 246            PQgetvalue(res, i, 6), 31);
 247    out_items[i].last_restocked_at[31] = '\0';
 48  }
 49
 150  PQclear(res);
 151  db_pool_release(conn_wrapper);
 152  return count;
 53}
 54
 155bool update_inventory_quantity(int part_id, int change) {
 156  DBConnection *conn_wrapper = db_pool_acquire();
 57
 158  if (!conn_wrapper)
 059    return false;
 60
 61  char query[256];
 162  snprintf(query, sizeof(query),
 63           "UPDATE inventory SET quantity = quantity + (%d) WHERE id = %d;",
 64           change, part_id);
 165  PGresult *res = PQexec(conn_wrapper->pg_conn, query);
 166  bool success = (PQresultStatus(res) == PGRES_COMMAND_OK);
 67
 168  if (!success) {
 069    LOG_ERROR("Failed to update inventory: %s",
 70              PQerrorMessage(conn_wrapper->pg_conn));
 71  }
 72
 173  PQclear(res);
 174  db_pool_release(conn_wrapper);
 175  return success;
 76}
 77
 178int get_low_stock_items(InventoryItem *out_items, int max_items) {
 179  if (!out_items || max_items <= 0)
 080    return 0;
 81
 182  DBConnection *conn_wrapper = db_pool_acquire();
 83
 184  if (!conn_wrapper)
 085    return 0;
 86
 187  const char *query =
 88    "SELECT id, part_name, sku, quantity, min_stock_level, unit_cost, "
 89    "to_char(last_restocked_at, 'YYYY-MM-DD HH24:MI:SS') "
 90    "FROM inventory WHERE quantity < min_stock_level;";
 191  PGresult *res = PQexec(conn_wrapper->pg_conn, query);
 92
 193  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
 094    PQclear(res);
 095    db_pool_release(conn_wrapper);
 096    return 0;
 97  }
 98
 199  int rows = PQntuples(res);
 1100  int count = (rows < max_items) ? rows : max_items;
 101
 3102  for (int i = 0; i < count; i++) {
 2103    out_items[i].id = atoi(PQgetvalue(res, i, 0));
 2104    strncpy(out_items[i].part_name, PQgetvalue(res, i, 1), 99);
 2105    out_items[i].part_name[99] = '\0';
 2106    strncpy(out_items[i].sku, PQgetvalue(res, i, 2), 49);
 2107    out_items[i].sku[49] = '\0';
 2108    out_items[i].quantity = atoi(PQgetvalue(res, i, 3));
 2109    out_items[i].min_stock_level = atoi(PQgetvalue(res, i, 4));
 2110    out_items[i].unit_cost = atof(PQgetvalue(res, i, 5));
 2111    strncpy(out_items[i].last_restocked_at,
 2112            PQgetvalue(res, i, 6), 31);
 2113    out_items[i].last_restocked_at[31] = '\0';
 114  }
 115
 1116  PQclear(res);
 1117  db_pool_release(conn_wrapper);
 1118  return count;
 119}
 120
 0121bool add_inventory_item(const char *name, const char *sku, int quantity, int min_stock, double cost) {
 0122  DBConnection *conn_wrapper = db_pool_acquire();
 123
 0124  if (!conn_wrapper) return false;
 125
 126  char query[1024];
 0127  snprintf(query, sizeof(query),
 128           "INSERT INTO inventory (part_name, sku, quantity, min_stock_level, unit_cost) "
 129           "VALUES ('%s', '%s', %d, %d, %.2f);",
 130           name, sku, quantity, min_stock, cost);
 0131  PGresult *res = PQexec(conn_wrapper->pg_conn, query);
 0132  bool success = (PQresultStatus(res) == PGRES_COMMAND_OK);
 0133  PQclear(res);
 0134  db_pool_release(conn_wrapper);
 0135  return success;
 136}
 137
 138#endif  // TEST_MODE
 139
 140
 141// ====================================================================
 142// MOCK IMPLEMENTATIONS FOR TESTING
 143// ====================================================================
 144
 145#ifdef TEST_MODE
 146
 4147int get_all_inventory(InventoryItem *items, int max_count) {
 4148  if (!items || max_count <= 0)
 0149    return 0;
 150
 4151  items[0].id = 1;
 4152  strcpy(items[0].part_name, "Motor Oil");
 4153  strcpy(items[0].sku, "MO-001");
 4154  items[0].quantity = 50;
 4155  items[0].min_stock_level = 10;
 4156  items[0].unit_cost = 25.5;
 4157  strcpy(items[0].last_restocked_at, "2025-01-01");
 4158  return 1;
 159}
 160
 0161bool update_inventory_quantity(int part_id, int change) {
 162  (void)part_id;
 163  (void)change;
 0164  return true;
 165}
 166
 0167int get_low_stock_items(InventoryItem *items, int max_count) {
 0168  if (!items || max_count <= 0)
 0169    return 0;
 170
 0171  items[0].id = 2;
 0172  items[0].quantity = 5;
 0173  items[0].min_stock_level = 10;
 0174  return 1;
 175}
 176
 1177bool add_inventory_item(const char *name, const char *sku, int quantity, int min_stock, double cost) {
 178  (void)name;
 179  (void)sku;
 180  (void)quantity;
 181  (void)min_stock;
 182  (void)cost;
 1183  return true;
 184}
 185
 186#endif