128 lines
4.6 KiB
PHP
128 lines
4.6 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace App\Tests\Integration\Infrastructure\Channel\Ebay;
|
||
|
|
|
||
|
|
use App\Infrastructure\Channel\Ebay\EbayOAuthClient;
|
||
|
|
use App\Infrastructure\Channel\Ebay\EbayTaxonomyService;
|
||
|
|
use PHPUnit\Framework\TestCase;
|
||
|
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||
|
|
use Symfony\Component\HttpClient\HttpClient;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Integration tests against the eBay Sandbox Taxonomy API.
|
||
|
|
* Uses application token (client_credentials) — no user OAuth needed.
|
||
|
|
*
|
||
|
|
* Requires EBAY_CLIENT_ID, EBAY_CLIENT_SECRET, EBAY_API_BASE_URL,
|
||
|
|
* EBAY_OAUTH_BASE_URL, EBAY_MARKETPLACE_ID in .env.local.
|
||
|
|
*
|
||
|
|
* Run with: bin/test-integration tests/Integration/Infrastructure/Channel/Ebay/
|
||
|
|
*/
|
||
|
|
final class EbayTaxonomyIntegrationTest extends TestCase
|
||
|
|
{
|
||
|
|
private EbayTaxonomyService $taxonomy;
|
||
|
|
private EbayOAuthClient $oauth;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
$clientId = $_SERVER['EBAY_CLIENT_ID'] ?? getenv('EBAY_CLIENT_ID');
|
||
|
|
$clientSecret = $_SERVER['EBAY_CLIENT_SECRET'] ?? getenv('EBAY_CLIENT_SECRET');
|
||
|
|
$apiBaseUrl = $_SERVER['EBAY_API_BASE_URL'] ?? getenv('EBAY_API_BASE_URL');
|
||
|
|
$oauthBaseUrl = $_SERVER['EBAY_OAUTH_BASE_URL'] ?? getenv('EBAY_OAUTH_BASE_URL');
|
||
|
|
$marketplaceId = $_SERVER['EBAY_MARKETPLACE_ID'] ?? getenv('EBAY_MARKETPLACE_ID') ?: 'EBAY_DE';
|
||
|
|
|
||
|
|
if (!$clientId || !$clientSecret || !$apiBaseUrl || !$oauthBaseUrl) {
|
||
|
|
$this->markTestSkipped('EBAY_* env vars not set');
|
||
|
|
}
|
||
|
|
|
||
|
|
$http = HttpClient::create();
|
||
|
|
$cache = new ArrayAdapter();
|
||
|
|
|
||
|
|
$this->oauth = new EbayOAuthClient(
|
||
|
|
$http,
|
||
|
|
$cache,
|
||
|
|
(string) $clientId,
|
||
|
|
(string) $clientSecret,
|
||
|
|
(string) $oauthBaseUrl,
|
||
|
|
);
|
||
|
|
|
||
|
|
$this->taxonomy = new EbayTaxonomyService(
|
||
|
|
$http,
|
||
|
|
$this->oauth,
|
||
|
|
$cache,
|
||
|
|
(string) $apiBaseUrl,
|
||
|
|
(string) $marketplaceId,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_fetches_application_token(): void
|
||
|
|
{
|
||
|
|
$token = $this->oauth->getAccessToken();
|
||
|
|
|
||
|
|
$this->assertNotEmpty($token);
|
||
|
|
$this->assertStringStartsWith('v^1.1', $token);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_fetches_aspects_for_notebooks_category(): void
|
||
|
|
{
|
||
|
|
// 177 = Notebooks & Netbooks in EBAY_DE
|
||
|
|
$aspects = $this->taxonomy->getCategoryAspects('177');
|
||
|
|
|
||
|
|
$this->assertNotEmpty($aspects, 'Category 177 should have aspects');
|
||
|
|
|
||
|
|
// Each aspect must have the expected shape
|
||
|
|
foreach ($aspects as $aspect) {
|
||
|
|
$this->assertArrayHasKey('name', $aspect);
|
||
|
|
$this->assertArrayHasKey('required', $aspect);
|
||
|
|
$this->assertArrayHasKey('values', $aspect);
|
||
|
|
$this->assertIsString($aspect['name']);
|
||
|
|
$this->assertIsBool($aspect['required']);
|
||
|
|
$this->assertIsArray($aspect['values']);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Notebooks should have at least a Prozessor/CPU aspect
|
||
|
|
$names = array_column($aspects, 'name');
|
||
|
|
$this->assertNotEmpty(array_filter($names, static fn (string $n) => str_contains(strtolower($n), 'prozes') || str_contains(strtolower($n), 'cpu') || str_contains(strtolower($n), 'speicher')), 'Expected at least one hardware aspect (CPU/RAM)');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_required_aspects_are_flagged(): void
|
||
|
|
{
|
||
|
|
$aspects = $this->taxonomy->getCategoryAspects('177');
|
||
|
|
|
||
|
|
$required = array_filter($aspects, static fn (array $a) => $a['required']);
|
||
|
|
|
||
|
|
$this->assertNotEmpty($required, 'Category 177 should have at least one required aspect');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_aspects_with_predefined_values_have_options(): void
|
||
|
|
{
|
||
|
|
$aspects = $this->taxonomy->getCategoryAspects('177');
|
||
|
|
|
||
|
|
// At least some aspects should have predefined value lists (e.g. Zustand, Prozessorfamilie)
|
||
|
|
$withOptions = array_filter($aspects, static fn (array $a) => [] !== $a['values']);
|
||
|
|
|
||
|
|
$this->assertNotEmpty($withOptions, 'Some aspects should have predefined selectable values');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_caches_aspects_on_second_call(): void
|
||
|
|
{
|
||
|
|
// First call hits the API
|
||
|
|
$first = $this->taxonomy->getCategoryAspects('177');
|
||
|
|
// Second call should return from cache (same ArrayAdapter instance)
|
||
|
|
$second = $this->taxonomy->getCategoryAspects('177');
|
||
|
|
|
||
|
|
$this->assertSame($first, $second);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_fetches_aspects_for_ram_category(): void
|
||
|
|
{
|
||
|
|
// 170083 = RAM/Speicher in EBAY_DE — useful for our memory article types
|
||
|
|
$aspects = $this->taxonomy->getCategoryAspects('170083');
|
||
|
|
|
||
|
|
$this->assertNotEmpty($aspects);
|
||
|
|
$names = array_map(static fn (array $a) => $a['name'], $aspects);
|
||
|
|
$this->assertNotEmpty($names);
|
||
|
|
}
|
||
|
|
}
|