Skip to content
This repository has been archived by the owner on Jun 22, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from HelgeSverre/master
Browse files Browse the repository at this point in the history
Add "nextUnfinishedStep" method
  • Loading branch information
calebporzio committed Jan 15, 2018
2 parents fff8674 + 92f30d8 commit 4ed6e8a
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 89 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,36 @@ Onboard::addStep('Step w/ custom attributes')
$step->name;
$step->shirt_color;
```


## Example middlware

If you want to ensure that your user is redirected to the next
unfinished onboarding step, whenever they access your web application,
you can use the following middleware as a starting point:

```php
<?php

namespace App\Http\Middleware;

use Auth;
use Closure;

class RedirectToUnfinishedOnboardingStep
{
public function handle($request, Closure $next)
{
if (Auth::user()->onboarding()->inProgress()) {
return redirect()->to(
Auth::user()->onboarding()->nextUnfinishedStep->link
);
}

return $next($request);
}
}
```

**Quick tip**: Don't add this middleware to routes that update the state
of the onboarding steps, your users will not be able to progress because they will be redirected back to the onboarding step.
12 changes: 12 additions & 0 deletions src/OnboardingManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,16 @@ public function finished()
// Report onboarding is finished if no incomplete steps remain.
->isEmpty();
}

/**
* Get the next unfinished onboarding step, or null if already all steps are completed.
*
* @return null|OnboardingStep
*/
public function nextUnfinishedStep()
{
return collect($this->steps)->first(function ($step) {
return $step->incomplete();
});
}
}
89 changes: 0 additions & 89 deletions tests/OnbaordTest.php

This file was deleted.

146 changes: 146 additions & 0 deletions tests/OnboardTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php

use Calebporzio\Onboard\OnboardingSteps;
use Calebporzio\Onboard\OnboardingManager;
use PHPUnit\Framework\TestCase;

class OnboardTest extends TestCase
{
/**
* Dummy user object.
*/
protected $user;

public function setUp()
{
$this->user = $this->getMock('User');
}

/** @test */
public function steps_can_be_defined_and_configured()
{
$onboardingSteps = new OnboardingSteps;

$onboardingSteps->addStep('Test Step')
->link('/some/url')
->cta('Test This!')
->attributes(['another' => 'attribute'])
->completeIf(function () {
return true;
});

$this->assertEquals(1, $onboardingSteps->steps(new stdClass())->count());

$step = $onboardingSteps->steps(new stdClass())->first();

$this->assertEquals('/some/url', $step->link);
$this->assertEquals('Test This!', $step->cta);
$this->assertEquals('Test Step', $step->title);
$this->assertEquals('attribute', $step->another);
}

/** @test */
public function is_in_progress_when_all_steps_are_incomplete()
{
$onboardingSteps = new OnboardingSteps;
$onboardingSteps->addStep('Test Step');
$onboardingSteps->addStep('Another Test Step');

$onboarding = new OnboardingManager($this->user, $onboardingSteps);

$this->assertTrue($onboarding->inProgress());
$this->assertFalse($onboarding->finished());
}

/** @test */
public function is_finished_when_all_steps_are_complete()
{
$onboardingSteps = new OnboardingSteps;
$onboardingSteps->addStep('Test Step')
->completeIf(function () {
return true;
});

$onboarding = new OnboardingManager($this->user, $onboardingSteps);

$this->assertTrue($onboarding->finished());
$this->assertFalse($onboarding->inProgress());
}

/** @test */
public function it_returns_the_correct_next_unfinished_step()
{
$onboardingSteps = new OnboardingSteps;
$onboardingSteps->addStep('Step 1')
->link("/step-1")
->completeIf(function () {
return true;
});

$onboardingSteps->addStep('Step 2')
->link("/step-2")
->completeIf(function () {
return false;
});

$onboardingSteps->addStep('Step 3')
->link("/step-3")
->completeIf(function () {
return false;
});

$onboarding = new OnboardingManager($this->user, $onboardingSteps);

$nextStep = $onboarding->nextUnfinishedStep();

$this->assertNotNull($nextStep);
$this->assertEquals("Step 2", $nextStep->title);
$this->assertEquals("/step-2", $nextStep->link);
}

/** @test */
public function nextUnfinishedStep_returns_null_if_all_steps_are_completed()
{
$onboardingSteps = new OnboardingSteps;
$onboardingSteps->addStep('Step 1')
->completeIf(function () {
return true;
});

$onboardingSteps->addStep('Step 2')
->completeIf(function () {
return true;
});

$onboardingSteps->addStep('Step 3')
->completeIf(function () {
return true;
});

$onboarding = new OnboardingManager($this->user, $onboardingSteps);

$nextStep = $onboarding->nextUnfinishedStep();

$this->assertNull($nextStep);
}

/** @test */
public function the_proper_object_gets_passed_into_completion_callback()
{
$user = $this->getMock('User', ['testMe']);
$user->expects($this->once())->method('testMe');

$onboardingSteps = new OnboardingSteps;
$onboardingSteps->addStep('Test Step')
->completeIf(function ($user) {
// if this gets called, it ensures that the right object was passed through.
$user->testMe();
return true;
});

$onboarding = new OnboardingManager($user, $onboardingSteps);

// Calling finished() will triger the completeIf callback.
$this->assertTrue($onboarding->finished());
}
}

0 comments on commit 4ed6e8a

Please sign in to comment.