mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-01 09:40:28 +08:00
Improve testing suite
Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
name: check-integration-test
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
cypress-run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v2
|
||||
with:
|
||||
browser: chrome
|
||||
start: npm start
|
||||
wait-on: 'http://localhost:3000'
|
||||
command: npm run test:e2e
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: check-components
|
||||
name: check-unit-test
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
@@ -10,5 +10,5 @@ jobs:
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: npm ci
|
||||
- run: ./scripts/test
|
||||
- run: ./scripts/unit-test
|
||||
shell: bash
|
||||
@@ -5,3 +5,6 @@ NOTES
|
||||
# Coverage
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
# Integration Tests
|
||||
cypress/screenshots
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"heads": {
|
||||
"master": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
|
||||
"main": "56e4e029c294b08546386e1fb706b772c7433c49"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"header": {
|
||||
"sha1": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
|
||||
"author": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"summary": "initial commit",
|
||||
"description": "this is the first commit of many",
|
||||
"committer": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"committerTime": 1646236685
|
||||
},
|
||||
"stats": {
|
||||
"additions": 0,
|
||||
"deletions": 0
|
||||
},
|
||||
"diff": {
|
||||
"created": [
|
||||
"README.md"
|
||||
],
|
||||
"deleted": [
|
||||
"LICENSE"
|
||||
],
|
||||
"moved": [],
|
||||
"copied": [],
|
||||
"modified": [
|
||||
{
|
||||
"path": "foo.bar",
|
||||
"diff": {
|
||||
"type": "plain",
|
||||
"hunks": [
|
||||
{
|
||||
"header": "@@ -13,7 +13,11 @@ If executed, this proposal will:\n",
|
||||
"lines": [
|
||||
{
|
||||
"type": "context",
|
||||
"line": "\n",
|
||||
"lineNumOld": 13,
|
||||
"lineNumNew": 13
|
||||
},
|
||||
{
|
||||
"type": "context",
|
||||
"line": "After execution, the Timelock holds all Uniswap LP tokens for the RAD/USDC pair.\n",
|
||||
"lineNumOld": 14,
|
||||
"lineNumNew": 14
|
||||
},
|
||||
{
|
||||
"type": "context",
|
||||
"line": "\n",
|
||||
"lineNumOld": 15,
|
||||
"lineNumNew": 15
|
||||
},
|
||||
{
|
||||
"type": "deletion",
|
||||
"line": "To prevent front-running, the RAD/USDC balances are set through the Uniswap router *proxy* contract, deployed at `0xB76FC4EbE4fC0CC34AF440Ad79565A68Bfcb095e`. Only the Radicle Foundation can set these balances, via the `setLiquidity` function. This contract function must be called as close as possible to the execution of this proposal, to provide liquidity at the correct market price.\n",
|
||||
"lineNum": 16
|
||||
},
|
||||
{
|
||||
"type": "addition",
|
||||
"line": "To prevent front-running, the RAD/USDC balances are set through the Uniswap\n",
|
||||
"lineNum": 16
|
||||
},
|
||||
{
|
||||
"type": "addition",
|
||||
"line": "router *proxy* contract, deployed at `0xB76FC4EbE4fC0CC34AF440Ad79565A68Bfcb095e`.\n",
|
||||
"lineNum": 17
|
||||
},
|
||||
{
|
||||
"type": "addition",
|
||||
"line": "Only the Radicle Foundation can set these balances, via the `setLiquidity`\n",
|
||||
"lineNum": 18
|
||||
},
|
||||
{
|
||||
"type": "addition",
|
||||
"line": "function. This contract function must be called as close as possible to the\n",
|
||||
"lineNum": 19
|
||||
},
|
||||
{
|
||||
"type": "addition",
|
||||
"line": "execution of this proposal, to provide liquidity at the correct market price.\n",
|
||||
"lineNum": 20
|
||||
},
|
||||
{
|
||||
"type": "context",
|
||||
"line": "\n",
|
||||
"lineNumOld": 17,
|
||||
"lineNumNew": 21
|
||||
},
|
||||
{
|
||||
"type": "context",
|
||||
"line": "## Notes\n",
|
||||
"lineNumOld": 18,
|
||||
"lineNumNew": 22
|
||||
},
|
||||
{
|
||||
"type": "context",
|
||||
"line": "\n",
|
||||
"lineNumOld": 19,
|
||||
"lineNumNew": 23
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"branches": [
|
||||
"main",
|
||||
"master"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"headers": [
|
||||
{
|
||||
"sha1": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
|
||||
"author": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"summary": "initial commit",
|
||||
"description": "",
|
||||
"committer": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"committerTime": 1646236685
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"commits": 1,
|
||||
"branches": 1,
|
||||
"contributors": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"message": "Welcome!",
|
||||
"service": "radicle-http-api",
|
||||
"version": "0.2.0",
|
||||
"path": "/",
|
||||
"links": [
|
||||
{
|
||||
"href": "/v1/projects",
|
||||
"rel": "projects",
|
||||
"type": "GET"
|
||||
},
|
||||
{
|
||||
"href": "/v1/peer",
|
||||
"rel": "peer",
|
||||
"type": "GET"
|
||||
},
|
||||
{
|
||||
"href": "/v1/delegates/:urn/projects",
|
||||
"rel": "projects",
|
||||
"type": "GET"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"urn": "rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy",
|
||||
"name": "bright-forest-protocol",
|
||||
"description": "bfc-sc",
|
||||
"defaultBranch": "main",
|
||||
"delegates": [
|
||||
{
|
||||
"type": "indirect",
|
||||
"urn": "rad:git:hnrkqz68g6nddigodpgjmc1u8ydpzb8fqq8ro",
|
||||
"ids": [
|
||||
"hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke"
|
||||
]
|
||||
}
|
||||
],
|
||||
"head": "56e4e029c294b08546386e1fb706b772c7433c49"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
[{
|
||||
"urn": "rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy",
|
||||
"name": "mocked-seed-protocol",
|
||||
"description": "bfc-sc",
|
||||
"defaultBranch": "main",
|
||||
"delegates": [
|
||||
{
|
||||
"type": "indirect",
|
||||
"urn": "rad:git:hnrkqz68g6nddigodpgjmc1u8ydpzb8fqq8ro",
|
||||
"ids": [
|
||||
"hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke"
|
||||
]
|
||||
}
|
||||
],
|
||||
"head": "56e4e029c294b08546386e1fb706b772c7433c49"
|
||||
}]
|
||||
@@ -0,0 +1 @@
|
||||
{ "id": "hyy841u4phudmr8s5rg1jjwd1ct7x7438wmjwtsm464y8uyxyhyi6c" }
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"binary": false,
|
||||
"html": false,
|
||||
"content": "# Basic Sample Hardhat Project\n\nThis project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.\n\nTry running some of the following tasks:\n\n```shell\nnpx hardhat accounts\nnpx hardhat compile\nnpx hardhat clean\nnpx hardhat test\nnpx hardhat node\nnode scripts/sample-script.js\nnpx hardhat help\n```\n",
|
||||
"info": {
|
||||
"name": "README.md",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": {
|
||||
"sha1": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
|
||||
"author": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"summary": "initial commit",
|
||||
"description": "",
|
||||
"committer": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"committerTime": 1646236685
|
||||
}
|
||||
},
|
||||
"path": "README.md"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"id": "hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke",
|
||||
"name": "dabit3",
|
||||
"delegate": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"path": "",
|
||||
"entries": [
|
||||
{
|
||||
"path": "contracts",
|
||||
"info": {
|
||||
"name": "contracts",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "scripts",
|
||||
"info": {
|
||||
"name": "scripts",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "test",
|
||||
"info": {
|
||||
"name": "test",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"info": {
|
||||
"name": ".gitignore",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"info": {
|
||||
"name": "README.md",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "hardhat.config.js",
|
||||
"info": {
|
||||
"name": "hardhat.config.js",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "package-lock.json",
|
||||
"info": {
|
||||
"name": "package-lock.json",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "package.json",
|
||||
"info": {
|
||||
"name": "package.json",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "yarn.lock",
|
||||
"info": {
|
||||
"name": "yarn.lock",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": {
|
||||
"sha1": "56e4e029c294b08546386e1fb706b772c7433c49",
|
||||
"author": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"summary": "emit event",
|
||||
"description": "",
|
||||
"committer": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"committerTime": 1646237176
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"commits": 3,
|
||||
"branches": 1,
|
||||
"contributors": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"path": "",
|
||||
"entries": [
|
||||
{
|
||||
"path": "contracts",
|
||||
"info": {
|
||||
"name": "contracts",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "scripts",
|
||||
"info": {
|
||||
"name": "scripts",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "test",
|
||||
"info": {
|
||||
"name": "test",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"info": {
|
||||
"name": ".gitignore",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"info": {
|
||||
"name": "README.md",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "hardhat.config.js",
|
||||
"info": {
|
||||
"name": "hardhat.config.js",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "package-lock.json",
|
||||
"info": {
|
||||
"name": "package-lock.json",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "package.json",
|
||||
"info": {
|
||||
"name": "package.json",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "yarn.lock",
|
||||
"info": {
|
||||
"name": "yarn.lock",
|
||||
"objectType": "BLOB",
|
||||
"lastCommit": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "",
|
||||
"objectType": "TREE",
|
||||
"lastCommit": {
|
||||
"sha1": "56e4e029c294b08546386e1fb706b772c7433c49",
|
||||
"author": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"summary": "emit event",
|
||||
"description": "",
|
||||
"committer": {
|
||||
"name": "dabit3",
|
||||
"email": "dabit3@gmail.com"
|
||||
},
|
||||
"committerTime": 1646237176
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"commits": 3,
|
||||
"branches": 1,
|
||||
"contributors": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/// <reference types="cypress" />
|
||||
import { MockExtensionProvider } from "../support";
|
||||
|
||||
describe("Landing page", () => {
|
||||
it("Loads user, orgs and seeds", () => {
|
||||
cy.intercept("https://willow.radicle.garden:8777/", { fixture: "projectHome.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/peer", { fixture: "projectPeer.json" });
|
||||
cy.intercept("https://pine.radicle.garden:8777/", { fixture: "projectHome.json" });
|
||||
cy.intercept("https://pine.radicle.garden:8777/v1/peer", { fixture: "projectPeer.json" });
|
||||
cy.intercept("https://maple.radicle.garden:8777/", { fixture: "projectHome.json" });
|
||||
cy.intercept("https://maple.radicle.garden:8777/v1/peer", { fixture: "projectPeer.json" });
|
||||
cy.intercept("https://gateway.thegraph.com/api/1758a78ae257ad4906f9c638e4a68c19/subgraphs/id/0x2f0963e77ca6ac0c2dad1bf4147b6b40e0dd8728-0", {
|
||||
"data": { "safe": null }
|
||||
});
|
||||
cy.intercept("https://maple.radicle.garden:8777/v1/projects", { fixture: "projectList.json" });
|
||||
cy.intercept("https://pine.radicle.garden:8777/v1/projects", { fixture: "projectList.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects", { fixture: "projectList.json" });
|
||||
cy.visit("/", {
|
||||
onBeforeLoad(win) {
|
||||
win.ethereum = new MockExtensionProvider();
|
||||
},
|
||||
});
|
||||
cy.get("div.card-label")
|
||||
.first()
|
||||
.should("have.text", "willow.radicle.garden")
|
||||
.next()
|
||||
.should("have.text", "1 project(s)");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/// <reference types="cypress" />
|
||||
import { MockExtensionProvider } from "../support";
|
||||
|
||||
describe("Project View", () => {
|
||||
before(() => {
|
||||
cy.intercept("https://willow.radicle.garden:8777/", { fixture: "projectHome.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/peer", { fixture: "projectPeer.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/bright-forest-protocol", { fixture: "projectInfo.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy", { fixture: "projectInfo.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes", { fixture: "projectRemotes.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/tree/56e4e029c294b08546386e1fb706b772c7433c49", { fixture: "projectTree56e4e02.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/tree/cbf5df499ab4f4a908f1756fbe2c236a4530516a", { fixture: "projectTreecbf5df4.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke", { fixture: "projectBranches.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/readme/56e4e029c294b08546386e1fb706b772c7433c49", { fixture: "projectReadme.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/commits?parent=cbf5df499ab4f4a908f1756fbe2c236a4530516a", { fixture: "projectCommits.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/readme/cbf5df499ab4f4a908f1756fbe2c236a4530516a", { fixture: "projectReadme.json" });
|
||||
cy.intercept("https://willow.radicle.garden:8777/v1/projects/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/commits/cbf5df499ab4f4a908f1756fbe2c236a4530516a", { fixture: "projectCommit.json" });
|
||||
});
|
||||
|
||||
it("Load project view and use peer and branch selector ", () => {
|
||||
cy.visit("/seeds/willow.radicle.garden/bright-forest-protocol", {
|
||||
onBeforeLoad(win) {
|
||||
win.ethereum = new MockExtensionProvider();
|
||||
},
|
||||
});
|
||||
|
||||
cy.log("Check that the project view is loaded and populated with the stubbed data");
|
||||
cy.log("Page Header");
|
||||
cy.get("div.title").contains("bright-forest-protocol");
|
||||
cy.get("div.urn").contains("rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy");
|
||||
cy.get("div.description").contains("bfc-sc");
|
||||
|
||||
cy.log("README");
|
||||
cy.get("div.column-right article div.markdown h1").should("have.text", "Basic Sample Hardhat Project");
|
||||
|
||||
cy.log("Project Header");
|
||||
cy.get("div.stat.seed span").should("have.text", "willow.radicle.garden");
|
||||
cy.get("div.stat.commit-count").should("have.text", "3 commit(s)");
|
||||
cy.get("div.stat.contributor-count").should("have.text", "1 contributor(s)");
|
||||
cy.get("div.anchor span.anchor-label").contains("not anchored 🔓");
|
||||
cy.get("div.stat.branch").should("have.class", "not-allowed").should("have.text", "main");
|
||||
cy.get("div.hash.desktop").should("have.text", "56e4e02");
|
||||
|
||||
cy.get("div.clone").click();
|
||||
|
||||
cy.log("Peer Selection");
|
||||
cy.get("div.selector").click();
|
||||
cy.get("div.dropdown-item").contains("dabit3 hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke delegate").click();
|
||||
cy.location().should((location) => {
|
||||
expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/tree');
|
||||
});
|
||||
cy.get("span.peer-id span[title='hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke']").should("have.text", "hyndc7…j9oeke");
|
||||
cy.get("div.stat.peer span.peer-id").should("have.text", "dabit3");
|
||||
cy.get("div.stat.peer span.badge").should("have.text", "delegate");
|
||||
|
||||
cy.log("Branch Selection");
|
||||
cy.get("div.commit div.stat.branch").click();
|
||||
cy.get("div.dropdown-item")
|
||||
.first()
|
||||
.contains("main")
|
||||
.next()
|
||||
.contains("master")
|
||||
.click();
|
||||
cy.location().should((location) => {
|
||||
expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/tree/master');
|
||||
});
|
||||
cy.get("div.stat.branch").should("have.text", "master");
|
||||
cy.get("div.hash.desktop").should("have.text", "cbf5df4");
|
||||
|
||||
cy.log("Commit history view");
|
||||
cy.get("div.stat.commit-count")
|
||||
.should("not.have.class", "active")
|
||||
.click();
|
||||
cy.location().should((location) => {
|
||||
expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/history/master');
|
||||
});
|
||||
cy.get("div.stat.commit-count").should("have.class", "active");
|
||||
|
||||
cy.log("Commit Group");
|
||||
cy.get("header.commit-date").should("have.text", "Wednesday, March 2, 2022");
|
||||
|
||||
cy.log("Commit Trailer");
|
||||
cy.get("div.summary span.hash")
|
||||
.should("have.text", "cbf5df4")
|
||||
.next()
|
||||
.should("have.text", "initial commit");
|
||||
cy.get("div.commit div.right span")
|
||||
.first()
|
||||
.should("have.text", "dabit3")
|
||||
.next()
|
||||
.should("have.text", "Wed, 02 Mar 2022 15:58:05 GMT");
|
||||
cy.get("div.summary").click();
|
||||
|
||||
cy.log("Commit Detail View");
|
||||
cy.location().should((location) => {
|
||||
expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/commits/cbf5df499ab4f4a908f1756fbe2c236a4530516a');
|
||||
});
|
||||
cy.get("header div.summary h3").should("have.text", "initial commit");
|
||||
cy.get("header pre.description").should("have.text", "this is the first commit of many");
|
||||
cy.get("header div.meta")
|
||||
.first()
|
||||
.should("have.text", "Committed by dabit3 <dabit3@gmail.com> Wed, 02 Mar 2022 15:58:05 GMT")
|
||||
.next()
|
||||
.should("have.text", "Authored by dabit3 <dabit3@gmail.com>");
|
||||
cy.get("div.changeset-summary").should("have.text", "1 file(s) changed\n with\n 0 addition(s)\n and\n 0 deletion(s)");
|
||||
cy.get("header.file-header:nth-child(1) div.file-data > *")
|
||||
.first()
|
||||
.should("have.text", "README.md")
|
||||
.next()
|
||||
.should("have.text", "created");
|
||||
cy.get("tr.diff-line td.diff-line-number").contains("16");
|
||||
cy.get("tr.diff-line td.diff-line-content").contains("To prevent front-running, the RAD/USDC balances are set through the Uniswap router *proxy* contract");
|
||||
});
|
||||
});
|
||||
+45
-15
@@ -1,19 +1,49 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import '@cypress/code-coverage/support';
|
||||
import '@testing-library/cypress/add-commands';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
export const styles = {
|
||||
cssFile: "public/index.css",
|
||||
style: `
|
||||
.wrapper {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
declare global {
|
||||
interface Window {
|
||||
ethereum: any;
|
||||
}
|
||||
`,
|
||||
html: `
|
||||
<div class="wrapper">
|
||||
<div id="here" />
|
||||
</div>
|
||||
`
|
||||
};
|
||||
}
|
||||
|
||||
export class MockExtensionProvider extends ethers.providers.BaseProvider {
|
||||
isMetaMask = true;
|
||||
|
||||
constructor() {
|
||||
super({ name: "homestead", chainId: 1 });
|
||||
console.log("Creating Mock provider");
|
||||
}
|
||||
async request({ method, params }: { method: string; params: any }): Promise<any> {
|
||||
switch (method) {
|
||||
case 'eth_chainId':
|
||||
return "1";
|
||||
case 'net_version':
|
||||
return "1";
|
||||
case 'eth_call':
|
||||
return resolveEthCall(params);
|
||||
case 'eth_getCode':
|
||||
return "0x";
|
||||
default:
|
||||
console.log("Unknown method", method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveEthCall(params: { to: string; data: string }[]): string {
|
||||
// Get Resolver
|
||||
if (params[0].to === "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e") {
|
||||
return "0x0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41";
|
||||
// Get ENS Attributes
|
||||
} else if (params[0].to === "0x4976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41" && params[0].data === "0x59d1d43c567c364804de7bbedb53f583e483f6b73513fd2f44299e281024e4719da0b332000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000066176617461720000000000000000000000000000000000000000000000000000") {
|
||||
return "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001f68747470733a2f2f636c6f7564686561642e696f2f6176617461722e706e6700";
|
||||
// Get Org informations
|
||||
} else if (params[0].to === "0x8152237402e0f194176154c3a6ea1eb99b611482" && params[0].data === "0x8da5cb5b") {
|
||||
return "0x000000000000000000000000ceab094641905c209cc796fc8037dd9ecc87ca2f";
|
||||
} else {
|
||||
return "0x000000000000000000000000394b920c5d39e0ca40fca2871569b6b90d750c7c";
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1255
-264
File diff suppressed because it is too large
Load Diff
+10
-5
@@ -5,7 +5,10 @@
|
||||
"serve": "vite preview",
|
||||
"build": "scripts/build",
|
||||
"check": "scripts/check",
|
||||
"test": "cypress run-ct"
|
||||
"coverage": "npx nyc report",
|
||||
"test:unit": "vitest run",
|
||||
"test:components": "cypress run-ct",
|
||||
"test:e2e": "cypress run"
|
||||
},
|
||||
"type": "module",
|
||||
"engines": {
|
||||
@@ -16,20 +19,22 @@
|
||||
"@cypress/vite-dev-server": "^2.2.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.36",
|
||||
"@testing-library/cypress": "^8.0.2",
|
||||
"@testing-library/svelte": "^3.1.0",
|
||||
"@tsconfig/svelte": "^1.0.13",
|
||||
"@types/sanitize-html": "^2.6.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.26.1",
|
||||
"@typescript-eslint/parser": "^4.26.1",
|
||||
"cypress": "^9.3.1",
|
||||
"cypress": "^9.5.1",
|
||||
"eslint": "^7.28.0",
|
||||
"eslint-plugin-radicle": "^0.2.0",
|
||||
"eslint-plugin-svelte3": "^3.2.0",
|
||||
"radicle-svelte-unit-test": "^1.0.0",
|
||||
"happy-dom": "^2.50.0",
|
||||
"svelte-check": "^2.4.1",
|
||||
"typescript": "^4.2.4",
|
||||
"vite": "^2.7.13",
|
||||
"vite-plugin-istanbul": "^2.4.0",
|
||||
"vite-plugin-rewrite-all": "^0.1.2"
|
||||
"vite-plugin-istanbul": "^2.5.1",
|
||||
"vite-plugin-rewrite-all": "^0.1.2",
|
||||
"vitest": "^0.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@datamodels/identity-profile-basic": "^0.1.2",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
vite build
|
||||
cp _redirects build/_redirects
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
npx tsc --noEmit && npx svelte-check
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Checks local /node_modules,
|
||||
# if not found will download that package and execute it.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
npm test && npx nyc report
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
npm run test:unit
|
||||
npm run test:components
|
||||
@@ -0,0 +1,46 @@
|
||||
import BlockTimer from "./BlockTimer.svelte";
|
||||
import { render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
import type { EventType, Listener } from "@ethersproject/abstract-provider";
|
||||
|
||||
|
||||
describe('BlockTimer', function () {
|
||||
it("increases correctly the loading bar", () => {
|
||||
let block = 1;
|
||||
const props = {
|
||||
config: {
|
||||
provider: {
|
||||
on: (event: EventType, listener: Listener) => {
|
||||
if (event === "block") {
|
||||
listener(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
startBlock: 1,
|
||||
duration: 3
|
||||
};
|
||||
|
||||
const { rerender } = render(BlockTimer, props);
|
||||
|
||||
cy.get("div.loader").should("have.attr", "style", "width: 0%;").then(() => {
|
||||
block += 1;
|
||||
rerender(props);
|
||||
});
|
||||
|
||||
cy.get("div.loader").last().should("have.attr", "style", "width: 33%;").then(() => {
|
||||
block += 1;
|
||||
rerender(props);
|
||||
});
|
||||
|
||||
cy.get("div.loader").last().should("have.attr", "style", "width: 66%;").then(() => {
|
||||
block += 1;
|
||||
rerender(props);
|
||||
});
|
||||
|
||||
cy.get("div.loader").last().should("have.attr", "style", "width: 99%;").then(() => {
|
||||
block += 1;
|
||||
rerender(props);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -29,5 +29,5 @@
|
||||
</style>
|
||||
|
||||
<div class="parent">
|
||||
<div class="loader" style="width: {(currentBlock - startBlock) * 10}%" />
|
||||
<div class="loader" style="width: {(currentBlock - startBlock) * Math.floor(100 / duration)}%" />
|
||||
</div>
|
||||
|
||||
+17
-19
@@ -1,11 +1,11 @@
|
||||
import Error from "./Error.svelte";
|
||||
import { mount } from "radicle-svelte-unit-test";
|
||||
import { render } from "@testing-library/svelte";
|
||||
import { Failure } from '@app/error';
|
||||
import { styles } from "@test/support/index";
|
||||
import "@public/index.css";
|
||||
|
||||
describe('Error', function () {
|
||||
it("Open Error modal with default props", () => {
|
||||
mount(Error, { props: {
|
||||
it("should show passed in props", () => {
|
||||
render(Error, { props: {
|
||||
subtitle: "Subtitle of Modal",
|
||||
error: {
|
||||
type: Failure.InsufficientBalance,
|
||||
@@ -13,30 +13,28 @@ describe('Error', function () {
|
||||
message: "Not enough RAD"
|
||||
}
|
||||
}
|
||||
}, styles);
|
||||
cy.get("[slot=title]").should("have.text", " Error");
|
||||
cy.get("[slot=subtitle]").should("have.text", "Subtitle of Modal");
|
||||
cy.get("[slot=body]").should("have.text", "Error: Not enough RAD");
|
||||
cy.get("button").should("have.text", "Back");
|
||||
});
|
||||
cy.findByText("Error");
|
||||
cy.findByText("Subtitle of Modal");
|
||||
cy.findByText("Not enough RAD");
|
||||
cy.findByText("Back");
|
||||
});
|
||||
|
||||
it("Open Error modal with custom message", () => {
|
||||
mount(Error, { props: {
|
||||
it("should show custom error message", () => {
|
||||
render(Error, { props: {
|
||||
subtitle: "Subtitle of Modal",
|
||||
message: "Error message to check for",
|
||||
} }, styles);
|
||||
cy.get("[slot=subtitle]").should("have.text", "Subtitle of Modal");
|
||||
cy.get("[slot=body]").should("have.text", "Error: Error message to check for");
|
||||
cy.get("button").should("have.text", "Back");
|
||||
} });
|
||||
cy.findByText("Error message to check for");
|
||||
});
|
||||
|
||||
it("Check floating modal changes button label to Close", () => {
|
||||
mount(Error, { props: {
|
||||
it("should change button label to Close when floating", () => {
|
||||
render(Error, { props: {
|
||||
title: "Title of Modal",
|
||||
subtitle: "Subtitle of Modal",
|
||||
message: "Error message to check for",
|
||||
floating: true
|
||||
} }, styles);
|
||||
cy.get("button").should("have.text", "Close");
|
||||
} });
|
||||
cy.findByText("Close");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import NotFound from "./NotFound.svelte";
|
||||
import { render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
|
||||
describe('NotFound', function () {
|
||||
it("shows passed props correctly", () => {
|
||||
render(NotFound, {
|
||||
props: {
|
||||
title: "nakamoto",
|
||||
subtitle: "Sorry, the requested project was not found."
|
||||
}
|
||||
});
|
||||
cy.findByText("nakamoto");
|
||||
cy.findByText("Sorry, the requested project was not found.");
|
||||
cy.findByText("Back");
|
||||
});
|
||||
});
|
||||
+23
-11
@@ -1,18 +1,30 @@
|
||||
import Search from "./Search.svelte";
|
||||
import { mount } from "radicle-svelte-unit-test";
|
||||
import { styles } from "@test/support/index";
|
||||
import { fireEvent, render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
|
||||
describe('Search', function () {
|
||||
it("Renders correctly", () => {
|
||||
mount(Search, {}, styles);
|
||||
cy.get("input").should("exist");
|
||||
describe('Logic', () => {
|
||||
it("show a appropiate placeholder", () => {
|
||||
render(Search);
|
||||
cy.get("input").should("have.attr", "placeholder", "Search a name or address...");
|
||||
});
|
||||
|
||||
it("Search input displays and navigates correctly", () => {
|
||||
mount(Search, {}, styles);
|
||||
cy.get("input").type("cloudhead{enter}");
|
||||
cy.get("input").should("have.value", "cloudhead");
|
||||
cy.url().should("contain", "/resolver/query?q=cloudhead");
|
||||
it("allow input a query and navigates accordingly", () => {
|
||||
render(Search);
|
||||
cy.get("input").type("cloudhead.radicle.eth{enter}");
|
||||
cy.get("input").should("have.value", "cloudhead.radicle.eth");
|
||||
cy.url().should("contain", "/resolver/query?q=cloudhead.radicle.eth");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Events", () => {
|
||||
it("should fire an event when the input changes", () => {
|
||||
const { component } = render(Search);
|
||||
const mock = cy.spy();
|
||||
component.$on("search", mock);
|
||||
|
||||
cy.get("input").then(([input]) => {
|
||||
fireEvent.keyDown(input, { key: "Enter" });
|
||||
expect(mock).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+25
-6
@@ -1,18 +1,37 @@
|
||||
import SeedAddress from "./SeedAddress.svelte";
|
||||
import { mount } from "radicle-svelte-unit-test";
|
||||
import { styles } from "@test/support/index";
|
||||
import { render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
|
||||
describe('SeedAddress', function () {
|
||||
it("Renders correctly", () => {
|
||||
mount(SeedAddress, {
|
||||
it("shows the seed emoji and seed host", () => {
|
||||
render(SeedAddress, {
|
||||
props: {
|
||||
seed: {
|
||||
id: "hydkkkf5ksbe5fuszdhpqhytu3q36gwagj874wxwpo5a8ti8coygh1",
|
||||
emoji: "🐱",
|
||||
host: "seed.cloudhead.io",
|
||||
},
|
||||
port: 8776
|
||||
}
|
||||
}, styles);
|
||||
cy.findByText("seed.cloudhead.io").should("exist").should("have.attr", "href", "/seeds/seed.cloudhead.io");
|
||||
});
|
||||
cy.get("span.seed-icon").should("have.text", "🐱");
|
||||
cy.findByText("seed.cloudhead.io").should("have.attr", "href", "/seeds/seed.cloudhead.io").should("be.visible");
|
||||
});
|
||||
|
||||
it("shows the full seed id", () => {
|
||||
render(SeedAddress, {
|
||||
props: {
|
||||
seed: {
|
||||
id: "hydkkkf5ksbe5fuszdhpqhytu3q36gwagj874wxwpo5a8ti8coygh1",
|
||||
emoji: "🐱",
|
||||
host: "seed.cloudhead.io",
|
||||
},
|
||||
port: 8776,
|
||||
full: true
|
||||
}
|
||||
});
|
||||
cy.get("span.seed-icon").should("have.text", "🐱");
|
||||
cy.findByText("hydkkk…coygh1@seed.cloudhead.io").should("be.visible");
|
||||
cy.findByText(":8776").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import BranchSelector from "./BranchSelector.svelte";
|
||||
import { mount } from "radicle-svelte-unit-test";
|
||||
import { styles } from "@test/support/index";
|
||||
import { fireEvent, render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
|
||||
const defaultProps = {
|
||||
project: {
|
||||
@@ -18,41 +18,63 @@ const defaultProps = {
|
||||
},
|
||||
branches: { "master": "e678629cd37c770c640a2cd997fc76303c815772" },
|
||||
revision: "e678629cd37c770c640a2cd997fc76303c815772",
|
||||
toggleDropdown: () => "branch"
|
||||
};
|
||||
|
||||
describe('BranchSelector', function () {
|
||||
it("Render with commit = head and branch listing", () => {
|
||||
mount(BranchSelector, {
|
||||
props: defaultProps
|
||||
}, styles);
|
||||
cy.findByText("master").should("exist");
|
||||
cy.get("div.commit > div.hash.desktop").should("have.text", "e678629");
|
||||
describe('Logic', () => {
|
||||
it("should show defaultBranch label and head commit if revision == head", () => {
|
||||
const { rerender } = render(BranchSelector, {
|
||||
props: defaultProps,
|
||||
});
|
||||
cy.get("div.stat.branch").should("be.visible").should("have.text", "master");
|
||||
cy.get("div.hash.mobile").should("be.visible").should("have.text", "e678629");
|
||||
|
||||
// If project.head is null we should get the head from branches.
|
||||
rerender({
|
||||
props: {
|
||||
...defaultProps,
|
||||
project: {
|
||||
head: null,
|
||||
urn: "rad:git:hnrkqdpm9ub19oc8dccx44echy76hzfsezyio",
|
||||
name: "nakamoto",
|
||||
description: "Privacy-preserving Bitcoin light-client implementation in Rust",
|
||||
defaultBranch: "master",
|
||||
maintainers: [
|
||||
"rad:git:hnrkqdpm9ub19oc8dccx44echy76hzfsezyio"
|
||||
],
|
||||
delegates: [
|
||||
"hyn9diwfnytahjq8u3iw63h9jte1ydcatxax3saymwdxqu1zo645pe"
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
cy.get("div.stat.branch").should("be.visible").should("have.text", "master");
|
||||
cy.get("div.hash.mobile").should("be.visible").should("have.text", "e678629");
|
||||
});
|
||||
|
||||
it("Test Branch selection", () => {
|
||||
// The viewport here is to simulate desktop behaviour
|
||||
cy.viewport(800, 300);
|
||||
mount(BranchSelector, {
|
||||
it("should show the branch dropdown if branches available", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps, branches: {
|
||||
...defaultProps,
|
||||
branches: {
|
||||
"master": "e678629cd37c770c640a2cd997fc76303c815772",
|
||||
"feature-branch": "29e8b7b0f3019b8e8a6d9bfb0964ee78f4ff12f5",
|
||||
"xyz": "debf82ef3623ec11751a993bda85bac2ff1c6f00",
|
||||
},
|
||||
branchesDropdown: true,
|
||||
}, callbacks: {
|
||||
branchChanged: cy.stub().as("branchChanged")
|
||||
branchesDropdown: true
|
||||
}
|
||||
}, styles);
|
||||
cy.get("div.dropdown > div").first().click();
|
||||
cy.get("@branchChanged")
|
||||
.should("be.calledOnce")
|
||||
.its("firstCall.args.0.detail")
|
||||
.should("equal", "feature-branch");
|
||||
});
|
||||
cy.get("div.dropdown div.dropdown-item")
|
||||
.first()
|
||||
.should("contain.text", "feature-branch")
|
||||
.next()
|
||||
.should("contain.text", "master").should("have.class", "selected")
|
||||
.next()
|
||||
.should("contain.text", "xyz");
|
||||
});
|
||||
|
||||
it("Render with commit != head, passing a branch as rev and branch listing", () => {
|
||||
mount(BranchSelector, {
|
||||
it("should show feature-branch label and head commit, if branch label is passed as revision", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps, branches: {
|
||||
"master": "e678629cd37c770c640a2cd997fc76303c815772",
|
||||
@@ -61,42 +83,84 @@ describe('BranchSelector', function () {
|
||||
},
|
||||
revision: "feature-branch"
|
||||
}
|
||||
}, styles);
|
||||
cy.findByText("feature-branch").should("exist");
|
||||
cy.get("div.commit > div.hash.desktop").should("have.text", "29e8b7b");
|
||||
});
|
||||
cy.get("div.stat.branch").should("be.visible").should("have.text", "feature-branch");
|
||||
cy.get("div.hash.mobile").should("be.visible").should("have.text", "29e8b7b");
|
||||
});
|
||||
|
||||
it("Render with commit != head passing a commit as rev and branch listing", () => {
|
||||
mount(BranchSelector, {
|
||||
it("should show only commit if no branchLabel nor branches are available", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
revision: "debf82ef3623ec11751a993bda85bac2ff1c6f00"
|
||||
revision: "debf82ef3623ec11751a993bda85bac2ff1c6f00",
|
||||
branches: {}
|
||||
}
|
||||
}, styles
|
||||
);
|
||||
cy.get("div.commit > div.hash.desktop").should("have.text", "debf82ef3623ec11751a993bda85bac2ff1c6f00");
|
||||
});
|
||||
cy.get("div.hash.mobile").should("be.visible").should("have.text", "debf82e");
|
||||
cy.viewport("macbook-13");
|
||||
cy.get("div.hash.desktop").should("be.visible").should("have.text", "debf82ef3623ec11751a993bda85bac2ff1c6f00");
|
||||
});
|
||||
|
||||
it("Render with commit = head, without branch listing", () => {
|
||||
mount(BranchSelector, {
|
||||
it("should show only commit if branches are available but no branchLabel", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
revision: "debf82ef3623ec11751a993bda85bac2ff1c6f00",
|
||||
}
|
||||
});
|
||||
cy.get("div.hash.mobile").should("be.visible").should("have.text", "debf82e");
|
||||
cy.viewport("macbook-13");
|
||||
cy.get("div.hash.desktop").should("be.visible").should("have.text", "debf82ef3623ec11751a993bda85bac2ff1c6f00");
|
||||
});
|
||||
|
||||
it("should show defaultBranch label if revision == head", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
revision: "e678629cd37c770c640a2cd997fc76303c815772",
|
||||
branches: {},
|
||||
branches: {}
|
||||
}
|
||||
}, styles
|
||||
);
|
||||
cy.get("div.commit > div.hash.desktop").should("have.text", "e678629cd37c770c640a2cd997fc76303c815772");
|
||||
});
|
||||
cy.get("div.stat.branch.not-allowed").should("be.visible").should("have.text", "master");
|
||||
});
|
||||
});
|
||||
|
||||
it("Render without branch listing, commit != head", () => {
|
||||
mount(BranchSelector, {
|
||||
describe("Layout", () => {
|
||||
it("should show shortened commit when on mobile, and full hash when on desktop", () => {
|
||||
render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
revision: "6b84e519d3c535879eb2b9ee8457bb70ca275a75",
|
||||
branches: {},
|
||||
revision: "e678629cd37c770c640a2cd997fc76303c815772"
|
||||
}
|
||||
}, styles);
|
||||
cy.get("div.commit > div.hash.desktop").should("have.text", "6b84e519d3c535879eb2b9ee8457bb70ca275a75");
|
||||
});
|
||||
cy.viewport("iphone-x");
|
||||
cy.get("div.hash.mobile").should("be.visible");
|
||||
cy.get("div.hash.desktop").should("not.be.visible");
|
||||
cy.viewport("macbook-15");
|
||||
cy.get("div.hash.mobile").should("not.be.visible");
|
||||
cy.get("div.hash.desktop").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Events", () => {
|
||||
it("should dispatch a 'branchChanged' event on click", () => {
|
||||
const { getByText, component } = render(BranchSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
revision: "feature-branch",
|
||||
branchesDropdown: true,
|
||||
branches: {
|
||||
"feature-branch": "29e8b7b0f3019b8e8a6d9bfb0964ee78f4ff12f5",
|
||||
"xyz": "debf82ef3623ec11751a993bda85bac2ff1c6f00",
|
||||
}
|
||||
}
|
||||
});
|
||||
const branchLabel = getByText("xyz");
|
||||
|
||||
const mock = cy.spy();
|
||||
component.$on("branchChanged", mock);
|
||||
|
||||
fireEvent.click(branchLabel);
|
||||
expect(mock).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
$: branchList = Object.keys(branches).sort().map(b => ({ key: b, value: b, badge: null }));
|
||||
$: showSelector = branchList.length > 1;
|
||||
$: head = branches[project.defaultBranch];
|
||||
$: head = project.head ?? branches[project.defaultBranch];
|
||||
$: commit = getOid(revision, branches) || head;
|
||||
$: if (commit == head) {
|
||||
branchLabel = project.defaultBranch;
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
<div class="stat commit-count" class:active={content == ProjectContent.History} on:click={() => toggleContent(ProjectContent.History)}>
|
||||
<strong>{tree.stats.commits}</strong> commit(s)
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat contributor-count">
|
||||
<strong>{tree.stats.contributors}</strong> contributor(s)
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<div class="history">
|
||||
{#each history.headers as group (group.time)}
|
||||
<div class="commit-group">
|
||||
<header>
|
||||
<header class="commit-date">
|
||||
<p>{group.time}</p>
|
||||
</header>
|
||||
<div class="commit-group-headers">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import PeerSelector from "./PeerSelector.svelte";
|
||||
import { mount } from "radicle-svelte-unit-test";
|
||||
import { styles } from "@test/support/index";
|
||||
import { fireEvent, render } from "@testing-library/svelte";
|
||||
import "@public/index.css";
|
||||
|
||||
const defaultProps = {
|
||||
peer: "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
|
||||
@@ -14,67 +14,82 @@ const defaultProps = {
|
||||
toggleDropdown: () => console.log("toggle"),
|
||||
};
|
||||
|
||||
describe('PeerSelector', function () {
|
||||
it("Render correctly with default props", () => {
|
||||
mount(PeerSelector, {
|
||||
describe('Logic', function () {
|
||||
it("show delegate name and badge", () => {
|
||||
render(PeerSelector, {
|
||||
props: defaultProps
|
||||
}, styles);
|
||||
cy.get("span.peer-id").should("has.text", "sebastinez");
|
||||
cy.get("span.badge").should("has.text", "delegate");
|
||||
});
|
||||
cy.get("span.peer-id").should("have.text", "sebastinez");
|
||||
cy.get("span.badge.primary").should("have.text", "delegate");
|
||||
});
|
||||
|
||||
it("Test Peer selection", () => {
|
||||
mount(PeerSelector, {
|
||||
props: {
|
||||
...defaultProps, peers: [
|
||||
{
|
||||
"id": "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
|
||||
"name": "sebastinez",
|
||||
"delegate": false
|
||||
},
|
||||
{
|
||||
"id": "hydkkkf5ksbe5fuszdhpqhytu3q36gwagj874wxwpo5a8ti8coygh1",
|
||||
"name": "cloudhead",
|
||||
"delegate": true
|
||||
},
|
||||
],
|
||||
peersDropdown: true
|
||||
}, callbacks: {
|
||||
peerChanged: cy.stub().as("peerChanged")
|
||||
}
|
||||
}, styles);
|
||||
cy.get("div.dropdown > div").last().click();
|
||||
cy.get("@peerChanged")
|
||||
.should("be.calledOnce")
|
||||
.its("firstCall.args.0.detail")
|
||||
.should("equal", "hydkkkf5ksbe5fuszdhpqhytu3q36gwagj874wxwpo5a8ti8coygh1");
|
||||
});
|
||||
it("If no peers are provided, no dropdown should be showed", () => {
|
||||
mount(PeerSelector, {
|
||||
it("show peer id with badge if no name available", () => {
|
||||
render(PeerSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
peers: [],
|
||||
peersDropdown: true
|
||||
peers: [
|
||||
{
|
||||
"id": "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
|
||||
"delegate": true
|
||||
}
|
||||
],
|
||||
}
|
||||
}, styles);
|
||||
cy.get("div.dropdown > div.dropdown-item").should("not.exist");
|
||||
});
|
||||
cy.get("span.peer-id").should("have.text", "hyyg55…p7ofue");
|
||||
cy.get("span.badge.primary").should("have.text", "delegate");
|
||||
});
|
||||
it("If peer identity is not being resolved, fallback to peer id", () => {
|
||||
mount(PeerSelector, {
|
||||
|
||||
it("show only peer id if no additional data available", () => {
|
||||
render(PeerSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
peers: [
|
||||
{
|
||||
"id": "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
|
||||
}
|
||||
],
|
||||
peersDropdown: true
|
||||
]
|
||||
}
|
||||
}, styles);
|
||||
cy.get("span.peer-id").should("has.text", "hyyg55…p7ofue");
|
||||
cy.get("span.badge").should("not.exist");
|
||||
cy.get("div.dropdown > .dropdown-item")
|
||||
.first()
|
||||
.should("contain", "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue");
|
||||
});
|
||||
cy.get("span.peer-id").should("have.text", "hyyg55…p7ofue");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Layout", () => {
|
||||
it("should highlight the current peer", () => {
|
||||
render(PeerSelector, {
|
||||
props: { ...defaultProps, peersDropdown: true }
|
||||
});
|
||||
cy.get("div.dropdown-item").should("have.class", "selected");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Events', () => {
|
||||
it("dispatch peerChanged event if clicking on a peer", () => {
|
||||
cy.viewport("macbook-13");
|
||||
const { getByText, component } = render(PeerSelector, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
peersDropdown: true,
|
||||
peers: [
|
||||
{
|
||||
"id": "hyy841u4phudmr8s5rg1jjwd1ct7x7438wmjwtsm464y8uyxyhyi6c",
|
||||
"name": "cloudhead",
|
||||
"delegate": true
|
||||
},
|
||||
{
|
||||
"id": "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
|
||||
"name": "sebastinez",
|
||||
"delegate": true
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
const peer = getByText("cloudhead");
|
||||
const mock = cy.spy();
|
||||
component.$on("peerChanged", mock);
|
||||
|
||||
fireEvent.click(peer);
|
||||
expect(mock).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Seed } from "./Seed";
|
||||
import { Config } from "@app/config";
|
||||
|
||||
describe('Seed', function () {
|
||||
it("Constructs git host correctly", () => {
|
||||
const cfg = new Config({ name: "homestead", chainId: 1 }, null as any, null);
|
||||
const seed = new Seed({
|
||||
host: "seed.cloudhead.io",
|
||||
id: "hydzjm73tstmdcwhach3psfgkunbjpih7ztnuswhw9w6h9pi5sffd6",
|
||||
git: "git.seed.cloudhead.io",
|
||||
}, cfg);
|
||||
|
||||
expect(seed.git.host).to.eq("git.seed.cloudhead.io");
|
||||
expect(seed.git.port).to.eq(443);
|
||||
|
||||
expect(seed.host).to.eq("seed.cloudhead.io");
|
||||
expect(seed.api.host).to.eq(seed.host);
|
||||
expect(seed.api.port).to.eq(8777);
|
||||
});
|
||||
|
||||
it("Constructs git host correctly with custom port", () => {
|
||||
const cfg = new Config({ name: "homestead", chainId: 1 }, null as any, null);
|
||||
const seed = new Seed({
|
||||
host: "seed.cloudhead.io",
|
||||
id: "hydzjm73tstmdcwhach3psfgkunbjpih7ztnuswhw9w6h9pi5sffd6",
|
||||
git: "https://git.seed.cloudhead.io:8778",
|
||||
}, cfg);
|
||||
|
||||
expect(seed.git.host).to.eq("git.seed.cloudhead.io");
|
||||
expect(seed.git.port).to.eq(8778);
|
||||
});
|
||||
|
||||
it("Constructs api host correctly", () => {
|
||||
const cfg = new Config({ name: "homestead", chainId: 1 }, null as any, null);
|
||||
const seed = new Seed({
|
||||
host: "seed.cloudhead.io",
|
||||
id: "hydzjm73tstmdcwhach3psfgkunbjpih7ztnuswhw9w6h9pi5sffd6",
|
||||
api: "https://api.seed.cloudhead.io:8080",
|
||||
}, cfg);
|
||||
|
||||
expect(seed.api.host).to.eq("api.seed.cloudhead.io");
|
||||
expect(seed.api.port).to.eq(8080);
|
||||
|
||||
expect(seed.host).to.eq("api.seed.cloudhead.io");
|
||||
expect(seed.git.host).to.eq("seed.cloudhead.io");
|
||||
expect(seed.git.port).to.eq(443);
|
||||
});
|
||||
});
|
||||
+4
-2
@@ -8,8 +8,11 @@ import WalletConnect from "@walletconnect/client";
|
||||
import config from "@app/config.json";
|
||||
import { WalletConnectSigner } from "./WalletConnectSigner";
|
||||
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Cypress: any;
|
||||
ethereum: any;
|
||||
registrarState: any;
|
||||
}
|
||||
@@ -246,8 +249,7 @@ export async function getConfig(): Promise<Config> {
|
||||
if (metamask) {
|
||||
// If Metamask is detected, we use the network configured there.
|
||||
const ready = await checkMetaMask(metamask);
|
||||
if (ready === null) throw new Error("Not able to connect to Metamask, check for multiple Web3 providers");
|
||||
network = ready;
|
||||
if (ready) network = ready;
|
||||
}
|
||||
|
||||
const networkConfig = (<Record<string, any>> config)[network.name];
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// A simple mock for some HTMLCanvasElement functions to run in a node env.
|
||||
|
||||
HTMLCanvasElement.prototype.getContext = () => ({
|
||||
fillRect: () => null
|
||||
});
|
||||
|
||||
HTMLCanvasElement.prototype.toDataURL = () => null;
|
||||
@@ -0,0 +1,9 @@
|
||||
/* eslint-disable no-undef */
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
if (! globalThis.fetch) {
|
||||
globalThis.fetch = fetch;
|
||||
globalThis.Headers = fetch.Headers;
|
||||
globalThis.Request = fetch.Request;
|
||||
globalThis.Response = fetch.Response;
|
||||
}
|
||||
@@ -169,7 +169,6 @@ export function path(opts: PathOptions): string {
|
||||
}
|
||||
|
||||
// We need a SHA1 commit in some places, so we return early if the revision is a SHA and else we look into branches.
|
||||
// As fallback we use the head commit.
|
||||
export function getOid(revision: string, branches?: Branches): string | null {
|
||||
if (isOid(revision)) return revision;
|
||||
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
import { BigNumber } from "ethers";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import type { Config } from "./config";
|
||||
import * as utils from "./utils";
|
||||
|
||||
describe("Conversions", () => {
|
||||
test("toWei", () => {
|
||||
expect(
|
||||
utils.toWei("10")
|
||||
).toEqual(BigNumber.from("10000000000000000000"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Format functions", () => {
|
||||
test.each([
|
||||
{ cid: "Qm1234567890123456789012345678901234567890", expected: "https://ipfs.io/ipfs/Qm1234567890123456789012345678901234567890" },
|
||||
{ cid: undefined, expected: undefined }
|
||||
])("formatIpfsFile $cid => $expected", ({ cid, expected }) => {
|
||||
expect(
|
||||
utils.formatIpfsFile(cid)
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ amount: "1000", digits: 2, expected: "10.0" },
|
||||
{ amount: "10000000000000000000", expected: "10.0" },
|
||||
])("formatBalance", ({ amount, digits, expected }) => {
|
||||
expect(utils.formatBalance(BigNumber.from(amount), digits)).toEqual(expected);
|
||||
});
|
||||
|
||||
test("formatRadicleId", () => {
|
||||
expect(
|
||||
utils.formatRadicleId(
|
||||
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 38, 115, 99, 61, 118, 237, 10, 20, 115, 111, 188, 10, 117, 137, 59, 107, 76, 77, 86])
|
||||
))
|
||||
.toEqual("rad:git:hnrkjajuucc6zp5eknt3s9xykqsrus44cjimy");
|
||||
});
|
||||
|
||||
test("formatProjectHash", () => {
|
||||
expect(
|
||||
utils.formatProjectHash(
|
||||
new Uint8Array([17, 20, 69, 234, 87, 208, 172, 127, 33, 22, 110, 216, 52, 69, 104, 219, 88, 66, 50, 152, 115, 23])
|
||||
)
|
||||
).toEqual("45ea57d0ac7f21166ed8344568db584232987317");
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ hash: "#L42", expected: 42 },
|
||||
{ hash: "#ETH", expected: null },
|
||||
])("formatLocationHash $hash => $expected", ({ hash, expected }) => {
|
||||
expect(
|
||||
utils.formatLocationHash(hash))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ id: "hydkkkf5ksbe5fuszdhpqhytu3q36gwagj874wxwpo5a8ti8coygh1", expected: "hydkkk…coygh1" }
|
||||
])("formatSeedId $id => $expected", ({ id, expected }) => {
|
||||
expect(
|
||||
utils.formatSeedId(id))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test("formatRadicleUrn", () => {
|
||||
expect(
|
||||
utils.formatRadicleUrn("rad:git:hnrkemobagsicpf9sr95o3g551otspcd84c9o"))
|
||||
.toEqual("rad:git:hnrkem…d84c9o");
|
||||
});
|
||||
|
||||
test("formatRadicleUrn throw when wrong URN", () => {
|
||||
expect(() => utils.formatRadicleUrn("hnrkemobagsicpf9sr95o3g551otspcd84c9o"))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
test("formatCAIP10Address", () => {
|
||||
expect(
|
||||
utils.formatCAIP10Address(
|
||||
"0x1234567890123456789012345678901234567890",
|
||||
"eip155",
|
||||
1
|
||||
))
|
||||
.toEqual("0x1234567890123456789012345678901234567890@eip155:1");
|
||||
});
|
||||
|
||||
test("formatAddress", () => {
|
||||
expect(
|
||||
utils.formatAddress(
|
||||
"0xb5d85cbf7cb3ee0d56b3bb207d5fc4b82f43f511",
|
||||
)
|
||||
).toEqual("b5d8 – F511");
|
||||
|
||||
expect(
|
||||
() => utils.formatAddress(
|
||||
"0x8f91813",
|
||||
)
|
||||
).toThrowError('invalid address (argument="address", value="0x8f91813", code=INVALID_ARGUMENT, version=address/5.5.0)');
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ hash: "0x8f918133b56bb85c18ea192549503f0ea59e3beb1f88023f442656c660018e3a", expected: "0x8f91...8e3a" },
|
||||
{ hash: "0x8f91813", expected: "0x8f91813" }, // If the string length is less than 10 characters the entire string is returned.
|
||||
])("formatHash $hash => $expected", ({ hash, expected }) => {
|
||||
expect(
|
||||
utils.formatHash(hash)
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ commit: "a8a6a979a6261a2ec1ea85fc9a65a4a30aa22cc8", expected: "a8a6a97" },
|
||||
{ commit: "a8a6a97", expected: "a8a6a97" }
|
||||
])("formatCommit $commit => $expected", ({ commit, expected }) => {
|
||||
expect(
|
||||
utils.formatCommit(commit)
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("String Assertions", () => {
|
||||
test.each([
|
||||
{ a: "0x1234567890123456789012345678901234567890", b: "0x1234567890123456789012345678901234567890", expected: true },
|
||||
{ a: "0x1234567890123456789012345678901234567890", b: "0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0", expected: false }
|
||||
])("isAddressEqual", ({ a, b, expected }) => {
|
||||
expect(
|
||||
utils.isAddressEqual(a, b))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ domain: "alt-clients.radicle.xyz", expected: true },
|
||||
{ domain: "0.0.0.0", expected: true }, // Pass as true since we are not in production
|
||||
{ domain: "", expected: false },
|
||||
])("isDomain $domain => $expected", ({ domain, expected }) => {
|
||||
expect(
|
||||
utils.isDomain(domain))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ path: "README.md", expected: true },
|
||||
{ path: "README.mkd", expected: true },
|
||||
{ path: "README.markdown", expected: true },
|
||||
{ path: "", expected: false },
|
||||
])("isMarkdownPath $path => $expected", ({ path, expected }) => {
|
||||
expect(
|
||||
utils.isMarkdownPath(path))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ id: "rad:git:hnrkemobagsicpf9sr95o3g551otspcd84c9o", expected: true },
|
||||
{ id: "0x1234567890123456789012345678901234567890", expected: false },
|
||||
])("isRadicleId $id => $expected", ({ id, expected }) => {
|
||||
expect(
|
||||
utils.isRadicleId(id))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ oid: "a64ae9c6d572e0ad906faa9a4a7a8d43f113278c", expected: true },
|
||||
{ oid: "a64ae9c", expected: false }
|
||||
])("isOid $oid => $expected", ({ oid, expected }) => {
|
||||
expect(
|
||||
utils.isOid(oid))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ address: "0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0", expected: true },
|
||||
{ address: "0x5E813e48a81977c6fdd565ed5097eb600c73c4f0", expected: false }, // If address is badly checksummed => false
|
||||
{ address: "0x5e813e48a81977c6fdd565ed5097eb600c73c4f0", expected: true },
|
||||
])("isAddress $address => $expected", ({ address, expected }) => {
|
||||
expect(
|
||||
utils.isAddress(
|
||||
address,
|
||||
))
|
||||
.toBe(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ url: "https://app.radicle.network", expected: true },
|
||||
{ url: "http://app.radicle.network", expected: true },
|
||||
{ url: "http://app", expected: true },
|
||||
{ url: "://app", expected: false },
|
||||
{ url: "//app", expected: false },
|
||||
{ url: "app", expected: false },
|
||||
])("isUrl $url => $expected", ({ url, expected }) => {
|
||||
expect(
|
||||
utils.isUrl(
|
||||
url,
|
||||
))
|
||||
.toBe(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ did: "did:3:kjzl6cwe1jw1481xu9oyww9bhmueqr8f5uryk4xha9jzhj6vi063e0blpnil383", expected: true },
|
||||
{ did: "did:kjzl6cwe1jw1481xu9oyww9bhmueqr8f5uryk4xha9jzhj6vi063e0blpnil383", expected: false },
|
||||
])("isDid $did => $expected", ({ did, expected }) => {
|
||||
expect(
|
||||
utils.isDid(did))
|
||||
.toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Others", () => {
|
||||
test.each([
|
||||
{ viewer: "https://gnosis-safe.io/app/#/safes", name: "", expected: "https://gnosis-safe.io/app/#/safes/0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0" },
|
||||
{ viewer: null, name: "", expected: "https://etherscan.io/address/0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0" },
|
||||
])("safeLink $viewer => $expected", ({ name, viewer, expected }) => {
|
||||
expect(
|
||||
utils.safeLink(
|
||||
"0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0",
|
||||
{
|
||||
network: {
|
||||
name
|
||||
},
|
||||
safe: {
|
||||
viewer
|
||||
}
|
||||
} as Config
|
||||
))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ name: "rinkeby", expected: "https://rinkeby.etherscan.io/address/0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0" },
|
||||
{ name: "", expected: "https://etherscan.io/address/0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0" },
|
||||
])("explorerLink $name => $expected", ({ name, expected }) => {
|
||||
expect(
|
||||
utils.explorerLink(
|
||||
"0x5E813e48a81977c6Fdd565ed5097eb600C73C4f0",
|
||||
{
|
||||
network: {
|
||||
name,
|
||||
}
|
||||
} as Config
|
||||
))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ id: "rad:git:hnrkjajuucc6zp5eknt3s9xykqsrus44cjimy", expected: new Uint8Array([156, 38, 115, 99, 61, 118, 237, 10, 20, 115, 111, 188, 10, 117, 137, 59, 107, 76, 77, 86]) },
|
||||
{ id: "hnrkjajuucc6zp5eknt3s9xykqsrus44cjimy", expected: new Uint8Array([156, 38, 115, 99, 61, 118, 237, 10, 20, 115, 111, 188, 10, 117, 137, 59, 107, 76, 77, 86]) }
|
||||
])("decodeRadicleId", ({ id, expected }) => {
|
||||
expect(
|
||||
utils.decodeRadicleId(id))
|
||||
.toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Parse Strings", () => {
|
||||
test.each([
|
||||
{ label: "sebastinez.radicle.eth", expected: "sebastinez" },
|
||||
{ label: "sebastinez", expected: "sebastinez" },
|
||||
])("parseEnsLabel", ({ label, expected }) => {
|
||||
expect(
|
||||
utils.parseEnsLabel(
|
||||
label,
|
||||
{
|
||||
registrar: {
|
||||
address: "0x1234567890123456789012345678901234567890",
|
||||
domain: "radicle.eth"
|
||||
}
|
||||
} as Config
|
||||
)
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ input: "https://twitter.com/cloudhead", expected: "cloudhead" },
|
||||
{ input: "sebastinez", expected: "sebastinez" }
|
||||
])("parseUsername", ({ input, expected }) => {
|
||||
expect(
|
||||
utils.parseUsername(input)
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
+4
-2
@@ -98,6 +98,8 @@ export function formatSeedId(id: string): string {
|
||||
}
|
||||
|
||||
export function formatRadicleUrn(id: string): string {
|
||||
assert(isRadicleId(id));
|
||||
|
||||
return id.substring(0, 14)
|
||||
+ '…'
|
||||
+ id.substring(id.length - 6, id.length);
|
||||
@@ -125,6 +127,7 @@ export function formatIpfsFile(ipfs: string | undefined): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If the string is less than 10 characters the entire string is returned.
|
||||
export function formatHash(hash: string): string {
|
||||
if (hash.length < 10) return hash;
|
||||
return hash.substring(0, 6)
|
||||
@@ -149,8 +152,7 @@ export function capitalize(s: string): string {
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
|
||||
// Takes a domain name, eg. 'cloudhead.radicle.eth' and
|
||||
// returns the label, eg. 'cloudhead', otherwise `undefined`.
|
||||
// Takes a domain name, eg. 'cloudhead.radicle.eth' and returns the label, eg. 'cloudhead'.
|
||||
export function parseEnsLabel(name: string, config: Config): string {
|
||||
const domain = config.registrar.domain.replace(".", "\\.");
|
||||
const label = name.replace(new RegExp(`\\.${domain}$`), "");
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"include": [
|
||||
"src",
|
||||
"cypress"
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules/*"
|
||||
@@ -26,8 +25,8 @@
|
||||
"importsNotUsedAsValues": "error",
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@public/*": ["./public/*"],
|
||||
"@app/*": ["./src/*"],
|
||||
"@test/*": ["./cypress/*"]
|
||||
}
|
||||
},
|
||||
"noEmit": true
|
||||
|
||||
+25
-1
@@ -1,3 +1,4 @@
|
||||
///<reference types="vitest" />
|
||||
import path from 'path';
|
||||
import { UserConfig } from 'vite';
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
@@ -8,8 +9,26 @@ const config: UserConfig = {
|
||||
optimizeDeps: {
|
||||
exclude: ['svelte-routing', '@pedrouid/environment', '@pedrouid/iso-crypto']
|
||||
},
|
||||
test: {
|
||||
deps: {
|
||||
inline: [
|
||||
"@ethersproject/signing-key",
|
||||
"@ethersproject/basex",
|
||||
]
|
||||
},
|
||||
environment: "happy-dom",
|
||||
include: ["**/*.test.ts"],
|
||||
reporters: "verbose",
|
||||
coverage: {
|
||||
reporter: ["html"],
|
||||
all: true,
|
||||
excludeNodeModules: true,
|
||||
extension: [".svelte", ".ts", ".js"]
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
svelte({
|
||||
hot: !process.env.VITEST,
|
||||
compilerOptions: {
|
||||
dev: process.env.NODE_ENV !== "production"
|
||||
}
|
||||
@@ -26,8 +45,8 @@ const config: UserConfig = {
|
||||
alias: {
|
||||
// This is needed for vite not to choke.
|
||||
"caip": path.resolve("./node_modules/caip/dist/umd/index.min.js"),
|
||||
'@public': path.resolve('./public'),
|
||||
'@app': path.resolve('./src'),
|
||||
'@test': path.resolve('./cypress'),
|
||||
// Polyfill for Node.js 'stream' library.
|
||||
'stream': path.resolve('./src/polyfills/stream.ts'),
|
||||
'typedarray-to-buffer': path.resolve('./src/polyfills/typedarray-to-buffer.js'),
|
||||
@@ -46,4 +65,9 @@ const config: UserConfig = {
|
||||
}
|
||||
};
|
||||
|
||||
// For Vitest to work we need to unset READABLE_STREAM.
|
||||
if (process.env.VITEST) {
|
||||
config.define = undefined;
|
||||
}
|
||||
|
||||
export default config;
|
||||
|
||||
Reference in New Issue
Block a user