Files
boursecu_server/tests/Unit/ConfigServiceTradingHoursTest.php
T

210 lines
6.7 KiB
PHP
Raw Normal View History

<?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_marks_closed_without_hiding_status_when_home_price_off(): 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',
'show_last_price' => '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->applyHomePriceDisplayState([
'sell' => 100,
'buy' => 110,
'price' => 105,
'closed' => false,
'status' => 'open',
]);
$this->assertTrue($result['closed']);
$this->assertSame('closed', $result['status']);
Carbon::setTestNow();
}
public function test_outside_hours_shows_last_price_when_home_price_when_closed_is_on(): void
{
$cfg = $this->cfg([
'close_price' => 'true',
'show_home_price_when_closed' => 'true',
'show_last_price' => 'false',
'startDay' => '11:00',
'endDay' => '20:30',
]);
$now = Carbon::create(2026, 8, 25, 2, 3, 0);
Carbon::setTestNow($now);
$result = $cfg->applyHomePriceDisplayState([
'sell' => 168000000,
'buy' => 168798112,
'price' => 168798112,
'closed' => false,
'status' => 'open',
]);
$this->assertTrue($result['closed']);
$this->assertSame('open', $result['status']);
$this->assertSame(168798112, $result['buy']);
Carbon::setTestNow();
}
public function test_close_price_off_with_no_quote_is_no_quote(): void
{
$cfg = $this->cfg([
'close_price' => 'false',
'show_last_price' => 'false',
'show_home_price_when_closed' => 'false',
'startDay' => '11:00',
'endDay' => '20:30',
]);
$result = $cfg->applyHomePriceDisplayState([
'sell' => 0,
'buy' => 0,
'price' => 0,
'closed' => false,
]);
$this->assertFalse($result['closed']);
$this->assertSame('no_quote', $result['status']);
}
public function test_inside_hours_with_quote_is_open(): void
{
$cfg = $this->cfg([
'close_price' => 'true',
'show_last_price' => 'false',
'show_home_price_when_closed' => 'false',
'startDay' => '11:00',
'endDay' => '20:30',
]);
$now = Carbon::create(2026, 8, 25, 12, 0, 0);
Carbon::setTestNow($now);
$result = $cfg->applyHomePriceDisplayState([
'sell' => 100,
'buy' => 110,
'price' => 105,
]);
$this->assertFalse($result['closed']);
$this->assertSame('open', $result['status']);
Carbon::setTestNow();
}
public function test_trading_hours_setting_keys(): void
{
$cfg = new ConfigService();
$this->assertTrue($cfg->isTradingHoursSettingKey('close_price'));
$this->assertTrue($cfg->isTradingHoursSettingKey('trading_hours_by_day'));
$this->assertTrue($cfg->isTradingHoursSettingKey('show_home_price_when_closed'));
$this->assertFalse($cfg->isTradingHoursSettingKey('name_fa'));
}
}