Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-29 03:10:57 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-29 03:10:57 +0300
commite064cd3f07fbc239fb46106a1eaf71379ea01603 (patch)
treeeb1f478d6f6d5e73bc50639f7af7a99b4d34a392 /spec/frontend/behaviors
parent9037472904908109f5622a8a1e808c6225eced56 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/behaviors')
-rw-r--r--spec/frontend/behaviors/components/json_table_spec.js162
-rw-r--r--spec/frontend/behaviors/markdown/render_json_table_spec.js119
2 files changed, 281 insertions, 0 deletions
diff --git a/spec/frontend/behaviors/components/json_table_spec.js b/spec/frontend/behaviors/components/json_table_spec.js
new file mode 100644
index 00000000000..42b4a051d4d
--- /dev/null
+++ b/spec/frontend/behaviors/components/json_table_spec.js
@@ -0,0 +1,162 @@
+import { GlTable, GlFormInput } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import { merge } from 'lodash';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
+import { stubComponent, RENDER_ALL_SLOTS_TEMPLATE } from 'helpers/stub_component';
+import JSONTable from '~/behaviors/components/json_table.vue';
+
+const TEST_FIELDS = [
+ 'A',
+ {
+ key: 'B',
+ label: 'Second',
+ sortable: true,
+ other: 'foo',
+ },
+ {
+ key: 'C',
+ label: 'Third',
+ },
+ 'D',
+];
+const TEST_ITEMS = [
+ { A: 1, B: 'lorem', C: 2, D: null, E: 'dne' },
+ { A: 2, B: 'ipsum', C: 2, D: null, E: 'dne' },
+ { A: 3, B: 'dolar', C: 2, D: null, E: 'dne' },
+];
+
+describe('behaviors/components/json_table', () => {
+ let wrapper;
+
+ const buildWrapper = ({
+ fields = [],
+ items = [],
+ filter = undefined,
+ caption = undefined,
+ } = {}) => {
+ wrapper = shallowMountExtended(JSONTable, {
+ propsData: {
+ fields,
+ items,
+ hasFilter: filter,
+ caption,
+ },
+ stubs: {
+ GlTable: merge(stubComponent(GlTable), {
+ props: {
+ fields: {
+ type: Array,
+ required: true,
+ },
+ items: {
+ type: Array,
+ required: true,
+ },
+ },
+ template: RENDER_ALL_SLOTS_TEMPLATE,
+ }),
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findTable = () => wrapper.findComponent(GlTable);
+ const findTableCaption = () => wrapper.findByTestId('slot-table-caption');
+ const findFilterInput = () => wrapper.findComponent(GlFormInput);
+
+ describe('default', () => {
+ beforeEach(() => {
+ buildWrapper();
+ });
+
+ it('renders gltable', () => {
+ expect(findTable().props()).toEqual({
+ fields: [],
+ items: [],
+ });
+ expect(findTable().attributes()).toMatchObject({
+ filter: '',
+ 'show-empty': '',
+ });
+ });
+
+ it('does not render filter input', () => {
+ expect(findFilterInput().exists()).toBe(false);
+ });
+
+ it('renders caption', () => {
+ expect(findTableCaption().text()).toBe('Generated with JSON data');
+ });
+ });
+
+ describe('with filter', () => {
+ beforeEach(() => {
+ buildWrapper({
+ filter: true,
+ });
+ });
+
+ it('renders filter input', () => {
+ expect(findFilterInput().attributes()).toMatchObject({
+ value: '',
+ placeholder: 'Type to search',
+ });
+ });
+
+ it('when input is changed, updates table filter', async () => {
+ findFilterInput().vm.$emit('input', 'New value!');
+
+ await nextTick();
+
+ expect(findTable().attributes('filter')).toBe('New value!');
+ });
+ });
+
+ describe('with fields', () => {
+ beforeEach(() => {
+ buildWrapper({
+ fields: TEST_FIELDS,
+ items: TEST_ITEMS,
+ });
+ });
+
+ it('passes cleaned fields and items to table', () => {
+ expect(findTable().props()).toEqual({
+ fields: [
+ 'A',
+ {
+ key: 'B',
+ label: 'Second',
+ sortable: true,
+ },
+ {
+ key: 'C',
+ label: 'Third',
+ sortable: false,
+ },
+ 'D',
+ ],
+ items: TEST_ITEMS,
+ });
+ });
+ });
+
+ describe('with full mount', () => {
+ beforeEach(() => {
+ wrapper = mountExtended(JSONTable, {
+ propsData: {
+ fields: [],
+ items: [],
+ },
+ });
+ });
+
+ // We want to make sure all the props are passed down nicely in integration
+ it('renders table without errors', () => {
+ expect(findTable().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/behaviors/markdown/render_json_table_spec.js b/spec/frontend/behaviors/markdown/render_json_table_spec.js
new file mode 100644
index 00000000000..488492479f3
--- /dev/null
+++ b/spec/frontend/behaviors/markdown/render_json_table_spec.js
@@ -0,0 +1,119 @@
+import { nextTick } from 'vue';
+import { renderJSONTable } from '~/behaviors/markdown/render_json_table';
+
+describe('behaviors/markdown/render_json_table', () => {
+ let element;
+
+ const TEST_DATA = {
+ fields: [
+ { label: 'Field 1', key: 'a' },
+ { label: 'F 2', key: 'b' },
+ { label: 'F 3', key: 'c' },
+ ],
+ items: [
+ {
+ a: '1',
+ b: 'b',
+ c: 'c',
+ },
+ {
+ a: '2',
+ b: 'd',
+ c: 'e',
+ },
+ ],
+ };
+ const TEST_LABELS = TEST_DATA.fields.map((x) => x.label);
+
+ const tableAsData = (table) => ({
+ head: Array.from(table.querySelectorAll('thead th')).map((td) => td.textContent),
+ body: Array.from(table.querySelectorAll('tbody > tr')).map((tr) =>
+ Array.from(tr.querySelectorAll('td')).map((x) => x.textContent),
+ ),
+ });
+
+ const createTestSubject = async (json) => {
+ if (element) {
+ throw new Error('element has already been initialized');
+ }
+
+ const parent = document.createElement('div');
+ const pre = document.createElement('pre');
+
+ pre.textContent = json;
+ parent.appendChild(pre);
+
+ document.body.appendChild(parent);
+ renderJSONTable([parent]);
+
+ element = parent;
+
+ jest.runAllTimers();
+
+ await nextTick();
+ };
+
+ const findPres = () => document.querySelectorAll('pre');
+ const findTables = () => document.querySelectorAll('table');
+ const findAlerts = () => document.querySelectorAll('.gl-alert');
+ const findInputs = () => document.querySelectorAll('.gl-form-input');
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ element = null;
+ });
+
+ describe('default', () => {
+ beforeEach(async () => {
+ await createTestSubject(JSON.stringify(TEST_DATA, null, 2));
+ });
+
+ it('removes pre', () => {
+ expect(findPres()).toHaveLength(0);
+ });
+
+ it('replaces pre with table', () => {
+ const tables = findTables();
+
+ expect(tables).toHaveLength(1);
+ expect(tableAsData(tables[0])).toEqual({
+ head: TEST_LABELS,
+ body: [
+ ['1', 'b', 'c'],
+ ['2', 'd', 'e'],
+ ],
+ });
+ });
+
+ it('does not show filter', () => {
+ expect(findInputs()).toHaveLength(0);
+ });
+ });
+
+ describe('with invalid json', () => {
+ beforeEach(() => {
+ createTestSubject('funky but not json');
+ });
+
+ it('preserves pre', () => {
+ expect(findPres()).toHaveLength(1);
+ });
+
+ it('shows alert', () => {
+ const alerts = findAlerts();
+
+ expect(alerts).toHaveLength(1);
+ expect(alerts[0].textContent).toMatchInterpolatedText('Unable to parse JSON');
+ });
+ });
+
+ describe('with filter set', () => {
+ beforeEach(() => {
+ createTestSubject(JSON.stringify({ ...TEST_DATA, filter: true }));
+ });
+
+ it('shows filter', () => {
+ expect(findInputs()).toHaveLength(1);
+ });
+ });
+});