This commit is contained in:
Jernej Pregelj 2019-06-25 10:19:52 +02:00
commit 5caa62ea57
56 changed files with 1037 additions and 658 deletions

View File

@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [v0.5.3](https://github.com/oceanprotocol/commons/compare/v0.5.2...v0.5.3)
> 19 June 2019
- SEO component [`#159`](https://github.com/oceanprotocol/commons/pull/159)
#### [v0.5.2](https://github.com/oceanprotocol/commons/compare/v0.5.1...v0.5.2)
> 19 June 2019
- add config values for Pacific connection [`#161`](https://github.com/oceanprotocol/commons/pull/161)
- Refactor VersionNumbers to be sourced from squid-js [`#160`](https://github.com/oceanprotocol/commons/pull/160)
- output overall status [`059ae62`](https://github.com/oceanprotocol/commons/commit/059ae62f967f40d9635cc729d31ab84fa913df8b)
- SEO component [`b811379`](https://github.com/oceanprotocol/commons/commit/b8113798b6226f6f386a725e146f5b5ece37d9cc)
- switch to using squid-js for version numbers [`c4f862b`](https://github.com/oceanprotocol/commons/commit/c4f862baa5fa835ec3ff3aafeefa60f524d011b2)
#### [v0.5.1](https://github.com/oceanprotocol/commons/compare/v0.5.0...v0.5.1)
> 14 June 2019
- Submarine links and Pacific support [`#158`](https://github.com/oceanprotocol/commons/pull/158)
- link up transaction IDs with submarine, support pacific too [`97d6c27`](https://github.com/oceanprotocol/commons/commit/97d6c2756ed31f90f960dae21b8889d61232cd09)
- link version numbers to release pages [`6f7edfa`](https://github.com/oceanprotocol/commons/commit/6f7edfa30f3b188e87cbce3c2404db313920e305)
- Release 0.5.1 [`c063ad8`](https://github.com/oceanprotocol/commons/commit/c063ad82cb5e3a51b5083427fc50afc5b161533a)
#### [v0.5.0](https://github.com/oceanprotocol/commons/compare/v0.4.5...v0.5.0)
> 12 June 2019

View File

@ -3,6 +3,16 @@
# Commons will default connecting to Nile
#
#
# Connect to Pacific
#
# REACT_APP_NODE_URI="https://pacific.oceanprotocol.com"
# REACT_APP_AQUARIUS_URI="https://aquarius.pacific.dev-ocean.com"
# REACT_APP_BRIZO_URI="https://brizo.pacific.dev-ocean.com"
# REACT_APP_SECRET_STORE_URI="https://secret-store.pacific.oceanprotocol.com"
# REACT_APP_FAUCET_URI="https://faucet.pacific.dev-ocean.com"
# REACT_APP_BRIZO_ADDRESS="0x008c25ed3594e094db4592f4115d5fa74c4f41ea"
#
# Connect to Nile
#

View File

@ -31,6 +31,34 @@ const oceanMock = {
}
}
}
},
versions: {
get: jest.fn(() =>
Promise.resolve({
squid: {
name: 'Squid-js',
status: 'Working'
},
aquarius: {
name: 'Aquarius',
status: 'Working'
},
brizo: {
name: 'Brizo',
network: 'Nile',
status: 'Working',
contracts: {
hello: 'hello',
hello2: 'hello2'
}
},
status: {
ok: true,
network: true,
contracts: true
}
})
)
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "commons-client",
"version": "0.5.0",
"version": "0.5.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -1315,17 +1315,6 @@
"resolved": "https://registry.npmjs.org/@oceanprotocol/typographies/-/typographies-0.1.0.tgz",
"integrity": "sha512-kMsZsqvzpz9KzVbVZzllwhPoIC3zbqsdRrClagZL/C2PHzgLrKGC1kYn3gPt0RMIFg9ZjrwieKaxlgIK9i9zzg=="
},
"@react-mock/fetch": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@react-mock/fetch/-/fetch-0.3.0.tgz",
"integrity": "sha512-q1tqyrqeW4+J0R/rRghK86VG21fFFIMli1kxhi2z9wLAko10YNHB3UuI4fnXc+/kbjne0yVxyTp0s1xdzv+YzA==",
"dev": true,
"requires": {
"@babel/runtime": "^7.1.2",
"fetch-mock": "^7.0.7",
"lodash": "^4.17.11"
}
},
"@react-mock/state": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/@react-mock/state/-/state-0.1.8.tgz",
@ -2712,31 +2701,6 @@
"integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==",
"dev": true
},
"babel-polyfill": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
"dev": true,
"requires": {
"babel-runtime": "^6.26.0",
"core-js": "^2.5.0",
"regenerator-runtime": "^0.10.5"
},
"dependencies": {
"core-js": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
"dev": true
},
"regenerator-runtime": {
"version": "0.10.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
"dev": true
}
}
},
"babel-preset-jest": {
"version": "24.6.0",
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz",
@ -6497,43 +6461,6 @@
"pend": "~1.2.0"
}
},
"fetch-mock": {
"version": "7.3.3",
"resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-7.3.3.tgz",
"integrity": "sha512-MHKcwZ4n9TmnfnVfelUBrrfxtC9tztafIR+F8l/Yu9N+y48fU1BAwj3iSxhYFYELVw73rCZh2DPWtWCekY/t+w==",
"dev": true,
"requires": {
"babel-polyfill": "^6.26.0",
"glob-to-regexp": "^0.4.0",
"path-to-regexp": "^2.2.1",
"whatwg-url": "^6.5.0"
},
"dependencies": {
"glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
"path-to-regexp": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
"integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==",
"dev": true
},
"whatwg-url": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
"integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
"dev": true,
"requires": {
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"webidl-conversions": "^4.0.2"
}
}
}
},
"figgy-pudding": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
@ -12892,7 +12819,6 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
"dev": true,
"requires": {
"performance-now": "^2.1.0"
}
@ -12982,6 +12908,15 @@
}
}
},
"react-collapsed": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/react-collapsed/-/react-collapsed-2.0.1.tgz",
"integrity": "sha512-ullymRST/C5iy0szhxpYmIaLUhi+IC8EpFySmUjttoc+ErotaKAx+z1ff0d2PCJF7ksW8crTiOrIwGtFqYw3Tg==",
"requires": {
"@babel/runtime": "^7.3.1",
"raf": "^3.4.0"
}
},
"react-datepicker": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.6.0.tgz",

