jingcai-php/vendor/tymon/jwt-auth/tests/JWTGuardTest.php

436 lines
15 KiB
PHP
Executable File

<?php
/*
* This file is part of jwt-auth.
*
* (c) Sean Tymon <tymon148@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tymon\JWTAuth\Test;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Http\Request;
use Mockery;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\UserNotDefinedException;
use Tymon\JWTAuth\Factory;
use Tymon\JWTAuth\JWT;
use Tymon\JWTAuth\JWTGuard;
use Tymon\JWTAuth\Payload;
use Tymon\JWTAuth\Test\Stubs\LaravelUserStub;
class JWTGuardTest extends AbstractTestCase
{
/**
* @var \Tymon\JWTAuth\JWT|\Mockery\MockInterface
*/
protected $jwt;
/**
* @var \Illuminate\Contracts\Auth\UserProvider|\Mockery\MockInterface
*/
protected $provider;
/**
* @var \Tymon\JWTAuth\JWTGuard|\Mockery\MockInterface
*/
protected $guard;
public function setUp(): void
{
parent::setUp();
$this->jwt = Mockery::mock(JWT::class);
$this->provider = Mockery::mock(EloquentUserProvider::class);
$this->guard = new JWTGuard($this->jwt, $this->provider, Request::create('/foo', 'GET'));
}
/** @test */
public function it_should_get_the_request()
{
$this->assertInstanceOf(Request::class, $this->guard->getRequest());
}
/** @test */
public function it_should_get_the_authenticated_user_if_a_valid_token_is_provided()
{
$payload = Mockery::mock(Payload::class);
$payload->shouldReceive('offsetGet')->once()->with('sub')->andReturn(1);
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn('foo.bar.baz');
$this->jwt->shouldReceive('check')->once()->with(true)->andReturn($payload);
$this->jwt->shouldReceive('checkSubjectModel')
->once()
->with('\Tymon\JWTAuth\Test\Stubs\LaravelUserStub')
->andReturn(true);
$this->provider->shouldReceive('getModel')
->once()
->andReturn('\Tymon\JWTAuth\Test\Stubs\LaravelUserStub');
$this->provider->shouldReceive('retrieveById')
->once()
->with(1)
->andReturn((object) ['id' => 1]);
$this->assertSame(1, $this->guard->user()->id);
// check that the user is stored on the object next time round
$this->assertSame(1, $this->guard->user()->id);
$this->assertTrue($this->guard->check());
// also make sure userOrFail does not fail
$this->assertSame(1, $this->guard->userOrFail()->id);
}
/** @test */
public function it_should_get_the_authenticated_user_if_a_valid_token_is_provided_and_not_throw_an_exception()
{
$payload = Mockery::mock(Payload::class);
$payload->shouldReceive('offsetGet')->once()->with('sub')->andReturn(1);
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn('foo.bar.baz');
$this->jwt->shouldReceive('check')->once()->with(true)->andReturn($payload);
$this->jwt->shouldReceive('checkSubjectModel')
->once()
->with('\Tymon\JWTAuth\Test\Stubs\LaravelUserStub')
->andReturn(true);
$this->provider->shouldReceive('getModel')
->once()
->andReturn('\Tymon\JWTAuth\Test\Stubs\LaravelUserStub');
$this->provider->shouldReceive('retrieveById')
->once()
->with(1)
->andReturn((object) ['id' => 1]);
$this->assertSame(1, $this->guard->userOrFail()->id);
// check that the user is stored on the object next time round
$this->assertSame(1, $this->guard->userOrFail()->id);
$this->assertTrue($this->guard->check());
}
/** @test */
public function it_should_return_null_if_an_invalid_token_is_provided()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->twice()->andReturn('invalid.token.here');
$this->jwt->shouldReceive('check')->twice()->andReturn(false);
$this->jwt->shouldReceive('getPayload->get')->never();
$this->provider->shouldReceive('retrieveById')->never();
$this->assertNull($this->guard->user()); // once
$this->assertFalse($this->guard->check()); // twice
}
/** @test */
public function it_should_return_null_if_no_token_is_provided()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->andReturn(false);
$this->jwt->shouldReceive('check')->never();
$this->jwt->shouldReceive('getPayload->get')->never();
$this->provider->shouldReceive('retrieveById')->never();
$this->assertNull($this->guard->user());
$this->assertFalse($this->guard->check());
}
/** @test */
public function it_should_throw_an_exception_if_an_invalid_token_is_provided()
{
$this->expectException(UserNotDefinedException::class);
$this->expectExceptionMessage('An error occurred');
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->twice()->andReturn('invalid.token.here');
$this->jwt->shouldReceive('check')->twice()->andReturn(false);
$this->jwt->shouldReceive('getPayload->get')->never();
$this->provider->shouldReceive('retrieveById')->never();
$this->assertFalse($this->guard->check()); // once
$this->guard->userOrFail(); // twice, throws the exception
}
/** @test */
public function it_should_throw_an_exception_if_no_token_is_provided()
{
$this->expectException(UserNotDefinedException::class);
$this->expectExceptionMessage('An error occurred');
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->andReturn(false);
$this->jwt->shouldReceive('check')->never();
$this->jwt->shouldReceive('getPayload->get')->never();
$this->provider->shouldReceive('retrieveById')->never();
$this->assertFalse($this->guard->check());
$this->guard->userOrFail(); // throws the exception
}
/** @test */
public function it_should_return_a_token_if_credentials_are_ok_and_user_is_found()
{
$credentials = ['foo' => 'bar', 'baz' => 'bob'];
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveByCredentials')
->once()
->with($credentials)
->andReturn($user);
$this->provider->shouldReceive('validateCredentials')
->once()
->with($user, $credentials)
->andReturn(true);
$this->jwt->shouldReceive('fromUser')
->once()
->with($user)
->andReturn('foo.bar.baz');
$this->jwt->shouldReceive('setToken')
->once()
->with('foo.bar.baz')
->andReturnSelf();
$this->jwt->shouldReceive('claims')
->once()
->with(['foo' => 'bar'])
->andReturnSelf();
$token = $this->guard->claims(['foo' => 'bar'])->attempt($credentials);
$this->assertSame($this->guard->getLastAttempted(), $user);
$this->assertSame($token, 'foo.bar.baz');
}
/** @test */
public function it_should_return_true_if_credentials_are_ok_and_user_is_found_when_choosing_not_to_login()
{
$credentials = ['foo' => 'bar', 'baz' => 'bob'];
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveByCredentials')
->twice()
->with($credentials)
->andReturn($user);
$this->provider->shouldReceive('validateCredentials')
->twice()
->with($user, $credentials)
->andReturn(true);
$this->assertTrue($this->guard->attempt($credentials, false)); // once
$this->assertTrue($this->guard->validate($credentials)); // twice
}
/** @test */
public function it_should_return_false_if_credentials_are_invalid()
{
$credentials = ['foo' => 'bar', 'baz' => 'bob'];
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveByCredentials')
->once()
->with($credentials)
->andReturn($user);
$this->provider->shouldReceive('validateCredentials')
->once()
->with($user, $credentials)
->andReturn(false);
$this->assertFalse($this->guard->attempt($credentials));
}
/** @test */
public function it_should_magically_call_the_jwt_instance()
{
$this->jwt->shouldReceive('factory')->andReturn(Mockery::mock(Factory::class));
$this->assertInstanceOf(Factory::class, $this->guard->factory());
}
/** @test */
public function it_should_logout_the_user_by_invalidating_the_token()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn(true);
$this->jwt->shouldReceive('invalidate')->once()->andReturn(true);
$this->jwt->shouldReceive('unsetToken')->once();
$this->guard->logout();
$this->assertNull($this->guard->getUser());
}
/** @test */
public function it_should_refresh_the_token()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn(true);
$this->jwt->shouldReceive('refresh')->once()->andReturn('foo.bar.baz');
$this->assertSame($this->guard->refresh(), 'foo.bar.baz');
}
/** @test */
public function it_should_invalidate_the_token()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn(true);
$this->jwt->shouldReceive('invalidate')->once()->andReturn(true);
$this->assertTrue($this->guard->invalidate());
}
/** @test */
public function it_should_throw_an_exception_if_there_is_no_token_present_when_required()
{
$this->expectException(JWTException::class);
$this->expectExceptionMessage('Token could not be parsed from the request.');
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn(false);
$this->jwt->shouldReceive('refresh')->never();
$this->guard->refresh();
}
/** @test */
public function it_should_generate_a_token_by_id()
{
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveById')
->once()
->with(1)
->andReturn($user);
$this->jwt->shouldReceive('fromUser')
->once()
->with($user)
->andReturn('foo.bar.baz');
$this->assertSame('foo.bar.baz', $this->guard->tokenById(1));
}
/** @test */
public function it_should_not_generate_a_token_by_id()
{
$this->provider->shouldReceive('retrieveById')
->once()
->with(1)
->andReturn(null);
$this->assertNull($this->guard->tokenById(1));
}
/** @test */
public function it_should_authenticate_the_user_by_credentials_and_return_true_if_valid()
{
$credentials = ['foo' => 'bar', 'baz' => 'bob'];
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveByCredentials')
->once()
->with($credentials)
->andReturn($user);
$this->provider->shouldReceive('validateCredentials')
->once()
->with($user, $credentials)
->andReturn(true);
$this->assertTrue($this->guard->once($credentials));
}
/** @test */
public function it_should_attempt_to_authenticate_the_user_by_credentials_and_return_false_if_invalid()
{
$credentials = ['foo' => 'bar', 'baz' => 'bob'];
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveByCredentials')
->once()
->with($credentials)
->andReturn($user);
$this->provider->shouldReceive('validateCredentials')
->once()
->with($user, $credentials)
->andReturn(false);
$this->assertFalse($this->guard->once($credentials));
}
/** @test */
public function it_should_authenticate_the_user_by_id_and_return_boolean()
{
$user = new LaravelUserStub;
$this->provider->shouldReceive('retrieveById')
->twice()
->with(1)
->andReturn($user);
$this->assertTrue($this->guard->onceUsingId(1)); // once
$this->assertTrue($this->guard->byId(1)); // twice
}
/** @test */
public function it_should_not_authenticate_the_user_by_id_and_return_false()
{
$this->provider->shouldReceive('retrieveById')
->twice()
->with(1)
->andReturn(null);
$this->assertFalse($this->guard->onceUsingId(1)); // once
$this->assertFalse($this->guard->byId(1)); // twice
}
/** @test */
public function it_should_create_a_token_from_a_user_object()
{
$user = new LaravelUserStub;
$this->jwt->shouldReceive('fromUser')
->once()
->with($user)
->andReturn('foo.bar.baz');
$this->jwt->shouldReceive('setToken')
->once()
->with('foo.bar.baz')
->andReturnSelf();
$token = $this->guard->login($user);
$this->assertSame('foo.bar.baz', $token);
}
/** @test */
public function it_should_get_the_payload()
{
$this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
$this->jwt->shouldReceive('getToken')->once()->andReturn('foo.bar.baz');
$this->jwt->shouldReceive('getPayload')->once()->andReturn(Mockery::mock(Payload::class));
$this->assertInstanceOf(Payload::class, $this->guard->payload());
}
/** @test */
public function it_should_be_macroable()
{
$this->guard->macro('foo', function () {
return 'bar';
});
$this->assertEquals('bar', $this->guard->foo());
}
}