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

dataframe_util_spec.js « output « cells « notebook « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ddc1b3cfe26451d701b190f76580c5e3a005a25c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { isDataframe, convertHtmlTableToJson } from '~/notebook/cells/output/dataframe_util';
import { outputWithDataframeContent } from '../../mock_data';
import sanitizeTests from './html_sanitize_fixtures';

describe('notebook/cells/output/dataframe_utils', () => {
  describe('isDataframe', () => {
    describe('when output data has no text/html', () => {
      it('is is not a dataframe', () => {
        const input = { data: { 'image/png': ['blah'] } };

        expect(isDataframe(input)).toBe(false);
      });
    });

    describe('when output data has no text/html, but no mention of dataframe', () => {
      it('is is not a dataframe', () => {
        const input = { data: { 'text/html': ['blah'] } };

        expect(isDataframe(input)).toBe(false);
      });
    });

    describe('when output data has text/html, but no mention of dataframe in the first 20 lines', () => {
      it('is is not a dataframe', () => {
        const input = { data: { 'text/html': [...new Array(20).fill('a'), 'dataframe'] } };

        expect(isDataframe(input)).toBe(false);
      });
    });

    describe('when output data has text/html, and includes "dataframe" within the first 20 lines', () => {
      it('is is not a dataframe', () => {
        const input = { data: { 'text/html': ['dataframe'] } };

        expect(isDataframe(input)).toBe(true);
      });
    });
  });

  describe('convertHtmlTableToJson', () => {
    it('converts table correctly', () => {
      const input = outputWithDataframeContent;

      const output = {
        fields: [
          { key: 'index', label: '', sortable: true },
          { key: 'column_1', label: 'column_1', sortable: true },
          { key: 'column_2', label: 'column_2', sortable: true },
        ],
        items: [
          { index: 0, column_1: 'abc de f', column_2: 'a' },
          { index: 1, column_1: 'True', column_2: '0.1' },
        ],
      };

      expect(convertHtmlTableToJson(input)).toEqual(output);
    });

    describe('sanitizes input before parsing table', () => {
      it('sanitizes input html', () => {
        const parser = new DOMParser();
        const spy = jest.spyOn(parser, 'parseFromString');
        const input = 'hello<style>p {width:50%;}</style><script>alert(1)</script>';

        convertHtmlTableToJson(input, parser);

        expect(spy).toHaveBeenCalledWith('hello', 'text/html');
      });
    });

    describe('does not include harmful html', () => {
      const makeDataframeWithHtml = (html) => {
        return [
          '<table border="1" class="dataframe">\n',
          '  <thead>\n',
          '    <tr style="text-align: right;">\n',
          '      <th></th>\n',
          '      <th>column_1</th>\n',
          '    </tr>\n',
          '  </thead>\n',
          '  <tbody>\n',
          '    <tr>\n',
          '      <th>0</th>\n',
          `      <td>${html}</td>\n`,
          '    </tr>\n',
          '  </tbody>\n',
          '</table>\n',
          '</div>',
        ];
      };

      it.each([
        ['table', 0],
        ['style', 1],
        ['iframe', 2],
        ['svg', 3],
      ])('sanitizes output for: %p', (tag, index) => {
        const inputHtml = makeDataframeWithHtml(sanitizeTests[index][1].input);
        const convertedHtml = convertHtmlTableToJson(inputHtml).items[0].column_1;

        expect(convertedHtml).not.toContain(tag);
      });
    });

    describe('when dataframe is invalid', () => {
      it('returns empty', () => {
        const input = [' dataframe', ' blah'];

        expect(convertHtmlTableToJson(input)).toEqual({ fields: [], items: [] });
      });
    });
  });
});