|
@@ -67,6 +67,7 @@ class ActivityCatalogTest extends TestCase
|
|
|
(require dirname(__DIR__, 2) . '/database/migrations/2026_10_14_120000_add_activity_reward_quotas.php')->up();
|
|
(require dirname(__DIR__, 2) . '/database/migrations/2026_10_14_120000_add_activity_reward_quotas.php')->up();
|
|
|
$this->migration()->up();
|
|
$this->migration()->up();
|
|
|
(require dirname(__DIR__, 2) . '/database/migrations/2026_10_28_120000_add_activity_click_behavior.php')->up();
|
|
(require dirname(__DIR__, 2) . '/database/migrations/2026_10_28_120000_add_activity_click_behavior.php')->up();
|
|
|
|
|
+ (require dirname(__DIR__, 2) . '/database/migrations/2026_10_28_130000_add_activity_click_position.php')->up();
|
|
|
$this->request('');
|
|
$this->request('');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -173,22 +174,61 @@ class ActivityCatalogTest extends TestCase
|
|
|
$id = (int) DB::table('activity_rewards')->latest('id')->value('id');
|
|
$id = (int) DB::table('activity_rewards')->latest('id')->value('id');
|
|
|
$this->assertSame('none', DB::table('activity_rewards')->where('id', $id)->value('click_type'));
|
|
$this->assertSame('none', DB::table('activity_rewards')->where('id', $id)->value('click_type'));
|
|
|
foreach (['external' => 'https://example.com/promotion?from=activity', 'internal' => '/promotion/detail?id=3'] as $mode => $link) {
|
|
foreach (['external' => 'https://example.com/promotion?from=activity', 'internal' => '/promotion/detail?id=3'] as $mode => $link) {
|
|
|
- $body = $this->save(['id' => $id, 'type' => $type, 'click_type' => $mode, 'link' => $link]);
|
|
|
|
|
|
|
+ $body = $this->save(['id' => $id, 'type' => $type, 'click_type' => $mode, 'link' => $link, 'click_position' => $mode === 'external' ? 'cover' : 'detail']);
|
|
|
$this->assertSame(HttpStatus::OK, $body['code'], $body['msg']);
|
|
$this->assertSame(HttpStatus::OK, $body['code'], $body['msg']);
|
|
|
$this->assertSame(HttpStatus::OK, $this->save(['id' => $id, 'type' => $type, 'title' => '只改标题'])['code']);
|
|
$this->assertSame(HttpStatus::OK, $this->save(['id' => $id, 'type' => $type, 'title' => '只改标题'])['code']);
|
|
|
$row = collect($this->listing()['data'])->keyBy('id')->get($id);
|
|
$row = collect($this->listing()['data'])->keyBy('id')->get($id);
|
|
|
$this->assertSame($mode, $row['click_type']); $this->assertSame($link, $row['link']); $this->assertTrue($row['can_jump']);
|
|
$this->assertSame($mode, $row['click_type']); $this->assertSame($link, $row['link']); $this->assertTrue($row['can_jump']);
|
|
|
|
|
+ $this->assertSame($mode === 'external' ? 'cover' : 'detail', $row['click_position']);
|
|
|
}
|
|
}
|
|
|
- $this->assertSame(HttpStatus::OK, $this->save(['id' => $id, 'type' => $type, 'click_type' => 'none', 'link' => ['unused']])['code']);
|
|
|
|
|
|
|
+ $this->assertSame(HttpStatus::OK, $this->save(['id' => $id, 'type' => $type, 'click_type' => 'none', 'link' => ['unused'], 'click_position' => ['unused']])['code']);
|
|
|
$row = ActivityReward::findOrFail($id)->toArray();
|
|
$row = ActivityReward::findOrFail($id)->toArray();
|
|
|
$this->assertSame('none', $row['click_type']); $this->assertNull($row['link']); $this->assertFalse($row['can_jump']);
|
|
$this->assertSame('none', $row['click_type']); $this->assertNull($row['link']); $this->assertFalse($row['can_jump']);
|
|
|
|
|
+ $this->assertNull($row['click_position']);
|
|
|
|
|
+ $this->assertNull(DB::table('activity_rewards')->where('id', $id)->value('click_position'));
|
|
|
$this->assertNull(DB::table('activity_rewards')->where('id', $id)->value('link'));
|
|
$this->assertNull(DB::table('activity_rewards')->where('id', $id)->value('link'));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function test_nonempty_links_require_a_trigger_position_and_can_switch_position_independently(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $this->request('options');
|
|
|
|
|
+ $this->assertSame([['value' => 'cover', 'label' => '活动列表封面'], ['value' => 'detail', 'label' => '活动详情按钮']],
|
|
|
|
|
+ (new AdminActivityReward())->options()->getData(true)['data']['click_positions']);
|
|
|
|
|
+ foreach (['external' => 'https://example.com', 'internal' => '/detail'] as $mode => $link) {
|
|
|
|
|
+ foreach ([null, '', 'invalid', ['cover']] as $position) {
|
|
|
|
|
+ $this->assertSame(HttpStatus::CUSTOM_ERROR, $this->save(['click_type' => $mode, 'link' => $link, 'click_position' => $position])['code']);
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->assertSame(HttpStatus::CUSTOM_ERROR, $this->save(['click_type' => $mode, 'link' => $link])['code']);
|
|
|
|
|
+ $this->assertSame(0, DB::table('activity_rewards')->count());
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->save(['click_type' => 'internal', 'link' => '/detail', 'click_position' => 'cover']);
|
|
|
|
|
+ $id = (int) DB::table('activity_rewards')->value('id');
|
|
|
|
|
+ $this->assertSame(HttpStatus::OK, $this->save(['id' => $id, 'click_position' => 'detail'])['code']);
|
|
|
|
|
+ $row = ActivityReward::findOrFail($id)->toArray();
|
|
|
|
|
+ $this->assertSame('detail', $row['click_position']); $this->assertSame('/detail', $row['link']);
|
|
|
|
|
+ $this->assertSame('internal', $row['click_type']); $this->assertTrue($row['can_jump']);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_trigger_position_migration_keeps_old_links_on_the_cover(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $migration = require dirname(__DIR__, 2) . '/database/migrations/2026_10_28_130000_add_activity_click_position.php';
|
|
|
|
|
+ $migration->down();
|
|
|
|
|
+ $linked = $this->rawActivity(['click_type' => 'external', 'link' => 'https://example.com']);
|
|
|
|
|
+ $plain = $this->rawActivity();
|
|
|
|
|
+ $before = DB::table('activity_rewards')->orderBy('id')->get();
|
|
|
|
|
+ $migration->up();
|
|
|
|
|
+ $this->assertSame('cover', DB::table('activity_rewards')->where('id', $linked)->value('click_position'));
|
|
|
|
|
+ $this->assertNull(DB::table('activity_rewards')->where('id', $plain)->value('click_position'));
|
|
|
|
|
+ foreach ($before as $old) {
|
|
|
|
|
+ $new = DB::table('activity_rewards')->where('id', $old->id)->first();
|
|
|
|
|
+ foreach ((array) $old as $field => $value) $this->assertSame($value, $new->$field);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function test_invalid_activity_links_do_not_modify_the_activity(): void
|
|
public function test_invalid_activity_links_do_not_modify_the_activity(): void
|
|
|
{
|
|
{
|
|
|
- $this->save(['click_type' => 'internal', 'link' => '/original']);
|
|
|
|
|
|
|
+ $this->save(['click_type' => 'internal', 'link' => '/original', 'click_position' => 'cover']);
|
|
|
$id = (int) DB::table('activity_rewards')->value('id');
|
|
$id = (int) DB::table('activity_rewards')->value('id');
|
|
|
$before = DB::table('activity_rewards')->where('id', $id)->first();
|
|
$before = DB::table('activity_rewards')->where('id', $id)->first();
|
|
|
foreach ([['click_type' => 'activity'], ['click_type' => null], ['click_type' => ['none']],
|
|
foreach ([['click_type' => 'activity'], ['click_type' => null], ['click_type' => ['none']],
|
|
@@ -196,7 +236,7 @@ class ActivityCatalogTest extends TestCase
|
|
|
['click_type' => 'external', 'link' => 'https://user:pass@example.com'], ['click_type' => 'external', 'link' => '/relative'],
|
|
['click_type' => 'external', 'link' => 'https://user:pass@example.com'], ['click_type' => 'external', 'link' => '/relative'],
|
|
|
['click_type' => 'internal', 'link' => '//example.com'], ['click_type' => 'internal', 'link' => '/\\evil'],
|
|
['click_type' => 'internal', 'link' => '//example.com'], ['click_type' => 'internal', 'link' => '/\\evil'],
|
|
|
['click_type' => 'internal', 'link' => 'https://example.com'], ['click_type' => 'external', 'link' => ['bad']]] as $values) {
|
|
['click_type' => 'internal', 'link' => 'https://example.com'], ['click_type' => 'external', 'link' => ['bad']]] as $values) {
|
|
|
- $body = $this->save(['id' => $id] + $values);
|
|
|
|
|
|
|
+ $body = $this->save(['id' => $id] + $values + ['click_position' => 'cover']);
|
|
|
$this->assertSame(HttpStatus::CUSTOM_ERROR, $body['code']);
|
|
$this->assertSame(HttpStatus::CUSTOM_ERROR, $body['code']);
|
|
|
$this->assertEquals($before, DB::table('activity_rewards')->where('id', $id)->first());
|
|
$this->assertEquals($before, DB::table('activity_rewards')->where('id', $id)->first());
|
|
|
}
|
|
}
|