Files
ulthon_admin/tests/Feature/NoticeChannelTest.php

124 lines
4.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace tests\Feature;
use app\common\test\TestCase;
use base\common\notice\channel\EmailChannel;
use base\common\notice\channel\SmsChannel;
use base\common\notice\channel\WechatChannel;
use app\common\service\NoticeService;
use think\facade\Cache;
use think\facade\Db;
/**
* 渠道驱动集成测试(任务 4 增补).
*
* 覆盖:
* 1. EmailChannel 在 notify_email_enable=0 时抛异常(渠道总闸关闭=投递失败信号)
* 2. SmsChannel send() 返回 true(骨架恒成功)
* 3. WechatChannel send() 返回 true(骨架恒成功)
* 4. 驱动 name() 标识与 channels() 映射一致
*
* fixture 均为事务内自造数据,tearDown 自动回滚;
* sysconfig 缓存不受事务回滚影响,配置行写入后显式清 tag(见 setNotifyConfig/tearDown)。
*/
class NoticeChannelTest extends TestCase
{
/** 本测试类是否写过 notify 配置行(决定 tearDown 是否清 sysconfig 缓存) */
private bool $touchedSysconfig = false;
// =========================================================================
// 1. EmailChannel 总闸关闭抛异常
// =========================================================================
public function test_email_channel_throws_when_disabled(): void
{
// 插入关闭配置行(value='0')并清 sysconfig 缓存(缓存不受事务回滚影响)
$this->setNotifyConfig('notify_email_enable', '0');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('渠道未启用');
(new EmailChannel())->send(
['channel' => 'email', 'target_addr' => 'disabled@test.com', 'status' => 0],
['id' => 1, 'scene' => 'common', 'title' => '标题', 'content' => '内容']
);
}
// =========================================================================
// 2. SmsChannel 骨架恒成功
// =========================================================================
public function test_sms_channel_send_returns_true(): void
{
$this->assertTrue((new SmsChannel())->send(
['channel' => 'sms', 'target_addr' => '13800138000', 'status' => 0],
['id' => 1, 'scene' => 'common', 'title' => '标题', 'content' => '内容']
));
}
// =========================================================================
// 3. WechatChannel 骨架恒成功
// =========================================================================
public function test_wechat_channel_send_returns_true(): void
{
$this->assertTrue((new WechatChannel())->send(
['channel' => 'wechat', 'target_addr' => 'openid_demo', 'status' => 0],
['id' => 1, 'scene' => 'common', 'title' => '标题', 'content' => '内容']
));
}
// =========================================================================
// 4. name() 契约与 channels() 映射一致
// =========================================================================
public function test_channel_names_match_service_mapping(): void
{
$this->assertSame('email', EmailChannel::name());
$this->assertSame('sms', SmsChannel::name());
$this->assertSame('wechat', WechatChannel::name());
$channels = NoticeService::channels();
$this->assertSame(EmailChannel::class, $channels['email']);
$this->assertSame(SmsChannel::class, $channels['sms']);
$this->assertSame(WechatChannel::class, $channels['wechat']);
}
// =========================================================================
// fixture 工厂(事务内运行,tearDown 自动回滚;缓存显式清理)
// =========================================================================
/**
* 写 notify 组配置行并清 sysconfig 缓存.
*
* sysconfig 缓存不受事务回滚影响:必须显式清 tag 才能让后续读取
* 看到事务内的新值(value='0' 因 empty('0') 恒不写缓存,但清理是
* 防御后续用例被前序非 '0' 缓存值污染的统一口径)。
*/
private function setNotifyConfig(string $name, string $value): void
{
Db::name('system_config')->insert([
'name' => $name,
'group' => 'notify',
'value' => $value,
'remark' => 'NoticeChannelTest fixture',
'sort' => 100,
'create_time' => time(),
'update_time' => time(),
]);
$this->touchedSysconfig = true;
Cache::tag('sysconfig')->clear();
}
protected function tearDown(): void
{
if ($this->touchedSysconfig) {
Cache::tag('sysconfig')->clear();
}
parent::tearDown();
}
}