Made some testcases for the new image populate command, found some bugs, fixed some errors due to discovering bugs during testing
This commit is contained in:
parent
c9993e0808
commit
ab2901f950
@ -10,6 +10,40 @@ use App\Models\ImageNode;
|
|||||||
|
|
||||||
class MakeImageDB extends Command
|
class MakeImageDB extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Summary of processImage
|
||||||
|
* @param mixed $file
|
||||||
|
* @param mixed $parentId
|
||||||
|
* @param int $userId
|
||||||
|
* @param string $basePath
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function processImage($file, ?int $parentId, int $userId, string $basePath): void{
|
||||||
|
$ext = strtolower($file->getExtension());
|
||||||
|
if (!in_array($ext, ['jpg', 'jpeg', 'png'])) return;
|
||||||
|
|
||||||
|
$imageFileName = $file->getFilename();
|
||||||
|
|
||||||
|
$relativePath = str_replace(public_path(), '', $file->getPathname());
|
||||||
|
$relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
|
||||||
|
$relativePath = '/' . ltrim($relativePath, '/');
|
||||||
|
|
||||||
|
ImageNode::create([
|
||||||
|
'user_id' => $userId,
|
||||||
|
'parent_id' => $parentId,
|
||||||
|
'name' => $imageFileName,
|
||||||
|
'fs_type' => 'file',
|
||||||
|
'fs_meta' => json_encode([
|
||||||
|
'real_name' => $file->getPathname(),
|
||||||
|
'symbolic_name' => $relativePath,
|
||||||
|
'title' => pathinfo($imageFileName, PATHINFO_FILENAME),
|
||||||
|
'description' => '',
|
||||||
|
'copyright' => '',
|
||||||
|
'mime_type' => File::mimeType($file->getPathname()),
|
||||||
|
'size' => $file->getSize(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Summary of scanFolder
|
* Summary of scanFolder
|
||||||
* @param string $fullPath
|
* @param string $fullPath
|
||||||
@ -18,49 +52,21 @@ class MakeImageDB extends Command
|
|||||||
* @param string $basePath
|
* @param string $basePath
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function scanFolder(string $fullPath, ?int $parentId, int $userId, string $basePath): void
|
private function scanFolder(string $fullPath, ?int $parentId, int $userId, string $basePath): void {
|
||||||
{
|
$folderName = basename($fullPath);
|
||||||
$entries = File::directories($fullPath);
|
$folderNode = ImageNode::create([
|
||||||
foreach ($entries as $folderPath) {
|
'user_id' => $userId,
|
||||||
$folderName = basename($folderPath);
|
'name' => $folderName,
|
||||||
|
'fs_type' => 'folder',
|
||||||
|
'parent_id' => $parentId,
|
||||||
|
]);
|
||||||
|
|
||||||
$folderNode = ImageNode::create([
|
foreach (File::directories($fullPath) as $subdir) {
|
||||||
'user_id' => $userId,
|
$this->scanFolder($subdir, $folderNode->id, $userId, $basePath);
|
||||||
'name' => $folderName,
|
|
||||||
'fs_type' => 'folder',
|
|
||||||
'parent_id' => $parentId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->scanFolder($folderPath, $folderNode->id, $userId, $basePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$files = File::files($fullPath);
|
foreach (File::files($fullPath) as $file) {
|
||||||
foreach ($files as $file) {
|
$this->processImage($file, $folderNode->id, $userId, $basePath);
|
||||||
$ext = strtolower($file->getExtension());
|
|
||||||
if (!in_array($ext, ['jpg', 'jpeg', 'png'])) {
|
|
||||||
continue; // skip unsupported file types
|
|
||||||
}
|
|
||||||
|
|
||||||
$imageFileName = $file->getFilename();
|
|
||||||
$relativePath = str_replace(public_path(), '', $file->getPathname());
|
|
||||||
$relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
|
|
||||||
$relativePath = '/' . ltrim($relativePath, '/');
|
|
||||||
|
|
||||||
ImageNode::create([
|
|
||||||
'user_id' => $userId,
|
|
||||||
'parent_id' => $parentId,
|
|
||||||
'name' => $imageFileName,
|
|
||||||
'fs_type' => 'file',
|
|
||||||
'fs_meta' => json_encode([
|
|
||||||
'real_name' => $file->getPathname(),
|
|
||||||
'symbolic_name' => $relativePath,
|
|
||||||
'title' => pathinfo($imageFileName, PATHINFO_FILENAME),
|
|
||||||
'description' => '',
|
|
||||||
'copyright' => '',
|
|
||||||
'mime_type' => File::mimeType($file->getPathname()),
|
|
||||||
'size' => $file->getSize(),
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +75,7 @@ class MakeImageDB extends Command
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'pagebuilder:make-imagedb';
|
protected $signature = 'pagebuilder:make-imagedb {--testmode : Use test-imagedb folder instead of imagedb for testing}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
@ -84,10 +90,19 @@ class MakeImageDB extends Command
|
|||||||
public function handle() {
|
public function handle() {
|
||||||
// The public path to the imagedb directory. If you change this, please also make sure you update
|
// The public path to the imagedb directory. If you change this, please also make sure you update
|
||||||
// the .gitignore file so you don't accidentally push garbage to the repository.
|
// the .gitignore file so you don't accidentally push garbage to the repository.
|
||||||
$imageDbPath = public_path('imagedb');
|
|
||||||
|
// We set up a test directory just for unit testing, so we don't polute the local database, or file
|
||||||
|
// system with test data
|
||||||
|
$imageDbPath = $this->option('testmode')
|
||||||
|
? public_path('test-imagedb')
|
||||||
|
: public_path('imagedb');
|
||||||
|
|
||||||
if (!File::exists($imageDbPath) || !File::isDirectory($imageDbPath)) {
|
if (!File::exists($imageDbPath) || !File::isDirectory($imageDbPath)) {
|
||||||
$this->error("The 'public/imagedb' directory does not exist.");
|
if ($this->option('testmode')) {
|
||||||
|
$this->error("The 'public/test-imagedb' directory does not exist.");
|
||||||
|
} else {
|
||||||
|
$this->error("The 'public/imagedb' directory does not exist.");
|
||||||
|
}
|
||||||
return Command::FAILURE;
|
return Command::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +111,11 @@ class MakeImageDB extends Command
|
|||||||
$subdirs = File::directories($imageDbPath);
|
$subdirs = File::directories($imageDbPath);
|
||||||
|
|
||||||
if (empty($contents) && empty($subdirs)) {
|
if (empty($contents) && empty($subdirs)) {
|
||||||
$this->error("The 'public/imagedb' directory is empty. Nothing to index.");
|
if ($this->option('testmode')) {
|
||||||
|
$this->error("The 'public/test-imagedb' directory is empty. Nothing to index.");
|
||||||
|
} else {
|
||||||
|
$this->error("The 'public/imagedb' directory is empty. Nothing to index.");
|
||||||
|
}
|
||||||
return Command::FAILURE;
|
return Command::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,9 +151,16 @@ class MakeImageDB extends Command
|
|||||||
|
|
||||||
$this->info("Selected user ID: $userId: $selectedLabel");
|
$this->info("Selected user ID: $userId: $selectedLabel");
|
||||||
$this->info("Scanning and indexing image directory...");
|
$this->info("Scanning and indexing image directory...");
|
||||||
$this->scanFolder($imageDbPath, null, $userId, $imageDbPath);
|
|
||||||
$this->info("Image DB creation complete.");
|
|
||||||
|
|
||||||
|
foreach (File::directories($imageDbPath) as $dir) {
|
||||||
|
$this->scanFolder($dir, null, $userId, $imageDbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (File::files($imageDbPath) as $file) {
|
||||||
|
$this->processImage($file, null, $userId, $imageDbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Image DB creation complete.");
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
92
tests/Feature/MakeImageDBCommandTest.php
Normal file
92
tests/Feature/MakeImageDBCommandTest.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Foundation\Testing\WithFaker;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\ImageNode;
|
||||||
|
|
||||||
|
class MakeImageDBCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected string $imageDbPath;
|
||||||
|
|
||||||
|
protected function setUp(): void {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
// Set up fake imagedb directory
|
||||||
|
$this->imageDbPath = public_path('test-imagedb');
|
||||||
|
File::deleteDirectory($this->imageDbPath);
|
||||||
|
File::makeDirectory($this->imageDbPath . '/subfolder', 0755, true);
|
||||||
|
|
||||||
|
// Create a sample image file
|
||||||
|
File::put($this->imageDbPath . '/subfolder/example.jpg', 'fake image content');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void {
|
||||||
|
File::deleteDirectory($this->imageDbPath);
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_indexes_folders_and_images_in_the_imagedb_directory() {
|
||||||
|
$user = User::factory()->create([
|
||||||
|
'name' => 'Test User',
|
||||||
|
'email' => 'test@example.com',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->artisan('pagebuilder:make-imagedb', ['--testmode' => true])
|
||||||
|
->expectsQuestion('Select a user to act as:', "{$user->name} ({$user->email})")
|
||||||
|
->expectsOutput('Clearing existing image nodes...')
|
||||||
|
->expectsOutput('Scanning and indexing image directory...')
|
||||||
|
->expectsOutput('Image DB creation complete.')
|
||||||
|
->assertExitCode(0);
|
||||||
|
|
||||||
|
$this->assertDatabaseCount('image_nodes', 2); // 1 folder + 1 image
|
||||||
|
|
||||||
|
$folder = ImageNode::where('fs_type', 'folder')->first();
|
||||||
|
$image = ImageNode::where('fs_type', 'file')->first();
|
||||||
|
|
||||||
|
$this->assertNotNull($folder);
|
||||||
|
$this->assertEquals('subfolder', $folder->name);
|
||||||
|
|
||||||
|
$this->assertNotNull($image);
|
||||||
|
$this->assertEquals('example.jpg', $image->name);
|
||||||
|
$this->assertEquals($folder->id, $image->parent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_errors_when_imagedb_directory_does_not_exist() {
|
||||||
|
// Ensure directory does not exist
|
||||||
|
File::deleteDirectory($this->imageDbPath);
|
||||||
|
|
||||||
|
$this->artisan('pagebuilder:make-imagedb', ['--testmode' => true])
|
||||||
|
->expectsOutput("The 'public/test-imagedb' directory does not exist.")
|
||||||
|
->assertExitCode(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_errors_when_imagedb_directory_is_empty() {
|
||||||
|
// Delete existing dir
|
||||||
|
File::deleteDirectory($this->imageDbPath);
|
||||||
|
// Create an empty directory
|
||||||
|
File::makeDirectory($this->imageDbPath, 0755, true);
|
||||||
|
|
||||||
|
$this->artisan('pagebuilder:make-imagedb', ['--testmode' => true])
|
||||||
|
->expectsOutput("The 'public/test-imagedb' directory is empty. Nothing to index.")
|
||||||
|
->assertExitCode(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_errors_when_no_users_exist() {
|
||||||
|
$this->artisan('pagebuilder:make-imagedb', ['--testmode' => true])
|
||||||
|
->expectsOutput("No users found in the database. Cannot continue!")
|
||||||
|
->expectsOutput('(Use artisan serve and npm run dev to spool up a local instance, and register a user from the web interface)')
|
||||||
|
->assertExitCode(1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user