CaiWuXiTong/tests/Unit/View/AccountBillsTableTest.php
qiuxiang c647559c40 fix: 淘系微信期初余额暂置为零 (#985)
淘系微信期初余额暂固定为零,待录入各店铺6月期末余额
2026-11-07 17:02:24 +08:00

259 lines
15 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
namespace Tests\Unit\View;
use PHPUnit\Framework\TestCase;
class AccountBillsTableTest extends TestCase
{
public function test_authoritative_bill_pages_use_stable_date_controls_and_existing_table_interactions(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("isDouyin(){return this.billType==='douyin';}", $source);
$this->assertStringContainsString("usesStableDateControl(){return true;}", $source);
$this->assertStringContainsString("{ 'is-stable-date': usesStableDateControl }", $source);
$this->assertStringContainsString('.tw-date.is-stable-date .tw-date-control', $source);
$this->assertStringContainsString("['douyin','pinduoduo','dewu','taobao-wechat','jd-transactions','jingxi','jd-wallet','vipshop','vipshop-jx','xiaohongshu','promotion-marketing'].indexOf(this.billType)!==-1", $source);
$this->assertStringContainsString('v-if="usesMirrorOptions && !filterOptionsError"', $source);
$this->assertStringContainsString(':page-key="pageKey"', $source);
$this->assertStringContainsString(':tab-key="billType"', $source);
$this->assertStringContainsString("value=\"page-visible\"", $source);
$this->assertStringContainsString("value=\"filtered-visible\"", $source);
$this->assertStringContainsString("value=\"filtered-all\"", $source);
$this->assertStringContainsString('position:sticky', $source);
$this->assertStringContainsString('overflow:auto', $source);
}
public function test_store_receiving_tabs_route_the_vipshop_jx_account(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/views/business/pages.js');
$this->assertStringContainsString(
"const GENERIC_TABS = ['taobao-wechat', 'pinduoduo', 'jd-wallet', 'jd-transactions', 'jingxi', 'douyin', 'dewu', 'vipshop', 'vipshop-jx', 'xiaohongshu', 'promotion-marketing'];",
$source,
);
$this->assertStringContainsString(
"const STORE_RECEIVING_TABS = ['taobao-alipay', 'taobao-wechat', 'pinduoduo', 'jd-wallet', 'jd-transactions', 'jingxi', 'douyin', 'dewu', 'vipshop', 'vipshop-jx', 'xiaohongshu'];",
$source,
);
$this->assertStringContainsString(
"context.page === 'store-receiving-bills' || context.tab === 'promotion-marketing'",
$source,
);
}
public function test_store_filter_remains_usable_when_options_are_empty_or_the_date_changes(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString('filterable allow-create default-first-option', $source);
$this->assertStringContainsString('没有匹配的店铺,输入后回车使用', $source);
$this->assertStringContainsString('暂无店铺,输入后回车使用', $source);
$this->assertStringContainsString('placeholder="输入店铺名称"', $source);
$this->assertStringContainsString(
'canUseStoreSelect(){return !this.filterOptionsError&&(this.filterOptionsLoading||this.filterOptions.shops.length>0);}',
$source,
);
$this->assertStringContainsString(
'if(selected&&shops.indexOf(selected)===-1)shops.unshift(selected);',
$source,
);
$this->assertStringContainsString(
"const dateRangeChanged=this.queryFilters.start!==this.filters.start||this.queryFilters.end!==this.filters.end;",
$source,
);
$this->assertStringContainsString(
'if(this.usesMirrorOptions&&!this.compact&&dateRangeChanged)requests.push(this.fetchFilterOptions());',
$source,
);
}
public function test_jd_and_jingxi_tabs_share_the_same_date_and_summary_behaviour(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("const JD_BILL_TABS = ['jd-transactions','jingxi'];", $source);
$this->assertStringContainsString("isJdBillTab(){return JD_BILL_TABS.indexOf(this.billType)!==-1;}", $source);
// 唯品会两个页签的筛选标签是「账单期间」(后端也只按 payload.settle_period 过滤)。
$this->assertStringContainsString("const DATE_FILTER_LABELS = {'jd-transactions':'费用结算时间','jingxi':'费用结算时间','jd-wallet':'费用结算时间','douyin':'结算时间','vipshop':'账单期间','vipshop-jx':'账单期间','xiaohongshu':'结算时间','promotion-marketing':'交易时间'};", $source);
$this->assertStringContainsString('{{ dateFilterLabel }}', $source);
$this->assertStringContainsString('v-if="isJdBillTab && sync"', $source);
$this->assertStringContainsString("netLabel=JD_BILL_TABS.indexOf(this.billType)!==-1", $source);
}
public function test_taobao_wechat_places_alipay_balances_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--taobao-wechat': billType === 'taobao-wechat'", $source);
$this->assertStringContainsString("if(this.billType==='taobao-wechat')", $source);
$this->assertStringContainsString("label:'期初余额'", $source);
$this->assertStringContainsString("label:'期末余额(最新)'", $source);
$this->assertStringContainsString('待录入各店铺6月期末余额', $source);
$this->assertStringContainsString("this.summary.balance_source==='unavailable'?'淘系支付宝余额暂不可用':'同淘系支付宝账户'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString('.tw-stats--taobao-wechat{grid-template-columns:repeat(5,minmax(0,1fr))}', $source);
}
public function test_jd_wallet_places_opening_balance_before_income_and_uses_period_formula(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--jd-wallet': billType === 'jd-wallet'", $source);
$this->assertStringContainsString("if(this.billType==='jd-wallet')", $source);
$this->assertStringContainsString("label:'期末余额'", $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertStringContainsString('聚水潭京东钱包最后一笔', $source);
$this->assertStringNotContainsString("this.billType==='jd-wallet'?'账户余额合计(最新)'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString('.tw-stats--jd-wallet{grid-template-columns:repeat(5,minmax(0,1fr))}', $source);
}
public function test_pinduoduo_places_rolled_opening_balance_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--pinduoduo': billType === 'pinduoduo'", $source);
$this->assertStringContainsString("if(this.billType==='pinduoduo')", $source);
$this->assertStringContainsString('平台实际期末余额', $source);
$this->assertStringContainsString('上一账期期末', $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString('.tw-stats--pinduoduo{grid-template-columns:repeat(5,minmax(0,1fr))}', $source);
}
public function test_douyin_places_rolled_opening_balance_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--douyin': billType === 'douyin'", $source);
$this->assertStringContainsString("if(this.billType==='douyin')", $source);
$this->assertStringContainsString('抖音6表期末余额', $source);
$this->assertStringContainsString('上一账期期末', $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString(
'.tw-stats--douyin { grid-template-columns: repeat(5, minmax(0, 1fr)); }',
$source,
);
}
public function test_xiaohongshu_places_rolled_opening_balance_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--xiaohongshu': billType === 'xiaohongshu'", $source);
$this->assertStringContainsString("if(this.billType==='xiaohongshu')", $source);
$this->assertStringContainsString('2026年10月起账,期初余额为0', $source);
$this->assertStringContainsString('上一账期期末', $source);
$this->assertStringContainsString("label:'期末余额'", $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString(
'.tw-stats--xiaohongshu { grid-template-columns: repeat(5, minmax(0, 1fr)); }',
$source,
);
}
public function test_vipshop_mp_places_rolled_opening_balance_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--vipshop': billType === 'vipshop'", $source);
$this->assertStringContainsString("if(this.billType==='vipshop')", $source);
$this->assertStringContainsString('店铺后台账单余额', $source);
$this->assertStringContainsString('上一账期期末', $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString(
'.tw-stats--vipshop { grid-template-columns: repeat(5, minmax(0, 1fr)); }',
$source,
);
}
public function test_vipshop_jx_places_rolled_opening_balance_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString("'tw-stats--vipshop-jx': billType === 'vipshop-jx'", $source);
$this->assertStringContainsString("if(this.billType==='vipshop-jx')", $source);
$this->assertStringContainsString('平台历史账单累计', $source);
$this->assertStringContainsString('上一账期期末', $source);
$this->assertStringContainsString("label:'期末余额'", $source);
$this->assertStringContainsString("note:'期初余额 + 收入合计 - 支出合计'", $source);
$this->assertLessThan(
strpos($source, "label:'收入合计'"),
strpos($source, "label:'期初余额'"),
);
$this->assertStringContainsString(
'.tw-stats--vipshop-jx { grid-template-columns: repeat(5, minmax(0, 1fr)); }',
$source,
);
}
public function test_promotion_marketing_card_opens_the_store_detail_modal(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/assets/js/components/business/AccountBills.vue');
$this->assertStringContainsString('推广费(营销账户)', $source);
$this->assertStringContainsString("label:'推广费(营销账户)'", $source);
$this->assertStringContainsString('查看明细 →', $source);
$this->assertStringContainsString('aria-labelledby="promotion-expense-detail-title"', $source);
$this->assertStringContainsString('<strong id="promotion-expense-detail-title">推广费(营销账户) · 明细汇总</strong>', $source);
$this->assertStringContainsString('>平台汇总</button>', $source);
$this->assertStringContainsString('>店铺明细</button>', $source);
$this->assertStringContainsString('aria-label="筛选平台"', $source);
$this->assertStringContainsString('aria-label="筛选店铺名称"', $source);
$this->assertStringContainsString('aria-label="筛选备注"', $source);
$this->assertStringContainsString('<th scope="col">平台</th>', $source);
$this->assertStringContainsString('<th scope="col">店铺名称</th>', $source);
$this->assertStringContainsString('<th scope="col" class="is-number">推广费金额(万元)</th>', $source);
$this->assertStringContainsString('promotionFilteredPlatformRows', $source);
$this->assertStringContainsString('promotionFilteredStoreRows', $source);
$this->assertStringContainsString('tw-stats--promotion-only', $source);
$this->assertStringContainsString('grid-template-columns:minmax(0,1.15fr) repeat(3,minmax(0,1fr))', $source);
$this->assertStringContainsString('tw-stats--promotion-compact', $source);
$this->assertStringContainsString('table-workspace--compact', $source);
$this->assertStringContainsString('class="tw-date-icon"', $source);
$this->assertStringContainsString("const overview={label:'推广费(营销账户)'", $source);
$this->assertStringContainsString("if(this.compact)return [overview];", $source);
$this->assertStringContainsString("label:'收入金额'", $source);
$this->assertStringContainsString("label:'支出金额'", $source);
$this->assertStringContainsString("label:'余额'", $source);
$this->assertStringContainsString("note:'收入金额 - 支出金额'", $source);
}
public function test_taobao_marketing_tab_places_the_promotion_card_before_income(): void
{
$source = file_get_contents(__DIR__ . '/../../../resources/views/banking/marketing_taobao_alipay_bills/partials/embedded-table.blade.php');
$promotionPosition = strpos($source, 'data-promotion-expense-summary');
$incomePosition = strpos($source, '收入合计(万元)');
$this->assertNotFalse($promotionPosition);
$this->assertNotFalse($incomePosition);
$this->assertLessThan($incomePosition, $promotionPosition);
$this->assertStringContainsString('sm:grid-cols-5', $source);
$this->assertStringContainsString('data-api-base=', $source);
}
}