File: /home/xedaptot/ai.naniguide.com/tests/Feature/ApiLicenseTest.php
<?php
/**
* Feature tests for POST /api/v1/license/refresh.
*
* Verifies auth gating + response shape when no license is installed.
* Real refresh-against-license-server (HTTP → verify.acellemail.com) is NOT
* covered here — smoke-tested manually per .support/HANDBOOK_DETAILS.md
* "License refresh API" section.
*/
use App\Model\Admin;
use App\Model\Setting;
use App\Model\User;
uses(\Tests\TestCase::class);
const API_LICENSE_REFRESH_URL = '/api/v1/license/refresh';
function makeUserWithTokenForLicense(string $emailSuffix = 'plain'): array
{
$user = new User();
$user->email = 'test-api-license-' . $emailSuffix . '-' . uniqid() . '@example.test';
$user->first_name = 'Test';
$user->last_name = 'User';
$user->password = bcrypt('test-' . uniqid());
$user->save();
$token = $user->fresh()->api_token;
return [$user, $token];
}
function makeAdminFromUserForLicense(User $user): Admin
{
$admin = new Admin();
$admin->user_id = $user->id;
$admin->timezone = 'UTC';
$admin->status = 'active';
$admin->color_scheme = 'default';
$admin->admin_group_id = 1; // Administrator — has setting_general = yes
$admin->save();
return $admin;
}
afterEach(function () {
foreach (User::where('email', 'like', 'test-api-license-%@example.test')->get() as $u) {
Admin::where('user_id', $u->id)->delete();
$u->delete();
}
});
// -----------------------------------------------------------------------------
// Auth gating
// -----------------------------------------------------------------------------
it('license refresh returns 401 without any token', function () {
$response = $this->postJson(API_LICENSE_REFRESH_URL, []);
expect($response->status())->toBe(401);
});
it('license refresh returns 401 for non-admin token', function () {
[, $token] = makeUserWithTokenForLicense('non-admin');
$response = $this->withHeaders(['Authorization' => 'Bearer ' . $token])
->postJson(API_LICENSE_REFRESH_URL, []);
expect($response->status())->toBe(401);
expect($response->json('message'))->toBe('Unauthorized');
});
// -----------------------------------------------------------------------------
// No license installed → 404
// -----------------------------------------------------------------------------
it('returns 404 when no license is installed', function () {
[$user, $token] = makeUserWithTokenForLicense('no-license');
makeAdminFromUserForLicense($user);
$savedLicense = Setting::get('license');
Setting::set('license', '');
try {
$response = $this->withHeaders(['Authorization' => 'Bearer ' . $token])
->postJson(API_LICENSE_REFRESH_URL, []);
expect($response->status())->toBe(404);
expect($response->json('message'))->toBe('No license installed');
expect($response->json('license'))->toBeNull();
} finally {
Setting::set('license', $savedLicense);
}
});