presseportale/tests/Feature/Web/MarketDataTest.php
Kevin Adametz bfad13af7d Spoke-Frontend-Audit: Fake-Inhalte raus, Newsletter-Rueckbau, echte Boersendaten, EN-Lokalisierung
Frontend-Umbau (Kevin, 06.07.2026), Ergebnis des businessportal24-Audits:

- Fake-Anzeigen und Mock-/Fallback-Daten entfernt (focus-ad, feed-ad,
  highlight-card, press-release-card, featured-releases, press-releases-grid);
  Sektionen rendern nur noch mit echten Daten oder gar nicht
- Newsletter-Strip und Newsletter-Box zurueckgebaut (Feature nachgelagert,
  vor Reaktivierung DOI-Flow noetig)
- Echte Boersendaten: MarketDataService (Yahoo-Finance-Quotes, config/market.php,
  Cache) + market:refresh alle 15 Min. im Scheduler; live-ticker blendet sich
  ohne Daten aus
- EN-Lokalisierung der Kern-Seiten via lang/de/web.php + lang/en/web.php;
  Carbon-Locale folgt app()->getLocale()
- Web-Tests auf den neuen Frontend-Stand nachgezogen (Suite: 993 gruen)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:36:23 +00:00

98 lines
3.1 KiB
PHP

<?php
use App\Services\Web\MarketDataService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
beforeEach(function () {
Cache::forget((string) config('market.cache_key'));
config()->set('market.enabled', true);
config()->set('market.symbols', [
['label' => 'DAX', 'symbol' => '^GDAXI', 'precision' => 0, 'suffix' => ''],
['label' => 'EUR/USD', 'symbol' => 'EURUSD=X', 'precision' => 2, 'suffix' => ''],
]);
});
function fakeYahooChart(float $price, float $previousClose): array
{
return [
'chart' => [
'result' => [
['meta' => ['regularMarketPrice' => $price, 'chartPreviousClose' => $previousClose]],
],
],
];
}
it('holt Kurse, berechnet Deltas und cacht die Slides', function () {
Http::fake([
'*GDAXI*' => Http::response(fakeYahooChart(24150.0, 24000.0)),
'*EURUSD*' => Http::response(fakeYahooChart(1.0815, 1.0902)),
]);
$slides = app(MarketDataService::class)->refresh();
expect($slides)->toHaveCount(2)
->and($slides[0]['label'])->toBe('DAX')
->and($slides[0]['value'])->toBe('24.150')
->and($slides[0]['delta'])->toBe('+0,6%')
->and($slides[0]['positive'])->toBeTrue()
->and($slides[1]['delta'])->toBe('-0,8%')
->and($slides[1]['positive'])->toBeFalse();
Http::fake();
expect(app(MarketDataService::class)->slides())->toBe($slides);
});
it('behält den Cache-Stand, wenn der Abruf komplett fehlschlägt', function () {
Cache::put((string) config('market.cache_key'), [
['label' => 'DAX', 'value' => '24.150', 'delta' => '+0,6%', 'positive' => true],
], 3600);
Http::fake(['*' => Http::response(null, 500)]);
$slides = app(MarketDataService::class)->refresh();
expect($slides)->toHaveCount(1)
->and($slides[0]['value'])->toBe('24.150');
});
it('liefert keine Slides, wenn Marktdaten deaktiviert sind', function () {
config()->set('market.enabled', false);
Cache::put((string) config('market.cache_key'), [
['label' => 'DAX', 'value' => '24.150', 'delta' => '+0,6%', 'positive' => true],
], 3600);
expect(app(MarketDataService::class)->slides())->toBe([]);
});
it('überspringt Symbole mit unbrauchbarer API-Antwort', function () {
Http::fake([
'*GDAXI*' => Http::response(['chart' => ['result' => [['meta' => []]]]]),
'*EURUSD*' => Http::response(fakeYahooChart(1.0815, 1.0902)),
]);
$slides = app(MarketDataService::class)->refresh();
expect($slides)->toHaveCount(1)
->and($slides[0]['label'])->toBe('EUR/USD');
});
it('aktualisiert Kurse über den Artisan-Command', function () {
Http::fake(['*' => Http::response(fakeYahooChart(24150.0, 24000.0))]);
$this->artisan('market:refresh')
->expectsOutputToContain('DAX')
->assertSuccessful();
expect(app(MarketDataService::class)->slides())->not->toBeEmpty();
});
it('meldet einen Fehlschlag des Commands ohne Kursdaten', function () {
Http::fake(['*' => Http::response(null, 500)]);
$this->artisan('market:refresh')->assertFailed();
});