Skip to content

Commit

Permalink
add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
leo108 committed Oct 12, 2016
1 parent 59d8276 commit fe270bf
Show file tree
Hide file tree
Showing 9 changed files with 735 additions and 30 deletions.
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
],
"require": {
"php": ">=5.5.9",
"illuminate/support": "5.1.* || 5.2.* || 5.3.*",
"illuminate/database": "5.1.* || 5.2.* || 5.3.*",
"illuminate/foundation": "5.1.* || 5.2.* || 5.3.*",
"illuminate/routing": "5.1.* || 5.2.* || 5.3.*",
"illuminate/queue": "5.1.* || 5.2.* || 5.3.*",
"illuminate/http": "5.1.* || 5.2.* || 5.3.*"
"illuminate/support": "5.1.*|5.2.*|5.3.*",
"illuminate/database": "5.1.*|5.2.*|5.3.*",
"illuminate/foundation": "5.1.*|5.2.*|5.3.*",
"illuminate/routing": "5.1.*|5.2.*|5.3.*",
"illuminate/queue": "5.1.*|5.2.*|5.3.*",
"illuminate/http": "5.1.*|5.2.*|5.3.*"
},
"require-dev": {
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~4.0",
"laravel/laravel": "5.1.* || 5.2.* || 5.3.*"
"laravel/laravel": "5.1.*|5.2.*|5.3.*"
},
"autoload": {
"psr-4": {
Expand Down
19 changes: 10 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CAS Server for Laravel

`CAS Server for Laravel` is a Laravel package that implements the server part of [CAS protocol](https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Specification.html) v1/v2/v3 without proxy.
laravel_cas_server is a Laravel package that implements the server part of [CAS protocol](https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Specification.html) v1/v2/v3 without the proxy ticket part.

Currently this package works for Laravel 5.1/5.2/5.3 .

Expand All @@ -16,11 +16,12 @@ Currently this package works for Laravel 5.1/5.2/5.3 .

## Installation && Usage

1. `composer require leo108/laravel_cas_server`
2. add `Leo108\CAS\CASServerServiceProvider::class` to the `providers` field in `config/app.php`
3. `php artisan vendor:publish --provider="Leo108\CAS\CASServerServiceProvider"`
4. modify `config/cas.php`, fields in config file are all self-described
5. make your `App\User` implement `Leo108\CAS\Contracts\Models\UserModel`
6. create a class implements `Leo108\CAS\Contracts\TicketLocker`
7. create a class implements `Leo108\CAS\Contracts\Interactions\UserLogin`
8. visit `http://your-domain/cas/login` to see the login page (assume that you didn't change the `router.prefix` value in `config/cas.php`)
- `composer require leo108/laravel_cas_server`
- add `Leo108\CAS\CASServerServiceProvider::class` to the `providers` field in `config/app.php`
- `php artisan vendor:publish --provider="Leo108\CAS\CASServerServiceProvider"`
- modify `config/cas.php`, fields in config file are all self-described
- `php artisan migrate`
- make your `App\User` implement `Leo108\CAS\Contracts\Models\UserModel`
- create a class implements `Leo108\CAS\Contracts\TicketLocker`
- create a class implements `Leo108\CAS\Contracts\Interactions\UserLogin`
- visit `http://your-domain/cas/login` to see the login page (assume that you didn't change the `router.prefix` value in `config/cas.php`)
12 changes: 6 additions & 6 deletions src/Events/CasUserLogoutEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

namespace Leo108\CAS\Events;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Illuminate\Queue\SerializesModels;
use Leo108\CAS\Contracts\Models\UserModel;

class CasUserLogoutEvent extends Event
{
Expand All @@ -20,16 +20,16 @@ class CasUserLogoutEvent extends Event
*/
protected $request;
/**
* @var Authenticatable
* @var UserModel
*/
protected $user;

/**
* CasUserLoginEvent constructor.
* @param Request $request
* @param Authenticatable $user
* @param Request $request
* @param UserModel $user
*/
public function __construct(Request $request, Authenticatable $user)
public function __construct(Request $request, UserModel $user)
{
$this->request = $request;
$this->user = $user;
Expand All @@ -54,7 +54,7 @@ public function getRequest()
}

/**
* @return Authenticatable
* @return UserModel
*/
public function getUser()
{
Expand Down
3 changes: 2 additions & 1 deletion src/Http/Controllers/ValidateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Leo108\CAS\Http\Controllers;

use Illuminate\Support\Str;
use Leo108\CAS\Contracts\TicketLocker;
use Leo108\CAS\Repositories\TicketRepository;
use Leo108\CAS\Exceptions\CAS\CasException;
Expand Down Expand Up @@ -212,7 +213,7 @@ protected function unlockTicket($ticket)
protected function removeXmlFirstLine($str)
{
$first = '<?xml version="1.0"?>';
if (stripos($str, $first) === 0) {
if (Str::startsWith($str, $first)) {
return trim(substr($str, strlen($first)));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Models/ServiceHost.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ public function service()
{
return $this->belongsTo(Service::class);
}
}
}
217 changes: 217 additions & 0 deletions tests/Http/Controllers/SecurityControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2016/10/12
* Time: 14:50
*/

namespace Leo108\CAS\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Leo108\CAS\Contracts\Interactions\UserLogin;
use Leo108\CAS\Events\CasUserLoginEvent;
use Leo108\CAS\Events\CasUserLogoutEvent;
use Leo108\CAS\Exceptions\CAS\CasException;
use Leo108\CAS\Repositories\ServiceRepository;
use Leo108\CAS\Repositories\TicketRepository;
use TestCase;
use Mockery;
use User;

class SecurityControllerTest extends TestCase
{
public function testShowLogin()
{
//not logged in with valid service url
$serviceRepository = Mockery::mock(ServiceRepository::class)
->shouldReceive('isUrlValid')
->andReturn(true)
->getMock();
app()->instance(ServiceRepository::class, $serviceRepository);
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('showLoginPage')
->andReturnUsing(
function ($request, $errors) {
$this->assertEmpty($errors);

return 'show login called';
}
)
->shouldReceive('getCurrentUser')
->andReturn(false)
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('what ever')
->getMock();
$this->assertEquals('show login called', app()->make(SecurityController::class)->showLogin($request));

//not logged in with invalid service url
$serviceRepository = Mockery::mock(ServiceRepository::class)
->shouldReceive('isUrlValid')
->andReturn(false)
->getMock();
app()->instance(ServiceRepository::class, $serviceRepository);
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('showLoginPage')
->andReturnUsing(
function ($request, $errors) {
$this->assertNotEmpty($errors);
$this->assertEquals(CasException::INVALID_SERVICE, $errors[0]);

return 'show login called';
}
)
->shouldReceive('getCurrentUser')
->andReturn(false)
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('what ever')
->getMock();
$this->assertEquals('show login called', app()->make(SecurityController::class)->showLogin($request));

//logged in with valid service url without warn parameter
$serviceRepository = Mockery::mock(ServiceRepository::class)
->shouldReceive('isUrlValid')
->andReturn(true)
->getMock();
$ticketRepository = Mockery::mock(TicketRepository::class);
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('getCurrentUser')
->andReturn(true)//just not false is OK
->getMock();
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('what ever')
->shouldReceive('get')
->withArgs(['warn'])
->andReturn(false)
->getMock();
$controller = Mockery::mock(
SecurityController::class,
[$serviceRepository, $ticketRepository, $loginInteraction]
)
->makePartial()
->shouldReceive('authenticated')
->andReturn('authenticated called')
->getMock();
$this->assertEquals('authenticated called', $controller->showLogin($request));
}

public function testAuthenticated()
{
//without service url
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('redirectToHome')
->andReturnUsing(
function () {
return 'redirectToHome called';
}
)
->shouldReceive('getCurrentUser')
->andReturn(new User())
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('')
->getMock();
$this->expectsEvents(CasUserLoginEvent::class);
$this->assertEquals('redirectToHome called', app()->make(SecurityController::class)->authenticated($request));

//with service url but apply ticket failed
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('redirectToHome')
->andReturnUsing(
function ($errors) {
$this->assertNotEmpty($errors);
$this->assertEquals(CasException::INTERNAL_ERROR, $errors[0]);

return 'redirectToHome called';
}
)
->shouldReceive('getCurrentUser')
->andReturn(new User())
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$ticketRepository = Mockery::mock(TicketRepository::class)
->shouldReceive('applyTicket')
->andThrow(new CasException(CasException::INTERNAL_ERROR))
->getMock();
app()->instance(TicketRepository::class, $ticketRepository);
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('http://leo108.com')
->getMock();
$this->expectsEvents(CasUserLoginEvent::class);
$this->assertEquals('redirectToHome called', app()->make(SecurityController::class)->authenticated($request));

//with service url
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('getCurrentUser')
->andReturn(new User())
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$ticket = Mockery::mock();
$ticket->ticket = 'ST-abc';
$ticketRepository = Mockery::mock(TicketRepository::class)
->shouldReceive('applyTicket')
->andReturn($ticket)
->getMock();
app()->instance(TicketRepository::class, $ticketRepository);
$request = Mockery::mock(Request::class)
->shouldReceive('get')
->withArgs(['service', ''])
->andReturn('http://leo108.com')
->getMock();
$this->expectsEvents(CasUserLoginEvent::class);
$resp = app()->make(SecurityController::class)->authenticated($request);
$this->assertInstanceOf(RedirectResponse::class, $resp);
$this->assertEquals($resp->getTargetUrl(), 'http://leo108.com?ticket=ST-abc');
}

public function testLogout()
{
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('logout')
->andReturnUsing(
function ($request, $callback) {
$this->expectsEvents(CasUserLogoutEvent::class);
call_user_func_array($callback, [$request]);

return 'logout called';
}
)
->shouldReceive('getCurrentUser')
->andReturn(new User())
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$request = Mockery::mock(Request::class);
$this->assertEquals('logout called', app()->make(SecurityController::class)->logout($request));
}

public function testLogin()
{
$loginInteraction = Mockery::mock(UserLogin::class)
->shouldReceive('login')
->andReturnUsing(
function () {
return 'login called';
}
)
->getMock();
app()->instance(UserLogin::class, $loginInteraction);
$request = Mockery::mock(Request::class);
$this->assertEquals('login called', app()->make(SecurityController::class)->login($request));
}
}
Loading

0 comments on commit fe270bf

Please sign in to comment.