fix(settings): honor per-day trading hours and refresh SuperAdmin overlay
Use trading_hours_by_day for close_price gates, prefer public SuperAdmin fetch, and add refresh endpoint/command so stale last-good cache no longer keeps switches like enable_automation off. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Services\ConfigService;
|
||||
use Carbon\Carbon;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ConfigServiceTradingHoursTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $values */
|
||||
private function cfg(array $values): ConfigService
|
||||
{
|
||||
$cfg = Mockery::mock(ConfigService::class)->makePartial();
|
||||
$cfg->shouldReceive('get')->andReturnUsing(function (string $key, $default = null) use ($values) {
|
||||
return array_key_exists($key, $values) ? $values[$key] : $default;
|
||||
});
|
||||
$cfg->shouldReceive('getString')->andReturnUsing(function (string $key, string $default = '') use ($values) {
|
||||
$value = $values[$key] ?? $default;
|
||||
|
||||
return trim((string) $value);
|
||||
});
|
||||
$cfg->shouldReceive('getBool')->andReturnUsing(function (string $key, bool $default = false) use ($values) {
|
||||
if (! array_key_exists($key, $values)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return filter_var($values[$key], FILTER_VALIDATE_BOOLEAN);
|
||||
});
|
||||
|
||||
return $cfg;
|
||||
}
|
||||
|
||||
public function test_per_day_schedule_closes_before_global_end_day(): void
|
||||
{
|
||||
$weekly = json_encode([
|
||||
'mode' => 'per_day',
|
||||
'days' => [
|
||||
'sat' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
'sun' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
'mon' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:00:00'],
|
||||
'tue' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
'wed' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
'thu' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
'fri' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
],
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$cfg = $this->cfg([
|
||||
'close_price' => 'true',
|
||||
'startDay' => '08:30',
|
||||
'endDay' => '21:30',
|
||||
'trading_hours_by_day' => $weekly,
|
||||
]);
|
||||
|
||||
$monday2115 = Carbon::create(2026, 8, 24, 21, 15, 0);
|
||||
$monday2059 = Carbon::create(2026, 8, 24, 20, 59, 0);
|
||||
|
||||
$this->assertTrue($cfg->isOutsideTradingHours($monday2115));
|
||||
$this->assertFalse($cfg->isOutsideTradingHours($monday2059));
|
||||
}
|
||||
|
||||
public function test_disabled_day_is_closed_all_day(): void
|
||||
{
|
||||
$weekly = json_encode([
|
||||
'mode' => 'per_day',
|
||||
'days' => [
|
||||
'fri' => ['enabled' => false, 'start' => '08:30:00', 'end' => '21:30:00'],
|
||||
],
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$cfg = $this->cfg([
|
||||
'close_price' => 'true',
|
||||
'startDay' => '08:30',
|
||||
'endDay' => '21:30',
|
||||
'trading_hours_by_day' => $weekly,
|
||||
]);
|
||||
|
||||
$fridayNoon = Carbon::create(2026, 8, 28, 12, 0, 0);
|
||||
|
||||
$this->assertTrue($cfg->isOutsideTradingHours($fridayNoon));
|
||||
}
|
||||
|
||||
public function test_apply_global_trading_hours_zeros_payload_when_closed(): void
|
||||
{
|
||||
$weekly = json_encode([
|
||||
'mode' => 'per_day',
|
||||
'days' => [
|
||||
'mon' => ['enabled' => true, 'start' => '08:30:00', 'end' => '21:00:00'],
|
||||
],
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$cfg = $this->cfg([
|
||||
'close_price' => 'true',
|
||||
'show_home_price_when_closed' => 'false',
|
||||
'startDay' => '08:30',
|
||||
'endDay' => '21:30',
|
||||
'trading_hours_by_day' => $weekly,
|
||||
]);
|
||||
|
||||
$now = Carbon::create(2026, 8, 24, 21, 15, 0);
|
||||
Carbon::setTestNow($now);
|
||||
|
||||
$result = $cfg->applyGlobalTradingHoursToPayload([
|
||||
'sell' => 100,
|
||||
'buy' => 110,
|
||||
'price' => 105,
|
||||
'closed' => false,
|
||||
'status' => 'open',
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['closed']);
|
||||
$this->assertSame('closed', $result['status']);
|
||||
$this->assertSame(0, $result['price']);
|
||||
|
||||
Carbon::setTestNow();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user