Skip to content

Commit

Permalink
Rename LimitContent to Truncate and add testing util for time waiting
Browse files Browse the repository at this point in the history
  • Loading branch information
cybersai committed Jan 20, 2024
1 parent 1250739 commit 5c202f2
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/Attributes/Transition.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
final class Transition
{
public function __construct(
public string $state,
public string|array|Decision $decision,
public string $to,
public string|array|Decision $match,
public null|string|array $callback = null
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
use Sparors\Ussd\Contracts\Decision;

#[Attribute(Attribute::TARGET_CLASS)]
final class LimitContent
final class Truncate
{
public function __construct(
public string|array|Decision $more,
public int $characters,
public string $moreText,
public int $limit,
public string $end,
public string|array|Decision $more
) {
}
}
7 changes: 6 additions & 1 deletion src/Commands/StateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class StateCommand extends GeneratorCommand

protected $signature = 'ussd:state
{name : The name of the USSD State}
{--init : Create the class as the initial USSD state}
{--init : Create the class as an initial USSD state}
{--cont : Create the class as a continuing USSD state}
{--force : Create the class even if USSD state already exists}';

protected function getStub()
Expand All @@ -19,6 +20,10 @@ protected function getStub()
return __DIR__.'/../../stubs/state.init.stub';
}

if ($this->option('cont')) {
return __DIR__.'/../../stubs/state.cont.stub';
}

return __DIR__.'/../../stubs/state.stub';
}

Expand Down
22 changes: 21 additions & 1 deletion src/Tests/Testing.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use DateInterval;
use DateTimeInterface;
use Illuminate\Http\Response as HttpResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\App;
use InvalidArgumentException;
Expand Down Expand Up @@ -144,8 +145,27 @@ public function actingAs(string $key)
return $this;
}

public function timeout()
public function wait(int|DateInterval|DateTimeInterface $ttl)
{
if ($ttl instanceof DateTimeInterface) {
$ttl = Carbon::now()->diffInSeconds($ttl);
}

if ($ttl instanceof DateInterval) {
$ttl = Carbon::now()->diffInSeconds(Carbon::now()->add($ttl));
}

Carbon::setTestNow(Carbon::now()->addSeconds($ttl));

return $this;
}

public function timeout(null|int|DateInterval|DateTimeInterface $ttl = null)
{
if ($ttl) {
$this->wait($ttl);
}

$this->actors[$this->actor][0] = Str::random();

$this->dispatch('');
Expand Down
35 changes: 20 additions & 15 deletions src/Ussd.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Sparors\Ussd\Contracts\State;
use Sparors\Ussd\Contracts\Action;
use Illuminate\Support\Facades\App;
use Sparors\Ussd\Attributes\LimitContent;
use Sparors\Ussd\Attributes\Truncate;
use Sparors\Ussd\Tests\PendingTest;
use Sparors\Ussd\Contracts\Response;
use Sparors\Ussd\Attributes\Paginate;
Expand Down Expand Up @@ -191,6 +191,11 @@ public function run(): mixed
[$message, $terminating] = $this->bail($exception);
}

if ($terminating && ContinuingMode::START !== $this->continuingMode) {
/** @var Record */ $record = App::make(Record::class);
$record->forget(static::SPUR, true);
}

