Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/Http/Controllers/Api/Client/AccountController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Facades\Activity;
use App\Http\Requests\Api\Client\Account\UpdateEmailRequest;
use App\Http\Requests\Api\Client\Account\UpdatePasswordRequest;
use App\Http\Requests\Api\Client\Account\UpdateUsernameRequest;
use App\Services\Users\UserUpdateService;
use App\Transformers\Api\Client\UserTransformer;
use Illuminate\Auth\AuthManager;
Expand Down Expand Up @@ -36,6 +37,25 @@ public function index(Request $request): array
->toArray();
}

/**
* Update username
*
* Update the authenticated user's username.
*/
public function updateUsername(UpdateUsernameRequest $request): JsonResponse
{
$original = $request->user()->username;
$this->updateService->handle($request->user(), $request->validated());

if ($original !== $request->input('username')) {
Activity::event('user:account.username-changed')
->property(['old' => $original, 'new' => $request->input('username')])
->log();
}

return new JsonResponse([], Response::HTTP_NO_CONTENT);
}

/**
* Update email
*
Expand Down
38 changes: 38 additions & 0 deletions app/Http/Requests/Api/Client/Account/UpdateUsernameRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Http\Requests\Api\Client\Account;

use App\Exceptions\Http\Base\InvalidPasswordProvidedException;
use App\Http\Requests\Api\Client\ClientApiRequest;
use App\Models\User;
use Illuminate\Container\Container;
use Illuminate\Contracts\Hashing\Hasher;

class UpdateUsernameRequest extends ClientApiRequest
{
/**
* @throws InvalidPasswordProvidedException
*/
public function authorize(): bool
{
if (!parent::authorize()) {
return false;
}

$hasher = Container::getInstance()->make(Hasher::class);

// Verify password matches when changing password or email.
if (!$hasher->check($this->input('password'), $this->user()->password)) {
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
}

return true;
}

public function rules(): array
{
$rules = User::getRulesForUpdate($this->user());

return ['username' => $rules['username']];
}
}
1 change: 1 addition & 0 deletions lang/en/activity.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
],
'user' => [
'account' => [
'username-changed' => 'Changed username from <b>:old</b> to <b>:new</b>',
'email-changed' => 'Changed email from <b>:old</b> to <b>:new</b>',
'password-changed' => 'Changed password',
],
Expand Down
1 change: 1 addition & 0 deletions routes/api-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
Route::prefix('/account')->middleware(AccountSubject::class)->group(function () {
Route::get('/', [Client\AccountController::class, 'index'])->name('api:client.account');

Route::put('/username', [Client\AccountController::class, 'updateUsername'])->name('api:client.account.update-username');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

LGTM — route mirrors existing email/password endpoints.

Add/verify API docs and tests cover this new route and name.


🏁 Script executed:

#!/bin/bash
# Find route, method, and tests/usages.
rg -nC2 $'/account/username|updateUsername|api:client.account.update-username'

Length of output: 1067


I can see the route, controller method, and parallel endpoints exist. Now I need to verify if API documentation and tests cover this route.<!-- [scratchpad_update]
[task verification_3/3: api_docs_and_tests]
Web search confirms Laravel API testing best practices exist (PHPUnit, Laravel testing framework). Now need to search repository for actual test files and API documentation files related to this endpoint.

[actions]

  • Search tests/ directory for test files matching updateUsername, account, or api tests
  • Search for API documentation files (.md, OpenAPI specs, etc.)
    [scratchpad_end] -->

🏁 Script executed:

#!/bin/bash
# Search for test files related to AccountController or updateUsername
find tests -type f -name "*.php" 2>/dev/null | xargs grep -l "updateUsername\|AccountController\|account.*update\|api:client.account" 2>/dev/null | head -20

Length of output: 120


🏁 Script executed:

#!/bin/bash
# Search for API documentation files
find . -type f \( -name "*api*doc*" -o -name "*.md" -o -name "openapi*" -o -name "swagger*" \) 2>/dev/null | grep -v node_modules | head -20

Length of output: 92


🏁 Script executed:

#!/bin/bash
# Look for test directories and their structure
find tests -type d | head -30

Length of output: 927


🏁 Script executed:

#!/bin/bash
# Check for any test files in tests directory
ls -la tests/ 2>/dev/null || echo "tests directory not found or empty"

Length of output: 587


🏁 Script executed:

#!/bin/bash
# Check AccountControllerTest.php for updateUsername test coverage
cat tests/Integration/Api/Client/AccountControllerTest.php

Length of output: 7059


🏁 Script executed:

#!/bin/bash
# Search markdown files for API documentation about this endpoint
grep -r "username\|account.*update\|/account/" readme.md contributing.md 2>/dev/null || echo "No matches in main docs"

Length of output: 23


Tests are missing for the new updateUsername route.

The route is well-formed and mirrors the email/password endpoints, but AccountControllerTest.php lacks test coverage for PUT /api/client/account/username. The parallel email and password update endpoints have comprehensive tests; add similar tests for username validation, success cases, and error handling. API documentation is also not discoverable in the repository's standard documentation files.

🤖 Prompt for AI Agents
In routes/api-client.php around line 24, the new PUT
/api/client/account/username route lacks test coverage and documentation; add
tests to AccountControllerTest.php mirroring the email/password update specs:
create tests for successful username change (authenticated client, send valid
username, assert 200, database updated and response body), validation failures
(too short/invalid chars, assert 422 and validation error messages), and
uniqueness/conflict handling if applicable (assert proper error code/message);
use the same setup helpers as existing email/password tests, call the route by
name ('api:client.account.update-username'), and add the route entry to the
project's API documentation files so the endpoint is discoverable.

Route::put('/email', [Client\AccountController::class, 'updateEmail'])->name('api:client.account.update-email');
Route::put('/password', [Client\AccountController::class, 'updatePassword'])->name('api:client.account.update-password');

Expand Down