View File

@ -1,7 +1,7 @@
{
"name": "commons-client",
"description": "Ocean Protocol marketplace frontend to explore, download, and publish open data sets.",
"version": "0.5.0",
"version": "0.5.3",
"license": "Apache-2.0",
"scripts": {
"start": "react-scripts start",
@ -25,6 +25,7 @@
"moment": "^2.24.0",
"query-string": "^6.5.0",
"react": "^16.8.6",
"react-collapsed": "^2.0.1",
"react-datepicker": "^2.5.0",
"react-dom": "^16.8.6",
"react-dotdotdot": "^1.3.0",
@ -39,7 +40,6 @@
"web3": "1.0.0-beta.37"
},
"devDependencies": {
"@react-mock/fetch": "^0.3.0",
"@react-mock/state": "^0.1.8",
"@testing-library/react": "^8.0.1",
"@types/classnames": "^2.2.7",

View File

@ -12,39 +12,6 @@
<title>Commons</title>
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
name="description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
name="image"
/>
<link href="https://commons.oceanprotocol.com" rel="canonical" />
<meta content="https://commons.oceanprotocol.com" property="og:url" />
<meta content="Commons" property="og:title" />
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
property="og:description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
property="og:image"
/>
<meta content="summary_large_image" name="twitter:card" />
<meta content="@oceanprotocol" name="twitter:creator" />
<meta content="Commons" name="twitter:title" />
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
name="twitter:description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
name="twitter:image"
/>
<style>
.loader {
display: block;

View File

@ -21,5 +21,5 @@
"start_url": ".",
"display": "standalone",
"theme_color": "#141414",
"background_color": "#141414"
"background_color": "#ffffff"
}

2
client/public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow: /search

View File

@ -0,0 +1 @@
declare module 'react-collapsed'

View File

@ -0,0 +1,71 @@
import React from 'react'
import Helmet from 'react-helmet'
import { withRouter, RouteComponentProps } from 'react-router-dom'
import meta from '../../data/meta.json'
import imageDefault from '../../img/share.png'
const MetaTags = ({
title,
description,
url,
image
}: {
title: string
description: string
url: string
image: string
}) => (
<Helmet defaultTitle={meta.title} titleTemplate={`%s - ${meta.title}`}>
<html lang="en" />
{title && <title>{title}</title>}
{/* General tags */}
<meta name="description" content={description} />
<meta name="image" content={image} />
<link rel="canonical" href={url} />
{/* OpenGraph tags */}
<meta property="og:url" content={url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
{/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content="@oceanprotocol" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} />
{/* Prevent search engine indexing except for live */}
{window.location.hostname !== 'commons.oceanprotocol.com' && (
<meta name="robots" content="noindex,nofollow" />
)}
</Helmet>
)
interface SeoProps extends RouteComponentProps {
title?: string
description?: string
shareImage?: string
}
const Seo = ({ title, description, shareImage, location }: SeoProps) => {
title = title || meta.title
description = description || meta.description
shareImage = shareImage || meta.url + imageDefault
const url = meta.url + location.pathname + location.search
return (
<MetaTags
title={title}
description={description}
url={url}
image={shareImage}
/>
)
}
export default withRouter(Seo)

View File

@ -1,87 +0,0 @@
import React, { Fragment } from 'react'
import { VersionNumbersState as VersionTableProps } from '.'
import styles from './VersionTable.module.scss'
import slugify from '@sindresorhus/slugify'
import Spinner from '../Spinner'
const VersionTableContracts = ({
contracts,
network
}: {
contracts: any
network: string
}) => (
<table>
<tbody>
{contracts &&
Object.keys(contracts).map(key => (
<tr key={key}>
<td>
<span className={styles.label}>{key}</span>
</td>
<td>
<a
href={`https://submarine${network === 'duero' &&
'.duero'}.dev-ocean.com/address/${
contracts[key]
}`}
>
<code>{contracts[key]}</code>
</a>
</td>
</tr>
))}
</tbody>
</table>
)
const VersionTable = ({ data }: { data: VersionTableProps }) => (
<div className={styles.tableWrap}>
<table className={styles.table}>
<tbody>
{Object.entries(data).map(([key, value]) => (
<Fragment key={key}>
<tr key={key}>
<td>
<a
href={
value.software &&
`https://github.com/oceanprotocol/${slugify(
value.software
)}`
}
>
<strong>{value.software}</strong>
</a>
</td>
<td>
{value.isLoading ? (
<Spinner small className={styles.spinner} />
) : value.version ? (
<>
<code>v{value.version}</code>
{value.network && `(${value.network})`}
</>
) : (
'Could not get version'
)}
</td>
</tr>
{key === 'keeperContracts' && data.brizo.contracts && (
<tr>
<td colSpan={2}>
<VersionTableContracts
contracts={data.brizo.contracts}
network={data.brizo.network}
/>
</td>
</tr>
)}
</Fragment>
))}
</tbody>
</table>
</div>
)
export default VersionTable

View File

@ -1,121 +0,0 @@
import React from 'react'
import { render, waitForElement } from '@testing-library/react'
import mockAxios from 'jest-mock-axios'
import { StateMock } from '@react-mock/state'
import { version as versionSquid } from '@oceanprotocol/squid/package.json'
import VersionNumbers, { commonsVersion } from '.'
afterEach(() => {
mockAxios.reset()
})
const stateMock = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
},
aquarius: {
isLoading: false,
software: 'Aquarius',
version: ''
},
brizo: {
isLoading: false,
software: 'Brizo',
version: '',
contracts: {},
network: '',
'keeper-version': '0.0.0',
'keeper-url': ''
},
keeperContracts: {
isLoading: false,
software: 'Keeper Contracts',
version: '',
contracts: {},
network: ''
},
faucet: {
isLoading: false,
software: 'Faucet',
version: ''
}
}
const stateMockIncomplete = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
},
aquarius: {
isLoading: false,
software: 'Aquarius',
version: undefined
},
brizo: {
isLoading: false,
software: 'Brizo',
version: undefined,
contracts: undefined,
network: undefined,
'keeper-version': undefined,
'keeper-url': undefined
},
keeperContracts: {
isLoading: false,
software: 'Keeper Contracts',
version: undefined,
contracts: undefined,
network: undefined
},
faucet: {
isLoading: false,
software: 'Faucet',
version: undefined
}
}
const mockResponse = {
data: {
software: 'Brizo',
version: '6.6.6',
contracts: { Hello: 'Hello', Another: 'Hello' },
network: 'hello',
'keeper-url': 'https://squid.com',
'keeper-version': '6.6.6'
}
}
const mockResponseFaulty = {
status: 404,
statusText: 'Not Found',
data: {}
}
describe('VersionNumbers', () => {
it('renders without crashing', () => {
const { container } = render(
<StateMock state={stateMock}>
<VersionNumbers />
</StateMock>
)
mockAxios.mockResponse(mockResponse)
expect(mockAxios.get).toHaveBeenCalled()
expect(container.firstChild).toBeInTheDocument()
})
it('renders without proper component response', () => {
const { container } = render(
<StateMock state={stateMockIncomplete}>
<VersionNumbers />
</StateMock>
)
mockAxios.mockResponse(mockResponseFaulty)
expect(mockAxios.get).toHaveBeenCalled()
expect(container.querySelector('table')).toHaveTextContent(
'Could not get version'
)
})
})

View File

@ -1,199 +0,0 @@
import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid'
import axios from 'axios'
import { version } from '../../../../package.json'
import { version as versionSquid } from '@oceanprotocol/squid/package.json'
import styles from './index.module.scss'
import { aquariusUri, brizoUri, faucetUri } from '../../../config'
import VersionTable from './VersionTable'
import { isJsonString } from './utils'
export const commonsVersion =
process.env.NODE_ENV === 'production' ? version : `${version}-dev`
interface VersionNumbersProps {
minimal?: boolean
}
export interface VersionNumbersState {
commons: {
software: string
version: string
}
squidJs: {
software: string
version: string
}
aquarius: {
isLoading: boolean
software: string
version: string
}
brizo: {
isLoading: boolean
software: string
version: string
network: string
'keeper-version': string
'keeper-url': string
contracts: any
}
keeperContracts: {
isLoading: boolean
software: string
version: string
network: string
contracts: any
}
faucet: {
isLoading: boolean
software?: string
version?: string
}
}
export default class VersionNumbers extends PureComponent<
VersionNumbersProps,
VersionNumbersState
> {
public state = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
},
aquarius: {
isLoading: true,
software: 'Aquarius',
version: ''
},
brizo: {
isLoading: true,
software: 'Brizo',
version: '',
contracts: {} as any,
network: '',
'keeper-version': '0.0.0',
'keeper-url': ''
},
keeperContracts: {
isLoading: true,
software: 'Keeper Contracts',
version: '',
contracts: {} as any,
network: ''
},
faucet: {
isLoading: true,
software: 'Faucet',
version: ''
}
}
// for canceling axios requests
public signal = axios.CancelToken.source()
public componentWillMount() {
this.setAquarius()
this.setBrizoAndKeeper()
this.setFaucet()
}
public componentWillUnmount() {
this.signal.cancel()
}
private async setAquarius() {
const aquarius = await this.getData(aquariusUri)
aquarius &&
aquarius.version !== undefined &&
this.setState({ aquarius: { isLoading: false, ...aquarius } })
}
private async setBrizoAndKeeper() {
const brizo = await this.getData(brizoUri)
const keeperVersion =
brizo['keeper-version'] && brizo['keeper-version'].replace('v', '')
const keeperNetwork =
brizo['keeper-url'] &&
new URL(brizo['keeper-url']).hostname.split('.')[0]
brizo &&
brizo.version !== undefined &&
this.setState({
brizo: {
isLoading: false,
...brizo
},
keeperContracts: {
...this.state.keeperContracts,
isLoading: false,
version: keeperVersion,
contracts: brizo.contracts,
network: keeperNetwork
}
})
}
private async setFaucet() {
const faucet = await this.getData(faucetUri)
// backwards compatibility
isJsonString(faucet) === false &&
this.setState({
faucet: { ...this.state.faucet, isLoading: false }
})
// the new thing
faucet &&
faucet.version !== undefined &&
this.setState({ faucet: { isLoading: false, ...faucet } })
}
private async getData(uri: string) {
try {
const response = await axios.get(uri, {
headers: { Accept: 'application/json' },
cancelToken: this.signal.token
})
// fail silently
if (response.status !== 200) return
return response.data
} catch (error) {
!axios.isCancel(error) && Logger.error(error.message)
}
}
public render() {
const { minimal } = this.props
const { commons, squidJs, brizo, aquarius, faucet } = this.state
const mimimalOutput = `${squidJs.software} v${squidJs.version} \n${
brizo.software
} v${brizo.version} \n${aquarius.software} v${
aquarius.version
} \nKeeper Contracts ${brizo['keeper-version']} \n${faucet.software} v${
faucet.version
}`
return minimal ? (
<p className={styles.versionsMinimal}>
<a title={mimimalOutput} href={'/about'}>
v{commons.version} {brizo.network && `(${brizo.network})`}
</a>
</p>
) : (
<div className={styles.versions} id="#oceanversions">
<h2 className={styles.versionsTitle}>
Ocean Components in use
</h2>
<VersionTable data={this.state} />
</div>
)
}
}

View File

@ -1,11 +0,0 @@
import { isJsonString } from './utils'
describe('isJsonString', () => {
it('detects json correctly', () => {
const testJson = isJsonString('{ "hello": "squid" }')
expect(testJson).toBeTruthy()
const testNonJson = isJsonString('<strong>')
expect(testNonJson).toBeFalsy()
})
})

View File

@ -1,8 +0,0 @@
export function isJsonString(str: string) {
try {
JSON.parse(str)
} catch (e) {
return false
}
return true
}

