You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
4.6 KiB
61 lines
4.6 KiB
|
3 weeks ago
|
<?php
|
||
|
|
namespace Tests\Feature;
|
||
|
|
use Tests\TestCase;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
use Illuminate\Support\Facades\Schema;
|
||
|
|
use Illuminate\Database\Schema\Blueprint;
|
||
|
|
|
||
|
|
class ImportedSupplyCleanupTest extends TestCase
|
||
|
|
{
|
||
|
|
private $backupDirectory;
|
||
|
|
protected function setUp(): void {
|
||
|
|
parent::setUp();
|
||
|
|
config(['database.default'=>'sqlite','database.connections.sqlite.database'=>':memory:']);DB::purge('sqlite');
|
||
|
|
require_once base_path('cleanup-imported-supply.php');
|
||
|
|
$this->backupDirectory=sys_get_temp_dir().'/supply-cleanup-test-'.bin2hex(random_bytes(6));
|
||
|
|
Schema::create('supply_demands',function(Blueprint $t){$t->id();$t->integer('is_proxy');$t->string('import_key')->nullable();$t->string('content');$t->integer('user_id')->default(0);$t->integer('status')->default(1);$t->timestamps();$t->softDeletes();});
|
||
|
|
Schema::create('dialogues',function(Blueprint $t){$t->id();$t->integer('supply_demand_id');});
|
||
|
|
Schema::create('messages',function(Blueprint $t){$t->id();$t->integer('supply_demand_id');$t->integer('dialogue_id');$t->string('content');$t->softDeletes();});
|
||
|
|
foreach ([[1,1,'import-a',null],[2,1,'import-b','2026-10-20 00:00:00'],[3,1,null,null],[4,0,'self-published',null]] as [$id,$proxy,$key,$deleted]) DB::table('supply_demands')->insert(['id'=>$id,'is_proxy'=>$proxy,'import_key'=>$key,'content'=>'原始内容'.$id,'user_id'=>123,'deleted_at'=>$deleted]);
|
||
|
|
}
|
||
|
|
protected function tearDown(): void {
|
||
|
|
if(is_dir($this->backupDirectory)){foreach(glob($this->backupDirectory.'/*') as $f)unlink($f);rmdir($this->backupDirectory);}
|
||
|
|
DB::disconnect('sqlite');parent::tearDown();
|
||
|
|
}
|
||
|
|
public function test_check_is_read_only_and_execute_backs_up_before_clearing_only_imports() {
|
||
|
|
$before=DB::table('supply_demands')->orderBy('id')->get();
|
||
|
|
$check=\ImportedSupplyCleanup::run(false,$this->backupDirectory);
|
||
|
|
$this->assertSame(2,$check['imported_demands']);$this->assertSame(0,$check['cleaned']);$this->assertFalse(is_dir($this->backupDirectory));
|
||
|
|
$this->assertEquals($before,DB::table('supply_demands')->orderBy('id')->get());
|
||
|
|
$done=\ImportedSupplyCleanup::run(true,$this->backupDirectory);
|
||
|
|
$this->assertSame(2,$done['cleaned']);$this->assertSame(hash_file('sha256',$done['backup']['file']),$done['backup']['sha256']);
|
||
|
|
$backup=json_decode(file_get_contents($done['backup']['file']),true);
|
||
|
|
$this->assertSame('import-a',$backup['supply_demands'][0]['import_key']);$this->assertNull($backup['supply_demands'][0]['deleted_at']);
|
||
|
|
$this->assertSame(0600,fileperms($done['backup']['file']) & 0777);
|
||
|
|
$this->assertSame(0,DB::table('supply_demands')->whereIn('id',[1,2])->whereNotNull('import_key')->count());
|
||
|
|
$this->assertSame(2,DB::table('supply_demands')->whereIn('id',[1,2])->whereNotNull('deleted_at')->count());
|
||
|
|
$this->assertSame('2026-10-20 00:00:00',DB::table('supply_demands')->where('id',2)->value('deleted_at'));
|
||
|
|
foreach([3,4] as $id)$this->assertEquals($before->firstWhere('id',$id),DB::table('supply_demands')->where('id',$id)->first());
|
||
|
|
$this->assertSame(123,DB::table('supply_demands')->where('id',1)->value('user_id'));
|
||
|
|
$this->assertSame(0,\ImportedSupplyCleanup::run(true,$this->backupDirectory)['cleaned']);
|
||
|
|
}
|
||
|
|
public function test_any_private_message_including_deleted_or_dialogue_only_stops_cleanup_after_backup() {
|
||
|
|
DB::table('dialogues')->insert(['id'=>10,'supply_demand_id'=>1]);
|
||
|
|
DB::table('messages')->insert(['id'=>1,'supply_demand_id'=>0,'dialogue_id'=>10,'content'=>'历史消息','deleted_at'=>'2026-10-20 00:00:00']);
|
||
|
|
$before=DB::table('supply_demands')->get();
|
||
|
|
$report=\ImportedSupplyCleanup::run(true,$this->backupDirectory);
|
||
|
|
$this->assertSame(1,$report['messages']);$this->assertSame(0,$report['cleaned']);
|
||
|
|
$this->assertFileExists($report['backup']['file']);
|
||
|
|
$backup=json_decode(file_get_contents($report['backup']['file']),true);
|
||
|
|
$this->assertSame('历史消息',$backup['messages'][0]['content']);
|
||
|
|
$this->assertEquals($before,DB::table('supply_demands')->get());
|
||
|
|
$this->assertSame(1,DB::table('messages')->count());$this->assertSame(1,DB::table('dialogues')->count());
|
||
|
|
}
|
||
|
|
public function test_backup_failure_prevents_business_changes() {
|
||
|
|
$before=DB::table('supply_demands')->get();
|
||
|
|
try { \ImportedSupplyCleanup::run(true,'/dev/null/unwritable');$this->fail('Expected backup failure'); }
|
||
|
|
catch(\Throwable $e){$this->assertStringNotContainsString('Expected backup failure',$e->getMessage());}
|
||
|
|
$this->assertEquals($before,DB::table('supply_demands')->get());
|
||
|
|
}
|
||
|
|
}
|