Skip to content
This repository has been archived by the owner on Aug 1, 2022. It is now read-only.

Commit

Permalink
feat(ui): network page (#2066)
Browse files Browse the repository at this point in the history
* network page
* remove from settings
* add network status to network page
* refactor to improve code structure
* add license
* fixes based on review
* fixing part of the tests
* change copy
* Fix specs

Signed-off-by: Rūdolfs Ošiņš <rudolfs@osins.org>
Co-authored-by: Rūdolfs Ošiņš <rudolfs@osins.org>
  • Loading branch information
juliendonck and rudolfs committed Jun 29, 2021
1 parent c1ede48 commit 8b1836c
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 262 deletions.
88 changes: 88 additions & 0 deletions cypress/integration/networking.spec.ts
Expand Up @@ -9,6 +9,9 @@ import * as path from "path";
import * as ipcStub from "../support/ipc-stub";
import * as nodeManager from "../support/nodeManager";

const validSeedAddress =
"hyy5s7ysg96fqa91gbe7h38yddh4mkokft7y4htt8szt9e17sxoe3h@seed.my.org:123";

context("p2p networking", () => {
context("network status indicator", () => {
it(
Expand Down Expand Up @@ -253,4 +256,89 @@ context("p2p networking", () => {
});
}
);

context("network", () => {
beforeEach(() => {
commands.resetProxyState();
commands.onboardUser();
cy.visit("public/index.html");
commands.pick("sidebar", "network").click();
});

it("validates the seed input", () => {
cy.log("checks the format");
commands.pasteInto(["seed-input"], "invalid-seed@seed.my.org:123");
commands.pick("add-seed").click();
commands
.pick("seed-entry-form")
.should("contain", "This is not a valid seed address");
cy.get(".seeds").find(".seed").should("have.length", 0);

cy.log("checks for duplication");
commands.pasteInto(["seed-input"], validSeedAddress);
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 1);
// add the same seed again
commands.pasteInto(["seed-input"], validSeedAddress);
commands.pick("add-seed").click();
commands
.pick("seed-entry-form")
.should("contain", "This seed already exists");
cy.get(".seeds").find(".seed").should("have.length", 1);
});

it("adds and removes seeds", () => {
cy.get(".seeds").find(".seed").should("have.length", 0);
commands.pasteInto(["seed-input"], validSeedAddress);

cy.log("adds a seed via button click");
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 1);

cy.log("persists adding a seed across app start");
commands.restartAndUnlock();
commands.pick("sidebar", "network").click();
cy.get(".seeds").find(".seed").should("have.length", 1);

cy.log("adds a seed via button click");
commands.pasteInto(["seed-input"], `${validSeedAddress}2`);
commands.pick("seed-input").type("{enter}");
cy.get(".seeds").find(".seed").should("have.length", 2);

cy.log("adds new seeds to the end of the list");
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}2`);
commands.pasteInto(["seed-input"], `${validSeedAddress}3`);
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 3);
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}3`);

cy.log("can delete seeds and persist the lists order");
cy.get(".seeds")
.find(".seed")
.eq(1)
.within(() => {
commands.pick("remove-seed").click();
});
cy.get(".seeds").find(".seed").should("have.length", 2);
cy.get(".seeds")
.find(".seed")
.first()
.should("contain", `${validSeedAddress}`);
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}3`);

cy.log("persists the removal across app start");
commands.restartAndUnlock();
commands.pick("sidebar", "network").click();
cy.get(".seeds").find(".seed").should("have.length", 2);
});
});
});
80 changes: 0 additions & 80 deletions cypress/integration/settings.spec.ts
Expand Up @@ -7,8 +7,6 @@
import * as commands from "../support/commands";
import * as ipcStub from "../support/ipc-stub";
import type { CyHttpMessages } from "cypress/types/net-stubbing";
const validSeedAddress =
"hyy5s7ysg96fqa91gbe7h38yddh4mkokft7y4htt8szt9e17sxoe3h@seed.my.org:123";

context("settings", () => {
beforeEach(() => {
Expand Down Expand Up @@ -42,84 +40,6 @@ context("settings", () => {
});
});

context("network", () => {
it("validates the seed input", () => {
cy.log("checks the format");
commands.pasteInto(["seed-input"], "invalid-seed@seed.my.org:123");
commands.pick("add-seed").click();
commands
.pick("seed-entry-form")
.should("contain", "This is not a valid seed address");
cy.get(".seeds").find(".seed").should("have.length", 0);

cy.log("checks for duplication");
commands.pasteInto(["seed-input"], validSeedAddress);
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 1);
// add the same seed again
commands.pasteInto(["seed-input"], validSeedAddress);
commands.pick("add-seed").click();
commands
.pick("seed-entry-form")
.should("contain", "This seed already exists");
cy.get(".seeds").find(".seed").should("have.length", 1);
});

it("adds and removes seeds", () => {
cy.get(".seeds").find(".seed").should("have.length", 0);
commands.pasteInto(["seed-input"], validSeedAddress);

cy.log("adds a seed via button click");
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 1);

cy.log("persists adding a seed across app start");
commands.restartAndUnlock();
commands.pick("sidebar", "settings").click();
cy.get(".seeds").find(".seed").should("have.length", 1);

cy.log("adds a seed via button click");
commands.pasteInto(["seed-input"], `${validSeedAddress}2`);
commands.pick("seed-input").type("{enter}");
cy.get(".seeds").find(".seed").should("have.length", 2);

cy.log("adds new seeds to the end of the list");
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}2`);
commands.pasteInto(["seed-input"], `${validSeedAddress}3`);
commands.pick("add-seed").click();
cy.get(".seeds").find(".seed").should("have.length", 3);
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}3`);

cy.log("can delete seeds and persist the lists order");
cy.get(".seeds")
.find(".seed")
.eq(1)
.within(() => {
commands.pick("remove-seed").click();
});
cy.get(".seeds").find(".seed").should("have.length", 2);
cy.get(".seeds")
.find(".seed")
.first()
.should("contain", `${validSeedAddress}`);
cy.get(".seeds")
.find(".seed")
.last()
.should("contain", `${validSeedAddress}3`);

cy.log("persists the removal across app start");
commands.restartAndUnlock();
commands.pick("sidebar", "settings").click();
cy.get(".seeds").find(".seed").should("have.length", 2);
});
});

context("app version", () => {
// Set `ui/src/updateChecker` for these constants.
const VERSION_CHECK_INTERVAL = 1000;
Expand Down
3 changes: 3 additions & 0 deletions ui/App.svelte
Expand Up @@ -38,6 +38,7 @@
import Profile from "ui/Screen/Profile.svelte";
import UserProfile from "ui/Screen/UserProfile.svelte";
import Project from "ui/Screen/Project.svelte";
import Network from "ui/Screen/Network.svelte";
import Settings from "ui/Screen/Settings.svelte";
import Wallet from "ui/Screen/Wallet.svelte";
Expand Down Expand Up @@ -140,6 +141,8 @@
<Project
activeView={$activeRouteStore.activeView}
urn={$activeRouteStore.urn} />
{:else if $activeRouteStore.type === "network"}
<Network />
{:else if $activeRouteStore.type === "settings"}
<Settings />
{:else if $activeRouteStore.type === "wallet"}
Expand Down
81 changes: 17 additions & 64 deletions ui/DesignSystem/Sidebar/ConnectionStatusIndicator.svelte
Expand Up @@ -6,73 +6,26 @@
LICENSE file.
-->
<script lang="typescript">
import { status, StatusType } from "ui/src/localPeer";
import * as svelteStore from "svelte/store";
import Icon from "ui/DesignSystem/Icon";
import Tooltip from "ui/DesignSystem/Tooltip.svelte";
import Syncing from "./ConnectionStatusIndicator/Syncing.svelte";
import Offline from "./ConnectionStatusIndicator/Offline.svelte";
import { activeRouteStore, push } from "ui/src/router";
import { status } from "ui/src/localPeer";
import { indicatorState } from "ui/src/network";
const connectedPeerCount = (peers: {
[peerId: string]: string[];
}): string => {
const count = Object.keys(peers).length;
return peerCount(count);
};
import Tooltip from "ui/DesignSystem/Tooltip.svelte";
import SidebarItem from "ui/DesignSystem/Sidebar/SidebarItem.svelte";
const peerCount = (count: number) => {
if (count === 1) {
return "1 peer";
} else {
return `${count} peers`;
}
};
const indicatorStatus = svelteStore.derived(status, indicatorState);
</script>

<style>
.item {
width: var(--sidebar-width);
height: 32px;
margin-bottom: 16px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
cursor: help;
}
</style>

<div>
{#if $status.type === StatusType.Online}
<Tooltip
value={`Network • You’re connected to ${connectedPeerCount(
$status.connectedPeers
)}`}>
<div class="item" data-cy="connection-status-online">
<Icon.Network />
</div>
</Tooltip>
{:else if $status.type === StatusType.Syncing}
<Tooltip
value={`Network • Syncing with ${peerCount(
$status.syncs
)} to get new content from your network`}>
<div class="item" data-cy="connection-status-syncing">
<Syncing />
</div>
</Tooltip>
{:else if $status.type === StatusType.Offline || $status.type === StatusType.Started}
<Tooltip value="Network • You’re not connected to any peers">
<div class="item" data-cy="connection-status-offline">
<Offline />
</div>
</Tooltip>
{:else if $status.type === StatusType.Stopped}
<Tooltip value="Network • The app couldn't start your peer">
<div class="item" data-cy="connection-status-stopped">
<Offline style="fill: var(--color-negative);" />
</div>
</Tooltip>
{/if}
<div data-cy="network">
<Tooltip value={$indicatorStatus.text}>
<SidebarItem
dataCy={$indicatorStatus.cy}
indicator
active={$activeRouteStore.type === "network"}
onClick={() => push({ type: "network" })}>
<svelte:component this={$indicatorStatus.icon} />
</SidebarItem>
</Tooltip>
</div>

0 comments on commit 8b1836c

Please sign in to comment.