Skip to content

Commit

Permalink
Merge pull request #36 from musimana/feature/10.x/PassStanLvl8
Browse files Browse the repository at this point in the history
[10.x] Pass Stan Level 8
  • Loading branch information
musimana authored Mar 30, 2024
2 parents ae73085 + bce60ff commit f2304c8
Show file tree
Hide file tree
Showing 18 changed files with 105 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class AuthenticatedSessionController extends Controller
public function create(): RedirectResponse|Response
{
if (auth()->check()) {
return redirect(route('home'));
return to_route('dashboard');
}

return (new AuthViewRepository)->getViewDetails(
Expand Down
12 changes: 4 additions & 8 deletions app/Http/Controllers/Auth/EmailVerificationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class EmailVerificationController extends Controller
/** Display the email verification prompt. */
public function show(): RedirectResponse|Response
{
return request()->user()->hasVerifiedEmail()
return request()->user()?->hasVerifiedEmail()
? redirect()->intended(RouteServiceProvider::HOME)
: (new AuthViewRepository)->getViewDetails(
self::TEMPLATE_EMAIL_VERIFY,
Expand All @@ -31,23 +31,19 @@ public function show(): RedirectResponse|Response
/** Send a new email verification notification, after a manual request by the user. */
public function store(): RedirectResponse
{
if (request()->user()->hasVerifiedEmail()) {
if (request()->user()?->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME);
}

request()->user()->sendEmailVerificationNotification();
request()->user()?->sendEmailVerificationNotification();

return back()->with('status', 'verification-link-sent');
}

/** Mark the authenticated user's email address as verified. */
public function edit(EmailVerificationRequest $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
}

if ($request->user()->markEmailAsVerified()) {
if (!$request->user()?->hasVerifiedEmail() && $request->user()?->markEmailAsVerified()) {
/** @var MustVerifyEmail $user */
$user = $request->user();
event(new Verified($user));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function show(): Response
public function store(Request $request): RedirectResponse
{
if (!Auth::guard('web')->validate([
'email' => $request->user()->email,
'email' => $request->user()?->email,
'password' => $request->password,
])) {
throw ValidationException::withMessages([
Expand Down
21 changes: 18 additions & 3 deletions app/Http/Controllers/Auth/ProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Inertia\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

final class ProfileController extends Controller
{
Expand Down Expand Up @@ -71,9 +72,17 @@ public function edit(): Response
);
}

/** Update the authenticated user's profile information. */
/**
* Update the authenticated user's profile information.
*
* @throws HttpException
*/
public function update(ProfileUpdateRequest $request): RedirectResponse
{
if (!$request->user()) {
abort(401);
}

$request->user()->fill($request->validated());

if ($request->user()->isDirty('email')) {
Expand All @@ -85,10 +94,16 @@ public function update(ProfileUpdateRequest $request): RedirectResponse
return to_route('profile.edit');
}

/** Delete the authenticated user's account. */
/**
* Delete the authenticated user's account.
*
* @throws HttpException
*/
public function destroy(ProfileDeleteRequest $request): RedirectResponse
{
$user = $request->user();
if (!$user = $request->user()) {
abort(401);
}

auth()->logout();

Expand Down
11 changes: 10 additions & 1 deletion app/Http/Controllers/Auth/ProfilePasswordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\PasswordUpdateRequest;
use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\HttpException;

final class ProfilePasswordController extends Controller
{
/** Update the authenticated user's password. */
/**
* Update the authenticated user's password.
*
* @throws HttpException
*/
public function update(PasswordUpdateRequest $request): RedirectResponse
{
if (!$request->user()) {
abort(401);
}

$inputs = $request->validated();

$request->user()->update([
Expand Down
12 changes: 10 additions & 2 deletions app/Http/Controllers/Public/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@

final class PageController extends Controller
{
/** Display the given page. */
/**
* Display the given page.
*
* @throws HttpException
*/
public function show(Page $page): Response
{
if (!$page->template) {
abort(404);
}

return (new PublicViewRepository)
->getViewDetails(
$page->template,
Expand Down Expand Up @@ -59,7 +67,7 @@ public function store(Request $request, Page $page): RedirectResponse
$files = [$files];
}

if (!$generated_filename = $files[0]->store('uploads/pdf')) {
if (!$generated_filename = $files[0]?->store('uploads/pdf')) {
Log::error('ERROR | Failed to store uploaded PDF file for request:', $response);

abort(500, 'Failed to store uploaded PDF file');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ final class ItemLinksNavbarResource implements NavbarItemInterface
/**
* Get the content array for the given page's public link.
*
* @return array<string, string|array<string, string>>
* @return array<string, null|string|array<string, null|string>>
*/
public function getItem(NavbarItem $navbar_item): array
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ final class HomepageSitemapResource implements ConstantItemInterface
*/
public function getItem(): array
{
$lastmod = strtotime(strval(Page::max('updated_at')));

return [
'loc' => route('home'),
'lastmod' => date('Y-m-d', strtotime(Page::max('updated_at'))),
'lastmod' => $lastmod ? date('Y-m-d', $lastmod) : '2024-03-01',
'changefreq' => 'weekly',
'priority' => 0.8,
];
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Resources/Views/Sitemaps/PageSitemapResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final class PageSitemapResource implements PageItemInterface
*/
public function getItem(Page $page): array
{
$updated_at = strtotime($page->updated_at);
$updated_at = strtotime(strval($page->updated_at));
$lastmod = $updated_at ? date('Y-m-d', $updated_at) : strval(config('metadata.first_published_year')) . '-01-01';

return [
Expand Down
8 changes: 1 addition & 7 deletions app/Models/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,13 @@ final class Page extends Model
'is_homepage' => 'boolean',
];

/** GETTERS */

/** Get the HTML content string for the page. */
public function getContent(): string
{
return $this->content ?? '';
}

/**
* Get the public URL's path for the page.
*/
/** Get the public URL's path for the page. */
public function getPath(): string
{
return $this->is_homepage
Expand All @@ -81,8 +77,6 @@ public function getUrl(): string
: route('page.show', $this->slug);
}

/** SCOPES */

/** Returns all Page models that should be in the sitemap (in_sitemap = 1). */
public function scopeInSitemap(Builder|QueryBuilder $query): Builder|QueryBuilder
{
Expand Down
40 changes: 26 additions & 14 deletions app/Providers/DuskServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,61 @@
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Browser;

/**
* @method string getScreenshotFilename(string $filename_base, string $count_string)
* @method Browser scrollToTop()
*/
final class DuskServiceProvider extends ServiceProvider implements DeferrableProvider
{
/** Register Dusk's browser macros. */
public function boot(): void
{
Browser::macro('getScreenshotFilename', function ($filename_base, $count) {
Browser::macro('getScreenshotFilename', function (string $filename_base, string $count_string) {
return date('Y-m-d') . '_' . str_replace(' ', '_', strtolower(config('app.name')))
. '/' . config('dusk.screen_width') . 'x' . config('dusk.screen_height')
. '/' . $filename_base . '_' . $count;
. '/' . $filename_base . '_' . $count_string;
});

Browser::macro('screenshotWholePage', function ($filename_base) {
$this->scrollToTop()->pause(config('dusk.pause_length'));
Browser::macro('screenshotWholePage', function (string $filename_base) {
/** @var Browser $browser */
$browser = $this;
$browser->scrollToTop()->pause(config('dusk.pause_length'));

$screen_max = ceil($this->script('return document.body.offsetHeight / window.innerHeight')[0]);
$screen_max = ceil($browser->script('return document.body.offsetHeight / window.innerHeight')[0]);

for ($screen = 1; $screen <= $screen_max; $screen++) {
$this->screenshot($this->getScreenshotFilename($filename_base, $screen))
$browser->screenshot($browser->getScreenshotFilename($filename_base, (string) $screen))
->pause(config('dusk.pause_length'))
->scrollDownScreenHeight();
}

$this->scrollToTop()->pause(config('dusk.pause_length'));
$browser->scrollToTop()->pause(config('dusk.pause_length'));

return $this;
return $browser;
});

Browser::macro('scrollToTop', function () {
$this->script('window.scrollTo(0, 0)');
/** @var Browser $browser */
$browser = $this;
$browser->script('window.scrollTo(0, 0)');

return $this;
return $browser;
});

Browser::macro('scrollDownScreenHeight', function () {
$this->script('window.scrollBy(0, window.innerHeight)');
/** @var Browser $browser */
$browser = $this;
$browser->script('window.scrollBy(0, window.innerHeight)');

return $this;
return $browser;
});

Browser::macro('scrollToEnd', function () {
$this->script('window.scrollTo(0, document.body.scrollHeight)');
/** @var Browser $browser */
$browser = $this;
$browser->script('window.scrollTo(0, document.body.scrollHeight)');

return $this;
return $browser;
});
}

Expand Down
30 changes: 22 additions & 8 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ parameters:
- tests/

# Level 9 is the highest level
level: 7

ignoreErrors:
level: 8

excludePaths:
- tests/Browser # 16 errors 2024-03-16, all `Call to an undefined method Laravel\Dusk\Browser::`
- tests/Feature # 252 errors 2024-03-16
- tests/Pest # 32 errors 2024-03-16
- tests/Unit # 150 errors 2024-03-16
- app/Providers/DuskServiceProvider.php # 8 errors 2024-02-01, all `Call to an undefined method App\Providers\DuskServiceProvider::`
- tests/Pest/Functions/CompositeTests # 5 errors 2024-03-29, whole directory needs refactoring

ignoreErrors:
- # From the way the methods are inherited by Pest
message: '#Call to an undefined method Pest\\#'
path: tests
- # To be fixed by adopting Pest syntax
message: '#Undefined variable: \$this#'
path: tests
- # From the way the methods are inherited by the Browser object
message: '#Call to an undefined method Laravel\\Dusk\\Browser::#'
path: tests/Browser
count: 16
- # From the way the methods are inherited by Pest
message: '#Function testNotifiedUpdate#'
path: tests/Feature/Http/Controllers/Auth/PasswordForgottenControllerTest.php
count: 5
- # From the way the methods are inherited by Pest
message: '#Access to an undefined property Pest\\Mixins\\Expectation\<App\\Models\\#'
path: tests/Unit
count: 3

checkGenericClassInNonGenericObjectType: false
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
$actual = $this->actingAs($user)->get($verificationUrl);

Event::assertDispatched(Verified::class);
expect($user->fresh()->hasVerifiedEmail())->toBeTrue();
expect($user->fresh()?->hasVerifiedEmail())->toBeTrue();

$actual
->assertSessionHasNoErrors()
Expand All @@ -96,5 +96,5 @@

$this->actingAs($user)->get($verificationUrl);

expect($user->fresh()->hasVerifiedEmail())->toBeFalse();
expect($user->fresh()?->hasVerifiedEmail())->toBeFalse();
})->with('users-unverified');
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use App\Http\Resources\Views\Auth\Metadata\DashboardMetadataResource;
use App\Http\Resources\Views\Auth\Metadata\ProfileEditMetadataResource;
use App\Models\User;
use Illuminate\Http\Request;

test('TEMPLATE_DASHBOARD Vue page component exists', function () {
$template = (new ReflectionClassConstant(
Expand Down Expand Up @@ -76,7 +75,7 @@
->toHaveCorrectPropsAuth(
ProfileController::TEMPLATE_PROFILE_EDIT,
[],
(new ProfileEditMetadataResource)->getItem(new Request)
(new ProfileEditMetadataResource)->getItem()
);
})->with('users');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

use App\Http\Resources\Views\Auth\Metadata\PasswordResetMetadataResource;
use App\Interfaces\Resources\Items\ConstantItemInterface;
use Illuminate\Http\Request;

arch('it implements the expected interface')
->expect(PasswordResetMetadataResource::class)
->toImplement(ConstantItemInterface::class);

test('getItem returns ok', function () {
$actual = (new PasswordResetMetadataResource)->getItem(new Request);
$actual = (new PasswordResetMetadataResource)->getItem();

expect($actual)
->toHaveCamelCaseKeys()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

use App\Http\Resources\Views\Auth\Metadata\ProfileEditMetadataResource;
use App\Interfaces\Resources\Items\ConstantItemInterface;
use Illuminate\Http\Request;

arch('it implements the expected interface')
->expect(ProfileEditMetadataResource::class)
->toImplement(ConstantItemInterface::class);

test('getItem returns ok', function () {
$actual = (new ProfileEditMetadataResource)->getItem(new Request);
$actual = (new ProfileEditMetadataResource)->getItem();

expect($actual)
->toHaveCamelCaseKeys()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
->toHaveCount(4)
->toMatchArray([
'loc' => url('/'),
'lastmod' => '1970-01-01',
'lastmod' => '2024-03-01',
'changefreq' => 'weekly',
'priority' => 0.8,
]);
Expand Down
Loading

0 comments on commit f2304c8

Please sign in to comment.