Newwebshop/tests/Integration/AdminControllerTest.php

390 lines
14 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Integration-Tests für Admin-Controller
*
* @author Webshop System
* @license GPL v3
*/
namespace Tests\Integration;
use PHPUnit\Framework\TestCase;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
class AdminControllerTest extends TestCase
{
private $conn;
private $adminSession;
protected function setUp(): void
{
// Test-Datenbank-Verbindung
$connectionParams = [
'dbname' => getenv('DB_DATABASE') ?: 'freeshop_test',
'user' => getenv('DB_USERNAME') ?: 'freeshop_user',
'password' => getenv('DB_PASSWORD') ?: 'freeshop_password',
'host' => getenv('DB_HOST') ?: 'db',
'driver' => 'pdo_mysql',
'port' => getenv('DB_PORT') ?: 3306,
'charset' => 'utf8mb4',
];
try {
$this->conn = DriverManager::getConnection($connectionParams);
$this->setupTestData();
$this->adminSession = $this->createAdminSession();
} catch (Exception $e) {
$this->markTestSkipped('Datenbankverbindung nicht verfügbar: ' . $e->getMessage());
}
}
protected function tearDown(): void
{
if ($this->conn) {
$this->cleanupTestData();
}
}
private function setupTestData()
{
// Admin-User erstellen
$this->conn->executeStatement('
INSERT INTO ws_user (username, email, password, role, active)
VALUES (?, ?, ?, ?, ?)
', ['admin_test', 'admin@test.com', password_hash('test123', PASSWORD_DEFAULT), 'admin', 1]);
// Test-Kategorie erstellen
$this->conn->executeStatement('
INSERT INTO ws_category (name, description, active)
VALUES (?, ?, ?)
', ['Test Kategorie', 'Test Beschreibung', 1]);
// Test-Produkte erstellen
$this->conn->executeStatement('
INSERT INTO ws_product (name, description, price, category_id, active)
VALUES (?, ?, ?, ?, ?)
', ['Test Produkt 1', 'Test Beschreibung 1', 19.99, 1, 1]);
}
private function cleanupTestData()
{
$this->conn->executeStatement('DELETE FROM ws_product WHERE name LIKE ?', ['Test Produkt%']);
$this->conn->executeStatement('DELETE FROM ws_category WHERE name = ?', ['Test Kategorie']);
$this->conn->executeStatement('DELETE FROM ws_user WHERE username = ?', ['admin_test']);
}
private function createAdminSession()
{
// Simuliere Admin-Session
return [
'user_id' => 1,
'username' => 'admin_test',
'role' => 'admin',
'authenticated' => true
];
}
public function testAdminLoginSuccess()
{
// Simuliere POST-Request für Login
$_POST['username'] = 'admin_test';
$_POST['password'] = 'test123';
// Login-Logik simulieren
$stmt = $this->conn->prepare('SELECT * FROM ws_user WHERE username = ? AND active = 1');
$stmt->execute(['admin_test']);
$user = $stmt->fetchAssociative();
$this->assertNotNull($user);
$this->assertEquals('admin_test', $user['username']);
$this->assertEquals('admin', $user['role']);
$this->assertTrue(password_verify('test123', $user['password']));
}
public function testAdminLoginFailure()
{
// Simuliere POST-Request für Login mit falschem Passwort
$_POST['username'] = 'admin_test';
$_POST['password'] = 'wrong_password';
// Login-Logik simulieren
$stmt = $this->conn->prepare('SELECT * FROM ws_user WHERE username = ? AND active = 1');
$stmt->execute(['admin_test']);
$user = $stmt->fetchAssociative();
$this->assertNotNull($user);
$this->assertFalse(password_verify('wrong_password', $user['password']));
}
public function testAdminDashboardAccess()
{
// Simuliere Admin-Dashboard-Zugriff
$this->assertTrue($this->adminSession['authenticated']);
$this->assertEquals('admin', $this->adminSession['role']);
// Dashboard-Daten laden
$stmt = $this->conn->prepare('SELECT COUNT(*) as product_count FROM ws_product WHERE active = 1');
$stmt->execute();
$productCount = $stmt->fetchAssociative()['product_count'];
$stmt = $this->conn->prepare('SELECT COUNT(*) as category_count FROM ws_category WHERE active = 1');
$stmt->execute();
$categoryCount = $stmt->fetchAssociative()['category_count'];
$this->assertGreaterThan(0, $productCount);
$this->assertGreaterThan(0, $categoryCount);
}
public function testProductCRUDOperations()
{
// CREATE - Produkt erstellen
$productData = [
'name' => 'Integration Test Produkt',
'description' => 'Test Beschreibung',
'price' => 25.99,
'category_id' => 1,
'active' => 1
];
$stmt = $this->conn->prepare('
INSERT INTO ws_product (name, description, price, category_id, active)
VALUES (?, ?, ?, ?, ?)
');
$result = $stmt->execute([
$productData['name'],
$productData['description'],
$productData['price'],
$productData['category_id'],
$productData['active']
]);
$this->assertTrue($result);
// READ - Produkt abrufen
$stmt = $this->conn->prepare('SELECT * FROM ws_product WHERE name = ?');
$stmt->execute([$productData['name']]);
$product = $stmt->fetchAssociative();
$this->assertNotNull($product);
$this->assertEquals($productData['name'], $product['name']);
$this->assertEquals($productData['price'], $product['price']);
// UPDATE - Produkt aktualisieren
$stmt = $this->conn->prepare('
UPDATE ws_product
SET name = ?, price = ?
WHERE id = ?
');
$result = $stmt->execute(['Aktualisiertes Test Produkt', 29.99, $product['id']]);
$this->assertTrue($result);
// Prüfen ob Update erfolgreich war
$stmt = $this->conn->prepare('SELECT * FROM ws_product WHERE id = ?');
$stmt->execute([$product['id']]);
$updatedProduct = $stmt->fetchAssociative();
$this->assertEquals('Aktualisiertes Test Produkt', $updatedProduct['name']);
$this->assertEquals(29.99, $updatedProduct['price']);
// DELETE - Produkt löschen
$stmt = $this->conn->prepare('DELETE FROM ws_product WHERE id = ?');
$result = $stmt->execute([$product['id']]);
$this->assertTrue($result);
// Prüfen ob Produkt gelöscht wurde
$stmt = $this->conn->prepare('SELECT * FROM ws_product WHERE id = ?');
$stmt->execute([$product['id']]);
$deletedProduct = $stmt->fetchAssociative();
$this->assertFalse($deletedProduct);
}
public function testCategoryCRUDOperations()
{
// CREATE - Kategorie erstellen
$categoryData = [
'name' => 'Integration Test Kategorie',
'description' => 'Test Kategorie Beschreibung',
'active' => 1
];
$stmt = $this->conn->prepare('
INSERT INTO ws_category (name, description, active)
VALUES (?, ?, ?)
');
$result = $stmt->execute([
$categoryData['name'],
$categoryData['description'],
$categoryData['active']
]);
$this->assertTrue($result);
// READ - Kategorie abrufen
$stmt = $this->conn->prepare('SELECT * FROM ws_category WHERE name = ?');
$stmt->execute([$categoryData['name']]);
$category = $stmt->fetchAssociative();
$this->assertNotNull($category);
$this->assertEquals($categoryData['name'], $category['name']);
// UPDATE - Kategorie aktualisieren
$stmt = $this->conn->prepare('
UPDATE ws_category
SET name = ?, description = ?
WHERE id = ?
');
$result = $stmt->execute(['Aktualisierte Test Kategorie', 'Neue Beschreibung', $category['id']]);
$this->assertTrue($result);
// Prüfen ob Update erfolgreich war
$stmt = $this->conn->prepare('SELECT * FROM ws_category WHERE id = ?');
$stmt->execute([$category['id']]);
$updatedCategory = $stmt->fetchAssociative();
$this->assertEquals('Aktualisierte Test Kategorie', $updatedCategory['name']);
$this->assertEquals('Neue Beschreibung', $updatedCategory['description']);
// DELETE - Kategorie löschen
$stmt = $this->conn->prepare('DELETE FROM ws_category WHERE id = ?');
$result = $stmt->execute([$category['id']]);
$this->assertTrue($result);
// Prüfen ob Kategorie gelöscht wurde
$stmt = $this->conn->prepare('SELECT * FROM ws_category WHERE id = ?');
$stmt->execute([$category['id']]);
$deletedCategory = $stmt->fetchAssociative();
$this->assertFalse($deletedCategory);
}
public function testOrderManagement()
{
// Test-Bestellung erstellen
$orderData = [
'customer_name' => 'Test Kunde',
'customer_email' => 'kunde@test.com',
'total_amount' => 59.97,
'status' => 'pending',
'created_at' => date('Y-m-d H:i:s')
];
$stmt = $this->conn->prepare('
INSERT INTO ws_order (customer_name, customer_email, total_amount, status, created_at)
VALUES (?, ?, ?, ?, ?)
');
$result = $stmt->execute([
$orderData['customer_name'],
$orderData['customer_email'],
$orderData['total_amount'],
$orderData['status'],
$orderData['created_at']
]);
$this->assertTrue($result);
// Bestellung abrufen
$stmt = $this->conn->prepare('SELECT * FROM ws_order WHERE customer_email = ?');
$stmt->execute([$orderData['customer_email']]);
$order = $stmt->fetchAssociative();
$this->assertNotNull($order);
$this->assertEquals($orderData['customer_name'], $order['customer_name']);
$this->assertEquals($orderData['total_amount'], $order['total_amount']);
// Bestellstatus aktualisieren
$stmt = $this->conn->prepare('
UPDATE ws_order
SET status = ?
WHERE id = ?
');
$result = $stmt->execute(['shipped', $order['id']]);
$this->assertTrue($result);
// Prüfen ob Status-Update erfolgreich war
$stmt = $this->conn->prepare('SELECT * FROM ws_order WHERE id = ?');
$stmt->execute([$order['id']]);
$updatedOrder = $stmt->fetchAssociative();
$this->assertEquals('shipped', $updatedOrder['status']);
// Bestellung löschen
$stmt = $this->conn->prepare('DELETE FROM ws_order WHERE id = ?');
$result = $stmt->execute([$order['id']]);
$this->assertTrue($result);
}
public function testSettingsManagement()
{
// Einstellungen abrufen
$stmt = $this->conn->prepare('SELECT * FROM ws_configuration');
$stmt->execute();
$configurations = $stmt->fetchAllAssociative();
$this->assertGreaterThan(0, count($configurations));
// Einstellung aktualisieren
$stmt = $this->conn->prepare('
UPDATE ws_configuration
SET value = ?
WHERE name = ?
');
$result = $stmt->execute(['Test Shop Name', 'shop_name']);
$this->assertTrue($result);
// Prüfen ob Update erfolgreich war
$stmt = $this->conn->prepare('SELECT * FROM ws_configuration WHERE name = ?');
$stmt->execute(['shop_name']);
$config = $stmt->fetchAssociative();
if ($config) {
$this->assertEquals('Test Shop Name', $config['value']);
}
}
public function testSecurityValidation()
{
// Test SQL-Injection-Schutz
$maliciousInput = "'; DROP TABLE ws_product; --";
$stmt = $this->conn->prepare('SELECT * FROM ws_product WHERE name = ?');
$stmt->execute([$maliciousInput]);
$result = $stmt->fetchAssociative();
// Sollte keine Exception werfen und sicher sein
$this->assertFalse($result);
// Test XSS-Schutz
$xssInput = '<script>alert("XSS")</script>';
$stmt = $this->conn->prepare('
INSERT INTO ws_product (name, description, price, category_id, active)
VALUES (?, ?, ?, ?, ?)
');
$result = $stmt->execute([$xssInput, 'Test', 19.99, 1, 1]);
$this->assertTrue($result);
// Prüfen ob Input sicher gespeichert wurde
$stmt = $this->conn->prepare('SELECT * FROM ws_product WHERE name = ?');
$stmt->execute([$xssInput]);
$product = $stmt->fetchAssociative();
$this->assertNotNull($product);
$this->assertEquals($xssInput, $product['name']);
// Test-Daten aufräumen
$stmt = $this->conn->prepare('DELETE FROM ws_product WHERE name = ?');
$stmt->execute([$xssInput]);
}
}