View File

@ -0,0 +1,22 @@
@import '../../../styles/variables';
.spinner {
composes: spinner, small from '../../atoms/Spinner.module.scss';
margin-right: $spacer;
}
.commit {
margin-left: $spacer / 8;
code {
color: $brand-grey-light;
font-size: $font-size-mini;
}
}
.network {
color: $brand-grey-light;
text-transform: capitalize;
margin-left: $spacer / 8;
font-size: $font-size-mini;
}

View File

@ -0,0 +1,23 @@
import React from 'react'
import { render } from '@testing-library/react'
import VersionNumber from './VersionNumber'
describe('VersionNumber', () => {
it('renders without crashing', () => {
const { container } = render(<VersionNumber name="Commons" />)
expect(container.firstChild).toBeInTheDocument()
})
it('renders with all props set', () => {
const { container } = render(
<VersionNumber
name="Commons"
version="6.6.6"
network="Nile"
commit="xxxxxxxxxxx"
/>
)
expect(container.firstChild).toBeInTheDocument()
expect(container.firstChild).toHaveTextContent('6.6.6')
})
})

View File

@ -0,0 +1,53 @@
import React from 'react'
import { OceanPlatformTechStatus } from '@oceanprotocol/squid'
import slugify from '@sindresorhus/slugify'
import Spinner from '../../atoms/Spinner'
import styles from './VersionNumber.module.scss'
const VersionNumber = ({
name,
version,
network,
status,
commit
}: {
name: string
version?: string
network?: string
status?: OceanPlatformTechStatus
commit?: string
}) =>
version ? (
<>
<a
href={`https://github.com/oceanprotocol/${slugify(
name
)}/releases/tag/v${version}`}
title="Go to release on GitHub"
>
<code>v{version}</code>
</a>
{commit && (
<a
href={`https://github.com/oceanprotocol/${slugify(
name
)}/commit/${commit}`}
className={styles.commit}
title={`Go to commit ${commit} on GitHub`}
>
<code>{commit.substring(0, 7)}</code>
</a>
)}
{network && <span className={styles.network}>{` ${network}`}</span>}
</>
) : (
<span>
{status === OceanPlatformTechStatus.Loading ? (
<Spinner className={styles.spinner} small />
) : (
status || 'Could not get version'
)}
</span>
)
export default VersionNumber

View File

@ -0,0 +1,37 @@
@import '../../../styles/variables';
.status {
text-align: center;
padding-top: $spacer / 2;
padding-bottom: $spacer;
display: flex;
justify-content: space-between;
}
.element {
display: inline-block;
margin-left: $spacer / 2;
margin-right: $spacer / 2;
text-align: center;
}
.indicator,
.indicatorActive {
display: inline-block;
margin-right: $spacer / 4;
margin-bottom: -.1rem;
}
.indicator {
composes: statusIndicator from '../AccountStatus/Indicator.module.scss';
}
.indicatorActive {
composes: statusIndicatorActive from '../AccountStatus/Indicator.module.scss';
}
.indicatorLabel {
font-family: $font-family-title;
color: $brand-grey;
text-transform: capitalize;
}

View File

