Skip to content
Snippets Groups Projects
Unverified Commit 3715839c authored by Anton Kulyk's avatar Anton Kulyk Committed by GitHub
Browse files

Add more E2E tests around joins (#34252)

* Test using columns from joined tables or cards

* Test multi stage joins

* Test removal on source table change

* Test RHS table column selection

* Reduce flakiness?

* Fix test

* Reduce flakiness?
parent 124a6a3d
No related branches found
No related tags found
No related merge requests found
......@@ -18,10 +18,12 @@ import {
selectSavedQuestionsToJoin,
startNewQuestion,
summarize,
visitQuestionAdhoc,
visualize,
} from "e2e/support/helpers";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
......@@ -45,6 +47,23 @@ describe("scenarios > question > joined questions", () => {
rhsSampleColumn: "Reviews - Product → ID",
});
openNotebook();
getNotebookStep("join").icon("chevrondown").click();
popover().within(() => {
cy.findByText("Product ID").click();
cy.findByText("Body").click();
cy.findByText("Created At").click();
});
visualize();
assertJoinValid({
lhsTable: "Orders",
rhsTable: "Reviews",
lhsSampleColumn: "Product ID",
rhsSampleColumn: "Reviews - Product → Reviewer",
});
queryBuilderMain().findByText("Body").should("not.exist");
// Post-join filters on the joined table (metabase#12221, metabase#15570)
openNotebook();
filter({ mode: "notebook" });
......@@ -79,13 +98,13 @@ describe("scenarios > question > joined questions", () => {
it("should join a native question", () => {
cy.createNativeQuestion({
name: "question a",
native: { query: "select 'foo' as a_column" },
native: { query: "select ID, PRODUCT_ID, TOTAL from orders" },
});
cy.createNativeQuestion(
{
name: "question b",
native: { query: "select 'foo' as b_column" },
native: { query: "select * from products" },
},
{
wrapId: true,
......@@ -95,8 +114,8 @@ describe("scenarios > question > joined questions", () => {
startNewQuestion();
selectSavedQuestionsToJoin("question a", "question b");
popover().findByText("A_COLUMN").click();
popover().findByText("B_COLUMN").click();
popover().findByText("PRODUCT_ID").click();
popover().findByText("ID").click();
visualize();
......@@ -104,12 +123,53 @@ describe("scenarios > question > joined questions", () => {
assertJoinValid({
lhsTable: "question a",
rhsTable: "question b",
lhsSampleColumn: "A_COLUMN",
rhsSampleColumn: `Question ${joinedQuestionId} → B Column`,
lhsSampleColumn: "TOTAL",
rhsSampleColumn: `Question ${joinedQuestionId} → ID`,
});
});
openNotebook();
getNotebookStep("join").icon("chevrondown").click();
popover().within(() => {
cy.findByText("EAN").click();
cy.findByText("VENDOR").click();
cy.findByText("PRICE").click();
cy.findByText("CATEGORY").click();
cy.findByText("CREATED_AT").click();
});
visualize();
cy.get("@joinedQuestionId").then(joinedQuestionId => {
assertJoinValid({
lhsTable: "question a",
rhsTable: "question b",
lhsSampleColumn: "TOTAL",
rhsSampleColumn: `Question ${joinedQuestionId} → Rating`,
});
});
queryBuilderMain().findByText("EAN").should("not.exist");
assertQueryBuilderRowCount(1);
openNotebook();
cy.get("@joinedQuestionId").then(joinedQuestionId => {
filter({ mode: "notebook" });
popover().within(() => {
cy.findByText(`Question ${joinedQuestionId}`).click();
cy.findByText("CATEGORY").click();
cy.findByPlaceholderText("Enter some text").type("Gadget");
cy.button("Add filter").click();
});
summarize({ mode: "notebook" });
addSummaryGroupingField({
table: `Question ${joinedQuestionId}`,
field: "CATEGORY",
});
});
visualize();
cy.findByTestId("qb-filters-panel")
.findByText("CATEGORY is Gadget")
.should("be.visible");
cy.get(".ScalarValue").contains("Gadget").should("be.visible");
});
it("should join structured questions (metabase#13000, metabase#13649, metabase#13744)", () => {
......@@ -161,21 +221,68 @@ describe("scenarios > question > joined questions", () => {
});
openNotebook();
getNotebookStep("join").icon("chevrondown").click();
popover().findByText("ID").click();
visualize();
// cy.log("joined questions should create custom column (metabase#13649)");
// add a custom column on top of the steps from the #13000 repro which was simply asserting
// that a question could be made by joining two previously saved questions
addCustomColumn();
cy.get("@joinedQuestionId").then(joinedQuestionId => {
assertJoinValid({
lhsTable: "Q1",
rhsTable: "Q2",
lhsSampleColumn: "Product ID",
rhsSampleColumn: `Question ${joinedQuestionId} → Sum of Total`,
});
queryBuilderMain()
.findByText(`Question ${joinedQuestionId} → ID`)
.should("not.exist");
});
openNotebook();
cy.get("@joinedQuestionId").then(joinedQuestionId => {
// add a custom column on top of the steps from the #13000 repro which was simply asserting
// that a question could be made by joining two previously saved questions
addCustomColumn();
enterCustomColumnDetails({
formula: `[Question ${joinedQuestionId} → Sum of Rating] / [Sum of Total]`,
name: "Sum Divide",
});
popover().button("Done").click();
filter({ mode: "notebook" });
popover().within(() => {
cy.findByText(`Question ${joinedQuestionId}`).click();
cy.findByText("ID").click();
cy.findByPlaceholderText("Enter an ID").type("12");
cy.button("Add filter").click();
});
});
popover().button("Done").click();
visualize();
queryBuilderMain().findByText("Sum Divide");
cy.findByTestId("qb-filters-panel")
.findByText("ID is 12")
.should("be.visible");
});
it("should handle joins on different stages", () => {
openOrdersTable({ mode: "notebook" });
join();
joinTable("Products");
summarize({ mode: "notebook" });
addSummaryField({ metric: "Count of rows" });
addSummaryGroupingField({ table: "Product", field: "ID" });
cy.findAllByTestId("action-buttons").last().button("Join data").click();
joinTable("Reviews", "ID", "Product ID");
visualize();
assertJoinValid({
lhsSampleColumn: "Count",
rhsSampleColumn: "Reviews → ID",
});
assertQueryBuilderRowCount(1136);
});
it("should allow joins with multiple conditions", () => {
......@@ -236,6 +343,43 @@ describe("scenarios > question > joined questions", () => {
cy.get(".ScalarValue").contains("2,087");
});
it("should remove a join when changing the source table", () => {
visitQuestionAdhoc(
{
dataset_query: {
type: "query",
database: SAMPLE_DB_ID,
query: {
"source-table": ORDERS_ID,
joins: [
{
alias: "Products",
condition: [
"=",
["field", ORDERS.PRODUCT_ID, null],
["field", PRODUCTS.ID, { "join-alias": "Products" }],
],
fields: "all",
"source-table": PRODUCTS_ID,
},
],
},
},
},
{ mode: "notebook" },
);
getNotebookStep("data").findByTestId("data-step-cell").click();
popover().findByText("People").click();
getNotebookStep("join").should("not.exist");
visualize();
queryBuilderMain()
.findAllByText(/Product/)
.should("have.length", 0);
});
});
function selectJoinStrategy(strategy) {
......
......@@ -7,6 +7,7 @@ import {
filterField,
getNotebookStep,
join,
openNotebook,
openOrdersTable,
openProductsTable,
openTable,
......@@ -441,6 +442,8 @@ describe("scenarios > question > notebook", { tags: "@slow" }, () => {
});
it("should prompt to join with a model if the question is based on a model", () => {
cy.intercept("GET", "/api/table/*/query_metadata").as("loadMetadata");
cy.createQuestion({
name: "Products model",
query: { "source-table": PRODUCTS_ID },
......@@ -448,16 +451,18 @@ describe("scenarios > question > notebook", { tags: "@slow" }, () => {
display: "table",
});
cy.createQuestion({
name: "Orders model",
query: { "source-table": ORDERS_ID },
dataset: true,
display: "table",
});
cy.createQuestion(
{
name: "Orders model",
query: { "source-table": ORDERS_ID },
dataset: true,
display: "table",
},
{ visitQuestion: true },
);
openNotebook();
startNewQuestion();
popover().findByText("Models").click();
popover().findByText("Products model").click();
join();
popover().findByText("Orders model").click();
popover().findByText("ID").click();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment