Skip to content
Snippets Groups Projects
Commit 1369bf51 authored by Atte Keinänen's avatar Atte Keinänen
Browse files

Merge branch 'master' of https://github.com/metabase/metabase into migrate-karma-to-jest

parents 5e55df17 bc1fc89b
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@ import { mbqlEq } from "./util";
import type { Field as FieldReference } from "metabase/meta/types/Query";
import type { Field, FieldId, FieldValues } from "metabase/meta/types/Field";
import type { Value } from "metabase/meta/types/Dataset";
// gets the target field ID (recursively) from any type of field, including raw field ID, fk->, and datetime-field cast.
export function getFieldTargetId(field: FieldReference): ?FieldId {
......
import _ from "underscore";
import { isa, isFK as isTypeFK, isPK as isTypePK, TYPE } from "metabase/lib/types";
import { getFieldValues, getHumanReadableValue } from "metabase/lib/query/field";
import { getFieldValues } from "metabase/lib/query/field";
// primary field types used for picking operators, etc
export const NUMBER = "NUMBER";
......@@ -182,7 +182,8 @@ function equivalentArgument(field, table) {
.filter(([value, displayValue]) => value != null)
.map(([value, displayValue]) => ({
key: value,
name: getHumanReadableValue(value, values)
// NOTE Atte Keinänen 8/7/17: Similar logic as in getHumanReadableValue of lib/query/field
name: displayValue ? displayValue : String(value)
}))
.sort((a, b) => a.key === b.key ? 0 : (a.key < b.key ? -1 : 1))
};
......
......@@ -9,8 +9,7 @@ import ExplicitSize from "metabase/components/ExplicitSize.jsx";
import Ellipsified from "metabase/components/Ellipsified.jsx";
import Icon from "metabase/components/Icon.jsx";
import { formatValue } from "metabase/lib/formatting";
import { getFriendlyName } from "metabase/visualizations/lib/utils";
import { formatColumn, formatValue } from "metabase/lib/formatting";
import { getTableCellClickedObject, isColumnRightAligned } from "metabase/visualizations/lib/table";
import cx from "classnames";
......@@ -112,7 +111,7 @@ export default class TableSimple extends Component {
width={8} height={8}
style={{ position: "absolute", right: "100%", marginRight: 3 }}
/>
<Ellipsified>{getFriendlyName(col)}</Ellipsified>
<Ellipsified>{formatColumn(col)}</Ellipsified>
</div>
</th>
)}
......
......@@ -135,7 +135,14 @@ export function getXValues(datas, chartType) {
}
export function getFriendlyName(column) {
return column.display_name || FRIENDLY_NAME_MAP[column.name.toLowerCase().trim()] || column.name;
if (column.display_name && column.display_name !== column.name) {
return column.display_name
} else {
// NOTE Atte Keinänen 8/7/17:
// Values `display_name` and `name` are same for breakout columns so check FRIENDLY_NAME_MAP
// before returning either `display_name` or `name`
return FRIENDLY_NAME_MAP[column.name.toLowerCase().trim()] || column.display_name || column.name;
}
}
export function getCardColors(card) {
......
......@@ -25,7 +25,12 @@ import { SET_ERROR_PAGE } from "metabase/redux/app";
import QueryHeader from "metabase/query_builder/components/QueryHeader";
import { VisualizationEmptyState } from "metabase/query_builder/components/QueryVisualization";
import { FETCH_TABLE_METADATA } from "metabase/redux/metadata";
import {
deleteFieldDimension,
updateFieldDimension,
updateFieldValues,
FETCH_TABLE_METADATA
} from "metabase/redux/metadata";
import FieldList, { DimensionPicker } from "metabase/query_builder/components/FieldList";
import FilterPopover from "metabase/query_builder/components/filters/FilterPopover";
......@@ -51,6 +56,10 @@ import ChartClickActions from "metabase/visualizations/components/ChartClickActi
import { delay } from "metabase/lib/promise";
const REVIEW_PRODUCT_ID = 32;
const REVIEW_RATING_ID = 33;
const PRODUCT_TITLE_ID = 27;
const initQbWithDbAndTable = (dbId, tableId) => {
return async () => {
const store = await createTestStore()
......@@ -724,4 +733,124 @@ describe("QueryBuilder", () => {
});
})
})
describe("remapping", () => {
beforeAll(async () => {
// add remappings
const store = await createTestStore()
// NOTE Atte Keinänen 8/7/17:
// We test here the full dimension functionality which lets you enter a dimension name that differs
// from the field name. This is something that field settings UI doesn't let you to do yet.
await store.dispatch(updateFieldDimension(REVIEW_PRODUCT_ID, {
type: "external",
name: "Product Name",
human_readable_field_id: PRODUCT_TITLE_ID
}));
await store.dispatch(updateFieldDimension(REVIEW_RATING_ID, {
type: "internal",
name: "Rating Description",
human_readable_field_id: null
}));
await store.dispatch(updateFieldValues(REVIEW_RATING_ID, [
[1, 'Awful'], [2, 'Unpleasant'], [3, 'Meh'], [4, 'Enjoyable'], [5, 'Perfecto']
]));
})
describe("for Rating category field with custom field values", () => {
// The following test case is very similar to earlier filter tests but in this case we use remapped values
it("lets you add 'Rating is Perfecto' filter", async () => {
const { store, qb } = await initQBWithReviewsTable();
// open filter popover
const filterSection = qb.find('.GuiBuilder-filtered-by');
const newFilterButton = filterSection.find('.AddButton');
newFilterButton.simulate("click");
// choose the field to be filtered
const filterPopover = filterSection.find(FilterPopover);
const ratingFieldButton = filterPopover.find(FieldList).find('h4[children="Rating Description"]')
expect(ratingFieldButton.length).toBe(1);
ratingFieldButton.simulate('click');
// check that field values seem correct
const fieldItems = filterPopover.find('li');
expect(fieldItems.length).toBe(5);
expect(fieldItems.first().text()).toBe("Awful")
expect(fieldItems.last().text()).toBe("Perfecto")
// select the last item (Perfecto)
const widgetFieldItem = fieldItems.last();
const widgetCheckbox = widgetFieldItem.find(CheckBox);
expect(widgetCheckbox.props().checked).toBe(false);
widgetFieldItem.children().first().simulate("click");
expect(widgetCheckbox.props().checked).toBe(true);
// add the filter
const addFilterButton = filterPopover.find('button[children="Add filter"]')
addFilterButton.simulate("click");
await store.waitForActions([SET_DATASET_QUERY])
store.resetDispatchedActions();
// validate the filter text value
expect(qb.find(FilterPopover).length).toBe(0);
const filterWidget = qb.find(FilterWidget);
expect(filterWidget.length).toBe(1);
expect(filterWidget.text()).toBe("Rating Description is equal toPerfecto");
})
it("shows remapped value correctly in Raw Data query with Table visualization", async () => {
const { store, qb } = await initQBWithReviewsTable();
qb.find(RunButton).simulate("click");
await store.waitForActions([QUERY_COMPLETED]);
const table = qb.find(TestTable);
const headerCells = table.find("thead tr").first().find("th");
const firstRowCells = table.find("tbody tr").first().find("td");
expect(headerCells.length).toBe(6)
expect(headerCells.at(4).text()).toBe("Rating Description")
expect(firstRowCells.length).toBe(6);
expect(firstRowCells.at(4).text()).toBe("Enjoyable");
})
});
describe("for Product ID FK field with a FK remapping", () => {
it("shows remapped values correctly in Raw Data query with Table visualization", async () => {
const { store, qb } = await initQBWithReviewsTable();
qb.find(RunButton).simulate("click");
await store.waitForActions([QUERY_COMPLETED]);
const table = qb.find(TestTable);
const headerCells = table.find("thead tr").first().find("th");
const firstRowCells = table.find("tbody tr").first().find("td");
expect(headerCells.length).toBe(6)
expect(headerCells.at(3).text()).toBe("Product Name")
expect(firstRowCells.length).toBe(6);
expect(firstRowCells.at(3).text()).toBe("Ergonomic Leather Pants");
})
});
afterAll(async () => {
const store = await createTestStore()
await store.dispatch(deleteFieldDimension(REVIEW_PRODUCT_ID));
await store.dispatch(deleteFieldDimension(REVIEW_RATING_ID));
await store.dispatch(updateFieldValues(REVIEW_RATING_ID, [
[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5']
]));
})
})
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment