Skip to content

Commit 57b9c08

Browse files
authored
Timer replay access
1 parent 831acb6 commit 57b9c08

File tree

11 files changed

+200
-0
lines changed

11 files changed

+200
-0
lines changed

src/Traits/AwaitWithTimeouts.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public static function awaitWithTimeout(int|string|CarbonInterval $seconds, $con
4545
++self::$context->index;
4646
return resolve(Serializer::unserialize($log->result));
4747
}
48+
49+
throw $exception;
4850
}
4951
}
5052
++self::$context->index;

src/Traits/Awaits.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public static function await($condition): PromiseInterface
4545
++self::$context->index;
4646
return resolve(Serializer::unserialize($log->result));
4747
}
48+
49+
throw $exception;
4850
}
4951
}
5052
++self::$context->index;

src/Traits/SideEffects.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public static function sideEffect($callable): PromiseInterface
4242
++self::$context->index;
4343
return resolve(Serializer::unserialize($log->result));
4444
}
45+
46+
throw $exception;
4547
}
4648
}
4749

src/Traits/Timers.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public static function timer(int|string|CarbonInterval $seconds): PromiseInterfa
4949
'index' => self::$context->index,
5050
'stop_at' => $when,
5151
]);
52+
} else {
53+
++self::$context->index;
54+
$deferred = new Deferred();
55+
return $deferred->promise();
5256
}
5357
}
5458

tests/Feature/TimerWorkflowTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tests\Feature;
66

7+
use Tests\Fixtures\TestTimerQueryWorkflow;
78
use Tests\Fixtures\TestTimerWorkflow;
89
use Tests\TestCase;
910
use Workflow\States\WorkflowCompletedStatus;
@@ -40,4 +41,17 @@ public function testTimerWorkflowDelay(): void
4041
$this->assertSame(WorkflowCompletedStatus::class, $workflow->status());
4142
$this->assertSame('workflow', $workflow->output());
4243
}
44+
45+
public function testTimerQueryDuringWait(): void
46+
{
47+
$workflow = WorkflowStub::make(TestTimerQueryWorkflow::class);
48+
49+
$workflow->start(10);
50+
51+
sleep(1);
52+
53+
$status = $workflow->getStatus();
54+
55+
$this->assertSame('waiting', $status);
56+
}
4357
}

tests/Feature/WebhookWorkflowTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public function testStart(): void
3939

4040
$workflow = WorkflowStub::load(1);
4141

42+
sleep(1);
43+
4244
$workflow->cancel();
4345

4446
while (! $workflow->isCanceled());
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Fixtures;
6+
7+
use Workflow\QueryMethod;
8+
use Workflow\Workflow;
9+
use Workflow\WorkflowStub;
10+
11+
final class TestTimerQueryWorkflow extends Workflow
12+
{
13+
private string $status = 'waiting';
14+
15+
#[QueryMethod]
16+
public function getStatus(): string
17+
{
18+
return $this->status;
19+
}
20+
21+
public function execute($seconds = 10)
22+
{
23+
yield WorkflowStub::timer($seconds);
24+
25+
$this->status = 'completed';
26+
27+
return 'done';
28+
}
29+
}

tests/Unit/Traits/AwaitWithTimeoutsTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tests\Unit\Traits;
66

7+
use Mockery;
78
use Tests\Fixtures\TestWorkflow;
89
use Tests\TestCase;
910
use Workflow\Models\StoredWorkflow;
@@ -114,4 +115,41 @@ public function testResolvesConflictingResult(): void
114115
]);
115116
$this->assertFalse(Serializer::unserialize($workflow->logs()->firstWhere('index', 0)->result));
116117
}
118+
119+
public function testThrowsQueryExceptionWhenNotDuplicateKey(): void
120+
{
121+
$workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id());
122+
$storedWorkflow = StoredWorkflow::findOrFail($workflow->id());
123+
124+
$mockLogs = Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class)
125+
->shouldReceive('whereIndex')
126+
->twice()
127+
->andReturnSelf()
128+
->shouldReceive('first')
129+
->twice()
130+
->andReturn(null)
131+
->shouldReceive('create')
132+
->andThrow(new \Illuminate\Database\QueryException('', '', [], new \Exception('Some other error')))
133+
->getMock();
134+
135+
$mockStoredWorkflow = Mockery::spy($storedWorkflow);
136+
137+
$mockStoredWorkflow->shouldReceive('logs')
138+
->andReturnUsing(static function () use ($mockLogs) {
139+
return $mockLogs;
140+
});
141+
142+
WorkflowStub::setContext([
143+
'storedWorkflow' => $mockStoredWorkflow,
144+
'index' => 0,
145+
'now' => now(),
146+
'replaying' => false,
147+
]);
148+
149+
$this->expectException(\Illuminate\Database\QueryException::class);
150+
151+
WorkflowStub::awaitWithTimeout('1 minute', static fn () => true);
152+
153+
Mockery::close();
154+
}
117155
}

tests/Unit/Traits/AwaitsTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tests\Unit\Traits;
66

7+
use Mockery;
78
use Tests\Fixtures\TestWorkflow;
89
use Tests\TestCase;
910
use Workflow\Models\StoredWorkflow;
@@ -100,4 +101,41 @@ public function testResolvesConflictingResult(): void
100101
]);
101102
$this->assertFalse(Serializer::unserialize($workflow->logs()->firstWhere('index', 0)->result));
102103
}
104+
105+
public function testThrowsQueryExceptionWhenNotDuplicateKey(): void
106+
{
107+
$workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id());
108+
$storedWorkflow = StoredWorkflow::findOrFail($workflow->id());
109+
110+
$mockLogs = Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class)
111+
->shouldReceive('whereIndex')
112+
->twice()
113+
->andReturnSelf()
114+
->shouldReceive('first')
115+
->twice()
116+
->andReturn(null)
117+
->shouldReceive('create')
118+
->andThrow(new \Illuminate\Database\QueryException('', '', [], new \Exception('Some other error')))
119+
->getMock();
120+
121+
$mockStoredWorkflow = Mockery::spy($storedWorkflow);
122+
123+
$mockStoredWorkflow->shouldReceive('logs')
124+
->andReturnUsing(static function () use ($mockLogs) {
125+
return $mockLogs;
126+
});
127+
128+
WorkflowStub::setContext([
129+
'storedWorkflow' => $mockStoredWorkflow,
130+
'index' => 0,
131+
'now' => now(),
132+
'replaying' => false,
133+
]);
134+
135+
$this->expectException(\Illuminate\Database\QueryException::class);
136+
137+
WorkflowStub::await(static fn () => true);
138+
139+
Mockery::close();
140+
}
103141
}

tests/Unit/Traits/SideEffectsTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tests\Unit\Traits;
66

7+
use Mockery;
78
use Tests\Fixtures\TestWorkflow;
89
use Tests\TestCase;
910
use Workflow\Models\StoredWorkflow;
@@ -86,4 +87,43 @@ public function testResolvesConflictingResult(): void
8687
]);
8788
$this->assertSame('test', Serializer::unserialize($workflow->logs()->firstWhere('index', 0)->result));
8889
}
90+
91+
public function testThrowsQueryExceptionWhenNotDuplicateKey(): void
92+
{
93+
$workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id());
94+
$storedWorkflow = StoredWorkflow::findOrFail($workflow->id());
95+
96+
$mockLogs = Mockery::mock(\Illuminate\Database\Eloquent\Relations\HasMany::class)
97+
->shouldReceive('whereIndex')
98+
->twice()
99+
->andReturnSelf()
100+
->shouldReceive('first')
101+
->twice()
102+
->andReturn(null)
103+
->shouldReceive('create')
104+
->andThrow(new \Illuminate\Database\QueryException('', '', [], new \Exception('Some other error')))
105+
->getMock();
106+
107+
$mockStoredWorkflow = Mockery::spy($storedWorkflow);
108+
109+
$mockStoredWorkflow->shouldReceive('logs')
110+
->andReturnUsing(static function () use ($mockLogs) {
111+
return $mockLogs;
112+
});
113+
114+
$mockStoredWorkflow->class = TestWorkflow::class;
115+
116+
WorkflowStub::setContext([
117+
'storedWorkflow' => $mockStoredWorkflow,
118+
'index' => 0,
119+
'now' => now(),
120+
'replaying' => false,
121+
]);
122+
123+
$this->expectException(\Illuminate\Database\QueryException::class);
124+
125+
WorkflowStub::sideEffect(static fn () => 'test');
126+
127+
Mockery::close();
128+
}
89129
}

0 commit comments

Comments
 (0)