|
|
|
|
@ -72,6 +72,70 @@ class SurveyWorkflowTest extends TestCase
|
|
|
|
|
return $response->json('id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCopyCreatesIndependentDraftWithAllDefinitionsAndNoReplies(): void
|
|
|
|
|
{
|
|
|
|
|
Schema::create('courses', function (Blueprint $table) { $table->id(); $table->softDeletes(); });
|
|
|
|
|
DB::table('courses')->insert([['id' => 11], ['id' => 12]]);
|
|
|
|
|
DB::table('course_content_evaluations')->where('id', 10)->update([
|
|
|
|
|
'desc' => '<p>富文本说明</p>', 'course_id' => '11', 'course_content_id' => '9', 'type_id' => '3',
|
|
|
|
|
'audience_course_ids' => json_encode([11, 12]), 'start_time' => '2026-12-01 00:00:00', 'end_time' => '2026-12-31 23:59:59',
|
|
|
|
|
]);
|
|
|
|
|
$definitions = [
|
|
|
|
|
['name' => '第一章', 'field' => 'chapter', 'edit_input' => 'section', 'sort' => 1],
|
|
|
|
|
['name' => '是否参加', 'field' => 'attend', 'edit_input' => 'radio', 'sort' => 2, 'need_fill' => true, 'select_item' => [['key' => 'yes', 'value' => '参加'], ['key' => 'no', 'value' => '不参加']]],
|
|
|
|
|
['name' => '会场', 'field' => 'venues', 'edit_input' => 'checkbox', 'sort' => 3, 'select_item' => [['key' => 'a', 'value' => '甲'], ['key' => 'b', 'value' => '乙']], 'config' => ['min_choices' => 1, 'max_choices' => 2, 'option_notes' => ['a' => ['placeholder' => '问题']], 'visible_when' => ['field' => 'attend', 'values' => ['yes'], 'required_values' => ['yes']]]],
|
|
|
|
|
['name' => '组合题', 'field' => 'group', 'edit_input' => 'multi_dimension', 'sort' => 4, 'dimensions' => [['field' => 'count', 'name' => '数量', 'edit_input' => 'number', 'config' => ['min' => 0, 'integer' => true]]]],
|
|
|
|
|
['name' => '资料', 'field' => 'docs', 'edit_input' => 'file', 'sort' => 5, 'config' => ['allowed_extensions' => ['pdf', 'docx'], 'max_files' => 2]],
|
|
|
|
|
['name' => '姓名', 'field' => 'name', 'edit_input' => 'text', 'sort' => 6, 'config' => ['user_field' => 'name']],
|
|
|
|
|
];
|
|
|
|
|
foreach ($definitions as $definition) \App\Models\CourseContentEvaluationAsk::create($definition + ['course_content_evaluation_id' => 10, 'course_id' => 11, 'course_content_id' => 9, 'admin_id' => 99]);
|
|
|
|
|
DB::table('course_content_evaluation_forms')->insert(['course_content_evaluation_id' => 10, 'user_id' => 200]);
|
|
|
|
|
$originals = \App\Models\CourseContentEvaluationAsk::where('course_content_evaluation_id', 10)->orderBy('sort')->get();
|
|
|
|
|
$response = $this->postJson('/api/admin/course-content-evaluations/save', ['copy_from_id' => 10, 'title' => '新问卷', 'status' => 1]);
|
|
|
|
|
$response->assertOk()->assertJsonPath('title', '新问卷')->assertJsonPath('status', 0)->assertJsonPath('desc', '<p>富文本说明</p>')->assertJsonPath('audience_course_ids', [11, 12]);
|
|
|
|
|
$id = $response->json('id'); $this->assertNotSame(10, $id);
|
|
|
|
|
$copies = \App\Models\CourseContentEvaluationAsk::where('course_content_evaluation_id', $id)->orderBy('sort')->get();
|
|
|
|
|
$this->assertCount(6, $copies);
|
|
|
|
|
foreach ($copies as $index => $question) {
|
|
|
|
|
$source = $originals[$index];
|
|
|
|
|
$this->assertNotSame($source->id, $question->id);
|
|
|
|
|
foreach (['field', 'name', 'edit_input', 'rule', 'help', 'sort', 'dimensions', 'config', 'select_item', 'need_fill', 'allow_input'] as $key) $this->assertSame($source->$key, $question->$key, $key);
|
|
|
|
|
$this->assertSame(9, (int) $question->course_content_id);
|
|
|
|
|
$this->assertSame(1, (int) $question->admin_id);
|
|
|
|
|
}
|
|
|
|
|
$this->assertSame(0, DB::table('course_content_evaluation_forms')->where('course_content_evaluation_id', $id)->count());
|
|
|
|
|
$this->postJson('/api/admin/course-content-evaluation-ask/save', ['id' => $copies[1]->id, 'name' => '新题目'])->assertOk()->assertJsonPath('name', '新题目');
|
|
|
|
|
$this->assertSame('是否参加', $originals[1]->fresh()->name);
|
|
|
|
|
$this->assertSame('1', (string) DB::table('course_content_evaluations')->where('id', 10)->value('status'));
|
|
|
|
|
$otherId = $this->postJson('/api/admin/course-content-evaluations/save', ['copy_from_id' => 10, 'title' => '其他课程', 'course_id' => 12, 'course_content_id' => '22'])->assertOk()->json('id');
|
|
|
|
|
$this->assertSame(0, \App\Models\CourseContentEvaluationAsk::where('course_content_evaluation_id', $otherId)->whereNotNull('course_content_id')->count());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testInvalidCopySourceCannotCreateOrOverwriteSurvey(): void
|
|
|
|
|
{
|
|
|
|
|
$url = '/api/admin/course-content-evaluations/save';
|
|
|
|
|
foreach ([['copy_from_id' => 999], ['copy_from_id' => []], ['id' => 10, 'copy_from_id' => 10]] as $input) {
|
|
|
|
|
$this->postJson($url, $input + ['title' => '无效复制'])->assertJsonPath('errcode', 10001);
|
|
|
|
|
}
|
|
|
|
|
$this->assertSame(1, DB::table('course_content_evaluations')->count());
|
|
|
|
|
$this->assertSame('培训问卷', DB::table('course_content_evaluations')->where('id', 10)->value('title'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCopyFailureRollsBackNewSurveyAndQuestions(): void
|
|
|
|
|
{
|
|
|
|
|
Schema::create('courses', function (Blueprint $table) { $table->id(); $table->softDeletes(); });
|
|
|
|
|
$this->createQuestion();
|
|
|
|
|
$failCopy = true;
|
|
|
|
|
\App\Models\CourseContentEvaluationAsk::creating(function ($question) use (&$failCopy) {
|
|
|
|
|
if ($failCopy && (int) $question->course_content_evaluation_id !== 10) throw new \RuntimeException('copy failed');
|
|
|
|
|
});
|
|
|
|
|
try {
|
|
|
|
|
$this->postJson('/api/admin/course-content-evaluations/save', ['copy_from_id' => 10, 'title' => '失败副本'])->assertStatus(500);
|
|
|
|
|
} finally { $failCopy = false; }
|
|
|
|
|
$this->assertSame(1, DB::table('course_content_evaluations')->count());
|
|
|
|
|
$this->assertSame(1, DB::table('course_content_evaluation_asks')->count());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSurveyAccessRequiresOnlyMobileEvenWhenOtherProfileFieldsAreMissing(): void
|
|
|
|
|
{
|
|
|
|
|
$id = $this->createQuestion();
|
|
|
|
|
|