Skip to content

Commit

Permalink
Merge branch 'main' into fix-community-width-for-posts
Browse files Browse the repository at this point in the history
  • Loading branch information
ailisp authored Dec 4, 2023
2 parents ba191a4 + 91d3bec commit b463e94
Show file tree
Hide file tree
Showing 16 changed files with 1,475 additions and 31 deletions.
27 changes: 27 additions & 0 deletions playwright-tests/storage-states/wallet-connected-admin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:8080",
"localStorage": [
{
"name": "near-wallet-selector:selectedWalletId",
"value": "near-wallet"
},
{
"name": "near_app_wallet_auth_key",
"value": "{\"accountId\":\"theori.near\"}"
},
{
"name": "near-social-vm:v01::accountId:",
"value": "theori.near"
},
{
"name": "flags",
"value": "{\"bosLoaderUrl\":\"http://127.0.0.1:3030\"}"
}
]
}
],
"sessionStorage": []
}
214 changes: 214 additions & 0 deletions playwright-tests/tests/admin.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { test, expect } from "@playwright/test";

test.describe("Wallet is connected", () => {
// sign in to wallet
test.use({
storageState: "playwright-tests/storage-states/wallet-connected-admin.json",
});

test("should be able to manage featured communities from home page settings tab", async ({
page,
}) => {
await page.goto("/devhub.near/widget/app?page=admin");

const buttonSelector = `button[data-testid="preview-homepage"]`;
// Wait for the first post history button to be visible
await page.waitForSelector(buttonSelector, {
state: "visible",
});

// Click on the first post history button
await page.getByPlaceholder("Community handle").nth(4).click();
await page
.getByPlaceholder("Community handle")
.nth(4)
.fill("thomasguntenaar");
await page.getByTestId("add-to-list").click();
await page.getByRole("button", { name: " Submit" }).click();
await page.getByText("Close").click();
await page.getByRole("button", { name: "" }).nth(3).click();
await page.getByRole("button", { name: " Submit" }).click();
await page.getByText("Can't set fewer than 4 communities").click();
await page
.getByText(
"NEAR BOS embeddable custom element /admin /communities /activity feed /about ↓ H"
)
.press("Escape");
await page.getByRole("button", { name: "Cancel" }).click();

await page.getByTestId("preview-homepage").click();
await page.getByRole("heading", { name: "/connect" }).click();
await page.getByTestId("preview-homepage").click();
});

test("should be able to manage moderators", async ({ page }) => {
await page.goto("/devhub.near/widget/app?page=admin");
const buttonSelector = `button[data-testid="preview-homepage"]`;
// Wait for the first post button to be visible
await page.waitForSelector(buttonSelector, {
state: "visible",
});

await page.getByRole("tab", { name: "Moderators" }).click();
await page.getByTestId("edit-members").click();
await page.locator("div:nth-child(9)").click();
await page
.locator(
"div:nth-child(9) > div > .d-flex > .input-group > .form-control"
)
.click();
await page
.locator(
"div:nth-child(9) > div > .d-flex > .input-group > .form-control"
)
.fill("thomasguntenaar.near");
await page.getByRole("button", { name: "" }).click();
await page.getByRole("button", { name: " Submit" }).click();
await page.getByText("Close").click();
await page.getByRole("button", { name: "Cancel" }).click();
await page.getByTestId("edit-members").click();
await page.locator("div:nth-child(9)").click();
await page.getByTestId("edit-members").click();
});

test("should be able to manage restricted labels", async ({ page }) => {
await page.goto("/devhub.near/widget/app?page=admin");
const buttonSelector = `button[data-testid="preview-homepage"]`;
// Wait for the first post button to be visible
await page.waitForSelector(buttonSelector, {
state: "visible",
});
await page.getByRole("tab", { name: "Restricted labels" }).click();
await page.getByTestId("create-team").click();
await page.getByRole("button", { name: "Cancel" }).click();
await page.getByTestId("create-team").click();
await page
.getByLabel("This team is allowed to edit-post with this / these labels")
.check();
await page
.getByLabel("Only this team and moderators are allowed to use this label")
.check();
await page.getByPlaceholder("Team name").click();
await page.getByPlaceholder("Team name").fill("tom");
await page.getByPlaceholder("Team name").press("Tab");
await page.getByLabel("Select type").press("Tab");
await page.getByPlaceholder("label").fill("thom");
await page.getByPlaceholder("label").press("Tab");
await page
.getByLabel("This team is allowed to edit-post with this / these labels")
.press("Tab");
await page
.getByLabel("Only this team and moderators are allowed to use this label")
.press("Tab");
await page.getByPlaceholder("member").fill("tom.near");
await page.getByRole("button", { name: "" }).click();
await page.getByRole("button", { name: " Submit" }).click();
await page.getByLabel("Close").click();
await page
.getByRole("row", {
name: "mnw Multiple labels with common prefix No members in this group  Edit",
})
.getByRole("button")
.click();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  Cancel  Submit",
})
.getByPlaceholder("member")
.click();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  Cancel  Submit",
})
.getByPlaceholder("member")
.fill("thomas.near");
await page.getByRole("table").getByRole("button", { name: "" }).click();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByLabel("This team is allowed to edit-post with this / these labels")
.uncheck();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByLabel("This team is allowed to edit-post with this / these labels")
.uncheck();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByLabel("Only this team and moderators are allowed to use this label")
.uncheck();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByPlaceholder("label")
.click();
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByPlaceholder("Team name")
.click({
clickCount: 3,
});
await page
.getByRole("rowheader", {
name: "Create label Group name Team name Would you like this group to limit their restrictions to a single label, or would you prefer them to restrict it with any label that follows a similar convention? Select type What would you like the restricted label to be? starts-with: label Select label permissions This team is allowed to edit-post with this / these labels Only this team and moderators are allowed to use this label member member  member member  Cancel  Submit",
})
.getByPlaceholder("Team name")
.fill("new-group-name");
await page
.getByRole("table")
.getByRole("button", { name: " Submit" })
.click();
await page.getByLabel("Close").click();
});

