Merge branch 'main' into avm99963-monorail

Merged commit 4137ed7879acadbf891e8c471108acb874dae886.

GitOrigin-RevId: b6100ffc5b1da355a35f37b13fcaaf746ee8b307
diff --git a/static_src/react/tests/AttachmentUploader.test.tsx b/static_src/react/tests/AttachmentUploader.test.tsx
new file mode 100644
index 0000000..344822e
--- /dev/null
+++ b/static_src/react/tests/AttachmentUploader.test.tsx
@@ -0,0 +1,52 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import React from 'react';
+import {assert} from 'chai';
+import {cleanup, render} from '@testing-library/react';
+import AttachmentUploader from 'react/issue-wizard/AttachmentUploader.tsx';
+
+describe('IssueWizard Attachment Uploader', () => {
+  afterEach(cleanup);
+
+  it('render', () => {
+    render(<AttachmentUploader files={[]} setFiles={()=>{}}/>)
+    const uploadButton = document.getElementById('file-uploader');
+    assert.isNotNull(uploadButton);
+  });
+
+  it('render files name', () => {
+    const files = [
+      {name: '1.txt'},
+      {name: '2.txt'},
+      {name: '3.txt'},
+    ];
+    render(<AttachmentUploader files={files} setFiles={()=>{}}/>)
+    const items = document.querySelectorAll('li');
+    assert.equal(items.length, 3);
+
+    assert.include(items[0].textContent, '1.txt');
+    assert.include(items[1].textContent, '2.txt');
+    assert.include(items[2].textContent, '3.txt');
+  });
+
+  it('remove files', () => {
+    let files = [
+      {name: '1.txt'},
+      {name: '2.txt'},
+      {name: '3.txt'},
+    ];
+    render(<AttachmentUploader files={files} setFiles={(f: Array<any>)=>{files = f;}} setSubmitEnable={()=>{}}/>)
+    const items = document.querySelectorAll('li');
+    assert.equal(items.length, 3);
+
+    const removeButton = items[1].querySelector('button');
+    assert.isNotNull(removeButton);
+
+    removeButton?.click();
+    assert.equal(files.length, 2);
+    assert.equal(files[0].name, '1.txt');
+    assert.equal(files[1].name, '3.txt');
+  })
+});
diff --git a/static_src/react/tests/ConfirmBackModal.test.tsx b/static_src/react/tests/ConfirmBackModal.test.tsx
new file mode 100644
index 0000000..94856d4
--- /dev/null
+++ b/static_src/react/tests/ConfirmBackModal.test.tsx
@@ -0,0 +1,19 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import React from 'react';
+import {assert} from 'chai';
+import {cleanup, render} from '@testing-library/react';
+import {ConfirmBackModal} from 'react/issue-wizard/ConfirmBackModal.tsx';
+
+describe('IssueWizard confirm back modal', () => {
+
+  afterEach(cleanup);
+
+  it('render', () => {
+    render(<ConfirmBackModal enable={true} setEnable={()=>{}} confirmBack={()=>{}}/>);
+    const buttons = document.querySelectorAll('Button');
+    assert.equal(2, buttons.length);
+  });
+});
diff --git a/static_src/react/tests/CustomQuestionsStep.test.tsx b/static_src/react/tests/CustomQuestionsStep.test.tsx
new file mode 100644
index 0000000..0b43dee
--- /dev/null
+++ b/static_src/react/tests/CustomQuestionsStep.test.tsx
@@ -0,0 +1,39 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import React from 'react';
+import {assert} from 'chai';
+import {render, cleanup} from '@testing-library/react';
+import CustomQuestionsStep from 'react/issue-wizard/CustomQuestionsStep.tsx';
+import {CustomQuestionType} from 'react/issue-wizard/IssueWizardTypes.tsx';
+
+describe('IssueWizard CustomQuestionsStep', () => {
+  afterEach(cleanup);
+  it('renders', async () => {
+    render(<CustomQuestionsStep questions={[]}/>);
+    const stepper = document.getElementById("mobile-stepper")
+
+    assert.isNotNull(stepper);
+  });
+
+  it('render InputType Question', async () => {
+    const questionList = [{
+      type: CustomQuestionType.Input,
+      question: "this is a test",
+    }]
+    const {container} = render(<CustomQuestionsStep questions={questionList}/>);
+    const input = container.querySelector('input');
+    assert.isNotNull(input);
+  })
+
+  it('render TextType Question', async () => {
+    const questionList = [{
+      type: CustomQuestionType.Text,
+      question: "this is a test",
+    }]
+    const {container} = render(<CustomQuestionsStep questions={questionList}/>);
+    const input = container.querySelector('textarea');
+    assert.isNotNull(input);
+  })
+});
diff --git a/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx b/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx
new file mode 100644
index 0000000..6e5edae
--- /dev/null
+++ b/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx
@@ -0,0 +1,34 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert, expect} from 'chai';
+import {expandDescriptions} from 'react/issue-wizard/IssueWizardDescriptionsUtils.tsx';
+
+describe('IssueWizardDescriptionsUtils', () => {
+  it('get expandDescription and labels', () => {
+    const {expandDescription, expandLabels} = expandDescriptions(
+      'Network / Downloading',
+      ['test url'],
+      false,
+      'test',
+      [],
+    )
+    assert.equal(expandLabels.length, 1);
+    expect(expandDescription).to.contain("test url");
+  });
+
+  it('get proper component value base on user answer', () => {
+    const {expandDescription, expandLabels, compVal} = expandDescriptions(
+      'Content',
+      ['test url', 'LABELS: Yes - this is'],
+      false,
+      'test',
+      [],
+    )
+    assert.equal(expandLabels.length, 1);
+    assert.equal(expandLabels[0].label, 'Type-Bug');
+    assert.equal(compVal, 'Blink');
+    expect(expandDescription).to.contain("test url");
+  });
+});
diff --git a/static_src/react/tests/IssueWizardUtils.test.tsx b/static_src/react/tests/IssueWizardUtils.test.tsx
new file mode 100644
index 0000000..4211160
--- /dev/null
+++ b/static_src/react/tests/IssueWizardUtils.test.tsx
@@ -0,0 +1,74 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert, expect} from 'chai';
+import {IssueWizardPersona, IssueCategory, CustomQuestionType} from '../issue-wizard/IssueWizardTypes.tsx';
+import {GetCategoriesByPersona, GetQuestionsByCategory, buildIssueDescription, getChromeVersion} from '../issue-wizard/IssueWizardUtils.tsx';
+
+describe('IssueWizardUtils', () => {
+  it('generate the issue categories to user persona map', () => {
+    const categories: IssueCategory[]= [
+      {
+        name: 't1',
+        description: 'd1',
+        persona: IssueWizardPersona.EndUser,
+        enabled: true,
+      },
+      {
+        name: 't2',
+        description: 'd2',
+        persona: IssueWizardPersona.EndUser,
+        enabled: false,
+      },
+    ];
+
+    const categoriesByPersonaMap = GetCategoriesByPersona(categories);
+    const validCategories = categoriesByPersonaMap.get(IssueWizardPersona.EndUser);
+
+    assert.equal(validCategories?.length, 1);
+    assert.equal(validCategories[0].name, 't1');
+    assert.equal(validCategories[0].description, 'd1');
+  });
+
+  it('generate custom questions to issue categories map', () => {
+    const categories: IssueCategory[]= [
+      {
+        name: 't1',
+        description: 'd1',
+        persona: IssueWizardPersona.EndUser,
+        enabled: true,
+        customQuestions: [
+          {
+            type: CustomQuestionType.Text,
+            question: 'q1',
+          }
+        ]
+      },
+    ];
+
+    const questionsByCategoryMap = GetQuestionsByCategory(categories);
+    const questions = questionsByCategoryMap.get('t1');
+
+    assert.equal(questions?.length, 1);
+    assert.equal(questions[0].question, 'q1');
+  });
+
+  it('create issue description', () => {
+    const description = buildIssueDescription('reproduce', 'description', 'comments', 'Mac', 'Chrome');
+    expect(description).to.contains('Steps to reproduce the problem:');
+    expect(description).to.contains('Problem Description:');
+    expect(description).to.contains('Additional Comments:');
+  });
+
+  it('test the chrome version regex match', () => {
+    const navigatorMock = {
+      userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36'
+    };
+    Object.defineProperty(window, 'navigator', {
+        value: navigatorMock
+      });
+    const chrome_version = getChromeVersion();
+    assert(chrome_version, '98.0.4758.109');
+  });
+});