我们有以下中间件。我们知道中间件可以正常工作,因为在浏览器中测试应用程序正常工作。可悲的是,在编写 HTTP 测试用例时,刀片说中间件定义的变量不存在。
<?php
namespace App\Http\Middleware;
use App\Repository\UserContract;
use Closure;
use Illuminate\Contracts\View\Factory as ViewFactory;
use Illuminate\Support\Facades\View;
class Authenticate
{
private $userRepository;
private $view;
public function __construct(UserContract $userRepository, ViewFactory $view)
{
$this->userRepository = $userRepository;
$this->view = $view;
}
public function handle($request, Closure $next)
{
$userId = null;
$username = null;
if ($request->hasCookie('auth')) {
$secret = $request->cookie('auth');
$userId = $this->userRepository->getUserIdBySecret($secret);
$username = $this->userRepository->getUsername($userId);
}
$this->view->share('username', $username);
$request['_user_id'] = $userId;
$request['_username'] = $username;
return $next($request);
}
}
我们进行如下 PHPUnit 测试:
/**
* @test
*/
public function it_shows_logged_in_username()
{
$app = $this->createApplication();
$encrypter = $app->get(Encrypter::class);
$userRepository = $app->make(UserContract::class);
$userRepository->addUser('jane', 'secret');
$secret = $encrypter->encrypt('secret', false);
$response = $this->call('GET', '/', [], ['auth' => $secret], [], [], null);
$response->assertSeeText('jane');
}
错误
ErrorException {#980
#message: "Undefined variable: username"
#code: 0
#file: "./storage/framework/views/db4b9232a3b0957f912084f26d9041e8a510bd6c.php"
#line: 3
#severity: E_NOTICE
trace: {
./storage/framework/views/db4b9232a3b0957f912084f26d9041e8a510bd6c.php:3 {
› <?php dump($comments); ?>
› <?php dump($username); ?>
任何意见,将不胜感激?
编辑
我必须使用View
外观添加它并调用它的share
方法使其工作,但我遇到了errors
应该由\Illuminate\View\Middleware\ShareErrorsFromSession
股票 laravel 中间件设置的变量的相同问题。
其他备注,我的中间件被调用Authenticate
,但它与 Laravel 的基于密码的普通身份验证无关。
这里UserContract
:
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Repository\Exception\UserAlreadyRegisteredException;
interface UserContract
{
public function isRegistered(string $username): bool;
public function getUserID(string $username): int;
public function getUserIdBySecret(string $secret): int;
/**
* @param int $userId
*
* @return string
* @throws
*/
public function getUsername(int $userId): string;
/**
* @param int $userId
*
* @return string
* @throws AuthSecretNotSetException
*/
public function getUserAuthSecret(int $userId): string;
public function getNextId(): int;
/**
* @param string $username
* @param string $authSecret
*
* @return int
* @throws UserAlreadyRegisteredException
*/
public function addUser(string $username, string $authSecret): int;
public function fetchUpdatedBetween(?\DateTimeInterface $start, ?\DateTimeInterface $end): array;
public function markAsSynced(int $userId): void;
public function isSynced(int $userId): bool;
public function delete(int $userId): void;
public function markAsDeleted(int $userId): void;
public function fetchDeletedIds(): array;
public function removeDeletedFlag(int $userId): void;
public function fetchStalledIds(\DateTimeInterface $dateTime): array;
public function purge(int $userId): void;
/**
* @param UserFetcherContract $fetcher the closure would be passed userId and it should return data or null
*/
public function setFallbackFetcher(UserFetcherContract $fetcher): void;
}