Update & Complete API controllers tests and Unit tests

This commit is contained in:
Bubka 2023-03-08 17:43:26 +01:00
parent 823acde49d
commit 0a8807d87a
18 changed files with 545 additions and 99 deletions

View File

@ -8,20 +8,14 @@
class ReleaseRadar
{
/**
* @var ReleaseRadarService
*/
protected $releaseRadar;
/**
* Create the event listener.
*
* @param \App\Services\ReleaseRadarService $releaseRadar
* @return void
*/
public function __construct(ReleaseRadarService $releaseRadar)
public function __construct()
{
$this->releaseRadar = $releaseRadar;
//
}
/**
@ -32,7 +26,9 @@ public function __construct(ReleaseRadarService $releaseRadar)
*/
public function handle(ScanForNewReleaseCalled $event)
{
$this->releaseRadar->scheduledScan();
$releaseRadarService = app()->make(ReleaseRadarService::class);
$releaseRadarService::scheduledScan();
Log::info('Scheduled release scan complete');
}
}

View File

@ -414,9 +414,7 @@ public function fillWithOtpParameters(array $parameters, bool $skipIconFetching
$this->enforceAsSteam();
}
$user = is_null($this->user) ? Auth::user() : $this->user;
if (! $this->icon && $user->preferences['getOfficialIcons'] && ! $skipIconFetching) {
if (! $this->icon && $this->shouldGetOfficialIcon() && ! $skipIconFetching) {
$this->icon = $this->getDefaultIcon();
}
@ -467,10 +465,8 @@ public function fillWithURI(string $uri, bool $isSteamTotp = false, bool $skipIc
if ($this->generator->hasParameter('image')) {
self::setIcon($this->generator->getParameter('image'));
}
$user = is_null($this->user) ? Auth::user() : $this->user;
if (! $this->icon && $user->preferences['getOfficialIcons'] && ! $skipIconFetching) {
if (! $this->icon && $this->shouldGetOfficialIcon() && ! $skipIconFetching) {
$this->icon = $this->getDefaultIcon();
}
@ -707,9 +703,20 @@ private function storeRemoteImageAsIcon(string $url) : string|null
private function getDefaultIcon()
{
$logoService = App::make(LogoService::class);
$user = is_null($this->user) ? Auth::user() : $this->user;
return $user->preferences['getOfficialIcons'] ? $logoService->getIcon($this->service) : null;
return $this->shouldGetOfficialIcon() ? $logoService->getIcon($this->service) : null;
}
/**
* Tells if an official icon should be fetched
*
* @return bool
*/
private function shouldGetOfficialIcon() : bool
{
return is_null($this->user)
? (bool) config('2fauth.preferences.getOfficialIcons')
: (bool) $this->user->preferences['getOfficialIcons'];
}
/**

View File

@ -14,10 +14,10 @@ class ReleaseRadarService
*
* @return void
*/
public function scheduledScan() : void
public static function scheduledScan() : void
{
if ((Settings::get('lastRadarScan') + (60 * 60 * 24 * 7)) < time()) {
$this->newRelease();
self::newRelease();
}
}
@ -26,9 +26,9 @@ public function scheduledScan() : void
*
* @return false|string False if no new release, the new release number otherwise
*/
public function manualScan() : false|string
public static function manualScan() : false|string
{
return $this->newRelease();
return self::newRelease();
}
/**
@ -36,9 +36,9 @@ public function manualScan() : false|string
*
* @return false|string False if no new release, the new release number otherwise
*/
protected function newRelease() : false|string
protected static function newRelease() : false|string
{
if ($latestReleaseData = json_decode($this->getLatestReleaseData())) {
if ($latestReleaseData = json_decode(self::getLatestReleaseData())) {
$githubVersion = Helpers::cleanVersionNumber($latestReleaseData->tag_name);
$installedVersion = Helpers::cleanVersionNumber(config('2fauth.version'));
@ -61,7 +61,7 @@ protected function newRelease() : false|string
*
* @return string|null
*/
protected function getLatestReleaseData() : string|null
protected static function getLatestReleaseData() : string|null
{
try {
$response = Http::retry(3, 100)

View File

@ -12,10 +12,15 @@
class UserControllerTest extends FeatureTestCase
{
/**
* @var \App\Models\User
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
private const PREFERENCE_JSON_STRUCTURE = [
'key',
'value',
];
/**
* @test
*/
@ -35,38 +40,196 @@ public function test_show_existing_user_when_authenticated_returns_success()
->json('GET', '/api/v1/user')
->assertOk()
->assertExactJson([
'name' => $this->user->name,
'id' => $this->user->id,
'email' => $this->user->email,
'name' => $this->user->name,
'id' => $this->user->id,
'email' => $this->user->email,
'is_admin' => $this->user->is_admin,
]);
}
/**
* @test
*/
public function test_show_existing_user_when_anonymous_returns_success()
public function test_allPreferences_returns_consistent_json_structure()
{
$response = $this->json('GET', '/api/v1/user/name')
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user/preferences')
->assertOk()
->assertExactJson([
'name' => $this->user->name,
->assertJsonStructure([
'*' => self::PREFERENCE_JSON_STRUCTURE,
]);
}
/**
* @test
*/
public function test_show_missing_user_returns_success_with_null_name()
public function test_allPreferences_returns_preferences_with_default_values()
{
User::destroy($this->user->id);
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user/preferences')
->assertJsonCount(count(config('2fauth.preferences')), $key = null);
foreach (config('2fauth.preferences') as $pref => $value) {
$response->assertJsonFragment([
'key' => $pref,
'value' => $value,
]);
}
}
/**
* @test
*/
public function test_allPreferences_returns_preferences_with_user_values()
{
$userPrefs = [
'showTokenAsDot' => true,
'closeOtpOnCopy' => true,
'copyOtpOnDisplay' => true,
'useBasicQrcodeReader' => true,
'displayMode' => 'grid',
'showAccountsIcons' => false,
'kickUserAfter' => 5,
'activeGroup' => 1,
'rememberActiveGroup' => false,
'defaultGroup' => 1,
'defaultCaptureMode' => 'advancedForm',
'useDirectCapture' => true,
'useWebauthnAsDefault' => true,
'useWebauthnOnly' => true,
'getOfficialIcons' => false,
'theme' => 'dark',
'formatPassword' => false,
'formatPasswordBy' => 1,
'lang' => 'fr',
];
$this->user['preferences->showTokenAsDot'] = $userPrefs['showTokenAsDot'];
$this->user['preferences->closeOtpOnCopy'] = $userPrefs['closeOtpOnCopy'];
$this->user['preferences->copyOtpOnDisplay'] = $userPrefs['copyOtpOnDisplay'];
$this->user['preferences->useBasicQrcodeReader'] = $userPrefs['useBasicQrcodeReader'];
$this->user['preferences->displayMode'] = $userPrefs['displayMode'];
$this->user['preferences->showAccountsIcons'] = $userPrefs['showAccountsIcons'];
$this->user['preferences->kickUserAfter'] = $userPrefs['kickUserAfter'];
$this->user['preferences->activeGroup'] = $userPrefs['activeGroup'];
$this->user['preferences->rememberActiveGroup'] = $userPrefs['rememberActiveGroup'];
$this->user['preferences->defaultGroup'] = $userPrefs['defaultGroup'];
$this->user['preferences->defaultCaptureMode'] = $userPrefs['defaultCaptureMode'];
$this->user['preferences->useDirectCapture'] = $userPrefs['useDirectCapture'];
$this->user['preferences->useWebauthnAsDefault'] = $userPrefs['useWebauthnAsDefault'];
$this->user['preferences->useWebauthnOnly'] = $userPrefs['useWebauthnOnly'];
$this->user['preferences->getOfficialIcons'] = $userPrefs['getOfficialIcons'];
$this->user['preferences->theme'] = $userPrefs['theme'];
$this->user['preferences->formatPassword'] = $userPrefs['formatPassword'];
$this->user['preferences->formatPasswordBy'] = $userPrefs['formatPasswordBy'];
$this->user['preferences->lang'] = $userPrefs['lang'];
$this->user->save();
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user')
->json('GET', '/api/v1/user/preferences')
->assertJsonCount(count(config('2fauth.preferences')), $key = null);
foreach ($userPrefs as $pref => $value) {
$response->assertJsonFragment([
'key' => $pref,
'value' => $value,
]);
}
}
/**
* @test
*/
public function test_showPreference_returns_preference_with_default_value()
{
/**
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
$this->user = User::factory()->create();
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user/preferences/showTokenAsDot')
->assertOk()
->assertExactJson([
'name' => $this->user->name,
'id' => $this->user->id,
'email' => $this->user->email,
'key' => 'showTokenAsDot',
'value' => config('2fauth.preferences.showTokenAsDot'),
]);
}
/**
* @test
*/
public function test_showPreference_returns_preference_with_custom_value()
{
$showTokenAsDot = ! config('2fauth.preferences.showTokenAsDot');
$this->user['preferences->showTokenAsDot'] = $showTokenAsDot;
$this->user->save();
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user/preferences/showTokenAsDot')
->assertJsonFragment([
'key' => 'showTokenAsDot',
'value' => $showTokenAsDot,
]);
}
/**
* @test
*/
public function test_showPreference_for_missing_preference_returns_not_found()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/user/preferences/unknown')
->assertNotFound();
}
/**
* @test
*/
public function test_setPreference_returns_updated_preference()
{
/**
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
$this->user = User::factory()->create();
$showTokenAsDot = ! config('2fauth.preferences.showTokenAsDot');
$response = $this->actingAs($this->user, 'api-guard')
->json('PUT', '/api/v1/user/preferences/showTokenAsDot', [
'key' => 'showTokenAsDot',
'value' => $showTokenAsDot,
])
->assertCreated()
->assertExactJson([
'key' => 'showTokenAsDot',
'value' => $showTokenAsDot,
]);
}
/**
* @test
*/
public function test_setPreference_for_missing_preference_returns_not_found()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('PUT', '/api/v1/user/preferences/unknown', [
'key' => 'showTokenAsDot',
'value' => true,
])
->assertNotFound();
}
/**
* @test
*/
public function test_setPreference_with_invalid_data_returns_validation_error()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('PUT', '/api/v1/user/preferences/showTokenAsDot', [
'key' => 'showTokenAsDot',
'value' => null,
])
->assertStatus(422);
}
}

View File

@ -2,7 +2,8 @@
namespace Tests\Api\v1\Controllers;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use App\Models\TwoFAccount;
use App\Models\User;
use Illuminate\Http\UploadedFile;
use Tests\FeatureTestCase;
@ -11,7 +12,20 @@
*/
class IconControllerTest extends FeatureTestCase
{
use WithoutMiddleware;
/**
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
/**
*
*/
public function setUp() : void
{
parent::setUp();
$this->user = User::factory()->create();
}
/**
* @test
@ -20,9 +34,10 @@ public function test_upload_icon_returns_filename()
{
$file = UploadedFile::fake()->image('testIcon.jpg');
$response = $this->json('POST', '/api/v1/icons', [
'icon' => $file,
])
$response = $this->actingAs($this->user, 'api-guard')
->json('POST', '/api/v1/icons', [
'icon' => $file,
])
->assertCreated()
->assertJsonStructure([
'filename',
@ -34,9 +49,10 @@ public function test_upload_icon_returns_filename()
*/
public function test_upload_with_invalid_data_returns_validation_error()
{
$response = $this->json('POST', '/api/v1/icons', [
'icon' => null,
])
$response = $this->actingAs($this->user, 'api-guard')
->json('POST', '/api/v1/icons', [
'icon' => null,
])
->assertStatus(422);
}
@ -45,9 +61,10 @@ public function test_upload_with_invalid_data_returns_validation_error()
*/
public function test_fetch_logo_returns_filename()
{
$response = $this->json('POST', '/api/v1/icons/default', [
'service' => 'twitter',
])
$response = $this->actingAs($this->user, 'api-guard')
->json('POST', '/api/v1/icons/default', [
'service' => 'twitter',
])
->assertStatus(201)
->assertJsonStructure([
'filename',
@ -59,9 +76,10 @@ public function test_fetch_logo_returns_filename()
*/
public function test_fetch_unknown_logo_returns_nothing()
{
$response = $this->json('POST', '/api/v1/icons/default', [
'service' => 'unknown_company',
])
$response = $this->actingAs($this->user, 'api-guard')
->json('POST', '/api/v1/icons/default', [
'service' => 'unknown_company',
])
->assertNoContent();
}
@ -70,7 +88,8 @@ public function test_fetch_unknown_logo_returns_nothing()
*/
public function test_delete_icon_returns_success()
{
$response = $this->json('DELETE', '/api/v1/icons/testIcon.jpg')
$response = $this->actingAs($this->user, 'api-guard')
->json('DELETE', '/api/v1/icons/testIcon.jpg')
->assertNoContent(204);
}
@ -79,7 +98,27 @@ public function test_delete_icon_returns_success()
*/
public function test_delete_invalid_icon_returns_success()
{
$response = $this->json('DELETE', '/api/v1/icons/null')
$response = $this->actingAs($this->user, 'api-guard')
->json('DELETE', '/api/v1/icons/null')
->assertNoContent(204);
}
/**
* @test
*/
public function test_delete_icon_of_another_user_is_forbidden()
{
$anotherUser = User::factory()->create();
TwoFAccount::factory()->for($anotherUser)->create([
'icon' => 'testIcon.jpg',
]);
$response = $this->actingAs($this->user, 'api-guard')
->json('DELETE', '/api/v1/icons/testIcon.jpg')
->assertForbidden()
->assertJsonStructure([
'message',
]);
}
}

View File

@ -13,9 +13,14 @@
class QrCodeControllerTest extends FeatureTestCase
{
/**
* @var \App\Models\User
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
protected $user, $anotherUser;
/**
* @var App\Models\TwoFAccount
*/
protected $twofaccount;
/**
* @test
@ -25,14 +30,9 @@ public function setUp() : void
parent::setUp();
$this->user = User::factory()->create();
}
$this->anotherUser = User::factory()->create();
/**
* @test
*/
public function test_show_qrcode_returns_base64_image()
{
$twofaccount = TwoFAccount::factory()->create([
$this->twofaccount = TwoFAccount::factory()->for($this->user)->create([
'otp_type' => 'totp',
'account' => 'account',
'service' => 'service',
@ -42,9 +42,15 @@ public function test_show_qrcode_returns_base64_image()
'period' => 30,
'legacy_uri' => 'otpauth://hotp/service:account?secret=A4GRFHZVRBGY7UIW&issuer=service',
]);
}
/**
* @test
*/
public function test_show_qrcode_returns_base64_image()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/twofaccounts/' . $twofaccount->id . '/qrcode')
->json('GET', '/api/v1/twofaccounts/' . $this->twofaccount->id . '/qrcode')
->assertJsonStructure([
'qrcode',
])
@ -66,6 +72,19 @@ public function test_show_missing_qrcode_returns_not_found()
]);
}
/**
* @test
*/
public function test_show_qrcode_of_another_user_is_forbidden()
{
$response = $this->actingAs($this->anotherUser, 'api-guard')
->json('GET', '/api/v1/twofaccounts/' . $this->twofaccount->id . '/qrcode')
->assertForbidden()
->assertJsonStructure([
'message',
]);
}
/**
* @test
*/

View File

@ -12,20 +12,20 @@
class SettingControllerTest extends FeatureTestCase
{
/**
* @var \App\Models\User
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
protected $user, $admin;
private const SETTING_JSON_STRUCTURE = [
'key',
'value',
];
private const TWOFAUTH_NATIVE_SETTING = 'showTokenAsDot';
private const TWOFAUTH_NATIVE_SETTING = 'checkForUpdate';
private const TWOFAUTH_NATIVE_SETTING_DEFAULT_VALUE = false;
private const TWOFAUTH_NATIVE_SETTING_DEFAULT_VALUE = true;
private const TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE = true;
private const TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE = false;
private const USER_DEFINED_SETTING = 'mySetting';
@ -41,6 +41,7 @@ public function setUp() : void
parent::setUp();
$this->user = User::factory()->create();
$this->admin = User::factory()->administrator()->create();
}
/**
@ -48,7 +49,7 @@ public function setUp() : void
*/
public function test_index_returns_setting_collection()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/api/v1/settings')
->assertOk()
->assertJsonStructure([
@ -59,9 +60,22 @@ public function test_index_returns_setting_collection()
/**
* @test
*/
public function test_show_native_unchanged_setting_returns_consistent_value()
public function test_index_is_forbidden_to_users()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/settings')
->assertForbidden()
->assertJsonStructure([
'message',
]);
}
/**
* @test
*/
public function test_show_native_unchanged_setting_returns_consistent_value()
{
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
->assertOk()
->assertExactJson([
@ -77,7 +91,7 @@ public function test_show_native_changed_setting_returns_consistent_value()
{
Settings::set(self::TWOFAUTH_NATIVE_SETTING, self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
->assertOk()
->assertExactJson([
@ -93,7 +107,7 @@ public function test_show_custom_user_setting_returns_consistent_value()
{
Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
->assertOk()
->assertExactJson([
@ -107,7 +121,7 @@ public function test_show_custom_user_setting_returns_consistent_value()
*/
public function test_show_missing_setting_returns_not_found()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/api/v1/settings/missing')
->assertNotFound();
}
@ -115,9 +129,22 @@ public function test_show_missing_setting_returns_not_found()
/**
* @test
*/
public function test_store_custom_user_setting_returns_success()
public function test_show_setting_is_forbidden_to_users()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
->assertForbidden()
->assertJsonStructure([
'message',
]);
}
/**
* @test
*/
public function test_store_custom_user_setting_returns_success()
{
$response = $this->actingAs($this->admin, 'api-guard')
->json('POST', '/api/v1/settings', [
'key' => self::USER_DEFINED_SETTING,
'value' => self::USER_DEFINED_SETTING_VALUE,
@ -134,7 +161,7 @@ public function test_store_custom_user_setting_returns_success()
*/
public function test_store_invalid_custom_user_setting_returns_validation_error()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('POST', '/api/v1/settings', [
'key' => null,
'value' => null,
@ -149,7 +176,7 @@ public function test_store_existing_custom_user_setting_returns_validation_error
{
Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('POST', '/api/v1/settings', [
'key' => self::USER_DEFINED_SETTING,
'value' => self::USER_DEFINED_SETTING_VALUE,
@ -162,7 +189,7 @@ public function test_store_existing_custom_user_setting_returns_validation_error
*/
public function test_update_unchanged_native_setting_returns_updated_setting()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('PUT', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING, [
'value' => self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE,
])
@ -180,7 +207,7 @@ public function test_update_custom_user_setting_returns_updated_setting()
{
Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('PUT', '/api/v1/settings/' . self::USER_DEFINED_SETTING, [
'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
])
@ -196,7 +223,7 @@ public function test_update_custom_user_setting_returns_updated_setting()
*/
public function test_update_missing_user_setting_returns_created_setting()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('PUT', '/api/v1/settings/' . self::USER_DEFINED_SETTING, [
'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
])
@ -214,7 +241,7 @@ public function test_destroy_user_setting_returns_success()
{
Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
->assertNoContent();
}
@ -224,7 +251,7 @@ public function test_destroy_user_setting_returns_success()
*/
public function test_destroy_native_setting_returns_bad_request()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('DELETE', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
->assertStatus(400)
->assertJsonStructure([
@ -238,8 +265,23 @@ public function test_destroy_native_setting_returns_bad_request()
*/
public function test_destroy_missing_user_setting_returns_not_found()
{
$response = $this->actingAs($this->user, 'api-guard')
$response = $this->actingAs($this->admin, 'api-guard')
->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
->assertNotFound();
}
/**
* @test
*/
public function test_destroy_is_forbidden_to_users()
{
Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
$response = $this->actingAs($this->user, 'api-guard')
->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
->assertForbidden()
->assertJsonStructure([
'message',
]);
}
}

View File

@ -4,9 +4,11 @@
use App\Api\v1\Requests\GroupStoreRequest;
use App\Models\Group;
use App\Models\User;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Mockery;
use Tests\FeatureTestCase;
/**
@ -15,9 +17,23 @@
class GroupStoreRequestTest extends FeatureTestCase
{
use WithoutMiddleware;
/**
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
protected String $uniqueGroupName = 'MyGroup';
/**
* @test
*/
public function setUp() : void
{
parent::setUp();
$this->user = User::factory()->create();
}
/**
* @test
*/
@ -37,7 +53,10 @@ public function test_user_is_authorized()
*/
public function test_valid_data(array $data) : void
{
$request = new GroupStoreRequest();
$request = Mockery::mock(GroupStoreRequest::class)->makePartial();
$request->shouldReceive('user')
->andReturn($this->user);
$validator = Validator::make($data, $request->rules());
$this->assertFalse($validator->fails());
@ -60,13 +79,14 @@ public function provideValidData() : array
*/
public function test_invalid_data(array $data) : void
{
$group = new Group([
$group = Group::factory()->for($this->user)->create([
'name' => $this->uniqueGroupName,
]);
$group->save();
$request = Mockery::mock(GroupStoreRequest::class)->makePartial();
$request->shouldReceive('user')
->andReturn($this->user);
$request = new GroupStoreRequest();
$validator = Validator::make($data, $request->rules());
$this->assertTrue($validator->fails());

View File

@ -17,7 +17,7 @@
class LoginTest extends FeatureTestCase
{
/**
* @var \App\Models\User
* @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;

View File

@ -0,0 +1,24 @@
<?php
namespace Tests\Unit\Events;
use App\Events\GroupDeleted;
use App\Models\Group;
use Tests\TestCase;
/**
* @covers \App\Events\GroupDeleted
*/
class GroupDeletedTest extends TestCase
{
/**
* @test
*/
public function test_event_constructor()
{
$group = Group::factory()->make();
$event = new GroupDeleted($group);
$this->assertSame($group, $event->group);
}
}

View File

@ -20,6 +20,6 @@ public function test_retreiving_a_user_returns_a_non_persisted_user_instance()
]);
$this->assertInstanceOf('\App\Models\User', $user);
$this->assertEquals(false, $user->exists);
$this->assertEquals(true, $user->exists);
}
}

View File

@ -2,9 +2,12 @@
namespace Tests\Unit;
use App\Events\GroupDeleted;
use App\Events\GroupDeleting;
use App\Models\User;
use App\Models\Group;
use App\Models\TwoFAccount;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Tests\ModelTestCase;
/**
@ -23,18 +26,33 @@ public function test_model_configuration()
['created_at', 'updated_at'],
['*'],
[],
['id' => 'int', 'twofaccounts_count' => 'integer'],
['deleting' => GroupDeleting::class]
['id' => 'int', 'twofaccounts_count' => 'integer'],
[
'deleting' => GroupDeleting::class,
'deleted' => GroupDeleted::class
]
);
}
/**
* @test
*/
public function test_groups_relation()
public function test_twofaccounts_relation()
{
$group = new Group();
$accounts = $group->twofaccounts();
$this->assertHasManyRelation($accounts, $group, new TwoFAccount());
}
/**
* @test
*/
public function test_user_relation()
{
$model = new Group;
$relation = $model->user();
$this->assertInstanceOf(BelongsTo::class, $relation);
$this->assertEquals('user_id', $relation->getForeignKeyName());
}
}

View File

@ -19,7 +19,7 @@ class CleanIconStorageTest extends TestCase
/**
* @test
*/
public function test_it_deletes_icon_file_on_twofaccount_deletion()
public function test_it_deletes_icon_file_using_storage_facade()
{
$settingService = $this->mock(SettingService::class, function (MockInterface $settingService) {
$settingService->shouldReceive('get')

View File

@ -0,0 +1,44 @@
<?php
namespace Tests\Unit\Listeners;
use App\Events\ScanForNewReleaseCalled;
use App\Listeners\ReleaseRadar;
use App\Services\ReleaseRadarService;
use Illuminate\Support\Facades\Event;
use Mockery\MockInterface;
use Tests\TestCase;
/**
* @covers \App\Listeners\ReleaseRadar
*/
class ReleaseRadarTest extends TestCase
{
/**
* @test
*/
public function test_it_starts_release_scan()
{
$this->mock(ReleaseRadarService::class, function (MockInterface $releaseRadarService) {
$releaseRadarService->shouldReceive('scheduledScan');
});
$event = new ScanForNewReleaseCalled();
$listener = new ReleaseRadar();
$this->assertNull($listener->handle($event));
}
/**
* @test
*/
public function test_ReleaseRadar_listen_to_ScanForNewReleaseCalled_event()
{
Event::fake();
Event::assertListening(
ScanForNewReleaseCalled::class,
ReleaseRadar::class
);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Tests\Unit\Listeners;
use App\Events\GroupDeleted;
use App\Listeners\ResetUsersPreference;
use Illuminate\Support\Facades\Event;
use Mockery\MockInterface;
use Tests\TestCase;
/**
* @covers \App\Listeners\ResetUsersPreference
*/
class ResetUsersPreferenceTest extends TestCase
{
/**
* @test
*/
public function test_ResetUsersPreference_listen_to_GroupDeleted_event()
{
Event::fake();
Event::assertListening(
GroupDeleted::class,
ResetUsersPreference::class
);
}
}

View File

@ -7,6 +7,8 @@
use App\Exceptions\UnsupportedMigrationException;
use App\Factories\MigratorFactory;
use App\Models\TwoFAccount;
use App\Models\User;
use App\Services\LogoService;
use App\Services\Migrators\AegisMigrator;
use App\Services\Migrators\GoogleAuthMigrator;
use App\Services\Migrators\Migrator;
@ -57,7 +59,7 @@ class MigratorTest extends TestCase
/**
* App\Models\TwoFAccount $GAuthTotpBisTwofaccount
*/
protected $GAuthTotpBisTwofaccount;
protected $GAuthTotpBisTwofaccount, $fakeTwofaccount;
public function setUp() : void
{
@ -67,12 +69,15 @@ public function setUp() : void
$settingService->allows()
->get('useEncryption')
->andReturn(false);
$settingService->allows()
->get('getOfficialIcons')
->andReturn(false);
});
$this->mock(LogoService::class, function (MockInterface $logoService) {
$logoService->allows([
'getIcon' => null,
]);
});
$this->totpTwofaccount = new TwoFAccount;
$this->totpTwofaccount->legacy_uri = OtpTestData::TOTP_FULL_CUSTOM_URI_NO_IMG;
$this->totpTwofaccount->service = OtpTestData::SERVICE;

View File

@ -6,6 +6,7 @@
use App\Helpers\Helpers;
use App\Models\TwoFAccount;
use App\Services\SettingService;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Crypt;
use Mockery\MockInterface;
use Tests\ModelTestCase;
@ -138,4 +139,16 @@ public function test_secret_is_uppercased_and_padded_at_setup()
$this->assertEquals('YYYY====', $twofaccount->secret);
}
/**
* @test
*/
public function test_user_relation()
{
$model = new TwoFAccount();
$relation = $model->user();
$this->assertInstanceOf(BelongsTo::class, $relation);
$this->assertEquals('user_id', $relation->getForeignKeyName());
}
}

View File

@ -2,6 +2,8 @@
namespace Tests\Unit;
use App\Models\Group;
use App\Models\TwoFAccount;
use App\Models\User;
use Tests\ModelTestCase;
@ -20,7 +22,13 @@ public function test_model_configuration()
['password', 'remember_token'],
['*'],
[],
['id' => 'int', 'email_verified_at' => 'datetime']
[
'id' => 'int',
'email_verified_at' => 'datetime',
'is_admin' => 'boolean',
'twofaccounts_count' => 'integer',
'groups_count' => 'integer',
]
);
}
@ -35,4 +43,24 @@ public function test_email_is_set_lowercased()
$this->assertEquals(strtolower('UPPERCASE@example.COM'), $user->email);
}
/**
* @test
*/
public function test_twofaccounts_relation()
{
$user = new User();
$accounts = $user->twofaccounts();
$this->assertHasManyRelation($accounts, $user, new TwoFAccount());
}
/**
* @test
*/
public function test_groups_relation()
{
$user = new User();
$groups = $user->groups();
$this->assertHasManyRelation($groups, $user, new Group());
}
}