Skip to content
Snippets Groups Projects
Unverified Commit 3bda45de authored by Nemanja Glumac's avatar Nemanja Glumac Committed by GitHub
Browse files

Add Cypress custom command for sandboxing tables (#15038)


* Add Cypress custom command `cy.sandboxTable`

* Apply `cy.sandboxTable()` to all related tests

* Tuck permissions updating within sandboxing custom command
This abstracts away one layer of sandboxing that is necessary, but at the same time made tests harder to read.

* Account for the possibility of passing multiple user attributes

Co-authored-by: default avatarPaul Rosenzweig <paulrosenzweig@users.noreply.github.com>
parent 79ef63ab
No related branches found
No related tags found
No related merge requests found
......@@ -100,11 +100,9 @@ describeWithToken("formatting > sandboxes", () => {
// Orders join Products
createJoinedQuestion(QUESTION_NAME);
// Sandbox Orders table on "User ID"
cy.request("POST", "/api/mt/gtap", {
group_id: DATA_GROUP,
cy.sandboxTable({
table_id: ORDERS_ID,
card_id: null,
group_id: DATA_GROUP,
attribute_remappings: {
[USER_ATTRIBUTE]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
......@@ -126,27 +124,16 @@ describeWithToken("formatting > sandboxes", () => {
},
},
}).then(({ body: { id: QUESTION_ID } }) => {
// Sandbox `People` table based on previously created SQL question
cy.request("POST", "/api/mt/gtap", {
group_id: DATA_GROUP,
cy.sandboxTable({
table_id: PEOPLE_ID,
card_id: QUESTION_ID,
group_id: DATA_GROUP,
attribute_remappings: {
[USER_ATTRIBUTE]: ["dimension", ["template-tag", TTAG_NAME]],
},
});
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[ORDERS_ID]: { query: "segmented", read: "all" },
[PEOPLE_ID]: { query: "segmented", read: "all" },
},
},
user_group: DATA_GROUP,
});
signOut();
signInAsNormalUser();
});
......@@ -214,22 +201,17 @@ describeWithToken("formatting > sandboxes", () => {
});
it("should allow joins to the sandboxed table (metabase-enterprise#154)", () => {
cy.log("Sandbox `People` table on `user_id` attribute for `data` group");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PEOPLE_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", PEOPLE.ID]],
},
card_id: null,
group_id: COLLECTION_GROUP,
table_id: PEOPLE_ID,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[ORDERS_ID]: "all",
[PEOPLE_ID]: { query: "segmented", read: "all" },
[PRODUCTS_ID]: "all",
[REVIEWS_ID]: "all",
},
......@@ -273,23 +255,11 @@ describeWithToken("formatting > sandboxes", () => {
const QUESTION_NAME = "EE_548";
const CC_NAME = "CC_548"; // Custom column
cy.log("Sandbox `Orders` table on `user_id` attribute");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
group_id: COLLECTION_GROUP,
table_id: ORDERS_ID,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
cy.createQuestion({
......@@ -342,22 +312,17 @@ describeWithToken("formatting > sandboxes", () => {
});
}
cy.log("Sandbox `Orders` table on `user_id` attribute");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
group_id: COLLECTION_GROUP,
table_id: ORDERS_ID,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: "all",
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
......@@ -415,22 +380,17 @@ describeWithToken("formatting > sandboxes", () => {
const PRODUCTS_ALIAS = "Products";
const QUESTION_NAME = "EE_535";
cy.log("Sandbox `Orders` table on `user_id` attribute");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
group_id: COLLECTION_GROUP,
table_id: ORDERS_ID,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: "all",
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
......@@ -515,17 +475,12 @@ describeWithToken("formatting > sandboxes", () => {
filter: [">", ["field-id", ORDERS.TOTAL], 10],
},
}).then(({ body: { id: CARD_ID } }) => {
cy.log(
"Sandbox `Orders` table based on this QB question and user attribute",
);
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
card_id: CARD_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: CARD_ID,
group_id: COLLECTION_GROUP,
table_id: ORDERS_ID,
});
});
......@@ -537,29 +492,15 @@ describeWithToken("formatting > sandboxes", () => {
filter: [">", ["field-id", PRODUCTS.PRICE], 10],
},
}).then(({ body: { id: CARD_ID } }) => {
cy.log(
"Sandbox `Products` table based on this QB question and user attribute",
);
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PRODUCTS_ID,
card_id: CARD_ID,
attribute_remappings: {
[ATTR_CAT]: ["dimension", ["field-id", PRODUCTS.CATEGORY]],
},
card_id: CARD_ID,
group_id: COLLECTION_GROUP,
table_id: PRODUCTS_ID,
});
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: { query: "segmented", read: "all" },
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
signOut();
signInAsSandboxedUser();
......@@ -617,15 +558,12 @@ describeWithToken("formatting > sandboxes", () => {
? runAndSaveQuestion({ question: CARD_ID, sandboxValue: "1" })
: null;
cy.log("Sandbox `Orders` table based on this question");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
card_id: CARD_ID,
attribute_remappings: {
[ATTR_UID]: ["variable", ["template-tag", "sandbox"]],
},
card_id: CARD_ID,
group_id: COLLECTION_GROUP,
table_id: ORDERS_ID,
});
});
......@@ -651,27 +589,15 @@ describeWithToken("formatting > sandboxes", () => {
})
: null;
cy.log("Sandbox `Products` table based on this question");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PRODUCTS_ID,
card_id: CARD_ID,
attribute_remappings: {
[ATTR_CAT]: ["variable", ["template-tag", "sandbox"]],
},
card_id: CARD_ID,
group_id: COLLECTION_GROUP,
table_id: PRODUCTS_ID,
});
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: { query: "segmented", read: "all" },
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
signOut();
signInAsSandboxedUser();
......@@ -716,12 +642,8 @@ describeWithToken("formatting > sandboxes", () => {
cy.server();
cy.route("POST", "/api/dataset").as("dataset");
cy.log("Sandbox `Orders` table based on user attribute `attr_uid`");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
group_id: COLLECTION_GROUP,
card_id: null,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
......@@ -730,7 +652,6 @@ describeWithToken("formatting > sandboxes", () => {
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[ORDERS_ID]: { query: "segmented", read: "all" },
[PRODUCTS_ID]: "all",
},
},
......@@ -762,39 +683,20 @@ describeWithToken("formatting > sandboxes", () => {
});
}
cy.log("Sandbox `Orders` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
user_id: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
table_id: ORDERS_ID,
group_id: COLLECTION_GROUP,
});
cy.log("Sandbox `Products` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PRODUCTS_ID,
attribute_remappings: {
user_cat: ["dimension", ["field-id", PRODUCTS.CATEGORY]],
},
card_id: null,
table_id: PRODUCTS_ID,
group_id: COLLECTION_GROUP,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: { query: "segmented", read: "all" },
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
cy.log("Create question with joins");
cy.createQuestion({
name: QUESTION_NAME,
query: {
......@@ -911,33 +813,18 @@ describeWithToken("formatting > sandboxes", () => {
cy.server();
cy.route("POST", "/api/dataset").as("dataset");
cy.log("Sandbox `Orders` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
table_id: ORDERS_ID,
group_id: COLLECTION_GROUP,
});
cy.log("Sandbox `Products` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PRODUCTS_ID,
attribute_remappings: {
[ATTR_CAT]: ["dimension", ["field-id", PRODUCTS.CATEGORY]],
},
card_id: null,
table_id: PRODUCTS_ID,
group_id: COLLECTION_GROUP,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: { query: "segmented", read: "all" },
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
signOut();
......@@ -970,44 +857,25 @@ describeWithToken("formatting > sandboxes", () => {
});
it("should work with pivot tables (metabase#14969)", () => {
cy.log("Sandbox `Orders` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
table_id: ORDERS_ID,
group_id: COLLECTION_GROUP,
});
cy.log("**-- 2. Sandbox `People` table --**");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PEOPLE_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", PEOPLE.ID]],
},
card_id: null,
table_id: PEOPLE_ID,
group_id: COLLECTION_GROUP,
});
cy.log("**-- 3. Sandbox `Products` table --**");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PRODUCTS_ID,
attribute_remappings: {
[ATTR_CAT]: ["dimension", ["field-id", PRODUCTS.CATEGORY]],
},
card_id: null,
table_id: PRODUCTS_ID,
group_id: COLLECTION_GROUP,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[PRODUCTS_ID]: { query: "segmented", read: "all" },
[ORDERS_ID]: { query: "segmented", read: "all" },
[PEOPLE_ID]: { query: "segmented", read: "all" },
},
},
});
cy.request("POST", "/api/card/", {
......@@ -1063,23 +931,13 @@ describeWithToken("formatting > sandboxes", () => {
});
it.skip("should show dashboard subscriptions for sandboxed user (metabase#14990)", () => {
cy.log("Sandbox `Orders` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: ORDERS_ID,
attribute_remappings: {
[ATTR_UID]: ["dimension", ["field-id", ORDERS.USER_ID]],
},
card_id: null,
table_id: ORDERS_ID,
group_id: COLLECTION_GROUP,
});
cy.updatePermissionsSchemas({
schemas: {
PUBLIC: {
[ORDERS_ID]: { query: "segmented", read: "all" },
},
},
});
signInAsSandboxedUser();
cy.visit("/dashboard/1");
cy.icon("share").click();
......
......@@ -94,7 +94,6 @@ Cypress.Commands.add(
throw new Error("`schemas` must be an object!");
}
cy.log("Fetch permissions graph");
cy.request("GET", "/api/permissions/graph").then(
({ body: { groups, revision } }) => {
const UPDATED_GROUPS = Object.assign(groups, {
......@@ -134,6 +133,42 @@ Cypress.Commands.add("updateCollectionGraph", (groupsCollectionObject = {}) => {
);
});
Cypress.Commands.add(
"sandboxTable",
({
attribute_remappings = {},
card_id = null,
group_id = 4,
table_id = 2,
} = {}) => {
// Extract the name of the table, as well as `schema` and `db_id` that we'll need later on for `cy.updatePermissionsSchemas()`
cy.request("GET", "/api/table").then(({ body: tables }) => {
const { name, schema, db_id } = tables.find(
table => table.id === table_id,
);
const attr = Object.keys(attribute_remappings).join(", "); // Account for the possiblity of passing multiple user attributes
cy.log(`Sandbox "${name}" table on "${attr}"`);
cy.request("POST", "/api/mt/gtap", {
attribute_remappings,
card_id,
group_id,
table_id,
});
cy.updatePermissionsSchemas({
schemas: {
[schema]: {
[table_id]: { query: "segmented", read: "all" },
},
},
user_group: group_id,
database_id: db_id,
});
});
},
);
/**
* OVERWRITES
*/
......
......@@ -79,23 +79,11 @@ describeWithToken("postgres > user > query", () => {
cy.server();
cy.route("POST", `/api/card/${QUESTION_ID}/query`).as("cardQuery");
cy.log("Sandbox `People` table");
cy.request("POST", "/api/mt/gtap", {
cy.sandboxTable({
table_id: PEOPLE_ID,
attribute_remappings: {
user_id: ["dimension", ["field-id", PEOPLE.ID]],
},
card_id: null,
table_id: PEOPLE_ID,
group_id: COLLECTION_GROUP,
});
cy.updatePermissionsSchemas({
database_id: PG_DB_ID,
schemas: {
public: {
[PEOPLE_ID]: { query: "segmented", read: "all" },
},
},
});
signOut();
......
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