Show only the name and email, not who the account books for
CI / Tests (PHP 8.2) (pull_request) Successful in 42s
CI / PHPStan (pull_request) Successful in 2m56s
CI / Coding Standards (pull_request) Successful in 2m57s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m44s
CI / Tests (PHP 8.1) (pull_request) Successful in 53s
CI / No Debug Code (pull_request) Successful in 2s
CI / Build Plugin Zip (pull_request) Skipped

The block reports who is signed in and nothing more. Dropping the "Booking
for …" line takes GuardianService with it — it was the only reason the page
had a dependency at all, so AccountPage now constructs with no arguments.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-07-29 22:35:04 -03:00
co-authored by Claude Opus 5
parent 46cee7a454
commit 4c92d19d2e
9 changed files with 7 additions and 84 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ each change under the current top section as you work.
## [1.3.1] ## [1.3.1]
### Added ### Added
- An **Account** block (`[us_account]`) showing who is signed in — their name, their email, the students they book for if that is anyone besides themselves — and a **Sign out** link. Signing out returns to the login page chosen in the block, or to the page the visitor was already on when none is set, so putting it in a site header does not also move people somewhere. To a signed-out visitor it shows a **Sign in** link when a login page is chosen, and nothing at all when one is not: a panel about who is signed in has nothing to tell a stranger, and a notice they cannot act on is just clutter in a header. - An **Account** block (`[us_account]`) showing who is signed in — their name and their email — and a **Sign out** link. Signing out returns to the login page chosen in the block, or to the page the visitor was already on when none is set, so putting it in a site header does not also move people somewhere. To a signed-out visitor it shows a **Sign in** link when a login page is chosen, and nothing at all when one is not: a panel about who is signed in has nothing to tell a stranger, and a notice they cannot act on is just clutter in a header.
### Changed ### Changed
- A student's **name and birth year are now required**, marked in the form the same way a required registration question is and enforced on the server whichever way they were submitted. On signup the requirement applies only once the parent/guardian box is ticked, so registering for yourself is unaffected. A student block you have started filling in is now reported back to you rather than silently dropped when the name is missing — only a completely untouched spare block is still ignored. - A student's **name and birth year are now required**, marked in the form the same way a required registration question is and enforced on the server whichever way they were submitted. On signup the requirement applies only once the parent/guardian box is ticked, so registering for yourself is unaffected. A student block you have started filling in is now reported back to you rather than silently dropped when the name is missing — only a completely untouched spare block is still ignored.
+1 -2
View File
@@ -538,8 +538,7 @@
font-weight: 600; font-weight: 600;
} }
.us-account-email, .us-account-email {
.us-account-students {
display: block; display: block;
font-size: 0.9em; font-size: 0.9em;
opacity: 0.75; opacity: 0.75;
+1 -1
View File
@@ -310,7 +310,7 @@
{ {
name: 'us-scheduler/account', name: 'us-scheduler/account',
title: __('Account', 'unsupervised-schedular'), title: __('Account', 'unsupervised-schedular'),
description: __('Shows who is signed in, who they book for, and a sign out link. Renders nothing for signed-out visitors unless a login page is chosen.', 'unsupervised-schedular'), description: __('Shows the name and email of whoever is signed in, with a sign out link. Renders nothing for signed-out visitors unless a login page is chosen.', 'unsupervised-schedular'),
icon: 'admin-users', icon: 'admin-users',
keywords: ['account', 'sign out', 'log out', 'signed in', 'profile'], keywords: ['account', 'sign out', 'log out', 'signed in', 'profile'],
shortcode: 'us_account', shortcode: 'us_account',
+2 -3
View File
@@ -142,7 +142,6 @@ header is noise that cannot be acted on, so:
- **Login page chosen** → a single **Sign in** link. - **Login page chosen** → a single **Sign in** link.
Signed in, it shows the display name (`Auth\UserName::format()`, so a username Signed in, it shows the display name (`Auth\UserName::format()`, so a username
is never exposed), the account email, a **Sign out** link, and — only on an is never exposed), the account email, and a **Sign out** link — deliberately
account that books for someone other than itself — the students it books for. nothing else. Signing out returns to the chosen login page, or to the current page when there
Signing out returns to the chosen login page, or to the current page when there
is none, so a header sign-out does not also navigate the visitor somewhere. is none, so a header sign-out does not also navigate the visitor somewhere.
-13
View File
@@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Unsupervised\Schedular\Auth; namespace Unsupervised\Schedular\Auth;
use Unsupervised\Schedular\Guardian\GuardianService;
use Unsupervised\Schedular\Val; use Unsupervised\Schedular\Val;
/** /**
@@ -15,8 +14,6 @@ use Unsupervised\Schedular\Val;
*/ */
class AccountPage { class AccountPage {
public function __construct( private GuardianService $guardians ) {}
/** /**
* Renders the account shortcode/block output. * Renders the account shortcode/block output.
* *
@@ -55,16 +52,6 @@ class AccountPage {
$name = UserName::format( $user, get_current_user_id() ); $name = UserName::format( $user, get_current_user_id() );
$email = $user->user_email; $email = $user->user_email;
// Whose lessons this account books, when that is more than just their own.
// A parent's first question on seeing "signed in as Grace" is whether this
// is the account their children's lessons are on.
$students = [];
foreach ( $this->guardians->bookableStudents( get_current_user_id() ) as $student ) {
if ( ! $student['is_self'] ) {
$students[] = $student['name'];
}
}
// Back to where they were, so signing out of a header link does not also // Back to where they were, so signing out of a header link does not also
// navigate them somewhere. The login page is the better landing spot when // navigate them somewhere. The login page is the better landing spot when
// one is configured, since the current page may be members-only. // one is configured, since the current page may be members-only.
-8
View File
@@ -220,18 +220,10 @@ class BlockPreview {
'<div class="us-account">%s' '<div class="us-account">%s'
. '<p class="us-account-who"><span class="us-account-name">%s</span>' . '<p class="us-account-who"><span class="us-account-name">%s</span>'
. '<span class="us-account-email">%s</span></p>' . '<span class="us-account-email">%s</span></p>'
. '<p class="us-account-students">%s</p>'
. '<p class="us-account-actions"><a class="us-account-signout" href="#">%s</a></p></div>', . '<p class="us-account-actions"><a class="us-account-signout" href="#">%s</a></p></div>',
self::note( __( 'Editor preview — each visitor sees their own account here.', 'unsupervised-schedular' ) ), self::note( __( 'Editor preview — each visitor sees their own account here.', 'unsupervised-schedular' ) ),
esc_html__( 'Grace Hopper', 'unsupervised-schedular' ), esc_html__( 'Grace Hopper', 'unsupervised-schedular' ),
esc_html__( '[email protected]', 'unsupervised-schedular' ), esc_html__( '[email protected]', 'unsupervised-schedular' ),
esc_html(
sprintf(
/* translators: %s: comma-separated list of the students this account books for. */
__( 'Booking for %s', 'unsupervised-schedular' ),
__( 'Ada, Alan', 'unsupervised-schedular' )
)
),
esc_html__( 'Sign out', 'unsupervised-schedular' ) esc_html__( 'Sign out', 'unsupervised-schedular' )
); );
} }
+1 -1
View File
@@ -100,7 +100,7 @@ class Plugin {
$registrationPage = new RegistrationPage( $invites, $policies, $policyVersions, $acceptances, $settings, $registrationMailer, $questions, $answers, $groupAccess, $guardians ); $registrationPage = new RegistrationPage( $invites, $policies, $policyVersions, $acceptances, $settings, $registrationMailer, $questions, $answers, $groupAccess, $guardians );
$groupClassPage = new GroupClassPage( $guardians ); $groupClassPage = new GroupClassPage( $guardians );
$familyPage = new FamilyPage( $guardians, $questions, $answers ); $familyPage = new FamilyPage( $guardians, $questions, $answers );
$accountPage = new AccountPage( $guardians ); $accountPage = new AccountPage();
( new ScheduledBillingRunner( $paymentService, $bookings, $enrollments, $offerings, new PaymentDueMailer(), $guardians ) )->register(); ( new ScheduledBillingRunner( $paymentService, $bookings, $enrollments, $offerings, new PaymentDueMailer(), $guardians ) )->register();
-13
View File
@@ -8,7 +8,6 @@ if (! defined('ABSPATH')) {
/** /**
* @var string $name Display name of the signed-in visitor. * @var string $name Display name of the signed-in visitor.
* @var string $email Their account email. * @var string $email Their account email.
* @var list<string> $students Names this account books for, excluding themselves; empty for a plain student account.
* @var string $logoutUrl Nonced sign-out URL, already carrying its redirect. * @var string $logoutUrl Nonced sign-out URL, already carrying its redirect.
*/ */
?> ?>
@@ -20,18 +19,6 @@ if (! defined('ABSPATH')) {
<?php endif; ?> <?php endif; ?>
</p> </p>
<?php if (! empty($students)) : ?>
<p class="us-account-students">
<?php
printf(
/* translators: %s: comma-separated list of the students this account books for. */
esc_html__('Booking for %s', 'unsupervised-schedular'),
esc_html(implode(', ', $students))
);
?>
</p>
<?php endif; ?>
<p class="us-account-actions"> <p class="us-account-actions">
<a class="us-account-signout" href="<?php echo esc_url($logoutUrl); ?>"><?php esc_html_e('Sign out', 'unsupervised-schedular'); ?></a> <a class="us-account-signout" href="<?php echo esc_url($logoutUrl); ?>"><?php esc_html_e('Sign out', 'unsupervised-schedular'); ?></a>
</p> </p>
+1 -42
View File
@@ -6,20 +6,17 @@ namespace Unsupervised\Schedular\Tests\Unit\Auth;
use Brain\Monkey\Functions; use Brain\Monkey\Functions;
use Mockery; use Mockery;
use Unsupervised\Schedular\Auth\AccountPage; use Unsupervised\Schedular\Auth\AccountPage;
use Unsupervised\Schedular\Guardian\GuardianService;
use Unsupervised\Schedular\Tests\Unit\TestCase; use Unsupervised\Schedular\Tests\Unit\TestCase;
class AccountPageTest extends TestCase class AccountPageTest extends TestCase
{ {
private GuardianService&Mockery\MockInterface $guardians;
private AccountPage $page; private AccountPage $page;
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
$this->guardians = Mockery::mock(GuardianService::class); $this->page = new AccountPage();
$this->page = new AccountPage($this->guardians);
Functions\when('is_user_logged_in')->justReturn(true); Functions\when('is_user_logged_in')->justReturn(true);
Functions\when('get_current_user_id')->justReturn(5); Functions\when('get_current_user_id')->justReturn(5);
@@ -47,16 +44,8 @@ class AccountPageTest extends TestCase
return $user; return $user;
} }
/** @param list<array{id: int, name: string, is_self: bool}> $students */
private function bookable(array $students): void
{
$this->guardians->shouldReceive('bookableStudents')->with(5)->andReturn($students);
}
public function testShowsTheSignedInNameAndEmail(): void public function testShowsTheSignedInNameAndEmail(): void
{ {
$this->bookable([['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true]]);
$html = $this->page->render([]); $html = $this->page->render([]);
self::assertStringContainsString('Grace Hopper', $html); self::assertStringContainsString('Grace Hopper', $html);
@@ -64,32 +53,8 @@ class AccountPageTest extends TestCase
self::assertStringContainsString('Sign out', $html); self::assertStringContainsString('Sign out', $html);
} }
public function testNamesTheStudentsTheAccountBooksFor(): void
{
$this->bookable([
['id' => 42, 'name' => 'Ada', 'is_self' => false],
['id' => 43, 'name' => 'Alan', 'is_self' => false],
['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true],
]);
self::assertStringContainsString('Booking for Ada, Alan', $this->page->render([]));
}
/**
* An account that only books for itself has nothing to add — "Booking for
* Grace Hopper" under "Grace Hopper" is noise.
*/
public function testSaysNothingAboutStudentsOnAPlainAccount(): void
{
$this->bookable([['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true]]);
self::assertStringNotContainsString('Booking for', $this->page->render([]));
}
public function testSigningOutReturnsToTheConfiguredLoginPage(): void public function testSigningOutReturnsToTheConfiguredLoginPage(): void
{ {
$this->bookable([['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true]]);
self::assertStringContainsString( self::assertStringContainsString(
rawurlencode('https://studio.test/sign-in/'), rawurlencode('https://studio.test/sign-in/'),
$this->page->render(['loginPageId' => 9]) $this->page->render(['loginPageId' => 9])
@@ -102,8 +67,6 @@ class AccountPageTest extends TestCase
*/ */
public function testSigningOutReturnsToTheCurrentPageWhenNoLoginPageIsSet(): void public function testSigningOutReturnsToTheCurrentPageWhenNoLoginPageIsSet(): void
{ {
$this->bookable([['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true]]);
self::assertStringContainsString( self::assertStringContainsString(
rawurlencode('https://studio.test/current/'), rawurlencode('https://studio.test/current/'),
$this->page->render([]) $this->page->render([])
@@ -112,8 +75,6 @@ class AccountPageTest extends TestCase
public function testTheShortcodeAttributeNameIsAccepted(): void public function testTheShortcodeAttributeNameIsAccepted(): void
{ {
$this->bookable([['id' => 5, 'name' => 'Grace Hopper', 'is_self' => true]]);
self::assertStringContainsString( self::assertStringContainsString(
rawurlencode('https://studio.test/sign-in/'), rawurlencode('https://studio.test/sign-in/'),
$this->page->render(['login_page_id' => 9]) $this->page->render(['login_page_id' => 9])
@@ -127,7 +88,6 @@ class AccountPageTest extends TestCase
public function testRendersNothingForASignedOutVisitorWithNoLoginPage(): void public function testRendersNothingForASignedOutVisitorWithNoLoginPage(): void
{ {
Functions\when('is_user_logged_in')->justReturn(false); Functions\when('is_user_logged_in')->justReturn(false);
$this->guardians->shouldNotReceive('bookableStudents');
self::assertSame('', $this->page->render([])); self::assertSame('', $this->page->render([]));
} }
@@ -135,7 +95,6 @@ class AccountPageTest extends TestCase
public function testOffersASignInLinkToASignedOutVisitorWhenAPageIsChosen(): void public function testOffersASignInLinkToASignedOutVisitorWhenAPageIsChosen(): void
{ {
Functions\when('is_user_logged_in')->justReturn(false); Functions\when('is_user_logged_in')->justReturn(false);
$this->guardians->shouldNotReceive('bookableStudents');
$html = $this->page->render(['loginPageId' => 9]); $html = $this->page->render(['loginPageId' => 9]);