|
6 | 6 | use Illuminate\Foundation\Testing\RefreshDatabase; |
7 | 7 | use Illuminate\Support\Facades\DB; |
8 | 8 | use Illuminate\Support\Facades\Queue; |
| 9 | +use PHPUnit\Framework\Attributes\DataProvider; |
9 | 10 | use Tests\Feature\Concerns\ServerTestHelpers; |
10 | 11 | use Tests\Fixtures\AwaitApprovalWorkflow; |
11 | 12 | use Tests\TestCase; |
@@ -209,6 +210,58 @@ public function test_workflow_list_query_rejects_undefined_search_attribute(): v |
209 | 210 | ); |
210 | 211 | } |
211 | 212 |
|
| 213 | + #[DataProvider('datetimeInstants')] |
| 214 | + public function test_datetime_visibility_preserves_offset_instants_and_microseconds(string $literal): void |
| 215 | + { |
| 216 | + foreach (['default', 'other'] as $namespace) { |
| 217 | + SearchAttributeDefinition::query()->create([ |
| 218 | + 'namespace' => $namespace, |
| 219 | + 'name' => 'occurred_at', |
| 220 | + 'type' => 'datetime', |
| 221 | + ]); |
| 222 | + } |
| 223 | + |
| 224 | + $this->startWorkflow('default', 'wf-date-match', [ |
| 225 | + 'occurred_at' => '2026-10-08T10:34:56.123456Z', |
| 226 | + ]); |
| 227 | + $this->startWorkflow('default', 'wf-date-neighbor', [ |
| 228 | + 'occurred_at' => '2026-10-08T10:34:56.123457Z', |
| 229 | + ]); |
| 230 | + $this->startWorkflow('other', 'wf-date-other', [ |
| 231 | + 'occurred_at' => '2026-10-08T10:34:56.123456Z', |
| 232 | + ]); |
| 233 | + |
| 234 | + $this->assertSame(['wf-date-match'], $this->workflowIdsForQuery('occurred_at = "'.$literal.'"')); |
| 235 | + $this->assertSame(['wf-date-neighbor'], $this->workflowIdsForQuery('occurred_at != "'.$literal.'"')); |
| 236 | + $this->assertSame(['wf-date-match'], $this->workflowIdsForQuery('occurred_at IN ("'.$literal.'")')); |
| 237 | + $this->assertSame(['wf-date-neighbor'], $this->workflowIdsForQuery('NOT occurred_at IN ("'.$literal.'")')); |
| 238 | + $this->assertSame(['wf-date-match'], $this->workflowIdsForQuery( |
| 239 | + 'occurred_at >= "'.$literal.'" AND occurred_at < "2026-10-08T10:34:56.123457Z"', |
| 240 | + )); |
| 241 | + $this->assertSame(['wf-date-other'], $this->workflowIdsForQuery('occurred_at = "'.$literal.'"', 'other')); |
| 242 | + |
| 243 | + DB::table('workflow_run_summaries')->where('workflow_instance_id', 'wf-date-match')->update([ |
| 244 | + 'started_at' => '2026-10-08 10:34:56.123456', |
| 245 | + ]); |
| 246 | + DB::table('workflow_run_summaries')->where('workflow_instance_id', 'wf-date-neighbor')->update([ |
| 247 | + 'started_at' => '2026-10-08 10:34:56.123457', |
| 248 | + ]); |
| 249 | + $this->assertSame(['wf-date-match'], $this->workflowIdsForQuery('StartTime = "'.$literal.'"')); |
| 250 | + $this->assertSame(['wf-date-match'], $this->workflowIdsForQuery('StartTime IN ("'.$literal.'")')); |
| 251 | + } |
| 252 | + |
| 253 | + /** |
| 254 | + * @return iterable<string, array{string}> |
| 255 | + */ |
| 256 | + public static function datetimeInstants(): iterable |
| 257 | + { |
| 258 | + yield 'positive offset' => ['2026-10-08T12:34:56.123456+02:00']; |
| 259 | + yield 'negative offset' => ['2026-10-08T06:34:56.123456-04:00']; |
| 260 | + yield 'next local day' => ['2026-10-09T00:34:56.123456+14:00']; |
| 261 | + yield 'previous local day' => ['2026-10-07T22:34:56.123456-12:00']; |
| 262 | + yield 'utc' => ['2026-10-08T10:34:56.123456Z']; |
| 263 | + } |
| 264 | + |
212 | 265 | /** |
213 | 266 | * @param array<string, scalar|list<string>|null> $searchAttributes |
214 | 267 | */ |
|
0 commit comments