Files
carei.pagedev.pl/softra-test.php
2026-03-23 12:32:36 +01:00

221 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
/**
* Softra API smoke test:
* 1) reads credentials from .env (format: "key: value")
* 2) authenticates (/account/auth)
* 3) fetches branches (/branch/list)
* 4) fetches car models (/car/model/list?includeBrandDetails=true)
*
* Usage:
* php softra-test.php
* php softra-test.php branch=BYDGOSZCZ from=2026-03-30T12:00:00 to=2026-04-02T12:00:00 category=
*/
function fail(string $message, int $code = 1): never
{
if (PHP_SAPI !== 'cli') {
http_response_code(500);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['ok' => false, 'error' => $message], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit($code);
}
if (defined('STDERR')) {
fwrite(STDERR, $message . PHP_EOL);
} else {
echo $message . PHP_EOL;
}
exit($code);
}
function parseEnvFile(string $path): array
{
if (!is_file($path)) {
fail("Brak pliku .env: {$path}");
}
$result = [];
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines === false) {
fail("Nie mogę odczytać pliku .env");
}
foreach ($lines as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#')) {
continue;
}
// supports:
// key: value
// key=value
$sepPos = strpos($line, ':');
if ($sepPos === false) {
$sepPos = strpos($line, '=');
}
if ($sepPos === false) {
continue;
}
$key = trim(substr($line, 0, $sepPos));
$value = trim(substr($line, $sepPos + 1));
$value = trim($value, "\"'");
if ($key !== '') {
$result[strtolower($key)] = $value;
}
}
return $result;
}
function parseInputArgs(?array $argv = null): array
{
$args = [];
if (PHP_SAPI === 'cli') {
$argv = $argv ?? [];
foreach (array_slice($argv, 1) as $arg) {
$pos = strpos($arg, '=');
if ($pos === false) {
continue;
}
$k = strtolower(trim(substr($arg, 0, $pos)));
$v = trim(substr($arg, $pos + 1));
$args[$k] = $v;
}
return $args;
}
foreach ($_GET as $k => $v) {
if (!is_string($k)) {
continue;
}
$args[strtolower($k)] = is_string($v) ? trim($v) : '';
}
return $args;
}
function requestJson(string $method, string $url, ?array $payload = null, array $headers = []): array
{
$ch = curl_init($url);
if ($ch === false) {
fail('Nie udało się zainicjować cURL');
}
$httpHeaders = array_merge(['Accept: application/json'], $headers);
if ($payload !== null) {
$httpHeaders[] = 'Content-Type: application/json';
}
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => strtoupper($method),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $httpHeaders,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 15,
]);
if ($payload !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
$raw = curl_exec($ch);
$err = curl_error($ch);
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($raw === false) {
fail("Błąd połączenia cURL: {$err}");
}
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
$decoded = ['raw' => $raw];
}
return [
'status' => $status,
'body' => $decoded,
'raw' => $raw,
];
}
$env = parseEnvFile(__DIR__ . DIRECTORY_SEPARATOR . '.env');
$args = parseInputArgs($argv ?? null);
$baseUrl = rtrim($env['url'] ?? '', '/');
$username = $env['username'] ?? '';
$password = $env['password'] ?? '';
if ($baseUrl === '' || $username === '' || $password === '') {
fail('W .env muszą być pola: url, username, password');
}
$authRes = requestJson('POST', $baseUrl . '/account/auth', [
'login' => $username,
'password' => $password,
]);
if ($authRes['status'] !== 200 || empty($authRes['body']['token'])) {
fail("Auth nieudany (HTTP {$authRes['status']}): {$authRes['raw']}");
}
$token = (string) $authRes['body']['token'];
$authHeader = ['Authorization: Bearer ' . $token];
$branchesRes = requestJson('GET', $baseUrl . '/branch/list', null, $authHeader);
if ($branchesRes['status'] !== 200 || !is_array($branchesRes['body'])) {
fail("Pobranie oddziałów nieudane (HTTP {$branchesRes['status']}): {$branchesRes['raw']}");
}
$branches = $branchesRes['body'];
if (count($branches) === 0) {
fail('API działa, ale /branch/list zwróciło pustą listę oddziałów');
}
$branch = $args['branch'] ?? ($branches[0]['relatedBranchName'] ?? $branches[0]['name'] ?? '');
if ($branch === '') {
fail('Nie udało się ustalić branchName (podaj ręcznie: branch=NAZWA)');
}
$from = $args['from'] ?? (new DateTimeImmutable('+7 days'))->format('Y-m-d\TH:i:s');
$to = $args['to'] ?? (new DateTimeImmutable('+10 days'))->format('Y-m-d\TH:i:s');
$category = $args['category'] ?? ''; // empty = all categories
$modelsRes = requestJson(
'POST',
$baseUrl . '/car/model/list?includeBrandDetails=true',
[
'dateFrom' => $from,
'dateTo' => $to,
'branchName' => $branch,
'category' => $category,
],
$authHeader
);
if ($modelsRes['status'] !== 200 || !is_array($modelsRes['body'])) {
fail("Pobranie listy aut nieudane (HTTP {$modelsRes['status']}): {$modelsRes['raw']}");
}
$models = $modelsRes['body'];
$result = [
'ok' => true,
'baseUrl' => $baseUrl,
'branch' => $branch,
'dateFrom' => $from,
'dateTo' => $to,
'modelsCount' => count($models),
'models' => $models,
];
if (PHP_SAPI !== 'cli') {
header('Content-Type: application/json; charset=utf-8');
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;