[ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ]]); DB::purge('business_mirror'); Schema::connection('business_mirror')->create('business_mirror_table_states', function ($table): void { $table->string('dataset_key')->primary(); $table->string('status')->nullable(); $table->dateTime('initial_completed_at')->nullable(); }); DB::connection('business_mirror')->table('business_mirror_table_states')->insert([ 'dataset_key' => 'jiansun.dbo.jst_workOrderInfo', 'status' => 'succeeded', 'initial_completed_at' => '2026-10-01 00:00:00', ]); } public function test_checks_label_coverage_then_syncs_requested_months(): void { $coverage = Mockery::mock(JstOrderLabelDailySynchronizer::class); $coverage->shouldReceive('assertCovered') ->once() ->with('2026-10-01', '2026-10-31', 1) ->andReturn(array_fill(0, 31, ['status' => 'ok'])); $workOrders = Mockery::mock(PlantingWorkOrderSynchronizer::class); $workOrders->shouldReceive('sync') ->once() ->with('2026-10-01', '2026-10-31', 1) ->andReturn(['orders' => 10, 'inserted' => 10]); $synchronizer = new StoreReceiptPlantingDailySynchronizer( app(DatabaseManager::class), $coverage, $workOrders, ); $result = $synchronizer->sync('2026-10-01', '2026-10-31', 1, ['2026-10']); $this->assertSame('ready_to_refresh', $result['status']); $this->assertSame(['2026-10'], $result['months']); $this->assertSame(31, $result['checked_days']); $this->assertSame(10, $result['planting_sync']['2026-10']['orders']); } public function test_defaults_to_current_and_previous_month(): void { $coverage = Mockery::mock(JstOrderLabelDailySynchronizer::class); $coverage->shouldReceive('assertCovered')->once()->andReturn([['status' => 'ok']]); $workOrders = Mockery::mock(PlantingWorkOrderSynchronizer::class); $workOrders->shouldReceive('sync') ->once() ->with('2026-10-01', '2026-10-31', 1) ->andReturn([]); $workOrders->shouldReceive('sync') ->once() ->with('2026-11-01', '2026-11-30', 1) ->andReturn([]); $synchronizer = new StoreReceiptPlantingDailySynchronizer( app(DatabaseManager::class), $coverage, $workOrders, ); $result = $synchronizer->sync('2026-10-01', '2026-11-04', 1, ['2026-11', '2026-10']); $this->assertSame(['2026-10', '2026-11'], $result['months']); } public function test_blocks_recalculation_when_label_coverage_is_not_ready(): void { $coverage = Mockery::mock(JstOrderLabelDailySynchronizer::class); $coverage->shouldReceive('assertCovered') ->once() ->andThrow(new \RuntimeException('历史数据检查未通过')); $workOrders = Mockery::mock(PlantingWorkOrderSynchronizer::class); $workOrders->shouldNotReceive('sync'); $synchronizer = new StoreReceiptPlantingDailySynchronizer( app(DatabaseManager::class), $coverage, $workOrders, ); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('历史数据检查未通过'); $synchronizer->sync('2026-10-01', '2026-10-31', 1, ['2026-10']); } }