2FAuth/tests/Feature/Services/IconStoreServiceTest.php

791 lines
26 KiB
PHP
Raw Normal View History

2024-10-18 14:28:45 +02:00
<?php
namespace Tests\Feature\Services;
use App\Exceptions\FailedIconStoreDatabaseTogglingException;
use App\Facades\Settings;
use App\Models\Icon;
use App\Models\TwoFAccount;
use App\Models\User;
use App\Services\IconStoreService;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Mockery\MockInterface;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\PreserveGlobalState;
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
use PHPUnit\Framework\Attributes\Test;
use Tests\Data\OtpTestData;
use Tests\FeatureTestCase;
/**
* IconStoreTest test class
*/
#[CoversClass(IconStoreService::class)]
class IconStoreServiceTest extends FeatureTestCase
{
use WithoutMiddleware;
/**
* The IconStore under test
*/
protected IconStoreService $iconStore;
public function setUp() : void
{
parent::setUp();
Storage::fake('icons');
$this->iconStore = $this->app->make(IconStoreService::class);
}
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
#[Test]
public function test_get_returns_icon_content()
{
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
$content = $this->iconStore->get(OtpTestData::ICON_PNG);
$this->assertSame(OtpTestData::ICON_PNG_DATA, base64_encode($content));
}
#[Test]
public function test_get_returns_null_when_icon_is_missing()
{
$this->assertNull($this->iconStore->get(OtpTestData::ICON_PNG));
}
#[Test]
public function test_get_returns_content_when_icon_is_missing_on_disk_but_exists_in_db()
{
Settings::set('storeIconsInDatabase', true);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$content = $this->iconStore->get(OtpTestData::ICON_PNG);
$this->assertSame(OtpTestData::ICON_PNG_DATA, base64_encode($content));
}
#[Test]
public function test_get_returns_null_when_nothing_is_requested()
{
$this->assertNull($this->iconStore->get(''));
}
#[Test]
#[DataProvider('supportedMimeTypesProvider')]
public function test_mimeType_returns_correct_mimetype($name, $base64content, $expected)
{
Storage::disk('icons')->put($name, $base64content);
$mimeType = $this->iconStore->mimeType($name);
$this->assertStringContainsStringIgnoringCase($mimeType, $expected);
}
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
/**
* Provide data for index tests
*/
public static function supportedMimeTypesProvider()
{
return [
'PNG' => [
OtpTestData::ICON_PNG,
OtpTestData::ICON_PNG_DATA,
'image/png',
],
'JPEG' => [
OtpTestData::ICON_JPEG,
OtpTestData::ICON_JPEG_DATA,
'image/jpeg',
],
'WEBP' => [
OtpTestData::ICON_WEBP,
OtpTestData::ICON_WEBP_DATA,
'image/webp',
],
'BPM' => [
OtpTestData::ICON_BMP,
OtpTestData::ICON_BMP_DATA,
2024-11-09 10:18:45 +01:00
'image/bmp|image/x-ms-bmp',
2024-10-18 14:28:45 +02:00
],
'SVG' => [
OtpTestData::ICON_SVG,
OtpTestData::ICON_SVG_DATA_ENCODED,
'image/svg+xml',
],
];
}
#[Test]
public function test_mimeType_returns_correct_mimetype_of_fake_icon()
{
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_PNG_DATA));
$mimeType = $this->iconStore->mimeType(OtpTestData::ICON_JPEG);
$this->assertSame('image/png', $mimeType);
}
#[Test]
public function test_mimeType_returns_null_when_icon_is_missing()
{
$this->assertFalse($this->iconStore->mimeType(OtpTestData::ICON_PNG));
}
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
#[Test]
public function test_mimeType_returns_null_when_nothing_is_requested()
{
$this->assertFalse($this->iconStore->mimeType(''));
}
#[Test]
public function test_clear_deletes_all_icons_and_returns_true()
{
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$result = $this->iconStore->clear();
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_JPEG);
$this->assertEmpty(Storage::disk('icons')->allFiles());
$this->assertTrue($result);
}
#[Test]
public function test_clear_deletes_all_icons_in_database_and_returns_true()
{
Settings::set('storeIconsInDatabase', true);
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
$result = $this->iconStore->clear();
$this->assertEmpty(Storage::disk('icons')->allFiles());
$this->assertDatabaseEmpty('icons');
$this->assertTrue($result);
}
#[Test]
public function test_clear_empty_disk_returns_true()
{
$this->assertTrue($this->iconStore->clear());
$this->assertEmpty(Storage::disk('icons')->allFiles());
}
#[Test]
public function test_clear_empty_disk_deletes_icons_in_database()
{
Settings::set('storeIconsInDatabase', true);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
$result = $this->iconStore->clear();
$this->assertDatabaseEmpty('icons');
$this->assertTrue($result);
}
#[Test]
public function test_clear_deletes_only_supported_image_format_in_disk()
{
Storage::disk('icons')->put(OtpTestData::ICON_GIF, base64_decode(OtpTestData::ICON_GIF_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_BMP, base64_decode(OtpTestData::ICON_BMP_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_SVG, OtpTestData::ICON_SVG_DATA);
Storage::disk('icons')->put(OtpTestData::ICON_WEBP, base64_decode(OtpTestData::ICON_WEBP_DATA));
Storage::disk('icons')->assertExists(OtpTestData::ICON_GIF);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_BMP);
Storage::disk('icons')->assertExists(OtpTestData::ICON_SVG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_WEBP);
$this->iconStore->clear();
Storage::disk('icons')->assertExists(OtpTestData::ICON_GIF);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_JPEG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_BMP);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_SVG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_WEBP);
}
#[Test]
public function test_delete_deletes_provided_icon_and_returns_true()
{
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
$this->iconStore->delete(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
}
#[Test]
public function test_delete_deletes_provided_icon_in_database_and_returns_true()
{
Settings::set('storeIconsInDatabase', true);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->iconStore->delete(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
}
#[Test]
public function test_delete_deletes_provided_icon_in_database_when_disk_is_empty()
{
Settings::set('storeIconsInDatabase', true);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->iconStore->delete(OtpTestData::ICON_PNG);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
}
#[Test]
public function test_delete_deletes_provided_icons_and_returns_true()
{
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->iconStore->delete([
OtpTestData::ICON_PNG,
OtpTestData::ICON_JPEG,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_JPEG);
}
#[Test]
public function test_delete_deletes_provided_icons_in_database_and_returns_true()
{
Settings::set('storeIconsInDatabase', true);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
$this->iconStore->delete([
OtpTestData::ICON_PNG,
OtpTestData::ICON_JPEG,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_JPEG);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
}
#[Test]
public function test_delete_deletes_provided_icons_in_database_when_disk_is_empty()
{
Settings::set('storeIconsInDatabase', true);
2024-11-09 10:18:45 +01:00
2024-10-18 14:28:45 +02:00
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
$this->iconStore->delete([
OtpTestData::ICON_PNG,
OtpTestData::ICON_JPEG,
]);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_JPEG,
2024-10-18 14:28:45 +02:00
]);
}
#[Test]
public function test_delete_missing_icon_returns_true()
{
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$result = $this->iconStore->delete(OtpTestData::ICON_PNG);
$this->assertTrue($result);
}
#[Test]
public function test_delete_empty_icons_returns_true()
{
$result = $this->iconStore->delete([]);
$this->assertTrue($result);
}
#[Test]
public function test_delete_returns_false_when_it_fails()
{
Storage::fake('icons');
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::shouldReceive('disk->delete')
->andReturn(false);
$result = $this->iconStore->delete(OtpTestData::ICON_PNG);
$this->assertFalse($result);
}
#[Test]
public function test_store_writes_the_icon_to_disk_and_returns_true()
{
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$result = $this->iconStore->store(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
$this->assertTrue($result);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
}
#[Test]
public function test_store_writes_the_icon_to_disk_and_database_and_returns_true()
{
Settings::set('storeIconsInDatabase', true);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$this->assertDatabaseMissing('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
$result = $this->iconStore->store(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
$this->assertTrue($result);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
$this->assertDatabaseHas('icons', [
2024-11-09 10:18:45 +01:00
'name' => OtpTestData::ICON_PNG,
2024-10-18 14:28:45 +02:00
]);
}
#[Test]
public function test_store_returns_false_when_it_fails()
{
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$iconName = OtpTestData::ICON_PNG;
$iconContent = '';
Storage::shouldReceive('disk->put')
->with($iconName, $iconContent)
->andReturn(false);
2024-11-09 10:18:45 +01:00
2024-11-15 10:39:29 +01:00
Storage::shouldReceive('disk->mimeType')
->with($iconName)
->andReturn('image/png');
2024-10-18 14:28:45 +02:00
$result = $this->iconStore->store($iconName, $iconContent);
$this->assertFalse($result);
}
2024-11-15 10:39:29 +01:00
#[Test]
public function test_store_stores_sanitized_svg_content()
{
Settings::set('storeIconsInDatabase', true);
2024-11-17 23:26:40 +01:00
2024-11-15 10:39:29 +01:00
$result = $this->iconStore->store(OtpTestData::ICON_SVG, OtpTestData::ICON_SVG_DATA_INFECTED);
$this->assertTrue($result);
$this->assertStringNotContainsString(
OtpTestData::ICON_SVG_MALICIOUS_CODE,
Storage::disk('icons')->get(OtpTestData::ICON_SVG)
);
2024-11-17 23:26:40 +01:00
2024-11-15 10:39:29 +01:00
$dbRecord = DB::table('icons')->where('name', OtpTestData::ICON_SVG)->first();
2024-11-17 23:26:40 +01:00
2024-11-15 10:39:29 +01:00
$this->assertStringNotContainsString(
OtpTestData::ICON_SVG_MALICIOUS_CODE,
$dbRecord->content,
);
}
#[Test]
public function test_store_returns_false_when_svg_sanitize_failed()
{
$result = $this->iconStore->store(OtpTestData::ICON_SVG, 'this_will_make_svg_data_invalid' . OtpTestData::ICON_SVG_DATA);
$this->assertFalse($result);
}
#[Test]
public function test_store_deletes_svg_icon_that_cannot_be_sanitized()
{
Settings::set('storeIconsInDatabase', true);
2024-11-17 23:26:40 +01:00
2024-11-15 10:39:29 +01:00
$result = $this->iconStore->store(OtpTestData::ICON_SVG, 'this_will_make_svg_data_invalid' . OtpTestData::ICON_SVG_DATA);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_SVG);
$this->assertDatabaseMissing('icons', [
'name' => OtpTestData::ICON_SVG,
]);
}
2024-10-18 14:28:45 +02:00
#[Test]
public function test_exists_returns_true()
{
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
$this->assertTrue($this->iconStore->exists(OtpTestData::ICON_PNG));
}
#[Test]
public function test_exists_fixes_missing_file_in_disk()
{
Settings::set('storeIconsInDatabase', true);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
$this->iconStore->exists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
}
#[Test]
public function test_exists_returns_false()
{
$this->assertFalse($this->iconStore->exists(OtpTestData::ICON_PNG));
}
#[Test]
public function test_setDatabaseReplication_stores_icon_files_to_database()
{
$user = User::factory()->create();
$admin = User::factory()->administrator()->create();
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
TwoFAccount::factory()->for($admin)->create([
'icon' => OtpTestData::ICON_JPEG,
]);
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Settings::set('storeIconsInDatabase', true);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
$this->assertDatabaseHas('icons', [
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
$this->assertDatabaseCount('icons', 2);
}
#[Test]
public function test_setDatabaseReplication_stores_only_registered_icon_to_database()
{
2024-11-09 10:18:45 +01:00
$user = User::factory()->create();
2024-10-18 14:28:45 +02:00
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_JPEG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Settings::set('storeIconsInDatabase', true);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
$this->assertDatabaseMissing('icons', [
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
$this->assertDatabaseCount('icons', 1);
}
#[Test]
public function test_setDatabaseReplication_clears_database_before_replication()
{
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
Settings::set('storeIconsInDatabase', true);
$this->assertDatabaseEmpty('icons');
}
#[Test]
public function test_setDatabaseReplication_skips_icon_when_file_is_missing()
{
2024-11-09 10:18:45 +01:00
$user = User::factory()->create();
2024-10-18 14:28:45 +02:00
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
Storage::disk('icons')->assertMissing(OtpTestData::ICON_PNG);
Settings::set('storeIconsInDatabase', true);
$this->assertDatabaseEmpty('icons');
}
#[Test]
public function test_setDatabaseReplication_restores_icons_as_file_and_clears_database()
{
Settings::set('storeIconsInDatabase', true);
$user = User::factory()->create();
$admin = User::factory()->administrator()->create();
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
TwoFAccount::factory()->for($admin)->create([
'icon' => OtpTestData::ICON_JPEG,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
Settings::set('storeIconsInDatabase', false);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseEmpty('icons');
}
#[Test]
public function test_setDatabaseReplication_overrides_existing_files_during_restoration_from_database()
{
Settings::set('storeIconsInDatabase', true);
2024-11-09 10:18:45 +01:00
$user = User::factory()->create();
2024-10-18 14:28:45 +02:00
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_JPEG_DATA));
Settings::set('storeIconsInDatabase', false);
$this->assertEquals(base64_decode(OtpTestData::ICON_PNG_DATA), Storage::disk('icons')->get(OtpTestData::ICON_PNG));
}
#[Test]
#[RunInSeparateProcess]
#[PreserveGlobalState(false)]
public function test_setDatabaseReplication_On_sends_exception_and_does_nothing_if_filling_database_fails()
{
$user = User::factory()->create();
$admin = User::factory()->administrator()->create();
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
TwoFAccount::factory()->for($admin)->create([
'icon' => OtpTestData::ICON_JPEG,
]);
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_PNG_DATA));
Storage::disk('icons')->put(OtpTestData::ICON_PNG, base64_decode(OtpTestData::ICON_JPEG_DATA));
$this->expectException(FailedIconStoreDatabaseTogglingException::class);
$mock = $this->mock('overload:' . Icon::class, function (MockInterface $iconModel) {
$iconModel->shouldReceive('truncate')
->andReturn(true);
$iconModel->shouldReceive('firstOrNew')
->andThrow(new \Exception);
});
Settings::set('storeIconsInDatabase', true);
$this->assertDatabaseEmpty('icons');
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
}
#[Test]
public function test_setDatabaseReplication_Off_sends_exception_and_does_nothing_if_filling_database_fails()
{
Settings::set('storeIconsInDatabase', true);
$user = User::factory()->create();
$admin = User::factory()->administrator()->create();
TwoFAccount::factory()->for($user)->create([
'icon' => OtpTestData::ICON_PNG,
]);
TwoFAccount::factory()->for($admin)->create([
'icon' => OtpTestData::ICON_JPEG,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
DB::table('icons')->insert([
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
Storage::shouldReceive('disk->put')
2024-11-09 10:18:45 +01:00
->once()
->andThrow(new FailedIconStoreDatabaseTogglingException);
2024-10-18 14:28:45 +02:00
$this->expectException(FailedIconStoreDatabaseTogglingException::class);
Settings::set('storeIconsInDatabase', false);
Storage::disk('icons')->assertExists(OtpTestData::ICON_PNG);
Storage::disk('icons')->assertExists(OtpTestData::ICON_JPEG);
$this->assertDatabaseHas('icons', [
'name' => OtpTestData::ICON_PNG,
'content' => OtpTestData::ICON_PNG_DATA,
]);
$this->assertDatabaseHas('icons', [
'name' => OtpTestData::ICON_JPEG,
'content' => OtpTestData::ICON_JPEG_DATA,
]);
}
}