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.
wx.sstbc.com/tests/Feature/ImportedSupplyCleanupTest.php

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());
}
}