122 lines
4.6 KiB
PHP
122 lines
4.6 KiB
PHP
<?php
|
||
|
||
namespace Tests\Feature;
|
||
|
||
use App\Models\NoticeModel;
|
||
use App\Models\StoreModel;
|
||
|
||
/**
|
||
* 小程序消息通知:本店通知 + 全员广播;广播已读复制本店副本(data.broadcast_from 记来源),
|
||
* 列表排除已读广播。回归:列表曾报 Undefined property: stdClass::$data->broadcast_from
|
||
* (pluck JSON 路径被 Query Builder 当作结果列名读取 stdClass 属性)
|
||
* (门店即用户:通知按 store_id 归属,store_id=0 为全员广播)
|
||
*/
|
||
class MiniNoticeTest extends ProcurementTestCase
|
||
{
|
||
/** 造一家门店 */
|
||
private function makeStore(): StoreModel
|
||
{
|
||
return StoreModel::factory()->create();
|
||
}
|
||
|
||
/** 通知列表:本店通知 + 未读广播,unread_count 正确 */
|
||
public function test_notice_list_includes_personal_and_broadcast(): void
|
||
{
|
||
$store = $this->makeStore();
|
||
$this->actingAsMiniStore($store);
|
||
|
||
NoticeModel::create([
|
||
'store_id' => NoticeModel::BROADCAST_STORE_ID,
|
||
'type' => NoticeModel::TYPE_SYSTEM,
|
||
'title' => '系统公告',
|
||
'content' => '全员可见',
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
NoticeModel::create([
|
||
'store_id' => $store->id,
|
||
'type' => NoticeModel::TYPE_ORDER,
|
||
'title' => '订单状态更新',
|
||
'content' => '您的订单已接单',
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
|
||
$data = $this->getJson('/mini/notice')->assertOk()->json('data');
|
||
|
||
$this->assertSame(2, $data['total']);
|
||
$this->assertSame(2, $data['unread_count']);
|
||
}
|
||
|
||
/** 广播标记已读:复制本店已读副本,列表排除原广播(回归:列表不再报错) */
|
||
public function test_broadcast_read_creates_personal_copy(): void
|
||
{
|
||
$store = $this->makeStore();
|
||
$this->actingAsMiniStore($store);
|
||
|
||
$broadcast = NoticeModel::create([
|
||
'store_id' => NoticeModel::BROADCAST_STORE_ID,
|
||
'type' => NoticeModel::TYPE_SYSTEM,
|
||
'title' => '系统公告',
|
||
'content' => '全员可见',
|
||
'data' => ['foo' => 'bar'],
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
|
||
$this->putJson("/mini/notice/{$broadcast->id}/read")->assertJsonPath('success', true);
|
||
|
||
// 已读副本:本店记录、已读、broadcast_from 记来源且保留原 data
|
||
$copy = NoticeModel::where('store_id', $store->id)->first();
|
||
$this->assertNotNull($copy);
|
||
$this->assertSame(NoticeModel::READ, $copy->is_read);
|
||
$this->assertSame($broadcast->id, $copy->data['broadcast_from']);
|
||
$this->assertSame('bar', $copy->data['foo']);
|
||
|
||
// 列表:原广播被排除,仅剩已读副本,未读数归零
|
||
$data = $this->getJson('/mini/notice')->assertOk()->json('data');
|
||
$this->assertSame(1, $data['total']);
|
||
$this->assertSame(0, $data['unread_count']);
|
||
$this->assertSame($copy->id, $data['data'][0]['id']);
|
||
|
||
// 重复标记不重复复制
|
||
$this->putJson("/mini/notice/{$broadcast->id}/read")->assertJsonPath('success', true);
|
||
$this->assertSame(1, NoticeModel::where('store_id', $store->id)->count());
|
||
}
|
||
|
||
/** 定向通知标记已读:直接更新原记录,不产生副本 */
|
||
public function test_personal_notice_read_marks_directly(): void
|
||
{
|
||
$store = $this->makeStore();
|
||
$this->actingAsMiniStore($store);
|
||
|
||
$notice = NoticeModel::create([
|
||
'store_id' => $store->id,
|
||
'type' => NoticeModel::TYPE_ORDER,
|
||
'title' => '订单状态更新',
|
||
'content' => '您的订单已接单',
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
|
||
$this->putJson("/mini/notice/{$notice->id}/read")->assertJsonPath('success', true);
|
||
$this->assertSame(NoticeModel::READ, $notice->refresh()->is_read);
|
||
$this->assertSame(1, NoticeModel::count(), '定向通知直接更新,不产生副本');
|
||
}
|
||
|
||
/** 他店通知不可标记(仅本店通知与广播可读) */
|
||
public function test_other_stores_notice_not_found(): void
|
||
{
|
||
$store = $this->makeStore();
|
||
$this->actingAsMiniStore($store);
|
||
|
||
$other = $this->makeStore();
|
||
$notice = NoticeModel::create([
|
||
'store_id' => $other->id,
|
||
'type' => NoticeModel::TYPE_ORDER,
|
||
'title' => '订单状态更新',
|
||
'content' => '他店通知',
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
|
||
$this->putJson("/mini/notice/{$notice->id}/read")->assertJsonPath('success', false);
|
||
$this->assertSame(NoticeModel::UNREAD, $notice->refresh()->is_read);
|
||
}
|
||
}
|