$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(); } }