| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- <?php
- namespace Tests\Integration;
- use App\Http\Controllers\admin\CompanyReport;
- use App\Http\Controllers\agent\CompanyReportController;
- use App\Models\Agent\Agent;
- use App\Services\CompanyMonthlyReportService;
- use Carbon\Carbon;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Filesystem\FilesystemManager;
- use Illuminate\Http\Request;
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Schema;
- use PHPUnit\Framework\TestCase;
- use Symfony\Component\HttpFoundation\BinaryFileResponse;
- use Tests\Support\AgentTestEnvironment;
- /** 公司营业报表:总后台按月上传 / 重新上传,入股代理查看和下载。 */
- class CompanyMonthlyReportTest extends TestCase
- {
- use AgentTestEnvironment { setUp as environmentSetUp; tearDown as environmentTearDown; }
- private string $root;
- private array $temp = [];
- protected function setUp(): void
- {
- $this->environmentSetUp();
- Carbon::setTestNow('2026-11-12 10:00:00');
- (require dirname(__DIR__, 2) . '/database/migrations/2026_11_12_120000_create_company_monthly_reports.php')->up();
- Schema::create('admin', function (Blueprint $t) { $t->id(); $t->string('username'); });
- DB::table('admin')->insert([['id' => 1, 'username' => 'root'], ['id' => 2, 'username' => 'finance']]);
- $this->root = sys_get_temp_dir() . '/company-report-' . bin2hex(random_bytes(4));
- config(['filesystems.disks.local' => ['driver' => 'local', 'root' => $this->root]]);
- $this->app->instance('filesystem', new FilesystemManager($this->app));
- }
- protected function tearDown(): void
- {
- Carbon::setTestNow();
- foreach ($this->temp as $file) @unlink($file);
- if (is_dir($this->root)) { array_map('unlink', glob($this->root . '/company-reports/*') ?: []); @rmdir($this->root . '/company-reports'); @rmdir($this->root); }
- $this->environmentTearDown();
- }
- private function excel(string $name, string $head = "PK\x03\x04"): UploadedFile
- {
- $path = tempnam(sys_get_temp_dir(), 'xls');
- file_put_contents($path, $head . random_bytes(32));
- $this->temp[] = $path;
- return new UploadedFile($path, $name, null, null, true);
- }
- private function admin(string $action, array $params = [], array $files = [], int $adminId = 1)
- {
- $request = Request::create('/admin/companyReport/' . $action, $files ? 'POST' : 'GET', $params, [], $files);
- $request->user = (object) ['id' => $adminId];
- $this->app->instance('request', $request);
- $response = (new CompanyReport())->{$action === '' ? 'index' : $action}($request, new CompanyMonthlyReportService());
- return $response instanceof BinaryFileResponse ? $response : $response->getData(true);
- }
- private function agentCall(Agent $agent, string $action, array $params = [])
- {
- $request = Request::create('/agent/company-reports', 'GET', $params);
- $request->attributes->set('agent', $agent);
- $this->app->instance('request', $request);
- $response = (new CompanyReportController())->{$action}($request, new CompanyMonthlyReportService());
- return $response instanceof BinaryFileResponse ? $response : $response->getData(true);
- }
- public function test_admin_uploads_last_month_once_and_reuploads_through_edit(): void
- {
- $this->assertSame('2026-10', CompanyMonthlyReportService::allowedMonth());
- $wrong = $this->admin('create', ['month' => '2026-11'], ['file' => $this->excel('11月.xlsx')]);
- $this->assertSame('只能上传已结束月份的报表(2026-10 及以前)', $wrong['msg']);
- $this->assertSame('请上传 Excel 文件(.xlsx 或 .xls)', $this->admin('create', ['month' => '2026-10'], ['file' => $this->excel('a.pdf')])['msg']);
- $this->assertSame('请上传 Excel 文件(.xlsx 或 .xls)', $this->admin('create', ['month' => '2026-10'], ['file' => $this->excel('fake.xlsx', 'abcd')])['msg'], 'content must be excel');
- $encrypted = $this->admin('create', ['month' => '2026-08'], ['file' => $this->excel('8月-加密.xlsx', "\xD0\xCF\x11\xE0")]);
- $this->assertSame([0, '2026-08'], [$encrypted['code'], $encrypted['data']['month'] ?? null], 'a missed earlier month can be added; password-protected xlsx is OLE');
- $created = $this->admin('create', ['month' => '2026-10'], ['file' => $this->excel('10月营业报表.xlsx')]);
- $this->assertSame(0, $created['code'], $created['msg']);
- $this->assertSame(['2026-10', '10月营业报表.xlsx'], [$created['data']['month'], $created['data']['file_name']]);
- $this->assertArrayNotHasKey('file_path', $created['data']);
- $this->assertSame('2026-10 的报表已存在,请在列表中编辑重新上传', $this->admin('create', ['month' => '2026-10'], ['file' => $this->excel('again.xlsx')])['msg']);
- $oldPath = DB::table('company_monthly_reports')->where('month', '2026-10')->value('file_path');
- $this->assertFileExists($this->root . '/' . $oldPath);
- $updated = $this->admin('update', ['id' => $created['data']['id']], ['file' => $this->excel('10月营业报表-修正.xls', "\xD0\xCF\x11\xE0")], 2);
- $this->assertSame(0, $updated['code'], $updated['msg']);
- $this->assertSame(['2026-10', '10月营业报表-修正.xls'], [$updated['data']['month'], $updated['data']['file_name']]);
- $this->assertFileDoesNotExist($this->root . '/' . $oldPath, 'old file is removed after re-upload');
- $list = $this->admin('', [])['data'];
- $this->assertSame([2, '2026-10'], [$list['total'], $list['allowed_month']]);
- $this->assertSame(['2026-10', '2026-08'], array_column($list['list'], 'month'));
- $this->assertSame(['root', 'finance'], [$list['list'][0]['created_by_name'], $list['list'][0]['updated_by_name']]);
- $file = $this->admin('download', ['id' => $created['data']['id']]);
- $this->assertInstanceOf(BinaryFileResponse::class, $file);
- $this->assertStringContainsString('attachment', (string) $file->headers->get('content-disposition'));
- $this->assertSame('数据不存在', $this->admin('download', ['id' => 999])['msg']);
- }
- public function test_only_equity_agents_can_list_and_download(): void
- {
- Carbon::setTestNow('2026-10-05 10:00:00');
- $this->admin('create', ['month' => '2026-09'], ['file' => $this->excel('9月.xlsx')]);
- Carbon::setTestNow('2026-11-12 10:00:00');
- $id = $this->admin('create', ['month' => '2026-10'], ['file' => $this->excel('10月.xlsx')])['data']['id'];
- $equity = $this->agent(Agent::TYPE_EQUITY);
- $list = $this->agentCall($equity, 'index');
- $this->assertSame(0, $list['code'], $list['msg']);
- $this->assertSame(['2026-10', '2026-09'], array_column($list['data']['list'], 'month'), 'newest month first');
- $this->assertArrayNotHasKey('created_by', $list['data']['list'][0], 'admin info stays in the admin');
- $this->assertSame(['2026-09'], array_column($this->agentCall($equity, 'index', ['end_month' => '2026-09'])['data']['list'], 'month'));
- $this->assertInstanceOf(BinaryFileResponse::class, $this->agentCall($equity, 'download', ['id' => $id]));
- $joint = $this->agent();
- $this->assertSame('仅入股代理可查看公司营业报表', $this->agentCall($joint, 'index')['msg']);
- $this->assertSame('仅入股代理可查看公司营业报表', $this->agentCall($joint, 'download', ['id' => $id])['msg']);
- }
- }
|