Skip to content

Commit

Permalink
EVG-20177: Show Admin button to EVG admins (evergreen-ci#2035)
Browse files Browse the repository at this point in the history
  • Loading branch information
SupaJoon authored Sep 18, 2023
1 parent 34da89a commit f14f680
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 24 deletions.
2 changes: 2 additions & 0 deletions cypress/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const EVG_BASE_URL = "http://localhost:9090";
export const GQL_URL = `${EVG_BASE_URL}/graphql/query`;
58 changes: 46 additions & 12 deletions cypress/integration/nav_bar.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EVG_BASE_URL } from "../constants";

const PATCH_ID = "5e4ff3abe3c3317e352062e4";
const USER_ID = "admin";
const SPRUCE_URLS = {
Expand All @@ -6,19 +8,22 @@ const SPRUCE_URLS = {
cli: `/preferences/cli`,
};
const LEGACY_URLS = {
version: `/version/${PATCH_ID}`,
userPatches: `/patches/user/${USER_ID}`,
distros: `/distros`,
version: `${EVG_BASE_URL}/version/${PATCH_ID}`,
userPatches: `${EVG_BASE_URL}/patches/user/${USER_ID}`,
distros: `${EVG_BASE_URL}/distros`,
admin: `${EVG_BASE_URL}/admin`,
};
describe("Nav Bar", () => {
const projectCookie = "mci-project-cookie";

it("Should have a nav bar linking to the proper page on the legacy UI", () => {
cy.visit(SPRUCE_URLS.version);
cy.dataCy("legacy-ui-link").should("exist");
cy.dataCy("legacy-ui-link")
.should("have.attr", "href")
.and("include", LEGACY_URLS.version);
cy.dataCy("legacy-ui-link").should(
"have.attr",
"href",
LEGACY_URLS.version
);
});
it("Navigating to a different page should change the nav link to the legacy UI", () => {
cy.visit(SPRUCE_URLS.version);
Expand All @@ -28,9 +33,11 @@ describe("Nav Bar", () => {
.and("include", LEGACY_URLS.version);
cy.visit(SPRUCE_URLS.userPatches);
cy.dataCy("legacy-ui-link").should("exist");
cy.dataCy("legacy-ui-link")
.should("have.attr", "href")
.and("include", LEGACY_URLS.userPatches);
cy.dataCy("legacy-ui-link").should(
"have.attr",
"href",
LEGACY_URLS.userPatches
);
});
it("Visiting a page with no legacy equivalent should not display a nav link", () => {
cy.visit(SPRUCE_URLS.cli);
Expand All @@ -41,9 +48,7 @@ describe("Nav Bar", () => {
cy.dataCy("legacy_route").should("not.exist");
cy.dataCy("auxiliary-dropdown-link").click();
cy.dataCy("legacy_route").should("exist");
cy.dataCy("legacy_route")
.should("have.attr", "href")
.and("include", LEGACY_URLS.distros);
cy.dataCy("legacy_route").should("have.attr", "href", LEGACY_URLS.distros);
});
it("Nav Dropdown should link to patches page of most recent project if cookie exists", () => {
cy.setCookie(projectCookie, "spruce");
Expand Down Expand Up @@ -100,4 +105,33 @@ describe("Nav Bar", () => {
);
cy.getCookie(projectCookie).should("have.property", "value", "spruce");
});

describe("Admin settings", () => {
it("Should not show Admin button to non-admins", () => {
const userData = {
data: {
user: {
userId: "admin",
displayName: "Evergreen Admin",
emailAddress: "[email protected]",
permissions: {
canEditAdminSettings: false,
},
},
},
};
cy.overwriteGQL("User", userData);
cy.visit(SPRUCE_URLS.version);
cy.dataCy("user-dropdown-link").click();
cy.dataCy("admin-link").should("not.exist");
});

it("Should show Admin button to admins", () => {
cy.visit(SPRUCE_URLS.version);
cy.dataCy("user-dropdown-link").click();
cy.dataCy("admin-link")
.should("be.visible")
.should("have.attr", "href", LEGACY_URLS.admin);
});
});
});
2 changes: 1 addition & 1 deletion cypress/integration/version/action_buttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe("Action Buttons", () => {
it("Clicking 'Set Priority' button shows popconfirm with input and toast on success", () => {
const priority = "99";
cy.dataCy("prioritize-patch").click();
cy.dataCy("patch-priority-input").type(priority).type("{enter}");
cy.dataCy("patch-priority-input").type(`${priority}{enter}`);
cy.validateToast("success", priority);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { hasOperationName, GQL_URL } from "../../../utils/graphql-test-utils";
import { GQL_URL } from "../../../constants";
import { hasOperationName } from "../../../utils/graphql-test-utils";
import { mockErrorResponse } from "../../../utils/mockErrorResponse";

describe("Configure Patch Page", () => {
Expand Down
17 changes: 15 additions & 2 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { EVG_BASE_URL, GQL_URL } from "../constants";
import { hasOperationName } from "../utils/graphql-test-utils";

const user = {
username: "admin",
password: "password",
Expand Down Expand Up @@ -61,14 +64,14 @@ Cypress.Commands.add("getInputByLabel", (label: string) => {
Cypress.Commands.add("login", () => {
cy.getCookie("mci-token").then((c) => {
if (!c) {
cy.request("POST", "http://localhost:9090/login", { ...user });
cy.request("POST", `${EVG_BASE_URL}/login`, { ...user });
}
});
});

/* logout */
Cypress.Commands.add("logout", () => {
cy.origin("http://localhost:9090", () => {
cy.origin(EVG_BASE_URL, () => {
cy.request({ url: "/logout", followRedirect: false });
});
});
Expand Down Expand Up @@ -113,3 +116,13 @@ Cypress.Commands.add(
});
}
);

Cypress.Commands.add("overwriteGQL", (operationName: string, body: any) => {
cy.intercept("POST", GQL_URL, (req) => {
if (hasOperationName(req, operationName)) {
req.reply((res) => {
res.body = body;
});
}
});
});
6 changes: 6 additions & 0 deletions cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ declare global {
message?: string,
shouldClose?: boolean
): void;
/**
* Custom command to overwrite a GQL response
* @param operationName - The operation name of the query
* @param body - The replacement response body
*/
overwriteGQL(operationName: string, body: any);
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions cypress/utils/graphql-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,3 @@ export const aliasMutation = (
req.alias = `gql${operationName}Mutation`;
}
};

export const GQL_URL = "http://localhost:9090/graphql/query";
3 changes: 2 additions & 1 deletion cypress/utils/mockErrorResponse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GQL_URL, hasOperationName } from "./graphql-test-utils";
import { hasOperationName } from "./graphql-test-utils";
import { GQL_URL } from "../constants";

interface Args {
errorMessage: string;
Expand Down
1 change: 1 addition & 0 deletions src/analytics/navbar/useNavbarAnalytics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useAnalyticsRoot } from "analytics/useAnalyticsRoot";

type Action =
| { name: "Click Admin Link" }
| { name: "Click Legacy UI Link" }
| { name: "Click Logo Link" }
| { name: "Click Waterfall Link" }
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/NavDropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const NavDropdownMenuIcon: React.FC<{ open: boolean }> = ({ open }) => (
<Icon glyph={open ? "CaretUp" : "CaretDown"} role="presentation" />
);

interface MenuItemType {
export interface MenuItemType {
"data-cy"?: string;
text: string;
href?: string;
Expand Down
16 changes: 12 additions & 4 deletions src/components/Header/UserDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { useQuery } from "@apollo/client";
import { useNavbarAnalytics } from "analytics";
import { adminSettingsURL } from "constants/externalResources";
import { PreferencesTabRoutes, getPreferencesRoute } from "constants/routes";
import { useAuthDispatchContext } from "context/auth";
import { UserQuery } from "gql/generated/types";
import { GET_USER } from "gql/queries";
import { NavDropdown } from "./NavDropdown";
import { MenuItemType, NavDropdown } from "./NavDropdown";

export const UserDropdown = () => {
const { data } = useQuery<UserQuery>(GET_USER);
const { user } = data || {};
const { displayName } = user || {};
const { displayName, permissions } = user || {};

const { logoutAndRedirect } = useAuthDispatchContext();
const { sendEvent } = useNavbarAnalytics();

const menuItems = [
const menuItems: MenuItemType[] = [
{
text: "Preferences",
to: getPreferencesRoute(PreferencesTabRoutes.Profile),
Expand All @@ -31,7 +32,14 @@ export const UserDropdown = () => {
onClick: () => logoutAndRedirect(),
},
];

if (permissions?.canEditAdminSettings) {
menuItems.splice(1, 0, {
"data-cy": "admin-link",
text: "Admin",
href: adminSettingsURL,
onClick: () => sendEvent({ name: "Click Admin Link" }),
});
}
return (
<NavDropdown
dataCy="user-dropdown-link"
Expand Down
2 changes: 2 additions & 0 deletions src/constants/externalResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@ export const getHoneycombSystemMetricsUrl = (
query
)}&omitMissingValues`;
};

export const adminSettingsURL = `${getUiUrl()}/admin`;
2 changes: 2 additions & 0 deletions src/gql/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,7 @@ export type Permissions = {
__typename?: "Permissions";
canCreateDistro: Scalars["Boolean"]["output"];
canCreateProject: Scalars["Boolean"]["output"];
canEditAdminSettings: Scalars["Boolean"]["output"];
distroPermissions: DistroPermissions;
userId: Scalars["String"]["output"];
};
Expand Down Expand Up @@ -8314,6 +8315,7 @@ export type UserQuery = {
displayName: string;
emailAddress: string;
userId: string;
permissions: { __typename?: "Permissions"; canEditAdminSettings: boolean };
};
};

Expand Down
3 changes: 3 additions & 0 deletions src/gql/mocks/getUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export const getUserMock: ApolloMock<UserQuery, UserQueryVariables> = {
userId: "admin",
displayName: "Evergreen Admin",
emailAddress: "[email protected]",
permissions: {
canEditAdminSettings: true,
},
},
},
},
Expand Down
3 changes: 3 additions & 0 deletions src/gql/queries/get-user.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ query User {
user {
displayName
emailAddress
permissions {
canEditAdminSettings
}
userId
}
}

0 comments on commit f14f680

Please sign in to comment.