weitere Bearibeitung
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Core\Autoloader;
|
||||
use App\Core\Csrf;
|
||||
use App\Core\DatabaseSqlite;
|
||||
use App\Core\Env;
|
||||
use App\Core\Session;
|
||||
use App\Core\View;
|
||||
|
||||
/**
|
||||
* Test-Bootstrap für SQLite-basierte Entwicklungsumgebung.
|
||||
* Lädt .env.test oder .env, erstellt eine SQLite-Datenbank in storage/.
|
||||
*/
|
||||
|
||||
$rootPath = dirname(__DIR__);
|
||||
|
||||
require_once $rootPath . '/app/Support/helpers.php';
|
||||
require_once $rootPath . '/app/Core/Autoloader.php';
|
||||
|
||||
Autoloader::register($rootPath);
|
||||
|
||||
// Versuche zuerst .env.test, dann .env
|
||||
$envFile = $rootPath . '/.env.test';
|
||||
if (!is_file($envFile)) {
|
||||
$envFile = $rootPath . '/.env';
|
||||
}
|
||||
Env::load($envFile);
|
||||
|
||||
// Test-Konfiguration überschreiben falls .env.test Werte setzt
|
||||
$config = require $rootPath . '/config/app.php';
|
||||
$config['env'] = 'development';
|
||||
$config['debug'] = true;
|
||||
$config['name'] = 'Kaffeekasse DEV';
|
||||
$config['allow_public_registration'] = true;
|
||||
$config['rate_limits']['login']['max_attempts'] = 50;
|
||||
$config['rate_limits']['login']['window_seconds'] = 3600;
|
||||
$config['rate_limits']['registration']['max_attempts'] = 50;
|
||||
$config['rate_limits']['registration']['window_seconds'] = 3600;
|
||||
|
||||
date_default_timezone_set($config['timezone']);
|
||||
|
||||
// Session-Konfiguration NUR setzen, wenn noch keine Session aktiv
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
ini_set('session.use_strict_mode', '1');
|
||||
ini_set('session.use_only_cookies', '1');
|
||||
ini_set('session.use_trans_sid', '0');
|
||||
session_name('kaffeekasse_session_test');
|
||||
}
|
||||
|
||||
$session = new Session();
|
||||
$session->start();
|
||||
$csrf = new Csrf($session);
|
||||
|
||||
// SQLite-Datenbank
|
||||
$dbConfig = [
|
||||
'path' => $rootPath . '/storage/test.sqlite',
|
||||
];
|
||||
$database = new DatabaseSqlite($dbConfig);
|
||||
$database->initializeSchema();
|
||||
|
||||
// Prüfe, ob ein Plattform-Admin existiert, sonst lege Demo-Admin an
|
||||
try {
|
||||
$pdo = $database->pdo();
|
||||
$adminStmt = $pdo->query("SELECT id FROM users WHERE platform_role = 'platform_admin' LIMIT 1");
|
||||
if (!$adminStmt->fetchColumn()) {
|
||||
$pdo->prepare(
|
||||
"INSERT INTO users (full_name, email, password_hash, platform_role)
|
||||
VALUES (:full_name, :email, :password_hash, 'platform_admin')"
|
||||
)->execute([
|
||||
'full_name' => 'Admin',
|
||||
'email' => 'admin@demo.kaffeekasse',
|
||||
'password_hash' => password_hash('admin12345678', PASSWORD_BCRYPT),
|
||||
]);
|
||||
echo "[Test-Bootstrap] Demo-Admin angelegt: admin@demo.kaffeekasse / admin12345678\n";
|
||||
}
|
||||
|
||||
// Prüfe, ob ein Demo-Tenant existiert, sonst lege an
|
||||
$tenantStmt = $pdo->query("SELECT id FROM tenants WHERE slug = 'demo' LIMIT 1");
|
||||
if (!$tenantStmt->fetchColumn()) {
|
||||
$now = gmdate('Y-m-d H:i:s');
|
||||
|
||||
// Tenant
|
||||
$pdo->prepare(
|
||||
"INSERT INTO tenants (name, slug, plan, status, created_at)
|
||||
VALUES (:name, :slug, :plan, :status, :created_at)"
|
||||
)->execute([
|
||||
'name' => 'Demo-Tenant',
|
||||
'slug' => 'demo',
|
||||
'plan' => 'team',
|
||||
'status' => 'active',
|
||||
'created_at' => $now,
|
||||
]);
|
||||
$tenantId = (int) $pdo->lastInsertId();
|
||||
|
||||
// Owner-Benutzer
|
||||
$pdo->prepare(
|
||||
"INSERT INTO users (full_name, email, password_hash, platform_role)
|
||||
VALUES (:full_name, :email, :password_hash, 'user')"
|
||||
)->execute([
|
||||
'full_name' => 'Demo-Owner',
|
||||
'email' => 'owner@demo.kaffeekasse',
|
||||
'password_hash' => password_hash('owner12345678', PASSWORD_BCRYPT),
|
||||
]);
|
||||
$ownerUserId = (int) $pdo->lastInsertId();
|
||||
|
||||
// Member-Benutzer
|
||||
$pdo->prepare(
|
||||
"INSERT INTO users (full_name, email, password_hash, platform_role)
|
||||
VALUES (:full_name, :email, :password_hash, 'user')"
|
||||
)->execute([
|
||||
'full_name' => 'Demo-Member',
|
||||
'email' => 'member@demo.kaffeekasse',
|
||||
'password_hash' => password_hash('member12345678', PASSWORD_BCRYPT),
|
||||
]);
|
||||
$memberUserId = (int) $pdo->lastInsertId();
|
||||
|
||||
// Memberships
|
||||
$pdo->prepare(
|
||||
"INSERT INTO tenant_memberships (tenant_id, user_id, role, status)
|
||||
VALUES (:tenant_id, :user_id, :role, 'active')"
|
||||
)->execute(['tenant_id' => $tenantId, 'user_id' => $ownerUserId, 'role' => 'owner']);
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO tenant_memberships (tenant_id, user_id, role, status)
|
||||
VALUES (:tenant_id, :user_id, :role, 'active')"
|
||||
)->execute(['tenant_id' => $tenantId, 'user_id' => $memberUserId, 'role' => 'member']);
|
||||
|
||||
// Settings
|
||||
$pdo->prepare(
|
||||
"INSERT INTO tenant_settings (tenant_id, currency_code, default_product_price_cents, allow_self_service, allow_paper_lists, allow_rfid)
|
||||
VALUES (:tenant_id, 'EUR', 120, 1, 1, 0)"
|
||||
)->execute(['tenant_id' => $tenantId]);
|
||||
|
||||
// Members
|
||||
$pdo->prepare(
|
||||
"INSERT INTO members (tenant_id, user_id, display_name, email, status)
|
||||
VALUES (:tenant_id, :user_id, :display_name, :email, 'active')"
|
||||
)->execute(['tenant_id' => $tenantId, 'user_id' => $ownerUserId, 'display_name' => 'Demo-Owner', 'email' => 'owner@demo.kaffeekasse']);
|
||||
|
||||
$memberMemberIdStmt = $pdo->prepare(
|
||||
"INSERT INTO members (tenant_id, user_id, display_name, email, status)
|
||||
VALUES (:tenant_id, :user_id, :display_name, :email, 'active')"
|
||||
);
|
||||
$memberMemberIdStmt->execute(['tenant_id' => $tenantId, 'user_id' => $memberUserId, 'display_name' => 'Demo-Member', 'email' => 'member@demo.kaffeekasse']);
|
||||
$memberMemberId = (int) $pdo->lastInsertId();
|
||||
|
||||
// Capture Sources
|
||||
foreach ([
|
||||
['digital_self', 'Digitale Selbstbuchung', 'digital'],
|
||||
['paper_sheet', 'Papierliste / Nacherfassung', 'paper'],
|
||||
['admin_backoffice', 'Backoffice-Buchung', 'admin'],
|
||||
['rfid_reader', 'RFID-Geraet', 'rfid'],
|
||||
] as [$code, $sourceName, $channel]) {
|
||||
$pdo->prepare(
|
||||
"INSERT INTO capture_sources (tenant_id, code, name, channel, is_system)
|
||||
VALUES (:tenant_id, :code, :name, :channel, 1)"
|
||||
)->execute(['tenant_id' => $tenantId, 'code' => $code, 'name' => $sourceName, 'channel' => $channel]);
|
||||
}
|
||||
|
||||
// Products
|
||||
foreach ([
|
||||
['Kaffee', 120],
|
||||
['Espresso', 120],
|
||||
['Tee', 100],
|
||||
] as [$productName, $priceCents]) {
|
||||
$pdo->prepare(
|
||||
"INSERT INTO products (tenant_id, name, sku, is_active)
|
||||
VALUES (:tenant_id, :name, :sku, 1)"
|
||||
)->execute(['tenant_id' => $tenantId, 'name' => $productName, 'sku' => strtolower(str_replace(' ', '-', $productName))]);
|
||||
$productId = (int) $pdo->lastInsertId();
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO product_prices (tenant_id, product_id, price_cents, valid_from)
|
||||
VALUES (:tenant_id, :product_id, :price_cents, :valid_from)"
|
||||
)->execute(['tenant_id' => $tenantId, 'product_id' => $productId, 'price_cents' => $priceCents, 'valid_from' => $now]);
|
||||
}
|
||||
|
||||
echo "[Test-Bootstrap] Demo-Tenant 'demo' angelegt\n";
|
||||
echo " Owner-Login: owner@demo.kaffeekasse / owner12345678\n";
|
||||
echo " Member-Login: member@demo.kaffeekasse / member12345678\n";
|
||||
echo " Tenant-Pfad: /t/demo\n";
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "[Test-Bootstrap] Fehler: " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
$view = new View($rootPath, [
|
||||
'config' => $config,
|
||||
'session' => $session,
|
||||
'csrf' => $csrf,
|
||||
]);
|
||||
|
||||
return [
|
||||
'rootPath' => $rootPath,
|
||||
'config' => $config,
|
||||
'session' => $session,
|
||||
'csrf' => $csrf,
|
||||
'database' => $database,
|
||||
'view' => $view,
|
||||
];
|
||||
Reference in New Issue
Block a user