Add schema bootstrap for API tests and update GitHub Actions environment setup
- Introduced `ApiSchemaBootstrap` class to ensure database schema for API tests. - Modified GitHub Actions workflow to include schema bootstrapping configuration. - Switched to Xdebug for test coverage in workflows and adjusted `ini-values` accordingly. - Improved environment variable handling in `config.php` for enhanced runtime flexibility.
This commit is contained in:
@@ -17,9 +17,9 @@ jobs:
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
extensions: mysqli, curl, openssl, json, redis, pcov
|
||||
coverage: pcov
|
||||
ini-values: pcov.enabled=1
|
||||
extensions: mysqli, curl, openssl, json, redis, xdebug
|
||||
coverage: xdebug
|
||||
ini-values: variables_order=EGPCS,xdebug.mode=coverage
|
||||
|
||||
- name: Resolve dependencies
|
||||
working-directory: services/nginx/app
|
||||
@@ -72,6 +72,7 @@ jobs:
|
||||
with:
|
||||
php-version: '8.2'
|
||||
extensions: mysqli, curl, openssl, json, redis
|
||||
ini-values: variables_order=EGPCS
|
||||
|
||||
- name: Resolve dependencies
|
||||
working-directory: services/nginx/app
|
||||
@@ -139,6 +140,7 @@ jobs:
|
||||
with:
|
||||
php-version: '8.2'
|
||||
extensions: mysqli, curl, openssl, json, redis
|
||||
ini-values: variables_order=EGPCS
|
||||
|
||||
- name: Resolve dependencies
|
||||
working-directory: services/nginx/app
|
||||
@@ -148,6 +150,7 @@ jobs:
|
||||
working-directory: services/nginx/app
|
||||
env:
|
||||
RUN_API_TESTS: '1'
|
||||
API_TEST_BOOTSTRAP_SCHEMA: '1'
|
||||
USE_ENV: 'true'
|
||||
DEBUG: '0'
|
||||
ENCRYPTION_KEY: test-key
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
<?php global $CONFIG_DB, $DEBUG, $ENCRYPTION_KEY, $CORS, $ECONOMIC_API, $WORDPRESS_STATIC_TOKEN, $EMAIL_WASH_CERTIFICATE_TOKEN, $MINIO, $REDIS_CONFIG, $WORDPRESS_API_URL, $SLACK_DEFAULT_WEBHOOK, $ALL_CONFIG;
|
||||
|
||||
$runtimeEnvironment = getenv();
|
||||
if (is_array($runtimeEnvironment) && $runtimeEnvironment !== []) {
|
||||
$_ENV = array_merge($runtimeEnvironment, $_ENV ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the environment variables are set (If we are running in a Docker container)
|
||||
*/
|
||||
if (isset($_ENV['USE_ENV']) && $_ENV['USE_ENV'] === 'true') {
|
||||
if (strtolower(trim((string)($_ENV['USE_ENV'] ?? getenv('USE_ENV') ?? ''))) === 'true') {
|
||||
$readEnv = static function (string $key, string $default = ''): string {
|
||||
$value = $_ENV[$key] ?? getenv($key);
|
||||
if ($value === false || $value === null) {
|
||||
@@ -39,16 +44,16 @@ if (isset($_ENV['USE_ENV']) && $_ENV['USE_ENV'] === 'true') {
|
||||
'REDIS_CONFIG_USER' => 'user',
|
||||
'REDIS_CONFIG_DEBUG_PASSWORD' => 'debug_password'
|
||||
];
|
||||
$dbTarget = strtolower(trim((string)($_ENV['CONFIG_DB_TARGET'] ?? 'live')));
|
||||
$dbTarget = strtolower(trim($readEnv('CONFIG_DB_TARGET', 'live')));
|
||||
if ($dbTarget !== 'live' && $dbTarget !== 'debug') {
|
||||
$dbTarget = 'live';
|
||||
}
|
||||
|
||||
$resolveDbValue = function (string $key) use ($dbTarget): string {
|
||||
$resolveDbValue = function (string $key) use ($dbTarget, $readEnv): string {
|
||||
$liveKey = 'CONFIG_DB_' . $key;
|
||||
$debugKey = 'CONFIG_DB_DEBUG_' . $key;
|
||||
$liveValue = (string)($_ENV[$liveKey] ?? '');
|
||||
$debugValue = (string)($_ENV[$debugKey] ?? '');
|
||||
$liveValue = $readEnv($liveKey);
|
||||
$debugValue = $readEnv($debugKey);
|
||||
|
||||
if ($dbTarget === 'debug' && $debugValue !== '') {
|
||||
return $debugValue;
|
||||
@@ -71,15 +76,15 @@ if (isset($_ENV['USE_ENV']) && $_ENV['USE_ENV'] === 'true') {
|
||||
/**
|
||||
* Set the debug configuration
|
||||
*/
|
||||
$DEBUG = $_ENV['DEBUG'];
|
||||
$DEBUG = $readEnv('DEBUG');
|
||||
/**
|
||||
* Set the encryption key
|
||||
*/
|
||||
$ENCRYPTION_KEY = $_ENV['ENCRYPTION_KEY'];
|
||||
$ENCRYPTION_KEY = $readEnv('ENCRYPTION_KEY');
|
||||
/**
|
||||
* Set the CORS configuration
|
||||
*/
|
||||
$CORS = $_ENV['CORS'];
|
||||
$CORS = $readEnv('CORS');
|
||||
/**
|
||||
* Set the economic API configuration
|
||||
*/
|
||||
@@ -102,32 +107,32 @@ if (isset($_ENV['USE_ENV']) && $_ENV['USE_ENV'] === 'true') {
|
||||
/**
|
||||
* Set the WordPress static token
|
||||
*/
|
||||
$WORDPRESS_STATIC_TOKEN = $_ENV['WORDPRESS_STATIC_TOKEN'];
|
||||
$WORDPRESS_STATIC_TOKEN = $readEnv('WORDPRESS_STATIC_TOKEN');
|
||||
/**
|
||||
* Set the email wash certificate token
|
||||
*/
|
||||
$EMAIL_WASH_CERTIFICATE_TOKEN = $_ENV['EMAIL_WASH_CERTIFICATE_TOKEN'];
|
||||
$EMAIL_WASH_CERTIFICATE_TOKEN = $readEnv('EMAIL_WASH_CERTIFICATE_TOKEN');
|
||||
/**
|
||||
* Set the WordPress API URL
|
||||
*/
|
||||
$WORDPRESS_API_URL = $_ENV['WORDPRESS_API_URL'];
|
||||
$WORDPRESS_API_URL = $readEnv('WORDPRESS_API_URL');
|
||||
/**
|
||||
* Set the Minio configuration
|
||||
*/
|
||||
$MINIO = [
|
||||
'endpoint' => $_ENV['MINIO_ENDPOINT'],
|
||||
'access_key' => $_ENV['MINIO_ACCESS_KEY'],
|
||||
'secret_key' => $_ENV['MINIO_SECRET_KEY']
|
||||
'endpoint' => $readEnv('MINIO_ENDPOINT'),
|
||||
'access_key' => $readEnv('MINIO_ACCESS_KEY'),
|
||||
'secret_key' => $readEnv('MINIO_SECRET_KEY')
|
||||
];
|
||||
/**
|
||||
* Set the Slack default webhook
|
||||
*/
|
||||
$SLACK_DEFAULT_WEBHOOK = $_ENV['SLACK_DEFAULT_WEBHOOK'];
|
||||
$resolveRedisValue = function (string $key) use ($dbTarget): string {
|
||||
$SLACK_DEFAULT_WEBHOOK = $readEnv('SLACK_DEFAULT_WEBHOOK');
|
||||
$resolveRedisValue = function (string $key) use ($dbTarget, $readEnv): string {
|
||||
$liveKey = 'REDIS_CONFIG_' . $key;
|
||||
$debugKey = 'REDIS_CONFIG_DEBUG_' . $key;
|
||||
$liveValue = (string)($_ENV[$liveKey] ?? '');
|
||||
$debugValue = (string)($_ENV[$debugKey] ?? '');
|
||||
$liveValue = $readEnv($liveKey);
|
||||
$debugValue = $readEnv($debugKey);
|
||||
|
||||
if ($dbTarget === 'debug' && $debugValue !== '') {
|
||||
return $debugValue;
|
||||
@@ -148,7 +153,7 @@ if (isset($_ENV['USE_ENV']) && $_ENV['USE_ENV'] === 'true') {
|
||||
];
|
||||
|
||||
// Set the timezone
|
||||
$timezone = $_ENV['CONFIG_TIMEZONE'] ?? 'Europe/Copenhagen';
|
||||
$timezone = $readEnv('CONFIG_TIMEZONE', 'Europe/Copenhagen');
|
||||
date_default_timezone_set($timezone);
|
||||
|
||||
// Set the all config
|
||||
|
||||
@@ -0,0 +1,443 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Support\Api;
|
||||
|
||||
use mysqli;
|
||||
use RuntimeException;
|
||||
|
||||
final class ApiSchemaBootstrap
|
||||
{
|
||||
public function __construct(private readonly mysqli $db)
|
||||
{
|
||||
}
|
||||
|
||||
public function ensureSchema(): void
|
||||
{
|
||||
foreach ($this->tableStatements() as $name => $sql) {
|
||||
$this->execute($name, $sql);
|
||||
}
|
||||
|
||||
foreach ($this->viewStatements() as $name => $sql) {
|
||||
$this->execute($name, $sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function tableStatements(): array
|
||||
{
|
||||
return [
|
||||
'groups' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `groups` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'users' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`customer_number` INT NOT NULL,
|
||||
`display_name` VARCHAR(255) NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`phone_country_code` INT NULL,
|
||||
`phone` BIGINT NULL,
|
||||
`password` VARCHAR(255) NULL,
|
||||
`group_id` INT NOT NULL DEFAULT 0,
|
||||
`xlvask_customer_id` VARCHAR(255) NULL,
|
||||
`sms_notifications_enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`email_notifications_enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`wash_certificate_email` VARCHAR(255) NULL,
|
||||
`two_factor_enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`two_factor_secret` VARCHAR(255) NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_users_customer_number` (`customer_number`),
|
||||
KEY `idx_users_group_id` (`group_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'groups_permissions' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `groups_permissions` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`group_id` INT NOT NULL,
|
||||
`permission` VARCHAR(191) NOT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_groups_permissions_group_id` (`group_id`),
|
||||
KEY `idx_groups_permissions_permission` (`permission`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'departments' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `departments` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`economic_department_id` INT NOT NULL DEFAULT 0,
|
||||
`slack_webhook` TEXT NULL,
|
||||
`dimension` INT NOT NULL DEFAULT 0,
|
||||
`branding` INT NOT NULL DEFAULT 0,
|
||||
`visible` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`latitude` DECIMAL(10,7) NOT NULL DEFAULT 0,
|
||||
`longitude` DECIMAL(10,7) NOT NULL DEFAULT 0,
|
||||
`order_priority` INT NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_departments_visible` (`visible`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'department_variables' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `department_variables` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`department_id` INT NOT NULL,
|
||||
`variable` VARCHAR(191) NOT NULL,
|
||||
`value` TEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_department_variables_department_id` (`department_id`),
|
||||
KEY `idx_department_variables_variable` (`variable`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'department_gates' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `department_gates` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`department` INT NOT NULL,
|
||||
`is_entrance` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`is_exit` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`config` LONGTEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_department_gates_department` (`department`),
|
||||
KEY `idx_department_gates_deleted_at` (`deleted_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'categories' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `categories` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'department_categories' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `department_categories` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`department_id` INT NOT NULL,
|
||||
`category_id` INT NOT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_department_categories_department_id` (`department_id`),
|
||||
KEY `idx_department_categories_category_id` (`category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'collected_order_invoices' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `collected_order_invoices` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`customer_number` INT NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`notes` TEXT NULL,
|
||||
`processor` INT NOT NULL DEFAULT 0,
|
||||
`external_id` VARCHAR(255) NULL,
|
||||
`booked_invoice_id` INT NULL,
|
||||
`po_number` VARCHAR(255) NULL,
|
||||
`error_message` TEXT NULL,
|
||||
`closed_at` DATETIME NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_collected_order_invoices_customer_number` (`customer_number`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'orders' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `orders` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`customer_id` INT NOT NULL,
|
||||
`cashier_id` INT NOT NULL DEFAULT 0,
|
||||
`department_id` INT NOT NULL,
|
||||
`reference` VARCHAR(255) NOT NULL,
|
||||
`notes` TEXT NULL,
|
||||
`reg_1` VARCHAR(32) NULL,
|
||||
`reg_2` VARCHAR(32) NULL,
|
||||
`reg_3` VARCHAR(32) NULL,
|
||||
`invoice_collection_id` INT NULL,
|
||||
`booking_id` INT NULL,
|
||||
`wash_id` VARCHAR(255) NULL,
|
||||
`lane` INT NULL,
|
||||
`po` VARCHAR(255) NULL,
|
||||
`safety_seal` VARCHAR(255) NULL,
|
||||
`using_hand_held` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`include_in_invoice` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`completed_at` DATETIME NULL,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_orders_customer_id` (`customer_id`),
|
||||
KEY `idx_orders_department_id` (`department_id`),
|
||||
KEY `idx_orders_invoice_collection_id` (`invoice_collection_id`),
|
||||
KEY `idx_orders_reg_1` (`reg_1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'order_items' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `order_items` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`order_id` INT NOT NULL,
|
||||
`product_id` INT NOT NULL,
|
||||
`reference` VARCHAR(255) NULL,
|
||||
`notes` TEXT NULL,
|
||||
`cashier_id` INT NOT NULL DEFAULT 0,
|
||||
`price` INT NOT NULL DEFAULT 0,
|
||||
`quantity` INT NOT NULL DEFAULT 1,
|
||||
`related_item_id` INT NULL,
|
||||
`include_in_invoice` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_order_items_order_id` (`order_id`),
|
||||
KEY `idx_order_items_deleted_at` (`deleted_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'customer_vehicles' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `customer_vehicles` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`customer_id` INT NOT NULL,
|
||||
`type` INT NOT NULL DEFAULT 0,
|
||||
`reg` VARCHAR(32) NOT NULL,
|
||||
`wash_subscription` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`notes` TEXT NULL,
|
||||
`reference` VARCHAR(255) NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_customer_vehicles_customer_id` (`customer_id`),
|
||||
KEY `idx_customer_vehicles_reg` (`reg`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'customer_vehicles_addons' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `customer_vehicles_addons` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`vehicle_id` INT NOT NULL,
|
||||
`addon_id` INT NOT NULL,
|
||||
`amount` INT NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_customer_vehicles_addons_vehicle_id` (`vehicle_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'subusers' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `subusers` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`username` VARCHAR(255) NULL,
|
||||
`password` VARCHAR(255) NULL,
|
||||
`name` VARCHAR(255) NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`phone_country_code` INT NULL,
|
||||
`phone` BIGINT NULL,
|
||||
`two_factor_enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`two_factor_secret` VARCHAR(255) NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`suspended_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_subusers_username` (`username`),
|
||||
KEY `idx_subusers_phone` (`phone`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'subuser_grants' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `subuser_grants` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`billing_customer_number` INT NOT NULL,
|
||||
`subuser` INT NOT NULL,
|
||||
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`note` TEXT NULL,
|
||||
`permissions` LONGTEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_subuser_grants_subuser` (`subuser`),
|
||||
KEY `idx_subuser_grants_billing_customer_number` (`billing_customer_number`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'tokens' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `tokens` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NOT NULL,
|
||||
`type` VARCHAR(64) NOT NULL,
|
||||
`description` VARCHAR(255) NULL,
|
||||
`token` VARCHAR(255) NOT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uniq_tokens_token` (`token`),
|
||||
KEY `idx_tokens_user_id` (`user_id`),
|
||||
KEY `idx_tokens_type` (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'customer_attributes' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `customer_attributes` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NOT NULL,
|
||||
`attribute` VARCHAR(191) NOT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_customer_attributes_user_id` (`user_id`),
|
||||
KEY `idx_customer_attributes_attribute` (`attribute`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'module_config' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `module_config` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`module` VARCHAR(191) NOT NULL,
|
||||
`variable` VARCHAR(191) NOT NULL,
|
||||
`value` LONGTEXT NULL,
|
||||
`type` VARCHAR(64) NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uniq_module_config_module_variable` (`module`, `variable`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'user_key_value_pairs' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `user_key_value_pairs` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NOT NULL,
|
||||
`var` VARCHAR(191) NOT NULL,
|
||||
`val` LONGTEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_user_key_value_pairs_user_id` (`user_id`),
|
||||
KEY `idx_user_key_value_pairs_var` (`var`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'price_overrides' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `price_overrides` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NOT NULL,
|
||||
`is_category` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`product_or_category_id` VARCHAR(191) NOT NULL,
|
||||
`percentage` INT NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_price_overrides_user_id` (`user_id`),
|
||||
KEY `idx_price_overrides_lookup` (`user_id`, `is_category`, `product_or_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'products_options' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `products_options` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`product_id` INT NOT NULL,
|
||||
`option_id` INT NOT NULL,
|
||||
`name` VARCHAR(255) NULL,
|
||||
`min` INT NULL,
|
||||
`max` INT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_products_options_product_id` (`product_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'economic_module_orders' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `economic_module_orders` (
|
||||
`id` INT NOT NULL,
|
||||
`invoice_draft_id` INT NULL,
|
||||
`invoice_id` INT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'stripe_module_orders' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `stripe_module_orders` (
|
||||
`id` INT NOT NULL,
|
||||
`invoice_id` VARCHAR(255) NULL,
|
||||
`customer_id` VARCHAR(255) NULL,
|
||||
`email_sent` DATETIME NULL,
|
||||
`url` TEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'stripe_payment_intents' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `stripe_payment_intents` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`order_id` INT NOT NULL,
|
||||
`payment_intent_id` VARCHAR(255) NOT NULL,
|
||||
`client_secret` VARCHAR(255) NULL,
|
||||
`data` LONGTEXT NULL,
|
||||
`reader_id` VARCHAR(255) NULL,
|
||||
`tax_percentage` INT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_stripe_payment_intents_order_id` (`order_id`),
|
||||
KEY `idx_stripe_payment_intents_payment_intent_id` (`payment_intent_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
'object_attachments' => <<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `object_attachments` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`object_type` VARCHAR(191) NOT NULL,
|
||||
`object_id` INT NOT NULL,
|
||||
`content` LONGTEXT NULL,
|
||||
`created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_object_attachments_lookup` (`object_type`, `object_id`),
|
||||
KEY `idx_object_attachments_deleted_at` (`deleted_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function viewStatements(): array
|
||||
{
|
||||
return [
|
||||
'orders_with_invoice_collections' => <<<'SQL'
|
||||
CREATE OR REPLACE VIEW `orders_with_invoice_collections` AS
|
||||
SELECT
|
||||
o.*,
|
||||
coi.closed_at,
|
||||
coi.booked_invoice_id,
|
||||
coi.processor
|
||||
FROM `orders` o
|
||||
LEFT JOIN `collected_order_invoices` coi ON coi.id = o.invoice_collection_id
|
||||
SQL,
|
||||
];
|
||||
}
|
||||
|
||||
private function execute(string $name, string $sql): void
|
||||
{
|
||||
if ($this->db->query($sql) === false) {
|
||||
throw new RuntimeException(
|
||||
sprintf('Failed to bootstrap API test schema for "%s": %s', $name, (string)$this->db->error)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ final class ApiTestRuntime
|
||||
private ?ApiFixtures $fixtures = null;
|
||||
private ?ApiCleanup $cleanup = null;
|
||||
private bool $bootstrapped = false;
|
||||
private bool $schemaBootstrapped = false;
|
||||
private bool $shutdownRegistered = false;
|
||||
private string $baseUrl = self::DEFAULT_BASE_URL;
|
||||
private bool $usesExternalBaseUrl = false;
|
||||
@@ -38,6 +39,7 @@ final class ApiTestRuntime
|
||||
|
||||
try {
|
||||
$this->bootstrapEnvironment();
|
||||
$this->bootstrapSchemaIfRequested();
|
||||
} catch (Throwable $throwable) {
|
||||
return $throwable->getMessage();
|
||||
}
|
||||
@@ -53,6 +55,7 @@ final class ApiTestRuntime
|
||||
public function beginTest(): void
|
||||
{
|
||||
$this->bootstrapEnvironment();
|
||||
$this->bootstrapSchemaIfRequested();
|
||||
$this->cleanup = new ApiCleanup();
|
||||
$this->fixtures = new ApiFixtures($this->db(), $this->redis(), $this->cleanup);
|
||||
$this->ensureServerIsRunning();
|
||||
@@ -133,6 +136,7 @@ final class ApiTestRuntime
|
||||
}
|
||||
|
||||
$this->bootstrapped = false;
|
||||
$this->schemaBootstrapped = false;
|
||||
}
|
||||
|
||||
private function bootstrapEnvironment(): void
|
||||
@@ -182,6 +186,20 @@ final class ApiTestRuntime
|
||||
$this->bootstrapped = true;
|
||||
}
|
||||
|
||||
private function bootstrapSchemaIfRequested(): void
|
||||
{
|
||||
if ($this->schemaBootstrapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getenv('API_TEST_BOOTSTRAP_SCHEMA') !== '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
(new ApiSchemaBootstrap($this->db()))->ensureSchema();
|
||||
$this->schemaBootstrapped = true;
|
||||
}
|
||||
|
||||
private function ensureServerIsRunning(): void
|
||||
{
|
||||
if ($this->usesExternalBaseUrl) {
|
||||
|
||||
@@ -6,6 +6,7 @@ require_once __DIR__ . '/Api/ApiCleanup.php';
|
||||
require_once __DIR__ . '/Api/ApiResponse.php';
|
||||
require_once __DIR__ . '/Api/ApiClient.php';
|
||||
require_once __DIR__ . '/Api/ApiServer.php';
|
||||
require_once __DIR__ . '/Api/ApiSchemaBootstrap.php';
|
||||
require_once __DIR__ . '/Api/ApiFixtures.php';
|
||||
require_once __DIR__ . '/Api/ApiTestRuntime.php';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user