test("shouldn't be able to add a none existing community handle without a warning", async ({
page,
}) => {
await page.goto("/devhub.near/widget/app?page=admin");
const buttonSelector = `button[data-testid="preview-homepage"]`;
// Wait for the first post button to be visible
await page.waitForSelector(buttonSelector, {
state: "visible",
});
await page.getByPlaceholder("Community handle").nth(4).click();
await page
.getByPlaceholder("Community handle")
.nth(4)
.fill("arandomnonsensehandlethatwouldnotexist");
await page.getByTestId("add-to-list").click();
await page.getByTestId("add-to-list").click();
await page
.getByText(
"This community handle does not exist, make sure you use an existing handle."
)
.click();
});
});

test.describe("Wallet is not connect", () => {
test.use({
storageState: "playwright-tests/storage-states/wallet-not-connected.json",
});
test("should show banner that the user doesn't have access", async ({
page,
}) => {
await page.goto("/devhub.near/widget/app?page=admin");
const buttonSelector = "h2.alert.alert-danger";
// Wait for the first post history button to be visible

const banner = await page.waitForSelector(buttonSelector, {
state: "visible",
});
const bannerText = await banner.textContent();
expect(bannerText.trim()).toBe(
"Your account does not have administration permissions."
);
});
});
9 changes: 8 additions & 1 deletion src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,14 @@ function Page() {
/>
);
}

case "admin": {
return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.page.admin.index"}
props={passProps}
/>
);
}
default: {
// TODO: 404 page
return <p>404</p>;
Expand Down
12 changes: 12 additions & 0 deletions src/core/adapter/devhub-contract.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ function getRootMembers() {
return Near.view("${REPL_DEVHUB_CONTRACT}", "get_root_members") ?? null;
}

function removeMember(member) {
return Near.call("${REPL_DEVHUB_CONTRACT}", "remove_member", { member });
}

function hasModerator({ account_id }) {
return (
Near.view("${REPL_DEVHUB_CONTRACT}", "has_moderator", { account_id }) ??
Expand All @@ -25,6 +29,12 @@ function getFeaturedCommunities() {
);
}

function setFeaturedCommunities({ handles }) {
return Near.call("${REPL_DEVHUB_CONTRACT}", "set_featured_communities", {
handles,
});
}

function getAccountCommunityPermissions({ account_id, community_handle }) {
return (
Near.view("${REPL_DEVHUB_CONTRACT}", "get_account_community_permissions", {
Expand Down Expand Up @@ -213,10 +223,12 @@ function useQuery(name, params) {

return {
getRootMembers,
removeMember,
hasModerator,
createCommunity,
getCommunity,
getFeaturedCommunities,
setFeaturedCommunities,
getAccountCommunityPermissions,
updateCommunity,
deleteCommunity,
Expand Down
15 changes: 15 additions & 0 deletions src/devhub/components/atom/Alert.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const Alert = ({ onClose, message }) =>
message && (
<div class="alert alert-warning alert-dismissible fade show" role="alert">
{message}
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
onClick={onClose}
></button>
</div>
);

return Alert(props);
44 changes: 17 additions & 27 deletions src/devhub/components/island/connect.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
const { getFeaturedCommunities } = VM.require(
"${REPL_DEVHUB}/widget/core.adapter.devhub-contract"
);

if (!getFeaturedCommunities) {
return <p>Loading modules...</p>;
}

const communities = getFeaturedCommunities();

const [startIndex, setStartIndex] = useState(0);
const [endIndex, setEndIndex] = useState(2);

Expand Down Expand Up @@ -88,33 +98,13 @@ const Card = ({ title, description, href }) => {
);
};

const Cards = [
{
title: "DevHub Hacks",
description: "Host and support developer focused events around the globe.",
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=hacks",
},
{
title: "NEAR Platform Fellowship",
description: "Improve the NEAR dev experience with guidance & funding.",
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=fellowship",
},
{
title: "Protocol",
description: "Support the ongoing innovation of the NEAR protocol.",
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=protocol",
},
{
title: "Zero Knowledge",
description: "Build a Zero Knowledge ecosystem on NEAR.",
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=zero-knowledge",
},
{
title: "Contract Standards",
description: "Coordinate the contribution to the NEAR dapp standards.",
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=contract-standards",
},
];
const Cards = communities.map((com) => {
return {
title: com.name,
description: com.description,
href: "/${REPL_DEVHUB}/widget/app?page=community&handle=" + com.handle,
};
});

const ForwardButton = styled.button`
all: unset;
Expand Down
Loading

0 comments on commit b463e94

Please sign in to comment.