diff --git a/superset/assets/javascripts/components/FilterableTable/FilterableTable.jsx b/superset/assets/javascripts/components/FilterableTable/FilterableTable.jsx
index 7874aab921c..e54a6fc4fd5 100644
--- a/superset/assets/javascripts/components/FilterableTable/FilterableTable.jsx
+++ b/superset/assets/javascripts/components/FilterableTable/FilterableTable.jsx
@@ -97,10 +97,16 @@ export default class FilterableTable extends PureComponent {
const values = [];
for (const key in row) {
if (row.hasOwnProperty(key)) {
- values.push(row[key].toLowerCase());
+ const cellValue = row[key];
+ if (typeof cellValue === 'string') {
+ values.push(cellValue.toLowerCase());
+ } else if (typeof cellValue.toString === 'function') {
+ values.push(cellValue.toString());
+ }
}
}
- return values.some(v => v.includes(text.toLowerCase()));
+ const lowerCaseText = text.toLowerCase();
+ return values.some(v => v.includes(lowerCaseText));
}
headerRenderer({ dataKey, label, sortBy, sortDirection }) {
diff --git a/superset/assets/javascripts/modules/visUtils.js b/superset/assets/javascripts/modules/visUtils.js
index eef2babfb8f..974417966c3 100644
--- a/superset/assets/javascripts/modules/visUtils.js
+++ b/superset/assets/javascripts/modules/visUtils.js
@@ -1,9 +1,12 @@
export function getTextWidth(text, fontDetails = '12px Roboto') {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
- context.font = fontDetails;
- const metrics = context.measureText(text);
- return metrics.width;
+ if (context) {
+ // Won't work outside of a browser context (ie unit tests)
+ context.font = fontDetails;
+ return context.measureText(text).width;
+ }
+ return 100;
}
export default {
diff --git a/superset/assets/spec/javascripts/components/FilterableTable/FilterableTable_spec.jsx b/superset/assets/spec/javascripts/components/FilterableTable/FilterableTable_spec.jsx
index 240a8e499a1..a4ca9141ccf 100644
--- a/superset/assets/spec/javascripts/components/FilterableTable/FilterableTable_spec.jsx
+++ b/superset/assets/spec/javascripts/components/FilterableTable/FilterableTable_spec.jsx
@@ -1,15 +1,43 @@
import React from 'react';
import { describe, it } from 'mocha';
import { expect } from 'chai';
+import { mount } from 'enzyme';
import FilterableTable from '../../../../javascripts/components/FilterableTable/FilterableTable';
describe('FilterableTable', () => {
const mockedProps = {
- orderedColumnKeys: [],
- data: [],
- height: 0,
+ orderedColumnKeys: ['a', 'b', 'c'],
+ data: [
+ { a: 'a1', b: 'b1', c: 'c1', d: 0 },
+ { a: 'a2', b: 'b2', c: 'c2', d: 100 },
+ ],
+ height: 500,
};
+ let wrapper;
+ beforeEach(() => {
+ wrapper = mount();
+ });
it('is valid element', () => {
expect(React.isValidElement()).to.equal(true);
});
+ it('renders a grid with 2 rows', () => {
+ expect(wrapper.find('.ReactVirtualized__Grid')).to.have.length(1);
+ expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(2);
+ });
+ it('filters on a string', () => {
+ const props = {
+ ...mockedProps,
+ filterText: 'b1',
+ };
+ wrapper = mount();
+ expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(1);
+ });
+ it('filters on a number', () => {
+ const props = {
+ ...mockedProps,
+ filterText: '100',
+ };
+ wrapper = mount();
+ expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(1);
+ });
});