return $this->response instanceof Response
? ($this->response)->respond($message, $terminating)
: ($this->response)($message, $terminating);
Expand Down Expand Up @@ -276,14 +281,14 @@ private function next(State $state): string
{
$reflected = new ReflectionClass($state);

$attributes = $reflected->getAttributes(LimitContent::class);
$attributes = $reflected->getAttributes(Truncate::class);

foreach ($attributes as $attribute) {
$content = (string) App::call([$state, 'render']);

$limitContent = $attribute->newInstance();

if ($limitContent->characters > strlen($content)) {
if ($limitContent->limit > strlen($content)) {
continue;
}

Expand All @@ -298,7 +303,7 @@ private function next(State $state): string
"/ÙÛÚ/",
wordwrap(
$content,
$limitContent->characters - (strlen($limitContent->moreText) + 1),
$limitContent->limit - (strlen($limitContent->end) + 1),
"ÙÛÚ",
true
)
Expand Down Expand Up @@ -349,7 +354,7 @@ private function next(State $state): string

$reflected = new ReflectionClass($state);

$attributes = $reflected->getAttributes(LimitContent::class);
$attributes = $reflected->getAttributes(Truncate::class);

if (count($attributes) > 0) {
$limitId = Str::of($state::class)->replace('\\', '')->snake()->append('_limit')->value();
Expand Down Expand Up @@ -379,13 +384,13 @@ private function next(State $state): string
foreach($attributes as $attribute) {
$transition = $attribute->newInstance();

if (is_array($transition->decision)) {
$transition->decision = new $transition->decision[0](...array_slice($transition->decision, 1));
} elseif (is_string($transition->decision)) {
$transition->decision = new $transition->decision();
if (is_array($transition->match)) {
$transition->match = new $transition->match[0](...array_slice($transition->match, 1));
} elseif (is_string($transition->match)) {
$transition->match = new $transition->match();
}

if ($transition->decision->decide($this->context->input())) {
if ($transition->match->decide($this->context->input())) {
if ($transition->callback) {
if (is_array($transition->callback) && is_string($transition->callback[0])) {
$transition->callback[0] = App::make($transition->callback[0]);
Expand All @@ -394,7 +399,7 @@ private function next(State $state): string
App::call($transition->callback);
}

return $transition->state;
return $transition->to;
}
}

Expand Down Expand Up @@ -426,20 +431,20 @@ private function limit(State $state, Menu $menu): array

$reflected = new ReflectionClass($state);

$attributes = $reflected->getAttributes(LimitContent::class);
$attributes = $reflected->getAttributes(Truncate::class);

foreach ($attributes as $attribute) {
$limitContent = $attribute->newInstance();

if ($limitContent->characters > strlen($content)) {
if ($limitContent->limit > strlen($content)) {
continue;
}

$items = preg_split(
"/ÙÛÚ/",
wordwrap(
$content,
$limitContent->characters - (strlen($limitContent->moreText) + 1),
$limitContent->limit - (strlen($limitContent->end) + 1),
"ÙÛÚ",
true
)
Expand All @@ -451,7 +456,7 @@ private function limit(State $state, Menu $menu): array

return [
count($items) > $limit
? sprintf("%s\n%s", $items[$limit - 1], $limitContent->moreText)
? sprintf("%s\n%s", $items[$limit - 1], $limitContent->end)
: $items[$limit - 1],
count($items) > $limit,
];
Expand Down
20 changes: 20 additions & 0 deletions stubs/state.cont.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace {{ namespace }};

use Sparors\Ussd\Menu;
use Sparors\Ussd\Decisions\Equal;
use Sparors\Ussd\Contracts\ContinueState;

class {{ class }} implements ContinueState
{
public function render(): Menu
{
return Menu::build()->line('1.Continue');
}

public function confirm(): Decision
{
return new Equal(1);
}
}
4 changes: 2 additions & 2 deletions tests/Dummy/BeginningState.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

namespace Sparors\Ussd\Tests\Dummy;

use Sparors\Ussd\Attributes\LimitContent;
use Sparors\Ussd\Attributes\Truncate;
use Sparors\Ussd\Attributes\Transition;
use Sparors\Ussd\Context;
use Sparors\Ussd\Contracts\InitialState;
use Sparors\Ussd\Decisions\Equal;
use Sparors\Ussd\Menu;
use Sparors\Ussd\Record;

#[LimitContent([Equal::class, '#'], 18, '#.More')]
#[Truncate(18, '#.More', [Equal::class, '#'])]
#[Transition(PetitAction::class, [Equal::class, 1], [self::class, 'callback'])]
class BeginningState implements InitialState
{
Expand Down
4 changes: 2 additions & 2 deletions tests/Dummy/SophisticatedState.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Sparors\Ussd\Tests\Dummy;

use Sparors\Ussd\Attributes\LimitContent;
use Sparors\Ussd\Attributes\Truncate;
use Sparors\Ussd\Attributes\Paginate;
use Sparors\Ussd\Attributes\Terminate;
use Sparors\Ussd\Contracts\InitialState;
Expand All @@ -11,7 +11,7 @@
use Sparors\Ussd\Traits\WithPagination;

#[Terminate]
#[LimitContent([Equal::class, '#'], 150, '#.More')]
#[Truncate(150, '#.More', [Equal::class, '#'])]
#[Paginate([Equal::class, '#'], [Equal::class, '0'])]
class SophisticatedState implements InitialState
{
Expand Down
21 changes: 18 additions & 3 deletions tests/Integration/AssestionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

final class AssestionTest extends TestCase
{
public function test_assestion_runs_successfully()
public function test_ussd_assestions_work_successfully()
{
Ussd::test(BeginningState::class, ContinuingMode::CONFIRM, null, ContinuingState::class)
->additional(['foo' => 'bar'])
Expand Down Expand Up @@ -43,11 +43,26 @@ public function test_assestion_runs_successfully()
->assertRecordHas('wow')
->assertSee('Tadaa...')
->timeout()
->assertSee('Wanna continue?')
->input('9')
->assertSee('In the')
->input('1')
->assertSee('Pick one...')
->actingAs('isaac');
}

public function test_ussd_assestion_can_wait_for_some_time_to_pass()
{
Ussd::test(BeginningState::class, ContinuingMode::CONFIRM, 5, ContinuingState::class)
->actingAs('isaac')
->start()
->input('1')
->timeout(6)
->assertSee('In the')
->timeout(3)
->assertSee('Wanna continue')
->input('1')
->input('1')
->assertSee('Tadaa...')
->timeout()
->assertSee('In the');
}
}

0 comments on commit 5c202f2

Please sign in to comment.