diff --git a/composer.json b/composer.json index fe6189e..cdfc727 100644 --- a/composer.json +++ b/composer.json @@ -1,88 +1,88 @@ { - "name": "itiden/statamic-backup", - "description": "Backup your Statamic site", - "license": "MIT", - "authors": [ - { - "name": "Neo Lejondahl", - "role": "Developer" - } - ], - "require": { - "ext-zip": "*", - "statamic/cms": "^5.0.0", - "pixelfear/composer-dist-plugin": "^0.1.6" - }, - "require-dev": { - "orchestra/testbench": "^9.0", - "pestphp/pest": "^3.0", - "pestphp/pest-plugin-laravel": "^3.0", - "carthage-software/mago": "^0.11.0" - }, - "autoload": { - "psr-4": { - "Itiden\\Backup\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Itiden\\Backup\\Tests\\": "tests", - "Workbench\\App\\": "workbench/app/", - "Workbench\\Database\\Factories\\": "workbench/database/factories/", - "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" - }, - "files": [ - "tests/Helpers.php" - ] + "name": "itiden/statamic-backup", + "description": "Backup your Statamic site", + "license": "MIT", + "authors": [ + { + "name": "Neo Lejondahl", + "role": "Developer" + } + ], + "require": { + "ext-zip": "*", + "statamic/cms": "^5.0.0", + "pixelfear/composer-dist-plugin": "^0.1.6" + }, + "require-dev": { + "orchestra/testbench": "^9.0", + "pestphp/pest": "^3.0", + "pestphp/pest-plugin-laravel": "^3.0", + "carthage-software/mago": "^0.11.0" + }, + "autoload": { + "psr-4": { + "Itiden\\Backup\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Itiden\\Backup\\Tests\\": "tests", + "Workbench\\App\\": "workbench/app/", + "Workbench\\Database\\Factories\\": "workbench/database/factories/", + "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" }, - "scripts": { - "post-autoload-dump": [ - "@clear", - "@prepare" - ], - "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", - "prepare": "@php vendor/bin/testbench package:discover --ansi", - "build": "@php vendor/bin/testbench workbench:build --ansi", - "serve": [ - "Composer\\Config::disableProcessTimeout", - "@build", - "@php vendor/bin/testbench serve --ansi" - ], - "lint": [ - "@php vendor/bin/mago lint" - ], - "format": [ - "@php vendor/bin/mago format" - ], - "test": [ - "XDEBUG_MODE=coverage vendor/bin/pest --coverage" - ], - "qa": [ - "@format", - "@lint", - "@test" - ] + "files": [ + "tests/Helpers.php" + ] + }, + "scripts": { + "post-autoload-dump": [ + "@clear", + "@prepare" + ], + "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", + "prepare": "@php vendor/bin/testbench package:discover --ansi", + "build": "@php vendor/bin/testbench workbench:build --ansi", + "serve": [ + "Composer\\Config::disableProcessTimeout", + "@build", + "@php vendor/bin/testbench serve --ansi" + ], + "lint": [ + "@php vendor/bin/mago lint" + ], + "format": [ + "@php vendor/bin/mago format" + ], + "test": [ + "XDEBUG_MODE=coverage vendor/bin/pest --coverage" + ], + "qa": [ + "@format", + "@lint", + "@test" + ] + }, + "extra": { + "statamic": { + "name": "Backup", + "description": "Backup your Statamic site" }, - "extra": { - "statamic": { - "name": "Backup", - "description": "Backup your Statamic site" - }, - "laravel": { - "providers": [ - "Itiden\\Backup\\ServiceProvider" - ] - }, - "download-dist": { - "url": "https://github.com/itiden/statamic-backup/releases/download/{$version}/dist.tar.gz", - "path": "resources/dist" - } + "laravel": { + "providers": [ + "Itiden\\Backup\\ServiceProvider" + ] }, - "config": { - "allow-plugins": { - "pixelfear/composer-dist-plugin": true, - "pestphp/pest-plugin": true, - "carthage-software/mago": true - } + "download-dist": { + "url": "https://github.com/itiden/statamic-backup/releases/download/{$version}/dist.tar.gz", + "path": "resources/dist" + } + }, + "config": { + "allow-plugins": { + "pixelfear/composer-dist-plugin": true, + "pestphp/pest-plugin": true, + "carthage-software/mago": true } -} \ No newline at end of file + } +} diff --git a/config/backup.php b/config/backup.php index ad96b6c..9a688a8 100644 --- a/config/backup.php +++ b/config/backup.php @@ -1,12 +1,6 @@ storage_path('content'), /** * The backup destination options @@ -70,8 +64,27 @@ * All pipes are expected to be instances of Itiden\Backup\Abtracts\BackupPipe */ 'pipeline' => [ - Itiden\Backup\Pipes\Content::class, + Itiden\Backup\Pipes\StacheData::class, Itiden\Backup\Pipes\Assets::class, Itiden\Backup\Pipes\Users::class, ], + + /** + * The stache stores that should be backed up by the StacheData pipe, by key + */ + 'stache_stores' => [ + // stores configurations + 'asset-containers', + 'collections', + 'navigation', + 'taxonomies', + // content stores + 'terms', + 'entries', + 'globals', + 'global-variables', + 'collection-trees', + 'nav-trees', + 'form-submissions', + ], ]; diff --git a/docs/pages/pipeline.md b/docs/pages/pipeline.md index 028d350..9886f54 100644 --- a/docs/pages/pipeline.md +++ b/docs/pages/pipeline.md @@ -14,7 +14,7 @@ for example, maybe you don't want to backup your users, then just comment that o ```php 'pipeline' => [ - Itiden\Backup\Pipes\Content::class, + Itiden\Backup\Pipes\StacheData::class, Itiden\Backup\Pipes\Assets::class, // Itiden\Backup\Pipes\Users::class, ], @@ -68,7 +68,7 @@ use Itiden\Backup\Abstracts\BackupPipe; use Illuminate\Support\Facades\File; use Itiden\Backup\Support\Zipper; -final class Logs extends BackupPipe +final readonly class Logs extends BackupPipe { /** * Get the key of the driver. @@ -81,7 +81,7 @@ final class Logs extends BackupPipe /** * Run the restore process. */ - public function restore(string $restoringFromPath, Closure $next): void + public function restore(string $restoringFromPath, Closure $next): string { $path = $this->getDirectoryPath($restoringFromPath); // Implement the logic to restore data from the provided backup file at $path. @@ -93,7 +93,7 @@ final class Logs extends BackupPipe /** * Run the backup process. */ - public function backup(Zipper $zip, Closure $next): void + public function backup(Zipper $zip, Closure $next): Zipper { if (!file_exists(storage_path('logs'))) { return $this->skip( @@ -127,9 +127,9 @@ Finally, you can configure your backup to use the custom driver you've created. return [ // ... 'pipeline' => [ - Itiden\Backup\Drivers\Content::class, - Itiden\Backup\Drivers\Assets::class, - Itiden\Backup\Drivers\Users::class, + Itiden\Backup\Pipes\StacheData::class, + Itiden\Backup\Pipes\Assets::class, + Itiden\Backup\Pipes\Users::class, App\Backup\Pipes\Logs::class, ], // ... diff --git a/phpunit.xml b/phpunit.xml index f78b591..91540f8 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -18,6 +18,8 @@ + + diff --git a/src/Abstracts/BackupPipe.php b/src/Abstracts/BackupPipe.php index 252acc3..1981ba0 100644 --- a/src/Abstracts/BackupPipe.php +++ b/src/Abstracts/BackupPipe.php @@ -7,7 +7,7 @@ use Closure; use Itiden\Backup\Support\Zipper; -abstract class BackupPipe +abstract readonly class BackupPipe { /** * Get the key of the driver. diff --git a/src/Pipes/Assets.php b/src/Pipes/Assets.php index 1674ce1..4a13b07 100644 --- a/src/Pipes/Assets.php +++ b/src/Pipes/Assets.php @@ -5,13 +5,14 @@ namespace Itiden\Backup\Pipes; use Closure; +use Illuminate\Http\Request; use Illuminate\Support\Facades\File; use Itiden\Backup\Abstracts\BackupPipe; use Itiden\Backup\Support\Zipper; use Statamic\Assets\AssetContainer as Container; use Statamic\Facades\AssetContainer; -final class Assets extends BackupPipe +final readonly class Assets extends BackupPipe { public static function getKey(): string { diff --git a/src/Pipes/Content.php b/src/Pipes/Content.php deleted file mode 100644 index 9d1e687..0000000 --- a/src/Pipes/Content.php +++ /dev/null @@ -1,45 +0,0 @@ -getDirectoryPath($restoringFromPath), $destination); - - return $next($restoringFromPath); - } - - public function backup(Zipper $zip, Closure $next): Zipper - { - $contentPath = config('backup.content_path'); - - if (!File::exists($contentPath)) { - return $this->skip( - reason: 'Content directory didn\'t exist, is it configured correctly?', - next: $next, - zip: $zip, - ); - } - - $zip->addDirectory($contentPath, static::getKey()); - - return $next($zip); - } -} diff --git a/src/Pipes/StacheData.php b/src/Pipes/StacheData.php new file mode 100644 index 0000000..6abaa8f --- /dev/null +++ b/src/Pipes/StacheData.php @@ -0,0 +1,87 @@ +filter(static::shouldBackupStore(...)) + ->filter(static::storeHasSafeDirectory(...)) + ->filter(fn(Store $store) => File::exists(join_paths($restoringFromPath, static::prefixer($store)))) + ->each(function (Store $store) use ($restoringFromPath): void { + File::cleanDirectory($store->directory()); + + File::copyDirectory( + directory: join_paths($restoringFromPath, static::prefixer($store)), + destination: $store->directory(), + ); + }); + + return $next($restoringFromPath); + } + + public function backup(Zipper $zip, Closure $next): Zipper + { + return collect(Stache::stores()) + ->filter(static::shouldBackupStore(...)) + ->filter(static::storeHasSafeDirectory(...)) + ->filter(fn(Store $store) => File::isDirectory($store->directory())) + ->whenNotEmpty( + function (Collection $stores) use ($zip, $next): Zipper { + $stores->each(fn(Store $store) => $zip->addDirectory( + path: realpath($store->directory()), + prefix: static::prefixer($store), + )); + + return $next($zip); + }, + default: fn() => $this->skip( + reason: 'No stores found to backup, is the Stache configured correctly?', + next: $next, + zip: $zip, + ), + ); + } + + private static function prefixer(Store $store): string + { + return self::getKey() . '::' . $store->key(); + } + + private static function storeHasSafeDirectory(Store $store): bool + { + $path = $store->directory(); + + return !in_array( + needle: $path, + haystack: [ + '/', + ], + strict: true, + ); + } + + private static function shouldBackupStore(Store $store): bool + { + return in_array($store->key(), config('backup.stache_stores', []), strict: true); + } +} diff --git a/src/Pipes/Users.php b/src/Pipes/Users.php index 252d517..329f758 100644 --- a/src/Pipes/Users.php +++ b/src/Pipes/Users.php @@ -10,7 +10,7 @@ use Itiden\Backup\Support\Zipper; use Statamic\Facades\Stache; -final class Users extends BackupPipe +final readonly class Users extends BackupPipe { public static function getKey(): string { diff --git a/tests/Feature/RestoreBackupTest.php b/tests/Feature/RestoreBackupTest.php index a2305b1..d8bcdfc 100644 --- a/tests/Feature/RestoreBackupTest.php +++ b/tests/Feature/RestoreBackupTest.php @@ -9,6 +9,7 @@ use Itiden\Backup\Facades\Backuper; use Itiden\Backup\Events\BackupRestored; +use function Itiden\Backup\Tests\fixtures_path; use function Itiden\Backup\Tests\user; use function Pest\Laravel\actingAs; use function Pest\Laravel\postJson; @@ -81,13 +82,13 @@ it('will not restore from command if you say no', function (): void { $backup = Backuper::backup(); - File::cleanDirectory(config('backup.content_path')); + File::cleanDirectory(fixtures_path('content/collections')); $this ->artisan('statamic:backup:restore', ['--path' => Storage::path($backup->path)]) ->expectsConfirmation('Are you sure you want to restore your content?', 'no'); - expect(File::isEmptyDirectory(config('backup.content_path')))->toBeTrue(); + expect(File::isEmptyDirectory(fixtures_path('content/collections')))->toBeTrue(); $this ->artisan('statamic:backup:restore', ['--path' => Storage::path($backup->path), '--force' => true]) @@ -101,7 +102,7 @@ ->artisan('statamic:backup:restore', ['--path' => Storage::path($backup->path), '--force' => true]) ->assertExitCode(0); - expect(File::isEmptyDirectory(config('backup.content_path')))->toBeFalse(); + expect(File::isEmptyDirectory(fixtures_path('content')))->toBeFalse(); }); it('will add an restore entry to metadata', function (): void { diff --git a/tests/Helpers.php b/tests/Helpers.php index c3819a5..aa3a90d 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -10,6 +10,8 @@ use Statamic\Facades\Role; use Statamic\Facades\User; +use function Illuminate\Filesystem\join_paths; + /** * Split a file into chunks * @@ -75,3 +77,8 @@ function user(): StatamicUser ->set('roles', ['user']) ->save(); } + +function fixtures_path(string $path): string +{ + return join_paths(__DIR__, '__fixtures__', $path); +} diff --git a/tests/SkippingPipe.php b/tests/SkippingPipe.php index 5dcdae3..d2e53da 100644 --- a/tests/SkippingPipe.php +++ b/tests/SkippingPipe.php @@ -8,7 +8,7 @@ use Itiden\Backup\Abstracts\BackupPipe; use Itiden\Backup\Support\Zipper; -final class SkippingPipe extends BackupPipe +final readonly class SkippingPipe extends BackupPipe { public static function getKey(): string { diff --git a/tests/TestCase.php b/tests/TestCase.php index 56c60a8..1e73bde 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,8 +5,9 @@ namespace Itiden\Backup\Tests; use Illuminate\Support\Facades\File; +use Itiden\Backup\Enums\State; use Itiden\Backup\ServiceProvider; -use Statamic\Stache\Stores\UsersStore; +use Itiden\Backup\StateManager; use Statamic\Testing\AddonTestCase; class TestCase extends AddonTestCase @@ -27,7 +28,6 @@ protected function resolveApplicationConfiguration($app): void /** * Set backup path config values */ - $app['config']->set('backup.content_path', __DIR__ . '/__fixtures__/content'); $app['config']->set('backup.temp_path', __DIR__ . '/__fixtures__/temp'); /** @@ -36,17 +36,17 @@ protected function resolveApplicationConfiguration($app): void $app['config']->set('statamic.editions.pro', true); $app['config']->set('statamic.users.repository', 'file'); - - $app['config']->set('statamic.stache.stores.users', [ - 'class' => UsersStore::class, - 'directory' => __DIR__ . '/__fixtures__/users', - ]); } protected function setUp(): void { parent::setUp(); + /** + * Set the state to idle - in case of a previous run that failed + */ + app(StateManager::class)->setState(State::Idle); + /** * Create directories */ diff --git a/tests/Unit/BackuperTest.php b/tests/Unit/BackuperTest.php index 0a8569b..c71cf18 100644 --- a/tests/Unit/BackuperTest.php +++ b/tests/Unit/BackuperTest.php @@ -11,9 +11,14 @@ use Itiden\Backup\Enums\State; use Itiden\Backup\StateManager; use Itiden\Backup\Support\Zipper; +use Statamic\Facades\Stache; +use Symfony\Component\Finder\SplFileInfo; + +use function Itiden\Backup\Tests\user; describe('backuper', function (): void { it('can backup', function (): void { + $this->withoutExceptionHandling(); $backup = Backuper::backup(); expect($backup)->toBeInstanceOf(BackupDto::class); @@ -24,15 +29,61 @@ }); it('backups correct files', function (): void { + expect(File::allFiles(Stache::store('entries')->directory()))->toHaveCount(2); // 1 entry, 1 collection + expect(File::allFiles(Stache::store('form-submissions')->directory()))->toHaveCount(1); + user(); + + $backup = Backuper::backup(); + + $unzipped = config('backup.temp_path') . '/unzipped'; + Zipper::read(Storage::disk(config('backup.destination.disk'))->path($backup->path)) + ->extractTo($unzipped, config('backup.password')) + ->close(); + + $paths = collect(File::allFiles($unzipped)) + ->map(fn(SplFileInfo $file) => $file->getRelativePathname()) + ->toArray(); + + expect($paths)->toEqualCanonicalizing([ + // since the default collection store and entries store have the same directory, we will get duplicates. + 'stache-content::collections/pages.yaml', + 'stache-content::collections/pages/homepage.md', + 'stache-content::entries/pages.yaml', + 'stache-content::entries/pages/homepage.md', + 'stache-content::form-submissions/1743066599.5568.yaml', + 'users/test@example.com.yaml', + ]); + + File::deleteDirectory($unzipped); + }); + + it('backups correct files and only include stache stores in config', function (): void { + expect(File::allFiles(Stache::store('entries')->directory()))->toHaveCount(2); // 1 entry, 1 collection + expect(File::allFiles(Stache::store('form-submissions')->directory()))->toHaveCount(1); + user(); + + config()->set('backup.stache_stores', [ + 'form-submissions', + ]); + $backup = Backuper::backup(); $unzipped = config('backup.temp_path') . '/unzipped'; - Zipper::read(Storage::disk(config('backup.destination.disk'))->path($backup->path))->extractTo( - $unzipped, - config('backup.password'), - ); - expect(File::allFiles($unzipped)[0]->getRelativePathname())->toEqual('content/collections/pages/homepage.yaml'); + Zipper::read(Storage::disk(config('backup.destination.disk'))->path($backup->path)) + ->extractTo($unzipped, config('backup.password')) + ->close(); + + $paths = collect(File::allFiles($unzipped)) + ->map(fn(SplFileInfo $file) => $file->getRelativePathname()) + ->toArray(); + + expect($paths)->toEqualCanonicalizing([ + 'stache-content::form-submissions/1743066599.5568.yaml', + 'users/test@example.com.yaml', + ]); + + File::deleteDirectory($unzipped); }); it('can enforce max backups', function (): void { diff --git a/tests/Unit/ChunkyTest.php b/tests/Unit/ChunkyTest.php index e46aa72..39365df 100644 --- a/tests/Unit/ChunkyTest.php +++ b/tests/Unit/ChunkyTest.php @@ -25,17 +25,17 @@ it('can assemble file', function (): void { $chunks = chunk_file( - __DIR__ . '/../__fixtures__/content/collections/pages/homepage.yaml', + __DIR__ . '/../__fixtures__/content/collections/pages/homepage.md', config('backup.temp_path') . '/chunks/', 10, ); - $totalSize = File::size(__DIR__ . '/../__fixtures__/content/collections/pages/homepage.yaml'); + $totalSize = File::size(__DIR__ . '/../__fixtures__/content/collections/pages/homepage.md'); $dtos = $chunks->map( fn(string $chunk, int $index): ChunkyUploadDto => new ChunkyUploadDto( path: 'dir/test', - filename: 'homepage.yaml', + filename: 'homepage.md', totalChunks: $chunks->count(), currentChunk: $index + 1, totalSize: $totalSize, @@ -50,10 +50,10 @@ expect($responses ->last() ->getData(true))->toHaveKey('file'); - expect(Chunky::path() . '/backups/homepage.yaml')->toBeFile(); + expect(Chunky::path() . '/backups/homepage.md')->toBeFile(); - expect(File::get(Chunky::path() . '/backups/homepage.yaml'))->toBe(File::get( - __DIR__ . '/../__fixtures__/content/collections/pages/homepage.yaml', + expect(File::get(Chunky::path() . '/backups/homepage.md'))->toBe(File::get( + __DIR__ . '/../__fixtures__/content/collections/pages/homepage.md', )); File::deleteDirectory(Chunky::path()); diff --git a/tests/Unit/PipeTest.php b/tests/Unit/PipeTest.php index b271848..c036d4a 100644 --- a/tests/Unit/PipeTest.php +++ b/tests/Unit/PipeTest.php @@ -6,7 +6,7 @@ use Illuminate\Support\Facades\Storage; use Itiden\Backup\Contracts\Repositories\BackupRepository; use Itiden\Backup\Pipes\Assets; -use Itiden\Backup\Pipes\Content; +use Itiden\Backup\Pipes\StacheData; use Itiden\Backup\Pipes\Users; use Itiden\Backup\Support\Zipper; use Statamic\Facades\Stache; @@ -25,7 +25,7 @@ File::delete($temp_zip); })->with([ Users::class, - Content::class, + StacheData::class, Assets::class, ]); @@ -44,12 +44,11 @@ File::copyDirectory($fixtures_backup_path, $fixtues_path); })->with([ Users::class, - Content::class, + StacheData::class, Assets::class, ]); test('can skip a pipe with users', function (): void { - /** @var Users::class $pipe */ $pipe = app()->make(Users::class); $callable = function (Zipper $z): Zipper { @@ -68,30 +67,25 @@ $zipper->close(); }); - test('can skip a pipe with content', function (): void { - /** @var Users::class $pipe */ - $pipe = app()->make(Content::class); + test('can skip a pipe with stache content', function (): void { + $pipe = app()->make(StacheData::class); $callable = function (Zipper $z): Zipper { return $z; }; - File::copyDirectory(config('backup.content_path'), config('backup.content_path') . '_backup'); - File::deleteDirectory(config('backup.content_path')); + config()->set('backup.stache_stores', ['non-existing-store']); $zipper = Zipper::write(config('backup.temp_path') . '/backup.zip'); $pipe->backup(zip: $zipper, next: $callable); - expect($zipper->getMeta())->toHaveKey(Content::class); - expect($zipper->getMeta()[Content::class])->toHaveKey( + expect($zipper->getMeta())->toHaveKey(StacheData::class); + expect($zipper->getMeta()[StacheData::class])->toHaveKey( 'skipped', - 'Content directory didn\'t exist, is it configured correctly?', + 'No stores found to backup, is the Stache configured correctly?', ); $zipper->close(); - - File::copyDirectory(config('backup.content_path') . '_backup', config('backup.content_path')); - File::deleteDirectory(config('backup.content_path') . '_backup'); }); })->group('pipes'); diff --git a/tests/Unit/RestorerTest.php b/tests/Unit/RestorerTest.php index 871df6f..41c3b58 100644 --- a/tests/Unit/RestorerTest.php +++ b/tests/Unit/RestorerTest.php @@ -9,18 +9,48 @@ use Itiden\Backup\Facades\Restorer; use Itiden\Backup\Enums\State; use Itiden\Backup\StateManager; +use Statamic\Facades\Stache; + +use function Itiden\Backup\Tests\fixtures_path; +use function Itiden\Backup\Tests\user; describe('restorer', function (): void { it('can restore from timestamp', function (): void { $backup = Backuper::backup(); - File::cleanDirectory(config('backup.content_path')); + File::cleanDirectory(fixtures_path('content/collections')); - expect(File::isEmptyDirectory(config('backup.content_path')))->toBeTrue(); + expect(File::isEmptyDirectory(fixtures_path('content/collections')))->toBeTrue(); Restorer::restoreFromTimestamp($backup->timestamp); - expect(File::isEmptyDirectory(config('backup.content_path')))->toBeFalse(); + expect(File::isEmptyDirectory(fixtures_path('content/collections')))->toBeFalse(); + }); + + it('restores correct files', function (): void { + user(); + expect(File::allFiles(Stache::store('entries')->directory()))->toHaveCount(2); // 1 entry, 1 collection + expect(File::allFiles(Stache::store('form-submissions')->directory()))->toHaveCount(1); + expect(File::allFiles(Stache::store('users')->directory()))->toHaveCount(1); + + // config()->set('backup.stache_stores', [ + // 'form-submissions', + // ]); + + $backup = Backuper::backup(); + + File::cleanDirectory(fixtures_path('content')); // Simulate the stache directories doesnt exist anymore by removing the their parent directory + File::cleanDirectory(Stache::store('users')->directory()); + + expect(file_exists(Stache::store('entries')->directory()))->toBeFalse(); + expect(file_exists(Stache::store('form-submissions')->directory()))->toBeFalse(); + expect(File::allFiles(Stache::store('users')->directory()))->toHaveCount(0); + + Restorer::restore($backup); + + expect(File::allFiles(Stache::store('entries')->directory()))->toHaveCount(2); // 1 entry, 1 collection + expect(File::allFiles(Stache::store('form-submissions')->directory()))->toHaveCount(1); + expect(File::allFiles(Stache::store('users')->directory()))->toHaveCount(1); }); it('throws an exception if the backup path does not exist', function (): void { diff --git a/tests/Unit/ZipperTest.php b/tests/Unit/ZipperTest.php index 8a926f3..d24ed84 100644 --- a/tests/Unit/ZipperTest.php +++ b/tests/Unit/ZipperTest.php @@ -5,6 +5,8 @@ use Illuminate\Support\Facades\File; use Itiden\Backup\Support\Zipper; +use function Itiden\Backup\Tests\fixtures_path; + describe('zipper', function (): void { it('can create instance', function (): void { $zip = new Zipper(storage_path('test.zip')); @@ -45,7 +47,7 @@ it('can zip directory', function (): void { $path = storage_path('test.zip'); - Zipper::write($path)->addDirectory(config('backup.content_path'), 'example'); + Zipper::write($path)->addDirectory(fixtures_path('content/collections'), 'example'); expect($path)->toBeString(); expect(file_exists($path))->toBeTrue(); @@ -84,14 +86,14 @@ }); it('can unzip directory', function (): void { - $files = collect(File::allFiles(config('backup.content_path')))->map( + $files = collect(File::allFiles(fixtures_path('content/collections')))->map( fn(SplFileInfo $file): string => $file->getPathname(), ); $target = storage_path('test.zip'); Zipper::write($target) - ->addDirectory(config('backup.content_path'), 'example') + ->addDirectory(fixtures_path('content/collections'), 'example') ->close(); $unzip = storage_path('unzipdir'); diff --git a/tests/__fixtures__/content/collections/pages.yaml b/tests/__fixtures__/content/collections/pages.yaml new file mode 100644 index 0000000..cd92935 --- /dev/null +++ b/tests/__fixtures__/content/collections/pages.yaml @@ -0,0 +1,2 @@ +title: Pages +template: page diff --git a/tests/__fixtures__/content/collections/pages/homepage.yaml b/tests/__fixtures__/content/collections/pages/homepage.md similarity index 100% rename from tests/__fixtures__/content/collections/pages/homepage.yaml rename to tests/__fixtures__/content/collections/pages/homepage.md diff --git a/tests/__fixtures__/content/submissions/1743066599.5568.yaml b/tests/__fixtures__/content/submissions/1743066599.5568.yaml new file mode 100644 index 0000000..d66cf6a --- /dev/null +++ b/tests/__fixtures__/content/submissions/1743066599.5568.yaml @@ -0,0 +1 @@ +text_field: test!