znt/module/user/test/lib/ui/task.ui.class.php

249 lines
11 KiB
PHP
Raw Permalink 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
require_once dirname(__FILE__, 6) . '/test/lib/ui.php';
define('COLUMNS', array('id', 'name', 'pri', 'status', 'executionName', 'deadline', 'estimate', 'consumed', 'left'));
define('MENUS', array('assignedTo', 'openedBy', 'finishedBy', 'involvedIn', 'closedBy', 'canceledBy'));
define('PAGESIZE', array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 100, 200, 500, 1000, 2000));
class taskTester extends tester
{
/**
* 校验user模块task视图的内容是否正确对齐 todo.ui.class.php 的结构)
* 1) 外层循环用户2) 内层循环菜单3) 验证列与分页
*
* @param array $users 用户列表
* @param array $tasks 任务数据(含单人/多人)
* @param array $executions 执行列表(用于显示执行名称)
* @param array $taskteams 任务团队列表zt_taskteam用于多人任务参与判断
* @param int $pageSize 每页数量默认20对齐页面默认
* @access public
* @return object
*/
public function verifyUserTaskContentAndPagination($users = array(), $tasks = array(), $executions = array(), $taskteams = array(), $pageSize = 5)
{
if(!in_array($pageSize, PAGESIZE, true)) return $this->failed('pageSize不支持该值');
if(empty($users)) return $this->failed('用户列表不能为空');
if(empty($tasks)) return $this->failed('任务数据不能为空');
if(empty($executions)) return $this->failed('执行列表不能为空');
if(empty($taskteams)) return $this->failed('任务团队数据不能为空');
$this->login();
$form = $this->initForm('user', 'task', array('userID' => $users[0]->id), 'appIframe-system');
$form->wait(2);
// 1) 组织任务:按 id 建映射,过滤 deleted/vision并补充 executionName
$allTasks = array();
foreach($tasks as $t)
{
$deleted = isset($t->deleted) ? $t->deleted : 0;
$vision = isset($t->vision) ? $t->vision : null;
if($deleted != 0) continue;
if($this->config->vision && $vision && $vision !== $this->config->vision) continue;
$id = isset($t->id) ? (int)$t->id : null;
if($id === null) continue;
$allTasks[$id] = $t;
}
// 2) 组织执行id=>执行对象,并为任务补充 executionName
$execMap = array();
foreach($executions as $e)
{
$eid = is_object($e) ? (isset($e->id) ? (int)$e->id : null) : (isset($e['id']) ? (int)$e['id'] : null);
if($eid === null) continue;
$execMap[$eid] = is_object($e) ? $e : (object)$e;
}
foreach($allTasks as $tid => $t)
{
$execID = isset($t->execution) ? (int)$t->execution : null;
$t->executionName = ($execID !== null && isset($execMap[$execID])) ? (isset($execMap[$execID]->name) ? $execMap[$execID]->name : '') : '';
$allTasks[$tid] = $t;
}
// 3) 组织团队taskID => [account => status]
$teamByTask = array();
foreach($taskteams as $row)
{
$tid = is_object($row) ? (isset($row->task) ? (int)$row->task : null) : (isset($row['task']) ? (int)$row['task'] : null);
$account = is_object($row) ? (isset($row->account) ? $row->account : null) : (isset($row['account']) ? $row['account'] : null);
$status = is_object($row) ? (isset($row->status) ? $row->status : null) : (isset($row['status']) ? $row['status'] : null);
if($tid === null || $account === null) continue;
if(!isset($teamByTask[$tid])) $teamByTask[$tid] = array();
$teamByTask[$tid][$account] = $status;
}
// 逐个检查传入用户:切换视图并按该用户筛选
foreach($users as $user)
{
if($user != $users[0])
{
$form->dom->userPicker->picker($user->realname);
$form->wait(1);
if($form->dom->userPicker->getText() != $user->realname) return $this->failed('task页面切换用户显示失败');
}
$account = $user->account;
foreach(MENUS as $menu)
{
$form->dom->{$menu}->click();
$form->wait(1);
$userTasks = array();
foreach($allTasks as $t)
{
$closed = strtolower(isset($t->status) ? $t->status : '') === 'closed';
$isMulti = (isset($t->mode) ? $t->mode : 'single') === 'multi';
$inTeam = isset($teamByTask[$t->id]) && array_key_exists($account, $teamByTask[$t->id]);
$teamDone = $inTeam ? strtolower($teamByTask[$t->id][$account]) === 'done' : false;
switch($menu)
{
case 'openedBy':
case 'finishedBy':
case 'closedBy':
case 'canceledBy':
if((isset($t->{$menu}) ? $t->{$menu} : null) === $account) $userTasks[] = $t;
break;
case 'assignedTo':
$assigned = (isset($t->assignedTo) ? $t->assignedTo : null) === $account;
if($assigned || ($isMulti && $inTeam && !$closed && !$teamDone)) $userTasks[] = $t;
break;
case 'involvedIn':
$sessionAccount = $this->config->uitest->defaultAccount;
$inTeamBySession = isset($teamByTask[$t->id]) && array_key_exists($sessionAccount, $teamByTask[$t->id]);
// 查看他人时,团队项不计入;仅当会话账户与视图用户一致且任务未关闭/团队未完成时计入
$includeTeam = ($sessionAccount === $account) && $inTeamBySession && !$closed && !$teamDone;
$byAssigned = ((isset($t->assignedTo) ? $t->assignedTo : null) === $sessionAccount);
$byFinished = ((isset($t->finishedBy) ? $t->finishedBy : null) === $sessionAccount);
if($byAssigned || $byFinished || $includeTeam) $userTasks[] = $t;
break;
default:
break;
}
}
$ret = $this->verifyTaskColumns($form, $userTasks, $user, $menu, $pageSize);
if($ret) return $ret;
$ret = $this->verifyTaskPagination($form, $userTasks, $pageSize);
if($ret) return $ret;
}
}
return $this->success('开源版user模块视图层task界面测试成功');
}
/**
* 验证列数据
* Verify column data
*
* @param object $form
* @param array $tasks
* @param object $user
* @param string $menu
* @param int $pageSize
* @access private
* @return object
*/
private function verifyTaskColumns($form, $tasks, $user, $menu, $pageSize = 5)
{
if(count($tasks) > $pageSize)
{
$form->dom->pagerSizeMenu->click();
$form->wait(1);
$form->dom->dropdownPicker(max(PAGESIZE));
}
$menuInLang = $this->lang->todo->periods->{$menu} ?? $menu;
// 建立任务ID到任务对象的映射便于在列校验中读取 mode 等属性
$tasksById = array();
foreach($tasks as $t)
{
$tid = is_object($t) ? (isset($t->id) ? (string)$t->id : null) : (isset($t['id']) ? (string)$t['id'] : null);
if($tid !== null) $tasksById[$tid] = $t;
}
$display = array();
foreach(COLUMNS as $column)
{
$display[$column] = $form->dom->getElementListByXpathKey($column, true);
$header = isset($this->lang->task->$column) ? $this->lang->task->$column : $column;
if(count($display[$column]) != count($tasks)) return $this->failed("用户'{$user->realname}'的'{$menuInLang}'菜单'{$header}'列数据数量与实际不匹配");
if($column == 'id') continue;
foreach($display[$column] as $i => $item)
{
$id = $display['id'][$i];
$data = array_column($tasks, $column, 'id')[$id];
// 当列为 name 且任务为多人模式时,名称前应带有多人标记(如“多人”)
if($column === 'name')
{
$item = str_replace("\xC2\xA0", ' ', $item);
$item = preg_replace('/\s+/u', ' ', trim($item));
$data = str_replace("\xC2\xA0", ' ', $data);
$data = preg_replace('/\s+/u', ' ', trim($data));
$taskObj = isset($tasksById[(string)$id]) ? $tasksById[(string)$id] : null;
$isMulti = $taskObj && isset($taskObj->mode) ? ($taskObj->mode === 'multi') : false;
if($isMulti)
{
$badge = $this->lang->task->multipleAB;
$expectedNoSpace = $badge . $data;
$expectedWithSpace = $badge . ' ' . $data;
if($item === $expectedNoSpace || $item === $expectedWithSpace) $data = $item;
else $data = $expectedWithSpace;
}
}
if($column == 'status') $data = $this->lang->task->statusList->{$data};
if(in_array($column, array('estimate', 'consumed', 'left'))) $data = $data . $this->lang->task->suffixHour;
if($data != $item) return $this->failed("用户'{$user->realname}'的'{$menuInLang}'菜单'{$header}'列'id={$id}'时数据不匹配:期望'{$data}',实际’{$item}'");
}
}
return null;
}
/**
* 验证分页功能
* Verify pagination functionality
* @param object $form
* @param array $todos
* @param int $pageSize
* @access public
* @return object
*/
private function verifyTaskPagination($form, $tasks, $pageSize = 5)
{
$totalTasks = count($tasks);
$pages = (int) ceil($totalTasks / $pageSize);
if(count($tasks) > $pageSize)
{
$form->dom->pagerSizeMenu->click();
$form->wait(1);
$form->dom->dropdownPicker($pageSize);
$form->dom->firstPage->click();
$form->wait(1);
}
for($i = 1; $i <= $pages; $i++)
{
$totalActual = count($form->dom->getElementListByXpathKey('id' ));
$totalExpected = ($pages === 1) ? $totalTasks : ($i < $pages ? $pageSize : ($totalTasks - $pageSize * ($pages - 1)));
if($totalActual !== $totalExpected) return $this->failed("分页第{$i}页数量不匹配:期望{$totalExpected},实际{$totalActual}");
if($i < $pages && $form->dom->nextPage)
{
$form->dom->nextPage->click();
$form->wait(1);
}
}
return null;
}
}