| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- <?php
- /** Local HTTP smoke test; temporary tagged fixtures are removed in finally. Tokens never leave memory. */
- require dirname(__DIR__).'/vendor/autoload.php';
- \Dotenv\Dotenv::createUnsafeMutable(dirname(__DIR__))->load();
- \support\App::loadAllConfig(['route']);
- date_default_timezone_set('Asia/Shanghai');
- use plugin\saiadmin\app\model\water\{WaterModel,WaterSku,WaterEnterprise,WaterAccount,WaterDelivery,WaterDriver,WaterDriverShift,WaterRoute,WaterLedger,WaterDeliveryEvent};
- use plugin\saiadmin\app\service\{WaterBusiness,WaterDispatch};
- use Tinywan\Jwt\JwtToken;
- $tag='HTTP-FULFILL-'.bin2hex(random_bytes(5)); $date=date('Y-m-d'); $checks=0;
- $skuId=null; $enterpriseId=null; $driverId=null; $routeIds=[]; $taskIds=[];
- // A distinct short-lived client avoids replacing any user's single-device browser session.
- $token=JwtToken::generateToken(['id'=>1,'username'=>'admin','plat'=>'saiadmin','type'=>'web','client'=>$tag,'access_exp'=>120,'refresh_exp'=>120])['access_token'];
- function api(string $path,?array $data=null): array {
- global $token,$checks;
- $ch=curl_init('http://127.0.0.1:8787/core/water/'.$path);
- $options=[CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>15,CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.$token]];
- if ($data!==null) $options += [CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode($data)];
- curl_setopt_array($ch,$options); $raw=curl_exec($ch); $status=curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch);
- $result=json_decode($raw,true);
- if ($status!==200 || ($result['code']??null)!==200) throw new RuntimeException('HTTP '.$status.' '.$path.': '.($result['message']??'invalid response'));
- $checks++; return $result['data'];
- }
- function verify(bool $value,string $message): void { global $checks; if (!$value) throw new RuntimeException($message); $checks++; }
- try {
- WaterModel::transaction(function () use ($tag,$date,&$skuId,&$enterpriseId,&$driverId,&$taskIds,&$routeIds) {
- $b=new WaterBusiness(); $d=new WaterDispatch();
- $skuId=$b->save('sku',['name'=>$tag,'liters'=>18.9],1)['id'];
- $b->stock(['sku_id'=>$skuId,'mode'=>'inbound','quantity'=>10,'reference'=>$tag,'note'=>'temporary HTTP fixture'],1);
- $enterpriseId=$b->save('enterprise',['name'=>$tag,'contact'=>'test','phone'=>'TEST','address'=>'TEST DO NOT DELIVER','region'=>$tag],1)['id'];
- WaterAccount::query()->insert(['enterprise_id'=>$enterpriseId,'sku_id'=>$skuId,'entitlement'=>10,'empty_qty'=>2,'updated_at'=>date('Y-m-d H:i:s')]);
- $taskIds[]=$b->createDelivery(['enterprise_id'=>$enterpriseId,'sku_id'=>$skuId,'quantity'=>4,'date'=>$date],1)['id'];
- $driverId=$d->saveDriver(['name'=>$tag,'phone'=>$tag,'region'=>$tag,'capacity'=>10],1)['id'];
- $d->shift(['driver_id'=>$driverId,'date'=>$date,'state'=>'on'],1);
- $routeIds=$d->commit(['date'=>$date,'request_key'=>$tag,'routes'=>[['driver_id'=>$driverId,'task_ids'=>$taskIds]]],1)['route_ids'];
- });
- api('dispatch',['action'=>'depart','id'=>$taskIds[0]]);
- $receipt=['action'=>'receive','id'=>$taskIds[0],'accepted_qty'=>2,'empty_returned'=>2,'receiver'=>'HTTP test receiver','reason'=>'test partial receipt'];
- verify(api('dispatch',$receipt)['status']==='returning','partial status');
- verify(api('dispatch',$receipt)['replayed']===true,'HTTP receipt replay');
- $board=api('dispatch/board?keyword='.rawurlencode($tag));
- verify($board['summary']['returning']===1,'HTTP exception filter visible');
- api('dispatch',['action'=>'return_receive','id'=>$taskIds[0],'good_qty'=>1,'damaged_qty'=>1,'note'=>'test warehouse check']);
- $route=api('dispatch/route?id='.$routeIds[0]);
- verify($route['fulfillment']['can_settle']===true && $route['fulfillment']['empty_items'][0]['expected']===2,'HTTP route custody');
- api('dispatch',['action'=>'route_settle','route_id'=>$routeIds[0],'items'=>[['sku_id'=>$skuId,'actual'=>2,'lost'=>0]],'note'=>'test warehouse handover']);
- $new=api('dispatch',['action'=>'redeliver','id'=>$taskIds[0],'date'=>$date,'note'=>'test reschedule']); $taskIds[]=$new['id'];
- verify((int)WaterDelivery::query()->find($new['id'])->redelivery_of===$taskIds[0],'HTTP linked retry');
- api('dispatch',['action'=>'cancel','id'=>$new['id']]);
- verify(count(api('dispatch/history?id='.$taskIds[0]))>=3,'HTTP audit history');
- $s=WaterSku::query()->find($skuId); $a=WaterAccount::query()->where('enterprise_id',$enterpriseId)->first();
- verify((int)$s->available===7 && (int)$s->transit===0 && (int)$s->locked===0 && (int)$s->damaged_qty===1 && (int)$s->empty_qty===2,'HTTP full and empty stock reconciled');
- verify((int)$a->entitlement===8 && (int)$a->frozen===0 && (int)$a->full_qty===2,'HTTP rights reconciled');
- } finally {
- WaterModel::transaction(function () use ($tag,$skuId,$enterpriseId,$driverId) {
- if (!$skuId) return;
- $sku=WaterSku::query()->find($skuId);
- if (!$sku) return;
- if ($sku->name!==$tag) throw new RuntimeException('Fixture ownership changed; cleanup stopped');
- $tasks=WaterDelivery::query()->where('sku_id',$skuId)->get();
- if ($tasks->contains(fn($task)=>(int)$task->enterprise_id!==$enterpriseId)) throw new RuntimeException('Unexpected task attached to test SKU');
- $ids=$tasks->pluck('id')->all(); $routes=$tasks->pluck('route_id')->filter()->unique()->all();
- WaterDeliveryEvent::query()->whereIn('delivery_id',$ids)->orWhereIn('route_id',$routes)->delete();
- WaterLedger::query()->where('sku_id',$skuId)->delete();
- $refs=array_merge(array_map(fn($id)=>'route:'.$id,$routes),array_map(fn($id)=>'delivery:'.$id,$ids),['driver:'.$driverId]);
- WaterLedger::query()->where('kind','dispatch_config')->whereIn('reference',$refs)->delete();
- WaterDelivery::query()->whereIn('id',$ids)->delete();
- WaterRoute::query()->whereIn('id',$routes)->delete();
- WaterAccount::query()->where('sku_id',$skuId)->delete();
- if ($enterpriseId) WaterEnterprise::query()->where('id',$enterpriseId)->where('name',$tag)->delete();
- if ($driverId) { WaterDriverShift::query()->where('driver_id',$driverId)->delete(); WaterDriver::query()->where('id',$driverId)->where('name',$tag)->delete(); }
- WaterSku::query()->where('id',$skuId)->where('name',$tag)->delete();
- });
- }
- verify(!WaterSku::query()->where('name',$tag)->exists() && !WaterEnterprise::query()->where('name',$tag)->exists(),'temporary fixtures removed');
- echo "PASS: $checks local HTTP fulfillment checks; temporary fixtures removed; normal operation audit retained.\n";
|