import { mount, shallowMount } from "@vue/test-utils";
import { baseClassCase } from "@/utils/test-case-factories";
import DTable from "./index";
import config from "./config";
import { SIZE } from "@darwin-studio/ui-codegen/dist/constants/size";
import { PADDING } from "@darwin-studio/ui-codegen/dist/constants/padding";
import { TRANSITION } from "@darwin-studio/ui-codegen/dist/constants/transition";
import prepareCssClassName from "@darwin-studio/ui-codegen/src/utils/prepareCssClassName";
import codegenConfig from "@darwin-studio/ui-codegen/config.json";
import DButton from "@/components/atoms/d-button";
import { DLoaderAsync as DLoader } from "@/components/atoms/d-loader/async";
const headLabel0 = "head 1";
const headLabel1 = "head 2";
const headLabel2 = "head 3";
const headRows = [
[
headLabel0,
{headLabel1},
{headLabel2}
,
],
];
const bodyCell00 = "cell 11";
const bodyCell01 = "cell 12";
const bodyCell02 = "cell 13";
const bodyCell10 = "cell 21";
const bodyCell11 = "cell 12";
const bodyCell12 = "cell 13";
const bodyCell02OnClick = jest.fn();
const bodyRows = [
[
bodyCell00,
{bodyCell01},
{bodyCell02}
,
],
[
{bodyCell10}
,
bodyCell11,
{bodyCell12},
],
];
describe("DTable", () => {
const wrapper = shallowMount(DTable);
baseClassCase(wrapper, config.class);
it("Should render props.headClass to the thead element class", async () => {
const headClass = "some-head-class";
await wrapper.setProps({ headClass });
const theadEl = wrapper.find("thead");
expect(theadEl).toBeTruthy(); // TODO: empty wrapper is also truthy
expect(theadEl.classes()).toContain(headClass);
});
it("Should render props.headRows as tr elements inside the thead", async () => {
await wrapper.setProps({ headRows });
const thElements = wrapper.findAll("thead > tr > th");
expect(thElements.length).toBe(headRows[0].length);
expect(thElements[0].text()).toBe(headLabel0);
expect(thElements[1].text()).toBe(headLabel1);
expect(thElements[2].html()).toMatchSnapshot();
});
it("Should render props.headRowClass as tr elements inside the thead class", async () => {
const headRowClass = "some-head-row-class";
await wrapper.setProps({ headRows, headRowClass });
const headRowEl = wrapper.find("thead > tr");
expect(headRowEl.classes()).toContain(headRowClass);
});
it("Should render props.headCellClass as td elements inside the thead class", async () => {
const headCellClass = "some-head-row-class";
await wrapper.setProps({ headRows, headCellClass });
const thElements = wrapper.findAll("thead > tr > th");
thElements.forEach((thEl) => {
expect(thEl.classes()).toContain(headCellClass);
});
});
it("Should render props.headRowAttrs as tr elements inside the thead attrs", async () => {
const headRowAttrsObj = {
tabindex: "1",
"data-id": "123",
};
await wrapper.setProps({ headRows, headRowAttrs: () => headRowAttrsObj });
const headRowEl = wrapper.find("thead > tr");
expect(headRowEl.attributes("tabindex")).toBe(headRowAttrsObj.tabindex);
expect(headRowEl.attributes("data-id")).toBe(headRowAttrsObj["data-id"]);
});
it("Should render props.headCellAttrs as td elements inside the thead attrs", async () => {
const headCellAttrsObj = {
style: "background: red;",
onClick: jest.fn(),
};
await wrapper.setProps({ headRows, headCellAttrs: () => headCellAttrsObj });
const thElements = wrapper.findAll("thead > tr > th");
await Promise.all(
thElements.map(async (thEl) => {
expect(thEl.attributes("style")).toBe(headCellAttrsObj.style);
await thEl.trigger("click");
})
);
expect(headCellAttrsObj.onClick).toBeCalledTimes(headRows[0].length);
});
it("Should render props.bodyClass to the tbody element class", async () => {
const bodyClass = "some-body-class";
await wrapper.setProps({ bodyClass });
const theadEl = wrapper.find("tbody");
expect(theadEl).toBeTruthy(); // TODO: empty wrapper is also truthy
expect(theadEl.classes()).toContain(bodyClass);
});
it("Should render props.bodyRows as tr elements inside the tbody", async () => {
await wrapper.setProps({ bodyRows });
const trElements = wrapper.findAll("tbody > tr");
const tdElements0 = trElements[0].findAll("td");
expect(tdElements0[0].text()).toBe(bodyCell00);
expect(tdElements0[1].text()).toBe(bodyCell01);
expect(tdElements0[2].html()).toMatchSnapshot();
// TODO: await tdElements0[2].trigger("click");
// TODO: expect(bodyCell02OnClick).toBeCalled();
const tdElements1 = trElements[1].findAll("td");
expect(tdElements1[0].text()).toBe(bodyCell10);
expect(tdElements1[1].text()).toBe(bodyCell11);
expect(tdElements1[2].html()).toMatchSnapshot();
});
it("Should render props.bodyRowClass as tr elements inside the tbody class", async () => {
const bodyRowClass = "some-body-row-class";
await wrapper.setProps({ bodyRows, bodyRowClass });
const trElements = wrapper.findAll("tbody > tr");
trElements.forEach((trEl) => {
expect(trEl.classes()).toContain(bodyRowClass);
});
});
it("Should render props.bodyCellClass as td elements inside the tbody class", async () => {
const bodyCellClass = "some-body-cell-class";
await wrapper.setProps({ bodyRows, bodyCellClass });
const tdElements = wrapper.findAll("tbody > tr > td");
tdElements.forEach((tdEl) => {
expect(tdEl.classes()).toContain(bodyCellClass);
});
});
it("Should render props.bodyRowAttrs as tr elements inside the tbody attrs", async () => {
const bodyRowAttrsArr = [
{
style: "background: red;",
onClick: jest.fn(),
},
{
style: "background: black; color: white;",
onClick: jest.fn(),
},
];
await wrapper.setProps({
bodyRows,
bodyRowAttrs: (rowIndex: number) => bodyRowAttrsArr[rowIndex],
});
const trElements = wrapper.findAll("tbody > tr");
await Promise.all(
trElements.map(async (trEl, index) => {
expect(trEl.attributes("style")).toBe(bodyRowAttrsArr[index].style);
await trEl.trigger("click");
expect(bodyRowAttrsArr[index].onClick).toBeCalled();
})
);
});
it("Should render props.bodyCellAttrs as td elements inside the tbody attrs", async () => {
const bodyCellAttrsArr = [
[
{
style: "background: red;",
onClick: jest.fn(),
},
{
style: "background: black; color: white;",
onClick: jest.fn(),
},
{
style: "visibility: hidden;",
onClick: jest.fn(),
},
],
[
{
style: "background: black; color: white;",
onClick: jest.fn(),
},
{
style: "background: red;",
onClick: jest.fn(),
},
{
style: "visibility: hidden;",
onClick: jest.fn(),
},
],
];
await wrapper.setProps({
bodyRows,
bodyCellAttrs: (rowIndex: number, cellIndex: number) =>
bodyCellAttrsArr[rowIndex][cellIndex],
});
const trElements = wrapper.findAll("tbody > tr");
await Promise.all(
trElements.map(async (trEl, rowIndex) => {
const tdElements = trEl.findAll("td");
await Promise.all(
tdElements.map(async (tdEl, cellIndex) => {
expect(tdEl.attributes("style")).toBe(
bodyCellAttrsArr[rowIndex][cellIndex].style
);
await tdEl.trigger("click");
expect(bodyCellAttrsArr[rowIndex][cellIndex].onClick).toBeCalled();
})
);
})
);
});
it("Should render props.padding as td elements padding class", async () => {
const padding = PADDING.EQUAL;
const paddingClassName = prepareCssClassName(
codegenConfig.TOKENS.PADDING.CSS_CLASS_PREFIX,
padding
);
const size = SIZE.MEDIUM;
const paddingSizeClassName = prepareCssClassName(
codegenConfig.TOKENS.PADDING.CSS_CLASS_PREFIX,
`${padding}-${size}`
);
await wrapper.setProps({ headRows, bodyRows, padding, size });
const headThElement = wrapper.find("thead > tr > th");
expect(headThElement.classes()).toContain(paddingClassName);
expect(headThElement.classes()).toContain(paddingSizeClassName);
const bodyTdElement = wrapper.find("tbody > tr > td");
expect(bodyTdElement.classes()).toContain(paddingClassName);
expect(bodyTdElement.classes()).toContain(paddingSizeClassName);
});
it("Should render props.size as td elements size class", async () => {
const size = SIZE.HUGE;
await wrapper.setProps({ size });
const className = prepareCssClassName(
codegenConfig.TOKENS.SIZE.CSS_CLASS_PREFIX,
size
);
await wrapper.setProps({ headRows, bodyRows, size });
const headThElement = wrapper.find("thead > tr > th");
expect(headThElement.classes()).toContain(className);
const bodyTdElement = wrapper.find("tbody > tr > td");
expect(bodyTdElement.classes()).toContain(className);
});
it("Should render props.transition as td elements transition transition", async () => {
const transition = TRANSITION.AVERAGE;
await wrapper.setProps({ transition });
const className = prepareCssClassName(
codegenConfig.TOKENS.TRANSITION.CSS_CLASS_PREFIX,
transition
);
await wrapper.setProps({ headRows, bodyRows, transition });
const headTrElement = wrapper.find("thead > tr ");
expect(headTrElement.classes()).toContain(className);
const bodyTrElement = wrapper.find("tbody > tr");
expect(bodyTrElement.classes()).toContain(className);
});
it("Should render props.headRows and props.bodyRows as VNode", async () => {
const head = head html string;
const body = body html string;
const headHtml = `${head}`;
const bodyHtml = `${body}`;
await wrapper.setProps({
headRows: [[headHtml]],
bodyRows: [[bodyHtml]],
});
const headTdContentElement = wrapper.find("thead > tr > th");
expect(headTdContentElement.html()).toMatch(headHtml);
const bodyTdContentElement = wrapper.find("tbody > tr > td");
expect(bodyTdContentElement.html()).toMatch(bodyHtml);
});
// TODO: move to the factories
it("Should render DLoader if props.loading is true", async () => {
const wrapper = mount(DButton);
await wrapper.setProps({ loading: true });
const loader = wrapper.findComponent(DLoader);
expect(loader.exists()).toBeTruthy();
});
});