< Summary - Backend C Tests - Coverage Report (WSL)

Information
Class: inventory_service_c
Assembly: src.backend.database
File(s): ./src/backend/database/inventory_service.c
Line coverage
84%
Covered lines: 60
Uncovered lines: 11
Coverable lines: 71
Total lines: 160
Line coverage: 84.5%
Branch coverage
66%
Covered branches: 16
Total branches: 24
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 2/18/2026 - 10:50:55 PM Line coverage: 84.5% (60/71) Branch coverage: 66.6% (16/24) Total lines: 160 2/18/2026 - 10:50:55 PM Line coverage: 84.5% (60/71) Branch coverage: 66.6% (16/24) Total lines: 160

File(s)

./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
 121#endif  // TEST_MODE
 122
 123
 124// ====================================================================
 125// MOCK IMPLEMENTATIONS FOR TESTING
 126// ====================================================================
 127
 128#ifdef TEST_MODE
 129
 130int get_all_inventory(InventoryItem *items, int max_count) {
 131  if (!items || max_count <= 0)
 132    return 0;
 133
 134  items[0].id = 1;
 135  strcpy(items[0].part_name, "Motor Oil");
 136  strcpy(items[0].sku, "MO-001");
 137  items[0].quantity = 50;
 138  items[0].min_stock_level = 10;
 139  items[0].unit_cost = 25.5;
 140  strcpy(items[0].last_restocked_at, "2025-01-01");
 141  return 1;
 142}
 143
 144bool update_inventory_quantity(int part_id, int change) {
 145  (void)part_id;
 146  (void)change;
 147  return true;
 148}
 149
 150int get_low_stock_items(InventoryItem *items, int max_count) {
 151  if (!items || max_count <= 0)
 152    return 0;
 153
 154  items[0].id = 2;
 155  items[0].quantity = 5;
 156  items[0].min_stock_level = 10;
 157  return 1;
 158}
 159
 160#endif

Methods/Properties