From 40dda42eb7b2ada26868b1894b5f00a83f844103 Mon Sep 17 00:00:00 2001 From: liugang Date: Sat, 20 Sep 2025 10:11:26 +0800 Subject: [PATCH] * [misc] Enhance unit tests for fileModel::setSavePath() method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- module/file/test/lib/file.unittest.class.php | 110 +++++++++++++++++-- module/file/test/model/setsavepath.php | 17 ++- 2 files changed, 116 insertions(+), 11 deletions(-) diff --git a/module/file/test/lib/file.unittest.class.php b/module/file/test/lib/file.unittest.class.php index 5f812acf1c..e92b4d0a0c 100755 --- a/module/file/test/lib/file.unittest.class.php +++ b/module/file/test/lib/file.unittest.class.php @@ -283,18 +283,46 @@ class fileTest * 测试 setPathName 方法。 * Test setPathName method. * - * @param int $fileID - * @param string $extension + * @param int|string $fileID + * @param string $extension * @access public * @return array */ - public function setPathNameTest(int $fileID, string $extension): array + public function setPathNameTest(int|string $fileID, string $extension): array { + // 生成路径名 $pathName = $this->objectModel->setPathName($fileID, $extension); - $reg = date('Ym\\\/dHis', $this->objectModel->now) . $fileID . '\w+' . '\.' . $extension; + // 构建正则表达式模式,适应不同的扩展名 + $escapedExtension = preg_quote($extension, '/'); + if(empty($extension)) + { + $reg = date('Ym\\\/dHis', $this->objectModel->now) . $fileID . '\d+[a-zA-Z0-9]{3}\.'; + } + else + { + $reg = date('Ym\\\/dHis', $this->objectModel->now) . $fileID . '\d+[a-zA-Z0-9]{3}\.' . $escapedExtension; + } + + $result = array(); $result['name'] = $pathName; - $result['reg'] = preg_match("/{$reg}/", $pathName); + $result['reg'] = preg_match("/{$reg}/", $pathName) ? 1 : 0; + + // 测试路径名格式的完整性 + $formatPattern = '/^[0-9]{8}\/[0-9]{6}' . preg_quote((string)$fileID, '/') . '[0-9]+[a-zA-Z0-9]{3}\.' . $escapedExtension . '$/'; + $result['format'] = preg_match($formatPattern, $pathName) ? 1 : 0; + + // 测试唯一性 - 生成第二个路径名并比较 + $pathName2 = $this->objectModel->setPathName($fileID, $extension); + $result['uniqueness'] = ($pathName !== $pathName2) ? 1 : 0; + + // 测试时间戳格式 + $timePrefix = date('Ym/dHis', $this->objectModel->now); + $result['timeFormat'] = (strpos($pathName, $timePrefix) === 0) ? 1 : 0; + + // 测试包含文件ID + $result['containsFileID'] = (strpos($pathName, (string)$fileID) !== false) ? 1 : 0; + return $result; } @@ -323,14 +351,25 @@ class fileTest /** * Test set save path. * + * @param int $companyID * @access public * @return string */ - public function setSavePathTest() + public function setSavePathTest($companyID = null): string { + global $tester; + + // 设置测试公司ID + if($companyID !== null) + { + if(!isset($tester->app->company)) $tester->app->company = new stdclass(); + $tester->app->company->id = $companyID; + } + + // 执行测试方法 $this->objectModel->setSavePath(); - global $tester; + // 返回简化的路径用于测试 return substr($tester->file->savePath, strrpos($tester->file->savePath, '/data/')); } @@ -1107,4 +1146,61 @@ class fileTest return $result; } + + /** + * Test sendDownHeader method. + * + * @param string $fileName + * @param string $fileType + * @param string $content + * @param string $type + * @access public + * @return mixed + */ + public function sendDownHeaderTest($fileName, $fileType, $content, $type = 'content') + { + // 模拟sendDownHeader方法的逻辑,但不实际执行header操作 + $extension = $fileType ? ('.' . $fileType) : ''; + if($extension && strpos(strtolower($fileName), $extension) === false) $fileName .= $extension; + + // 检查文件类型 + $mimes = $this->objectModel->config->file->mimes; + $contentType = isset($mimes[$fileType]) ? $mimes[$fileType] : $mimes['default']; + + // Safari浏览器文件名编码测试 + if(isset($_SERVER['CONTENT_TYPE']) && isset($_SERVER['HTTP_USER_AGENT']) && + $_SERVER['CONTENT_TYPE'] == 'application/x-www-form-urlencoded' && + preg_match("/Safari/", $_SERVER["HTTP_USER_AGENT"])) + { + $fileName = rawurlencode($fileName); + $attachment = 'attachment; filename*=utf-8\'\'' . $fileName; + } + else + { + $fileName = str_replace("+", "%20", urlencode($fileName)); + $attachment = "attachment; filename=\"{$fileName}\";"; + } + + // 模拟不同type的处理 + if($type == 'content') + { + return $content; + } + + if($type == 'file') + { + // 安全检查:文件路径必须在basePath内 + if(file_exists($content)) + { + if(stripos($content, $this->objectModel->app->getBasePath()) !== 0) + { + return 'security_denied'; + } + return 'file_success'; + } + return 'file_not_found'; + } + + return 'unknown_type'; + } } diff --git a/module/file/test/model/setsavepath.php b/module/file/test/model/setsavepath.php index 6a418fbabf..1118b90e52 100755 --- a/module/file/test/model/setsavepath.php +++ b/module/file/test/model/setsavepath.php @@ -3,18 +3,27 @@ /** -title=测试 fileModel->setSavePath(); +title=测试 fileModel::setSavePath(); timeout=0 cid=0 -- 测试更新savePath @/data/upload/1/ +- 步骤1:测试默认公司ID(1)的savePath设置 @/data/upload/1/ +- 步骤2:测试不同公司ID(2)的savePath设置 @/data/upload/2/ +- 步骤3:测试公司ID为3的savePath设置 @/data/upload/3/ +- 步骤4:测试公司ID为10的savePath设置 @/data/upload/10/ +- 步骤5:测试重新设置回默认公司ID的savePath @/data/upload/1/ */ + include dirname(__FILE__, 5) . '/test/lib/init.php'; include dirname(__FILE__, 2) . '/lib/file.unittest.class.php'; + su('admin'); $file = new fileTest(); -global $app; -r($file->setSavePathTest()) && p() && e('/data/upload/1/'); // 测试更新savePath \ No newline at end of file +r($file->setSavePathTest()) && p() && e('/data/upload/1/'); // 步骤1:测试默认公司ID(1)的savePath设置 +r($file->setSavePathTest(2)) && p() && e('/data/upload/2/'); // 步骤2:测试不同公司ID(2)的savePath设置 +r($file->setSavePathTest(3)) && p() && e('/data/upload/3/'); // 步骤3:测试公司ID为3的savePath设置 +r($file->setSavePathTest(10)) && p() && e('/data/upload/10/'); // 步骤4:测试公司ID为10的savePath设置 +r($file->setSavePathTest(1)) && p() && e('/data/upload/1/'); // 步骤5:测试重新设置回默认公司ID的savePath \ No newline at end of file