@ -0,0 +1,23 @@
import React from 'react'
import { render } from '@testing-library/react'
import VersionStatus from './VersionStatus'
describe('VersionStatus', () => {
it('renders without crashing', () => {
const { container } = render(
<VersionStatus
status={{ ok: false, contracts: false, network: false }}
/>
)
expect(container.firstChild).toBeInTheDocument()
})
it('renders true states', () => {
const { container } = render(
<VersionStatus
status={{ ok: true, contracts: false, network: false }}
/>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -0,0 +1,41 @@
import React from 'react'
import styles from './VersionStatus.module.scss'
const statusInfo: { [key: string]: string } = {
ok: 'Shows if connection to all component endpoints can be established.',
network: 'Shows if all components are on the same network.',
contracts: 'Shows if contracts loaded by components are the same version.'
}
const VersionStatus = ({
status
}: {
status: { ok: boolean; network: boolean; contracts: boolean }
}) => {
return (
<div className={styles.status}>
{Object.entries(status).map(([key, value]) => (
<div
className={styles.element}
key={key}
title={statusInfo[key]}
>
<span
className={
value === true
? styles.indicatorActive
: styles.indicator
}
>
{value}
</span>
<span className={styles.indicatorLabel}>
{key === 'ok' ? 'components' : key}
</span>
</div>
))}
</div>
)
}
export default VersionStatus

View File

@ -7,11 +7,9 @@
}
.table {
display: table;
border-top: 1px solid $brand-grey-lighter;
table {
display: table;
margin-left: $spacer;
width: calc(100% - #{$spacer});
margin-bottom: -1px;
@ -29,6 +27,7 @@
td {
padding: $spacer / 4 $spacer / 2;
vertical-align: top;
&:last-child {
text-align: right;
@ -53,7 +52,6 @@
}
}
.spinner {
composes: spinner, small from '../Spinner.module.scss';
margin-right: $spacer;
.label {
min-width: 15rem;
}

View File

@ -0,0 +1,40 @@
import React from 'react'
import { render } from '@testing-library/react'
import { VersionTableContracts } from './VersionTable'
describe('VersionTableContracts', () => {
it('renders without crashing', () => {
const { container } = render(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="nile"
keeperVersion="6.6.6"
/>
)
expect(container.firstChild).toBeInTheDocument()
})
it('renders correct Submarine links', () => {
const { container, rerender } = render(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="duero"
keeperVersion="6.6.6"
/>
)
expect(container.querySelector('tr:last-child a').href).toMatch(
/submarine.duero.dev-ocean/
)
rerender(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="pacific"
keeperVersion="6.6.6"
/>
)
expect(container.querySelector('tr:last-child a').href).toMatch(
/submarine.pacific.dev-ocean/
)
})
})

View File

@ -0,0 +1,114 @@
import React from 'react'
import { VersionNumbersState } from '.'
import VersionTableRow from './VersionTableRow'
import styles from './VersionTable.module.scss'
import VersionNumber from './VersionNumber'
import {
serviceUri,
nodeUri,
aquariusUri,
brizoUri,
brizoAddress,
secretStoreUri,
faucetUri
} from '../../../config'
const commonsConfig = {
serviceUri,
nodeUri,
aquariusUri,
brizoUri,
brizoAddress,
secretStoreUri,
faucetUri
}
export const VersionTableContracts = ({
contracts,
network,
keeperVersion
}: {
contracts: {
[contractName: string]: string
}
network: string
keeperVersion?: string
}) => (
<table>
<tbody>
<tr>
<td>
<strong>Keeper Contracts</strong>
</td>
<td>
<VersionNumber
name={'Keeper Contracts'}
version={keeperVersion}
/>
</td>
</tr>
{contracts &&
Object.keys(contracts)
// sort alphabetically
.sort((a, b) => a.localeCompare(b))
.map(key => {
const submarineLink = `https://submarine${
network === 'duero'
? '.duero'
: network === 'pacific'
? '.pacific'
: ''
}.dev-ocean.com/address/${contracts[key]}`
return (
<tr key={key}>
<td>
<code className={styles.label}>{key}</code>
</td>
<td>
<a href={submarineLink}>
<code>{contracts[key]}</code>
</a>
</td>
</tr>
)
})}
</tbody>
</table>
)
export const VersionTableCommons = () => (
<table>
<tbody>
{Object.entries(commonsConfig).map(([key, value]) => (
<tr key={key}>
<td>
<code className={styles.label}>{key}</code>
</td>
<td>
<code>{value}</code>
</td>
</tr>
))}
</tbody>
</table>
)
const VersionTable = ({ data }: { data: VersionNumbersState }) => {
return (
<div className={styles.tableWrap}>
<table className={styles.table}>
<tbody>
{Object.entries(data)
.filter(([key]) => key !== 'status')
.map(([key, value]) => (
<VersionTableRow key={key} value={value} />
))}
</tbody>
</table>
</div>
)
}
export default VersionTable

View File

@ -0,0 +1,15 @@
@import '../../../styles/variables';
.handle {
display: inline-block;
border: 0;
background: none;
box-shadow: none;
padding: 0;
margin: 0;
margin-left: -1rem;
margin-top: -.1rem;
padding-right: .5rem;
cursor: pointer;
color: $brand-grey-light;
}

View File

@ -0,0 +1,76 @@
import React from 'react'
import useCollapse from 'react-collapsed'
import slugify from '@sindresorhus/slugify'
import styles from './VersionTableRow.module.scss'
import { VersionTableContracts, VersionTableCommons } from './VersionTable'
import VersionNumber from './VersionNumber'
const VersionTableRow = ({ value }: { value: any }) => {
const collapseStyles = {
transitionDuration: '0.01s'
}
const expandStyles = {
transitionDuration: '0.01s',
transitionTimingFunction: 'ease-out'
}
const { getCollapseProps, getToggleProps, isOpen } = useCollapse({
collapseStyles,
expandStyles
})
return (
<>
<tr>
<td>
{(value.name === 'Commons' || value.contracts) && (
<button className={styles.handle} {...getToggleProps()}>
{isOpen ? (
<span>&#9660;</span>
) : (
<span>&#9658;</span>
)}
</button>
)}
<a
href={`https://github.com/oceanprotocol/${slugify(
value.name || value.software
)}`}
>
<strong>{value.name || value.software}</strong>
</a>
</td>
<td>
<VersionNumber
name={value.name || value.software}
version={value.version}
status={value.status}
network={value.network}
commit={value.commit}
/>
</td>
</tr>
{value.name === 'Commons' && (
<tr {...getCollapseProps()}>
<td colSpan={2}>
<VersionTableCommons />
</td>
</tr>
)}
{value.contracts && (
<tr {...getCollapseProps()}>
<td colSpan={2}>
<VersionTableContracts
contracts={value.contracts}
network={value.network || ''}
keeperVersion={value.keeperVersion}
/>
</td>
</tr>
)}
</>
)
}
export default VersionTableRow

View File

@ -0,0 +1,85 @@
import React from 'react'
import { render } from '@testing-library/react'
import mockAxios from 'jest-mock-axios'
import { StateMock } from '@react-mock/state'
import VersionNumbers from '.'
import { User } from '../../../context'
import { userMockConnected } from '../../../../__mocks__/user-mock'
afterEach(() => {
mockAxios.reset()
})
const stateMockIncomplete = {
commons: {
name: 'Commons',
version: undefined
},
squid: {
name: 'Squid-js',
version: undefined
},
aquarius: {
name: 'Aquarius',
version: undefined
},
brizo: {
name: 'Brizo',
version: undefined,
contracts: undefined,
network: undefined,
keeperVersion: undefined,
keeperUrl: undefined
},
faucet: {
name: 'Faucet',
version: undefined
},
status: {
ok: false,
network: false,
contracts: false
}
}
const mockResponse = {
data: {
software: 'Faucet',
version: '6.6.6'
}
}
const mockResponseFaulty = {
status: 404,
statusText: 'Not Found',
data: {}
}
describe('VersionNumbers', () => {
it('renders without crashing', () => {
const { container } = render(
<User.Provider value={userMockConnected}>
<VersionNumbers />
</User.Provider>
)
mockAxios.mockResponse(mockResponse)
expect(mockAxios.get).toHaveBeenCalled()
expect(container.firstChild).toBeInTheDocument()
})
it('renders without proper component response', () => {
const { container } = render(
<User.Provider value={userMockConnected}>
<StateMock state={stateMockIncomplete}>
<VersionNumbers />
</StateMock>
</User.Provider>
)
mockAxios.mockResponse(mockResponseFaulty)
expect(mockAxios.get).toHaveBeenCalled()
expect(container.querySelector('table')).toHaveTextContent(
'Could not get version'
)
})
})

View File

@ -0,0 +1,163 @@
import React, { PureComponent } from 'react'
import {
OceanPlatformVersions,
OceanPlatformTechStatus,
Logger
} from '@oceanprotocol/squid'
import axios from 'axios'
import { version } from '../../../../package.json'
import styles from './index.module.scss'
import { nodeUri, faucetUri } from '../../../config'
import { User } from '../../../context'
import VersionTable from './VersionTable'
import VersionStatus from './VersionStatus'
// construct values which are not part of any response
export const commonsVersion =
process.env.NODE_ENV === 'production' ? version : `${version}-dev`
const commonsNetwork = new URL(nodeUri).hostname.split('.')[0]
const faucetNetwork = new URL(faucetUri).hostname.split('.')[1]
interface VersionNumbersProps {
minimal?: boolean
}
export interface VersionNumbersState extends OceanPlatformVersions {
commons: {
name: string
version: string
network: string
}
faucet: {
name: string
version: string
network: string
status: OceanPlatformTechStatus
}
}
export default class VersionNumbers extends PureComponent<
VersionNumbersProps,
VersionNumbersState
> {
public static contextType = User
// define a minimal default state to fill UI
public state: VersionNumbersState = {
commons: {
name: 'Commons',
network: commonsNetwork,
version: commonsVersion
},
squid: {
name: 'Squid-js',
status: OceanPlatformTechStatus.Loading
},
aquarius: {
name: 'Aquarius',
status: OceanPlatformTechStatus.Loading
},
brizo: {
name: 'Brizo',
status: OceanPlatformTechStatus.Loading
},
faucet: {
name: 'Faucet',
version: '',
network: faucetNetwork,
status: OceanPlatformTechStatus.Loading
},
status: {
ok: false,
network: false,
contracts: false
}
}
// for canceling axios requests
public signal = axios.CancelToken.source()
public async componentDidMount() {
this.getOceanVersions()
this.getFaucetVersion()
}
public componentWillUnmount() {
this.signal.cancel()
}
private async getOceanVersions() {
const { ocean } = this.context
// wait until ocean object is properly populated
if (ocean.versions === undefined) return
const response = await ocean.versions.get()
const { squid, brizo, aquarius, status } = response
this.setState({
...this.state,
squid,
brizo,
aquarius,
status
})
}
private async getFaucetVersion() {
try {
const response = await axios.get(faucetUri, {
headers: { Accept: 'application/json' },
cancelToken: this.signal.token
})
// fail silently
if (response.status !== 200) return
this.setState({
...this.state,
faucet: {
...this.state.faucet,
version: response.data.version,
status: OceanPlatformTechStatus.Working
}
})
} catch (error) {
!axios.isCancel(error) && Logger.error(error.message)
}
}
private MinimalOutput = () => {
const { commons, squid, brizo, aquarius } = this.state
return (
<p className={styles.versionsMinimal}>
<a
title={`${squid.name} v${squid.version}\n${brizo.name} v${
brizo.version
}\n${aquarius.name} v${aquarius.version}`}
href={'/about'}
>
v{commons.version} {squid.network && `(${squid.network})`}
</a>
</p>
)
}
public render() {
const { minimal } = this.props
return minimal ? (
<this.MinimalOutput />
) : (
<div className={styles.versions} id="#oceanversions">
<h2 className={styles.versionsTitle}>
Ocean Components Status
</h2>
<VersionStatus status={this.state.status} />
<VersionTable data={this.state} />
</div>
)
}
}

View File

@ -5,7 +5,7 @@ import { ReactComponent as AiCommons } from '../../img/aicommons.svg'
import styles from './Footer.module.scss'
import meta from '../../data/meta.json'
import VersionNumbers from '../atoms/VersionNumbers'
import VersionNumbers from '../molecules/VersionNumbers'
const Footer = () => (
<footer className={styles.footer}>

View File

@ -10,7 +10,6 @@ import CategoryImage from '../../atoms/CategoryImage'
import styles from './index.module.scss'
interface AssetProps {
location: Location
match: {
params: {
did: string

View File

@ -4,6 +4,7 @@ import Channel from './Channel'
import { User } from '../../context'
import { createMemoryHistory } from 'history'
import { userMockConnected } from '../../../__mocks__/user-mock'
import { MemoryRouter } from 'react-router'
describe('Channel', () => {
it('renders without crashing', () => {
@ -11,12 +12,14 @@ describe('Channel', () => {
const { container } = render(
<User.Provider value={userMockConnected}>
<Channel
match={{
params: { channel: 'ai-for-good' }
}}
history={history}
/>
<MemoryRouter>
<Channel
match={{
params: { channel: 'ai-for-good' }
}}
history={history}
/>
</MemoryRouter>
</User.Provider>
)
expect(container.firstChild).toBeInTheDocument()

View File

@ -1,18 +1,25 @@
import React from 'react'
import { render } from '@testing-library/react'
import Route from './Route'
import { BrowserRouter as Router } from 'react-router-dom'
describe('Route', () => {
it('renders without crashing', () => {
const { container } = render(<Route title="Hello Title">Hello</Route>)
const { container } = render(
<Router>
<Route title="Hello Title">Hello</Route>
</Router>
)
expect(container.firstChild).toBeInTheDocument()
})
it('renders title & description', () => {
const { container } = render(
<Route title="Hello Title" description="Hello Description">
Hello
</Route>
<Router>
<Route title="Hello Title" description="Hello Description">
Hello
</Route>
</Router>
)
expect(container.querySelector('.title')).toHaveTextContent(
'Hello Title'

View File

@ -1,51 +1,59 @@
import React from 'react'
import Helmet from 'react-helmet'
import Content from '../atoms/Content'
import styles from './Route.module.scss'
import meta from '../../data/meta.json'
import Markdown from '../atoms/Markdown'
import Seo from '../atoms/Seo'
interface RouteProps {
title: string
description?: string
image?: any
shareImage?: string
children: any
wide?: boolean
className?: string
}
const Route = ({
title,
description,
image,
shareImage,
wide,
children,
className
}: {
title: string
description?: string
image?: any
children: any
wide?: boolean
className?: string
}) => (
<div className={className}>
<Helmet defaultTitle={meta.title} titleTemplate={`%s - ${meta.title}`}>
{/* Strip HTML from passed title */}
<title>{title.replace(/(<([^>]+)>)/gi, '')}</title>
{description && <meta name="description" content={description} />}
</Helmet>
}: RouteProps) => {
// Strip HTML from passed title
const titleSanitized = title.replace(/(<([^>]+)>)/gi, '')
<article>
<header className={styles.header}>
<Content wide={wide}>
<h1 className={styles.title}>{title}</h1>
return (
<div className={className}>
<Seo
title={titleSanitized}
description={description}
shareImage={shareImage}
/>
{image && image}
<article>
<header className={styles.header}>
<Content wide={wide}>
<h1 className={styles.title}>{titleSanitized}</h1>
{description && (
<Markdown
text={description}
className={styles.description}
/>
)}
</Content>
</header>
{image && image}
{children}
</article>
</div>
)
{description && (
<Markdown
text={description}
className={styles.description}
/>
)}
</Content>
</header>
{children}
</article>
</div>
)
}
export default Route

View File

@ -153,14 +153,16 @@ export default class UserProvider extends PureComponent<{}, UserProviderState> {
await window.web3.eth.net.getId((err, netId) => {
if (err) return
const isPacific = netId === 0xcea11
const isNile = netId === 8995
const isDuero = netId === 2199
const isSpree = netId === 8996
const isPacific = netId === 846353
isOceanNetwork = isNile || isDuero || isSpree || isPacific
isOceanNetwork = isPacific || isNile || isDuero || isSpree
const network = isNile
const network = isPacific
? 'Pacific'
: isNile
? 'Nile'
: isDuero
? 'Duero'
@ -258,11 +260,11 @@ export default class UserProvider extends PureComponent<{}, UserProviderState> {
if (isWeb3) {
const network = await ocean.keeper.getNetworkName()
const isPacific = network === 'Pacific'
const isNile = network === 'Nile'
const isDuero = network === 'Duero'
const isSpree = network === 'Spree'
const isPacific = network === 'Pacific'
const isOceanNetwork = isNile || isDuero || isSpree || isPacific
const isOceanNetwork = isPacific || isNile || isDuero || isSpree
network !== this.state.network &&
this.setState({ isOceanNetwork, network })

View File

@ -2,6 +2,7 @@
"title": "Commons",
"description": "A marketplace to find and publish open data sets in the Ocean Network.",
"company": "Ocean Protocol Foundation Ltd.",
"url": "https://commons.oceanprotocol.com",
"social": [
{
"title": "Site",

BIN
client/src/img/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@ -1,10 +1,15 @@
import React from 'react'
import { render } from '@testing-library/react'
import { MemoryRouter } from 'react-router'
import About from './About'
describe('About', () => {
it('renders without crashing', () => {
const { container } = render(<About />)
const { container } = render(
<MemoryRouter>
<About />
</MemoryRouter>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'
import Route from '../components/templates/Route'
import Content from '../components/atoms/Content'
import VersionNumbers from '../components/atoms/VersionNumbers'
import VersionNumbers from '../components/molecules/VersionNumbers'
class About extends Component {
public render() {

View File

@ -1,5 +1,5 @@
import React from 'react'
import { BrowserRouter as Router } from 'react-router-dom'
import { MemoryRouter } from 'react-router'
import { render } from '@testing-library/react'
import Channels from './Channels'
import { User } from '../context'
@ -9,9 +9,9 @@ describe('Channels', () => {
it('renders without crashing', () => {
const { container } = render(
<User.Provider value={userMockConnected}>
<Router>
<MemoryRouter>
<Channels />
</Router>
</MemoryRouter>
</User.Provider>
)
expect(container.firstChild).toBeInTheDocument()

View File

@ -25,6 +25,13 @@
overflow-wrap: break-word;
display: inline;
}
a:hover,
a:focus {
code {
color: inherit;
}
}
}
.error {

View File

@ -1,5 +1,6 @@
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import { MemoryRouter } from 'react-router'
import Faucet from './Faucet'
import { User } from '../context'
import { userMockConnected } from '../../__mocks__/user-mock'
@ -7,7 +8,9 @@ import { userMockConnected } from '../../__mocks__/user-mock'
const setup = () => {
const utils = render(
<User.Provider value={userMockConnected}>
<Faucet />
<MemoryRouter>
<Faucet />
</MemoryRouter>
</User.Provider>
)
const button = utils.getByText('Request Ether')
@ -21,7 +24,7 @@ const setup = () => {
describe('Faucet', () => {
it('renders without crashing', () => {
const { container } = render(<Faucet />)
const { container } = setup()
expect(container.firstChild).toBeInTheDocument()
})

View File

@ -16,6 +16,8 @@ interface FaucetState {
}
export default class Faucet extends PureComponent<{}, FaucetState> {
public static contextType = User
public state = {
isLoading: false,
success: undefined,
@ -59,15 +61,31 @@ export default class Faucet extends PureComponent<{}, FaucetState> {
})
}
private Success = () => (
<div className={styles.success}>
<strong>{this.state.success}</strong>
<p>
<strong>Your Transaction Hash</strong>
<code>{this.state.trxHash}</code>
</p>
</div>
)
private Success = () => {
const { network } = this.context
const { trxHash } = this.state
const submarineLink = `https://submarine${
network === 'Duero'
? '.duero'
: network === 'Pacific'
? '.pacific'
: ''
}.dev-ocean.com/tx/${trxHash}`
return (
<div className={styles.success}>
<strong>{this.state.success}</strong>
<p>
<strong>Your Transaction Hash</strong>
<a href={submarineLink}>
<code>{trxHash}</code>
</a>
</p>
</div>
)
}
private Error = () => (
<div className={styles.error}>

View File

@ -1,11 +1,16 @@
import React from 'react'
import { render } from '@testing-library/react'
import { MemoryRouter } from 'react-router'
import { User } from '../context'
import History from './History'
describe('History', () => {
it('renders without crashing', () => {
const { container } = render(<History />)
const { container } = render(
<MemoryRouter>
<History />
</MemoryRouter>
)
expect(container.firstChild).toBeInTheDocument()
})
@ -27,7 +32,9 @@ describe('History', () => {
const { container } = render(
<User.Provider value={context}>
<History />
<MemoryRouter>
<History />
</MemoryRouter>
</User.Provider>
)
expect(container.querySelector('.message')).toBeInTheDocument()

View File

@ -1,10 +1,15 @@
import React from 'react'
import { render } from '@testing-library/react'
import NotFound from './NotFound'
import { MemoryRouter } from 'react-router'
describe('NotFound', () => {
it('renders without crashing', () => {
const { container } = render(<NotFound />)
const { container } = render(
<MemoryRouter>
<NotFound />
</MemoryRouter>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -17,7 +17,7 @@ const Item = ({
}) => (
<li>
<a href={item.url} className={styles.linkUrl} title={item.url}>
<Dotdotdot clamp={1}>{item.url}</Dotdotdot>
<Dotdotdot clamp={2}>{item.url}</Dotdotdot>
</a>
<div className={styles.details}>
<span>URL {item.found ? 'confirmed' : ' not confirmed'}</span>

View File

@ -1,11 +1,15 @@
import React from 'react'
import { render, fireEvent, waitForElement } from '@testing-library/react'
import { FetchMock } from '@react-mock/fetch'
import mockAxios from 'jest-mock-axios'
import { serviceUri } from '../../../config'
import Files from '.'
const onChange = jest.fn()
afterEach(() => {
mockAxios.reset()
})
const files = [
{
url: 'https://hello.com',
@ -20,31 +24,25 @@ const files = [
}
]
const mockResponse = {
data: {
result: {
url: 'https://demo.com',
contentType: 'application/zip',
contentLength: 237347827,
found: true
}
}
}
const renderComponent = () =>
render(
<FetchMock
mocks={[
{
matcher: `${serviceUri}/api/v1/urlcheck`,
method: 'POST',
response: {
result: {
url: 'https://demo.com',
contentType: 'application/zip',
contentLength: 237347827,
found: true
}
}
}
]}
>
<Files
files={files}
placeholder={'Hello'}
name={'Hello'}
onChange={onChange}
/>
</FetchMock>
<Files
files={files}
placeholder={'Hello'}
name={'Hello'}
onChange={onChange}
/>
)
describe('Files', () => {
@ -85,5 +83,7 @@ describe('Files', () => {
target: { value: 'https://hello.com' }
})
fireEvent.click(getByText('Add File'))
mockAxios.mockResponse(mockResponse)
expect(mockAxios).toHaveBeenCalled()
})
})

View File

@ -1,5 +1,6 @@
import React, { FormEvent, PureComponent, ChangeEvent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import axios from 'axios'
import Button from '../../../components/atoms/Button'
import Help from '../../../components/atoms/Form/Help'
import ItemForm from './ItemForm'
@ -45,6 +46,13 @@ export default class Files extends PureComponent<FilesProps, FilesStates> {
isFormShown: false
}
// for canceling axios requests
public signal = axios.CancelToken.source()
public componentWillUnmount() {
this.signal.cancel()
}
private toggleForm = (e: Event) => {
e.preventDefault()
@ -59,23 +67,21 @@ export default class Files extends PureComponent<FilesProps, FilesStates> {
}
try {
const response = await fetch(`${serviceUri}/api/v1/urlcheck`, {
const response = await axios({
method: 'POST',
body: JSON.stringify({ url: value }),
headers: {
'Content-Type': 'application/json'
}
headers: { 'Content-Type': 'application/json' },
url: `${serviceUri}/api/v1/urlcheck`,
data: { url: value },
cancelToken: this.signal.token
})
const json = await response.json()
const { contentLength, contentType, found } = json.result
const { contentLength, contentType, found } = response.data.result
file.contentLength = contentLength
file.contentType = contentType
file.compression = await cleanupContentType(contentType)
file.found = found
} catch (error) {
Logger.error(error.message)
!axios.isCancel(error) && Logger.error(error.message)
}
this.props.files.push(file)

View File

@ -1,4 +1,5 @@
import React from 'react'
import { MemoryRouter } from 'react-router'
import { render, fireEvent } from '@testing-library/react'
import Publish from '.'
import { User } from '../../context'
@ -8,7 +9,9 @@ describe('Publish', () => {
it('renders without crashing', () => {
const { container, getByText } = render(
<User.Provider value={userMockConnected}>
<Publish />
<MemoryRouter>
<Publish />
</MemoryRouter>
</User.Provider>
)
expect(container.firstChild).toBeInTheDocument()
@ -18,7 +21,9 @@ describe('Publish', () => {
it('next button works', () => {
const { getByText, getByLabelText, getByTestId } = render(
<User.Provider value={userMockConnected}>
<Publish />
<MemoryRouter>
<Publish />
</MemoryRouter>
</User.Provider>
)

View File

@ -1,10 +1,15 @@
import React from 'react'
import { render } from '@testing-library/react'
import Styleguide from './Styleguide'
import { MemoryRouter } from 'react-router'
describe('Styleguide', () => {
it('renders without crashing', () => {
const { container } = render(<Styleguide />)
const { container } = render(
<MemoryRouter>
<Styleguide />
</MemoryRouter>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -239,11 +239,6 @@ table {
width: 100%;
margin-bottom: $spacer * $line-height;
border-collapse: collapse;
display: block;
// make 'em scrollable
overflow: auto;
-webkit-overflow-scrolling: touch;
th,
td {

View File

@ -19,7 +19,7 @@
},
{
"name": "squid-js",
"version": "~0.5.14"
"version": "~0.5.17"
},
{
"name": "faucet",

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "commons",
"version": "0.5.0",
"version": "0.5.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,7 +1,7 @@
{
"name": "commons",
"description": "Ocean Protocol marketplace to explore, download, and publish open data sets.",
"version": "0.5.0",
"version": "0.5.3",
"license": "Apache-2.0",
"scripts": {
"install": "./scripts/install.sh",

View File

@ -1,6 +1,6 @@
{
"name": "commons-server",
"version": "0.5.0",
"version": "0.5.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,7 +1,7 @@
{
"name": "commons-server",
"description": "Ocean Protocol marketplace backend.",
"version": "0.5.0",
"version": "0.5.3",
"license": "Apache-2.0",
"main": "dist/server.js",
"scripts": {