1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

Merge pull request #156 from oceanprotocol/feature/network

version number fixes
This commit is contained in:
Matthias Kretschmann 2019-06-12 13:08:21 +02:00 committed by GitHub
commit c9f4871ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 284 additions and 78 deletions

View File

@ -73,7 +73,8 @@
"jest": {
"collectCoverageFrom": [
"src/**/*.{ts,tsx}",
"!src/serviceWorker.ts"
"!src/serviceWorker.ts",
"!src/**/*.d.ts"
]
}
}

View File

@ -29,6 +29,20 @@
padding-top: $spacer / 4;
}
.small {
composes: spinner;
margin: 0;
display: inline-block;
&:before {
width: $font-size-small;
height: $font-size-small;
margin-top: -($font-size-small);
margin-left: -($font-size-small / 2);
border-width: .1rem;
}
}
@keyframes spinner {
to {
transform: rotate(360deg);

View File

@ -1,15 +1,27 @@
import React from 'react'
import styles from './Spinner.module.scss'
const Spinner = ({ message }: { message?: string }) => (
<div className={styles.spinner}>
{message && (
<div
className={styles.spinnerMessage}
dangerouslySetInnerHTML={{ __html: message }}
/>
)}
</div>
)
const Spinner = ({
message,
small,
className
}: {
message?: string
small?: boolean
className?: string
}) => {
const classes = className || (small ? styles.small : styles.spinner)
return (
<div className={classes}>
{message && (
<div
className={styles.spinnerMessage}
dangerouslySetInnerHTML={{ __html: message }}
/>
)}
</div>
)
}
export default Spinner

View File

@ -52,3 +52,8 @@
}
}
}
.spinner {
composes: spinner, small from '../Spinner.module.scss';
margin-right: $spacer;
}

View File

@ -2,6 +2,7 @@ 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,
@ -12,23 +13,24 @@ const VersionTableContracts = ({
}) => (
<table>
<tbody>
{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>
))}
{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>
)
@ -42,18 +44,30 @@ const VersionTable = ({ data }: { data: VersionTableProps }) => (
<tr key={key}>
<td>
<a
href={`https://github.com/oceanprotocol/${slugify(
value.software
)}`}
href={
value.software &&
`https://github.com/oceanprotocol/${slugify(
value.software
)}`
}
>
<strong>{value.software}</strong>
</a>
</td>
<td>
<code>v{value.version}</code>
{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' && (
{key === 'keeperContracts' && data.brizo.contracts && (
<tr>
<td colSpan={2}>
<VersionTableContracts

View File

@ -1,29 +1,124 @@
import React from 'react'
import { render, waitForElement } from '@testing-library/react'
import mockAxios from 'jest-mock-axios'
import VersionNumbers from '.'
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'
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(<VersionNumbers />)
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'
)
})
it('minimal component versions in link title, prefixed with `v`', async () => {
const { getByTitle } = render(<VersionNumbers minimal />)
mockAxios.mockResponse(mockResponse)

View File

@ -18,8 +18,9 @@ import {
} from '../../../config'
import VersionTable from './VersionTable'
import { isJsonString } from './utils'
const commonsVersion =
export const commonsVersion =
process.env.NODE_ENV === 'production' ? version : `${version}-dev`
interface VersionNumbersProps {
@ -36,10 +37,12 @@ export interface VersionNumbersState {
version: string
}
aquarius: {
isLoading: boolean
software: string
version: string
}
brizo: {
isLoading: boolean
software: string
version: string
network: string
@ -48,13 +51,16 @@ export interface VersionNumbersState {
contracts: any
}
keeperContracts: {
isLoading: boolean
software: string
version: string
network: string
contracts: any
}
faucet: {
software: string
version: string
isLoading: boolean
software?: string
version?: string
}
}
@ -68,73 +74,113 @@ export default class VersionNumbers extends PureComponent<
software: 'Squid-js',
version: versionSquid
},
aquarius: { software: 'Aquarius', version: '0.0.0' },
aquarius: {
isLoading: true,
software: 'Aquarius',
version: ''
},
brizo: {
isLoading: true,
software: 'Brizo',
version: '0.0.0',
version: '',
contracts: {} as any,
network: '',
'keeper-version': '0.0.0',
'keeper-url': ''
},
keeperContracts: {
isLoading: true,
software: 'Keeper Contracts',
version: '0.0.0',
version: '',
contracts: {} as any,
network: ''
},
faucet: { software: 'Faucet', version: '0.0.0' }
faucet: {
isLoading: true,
software: 'Faucet',
version: ''
}
}
// for canceling axios requests
public signal = axios.CancelToken.source()
public componentWillMount() {
this.setComponentVersions()
this.setAquarius()
this.setBrizoAndKeeper()
this.setFaucet()
}
public componentWillUnmount() {
this.signal.cancel()
}
private async setComponentVersions() {
try {
const aquarius = await this.getData(
aquariusScheme,
aquariusHost,
aquariusPort
)
aquarius.version !== undefined && this.setState({ aquarius })
private async setAquarius() {
const aquarius = await this.getData(
aquariusScheme,
aquariusHost,
aquariusPort
)
aquarius &&
aquarius.version !== undefined &&
this.setState({ aquarius: { isLoading: false, ...aquarius } })
}
const brizo = await this.getData(brizoScheme, brizoHost, brizoPort)
private async setBrizoAndKeeper() {
const brizo = await this.getData(brizoScheme, brizoHost, brizoPort)
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,
keeperContracts: {
...this.state.keeperContracts,
version: brizo['keeper-version'].replace('v', ''),
contracts: brizo.contracts
}
})
this.setState({
brizo: {
isLoading: false,
...brizo
},
keeperContracts: {
...this.state.keeperContracts,
isLoading: false,
version: keeperVersion,
contracts: brizo.contracts,
network: keeperNetwork
}
})
}
const faucet = await this.getData(
faucetScheme,
faucetHost,
faucetPort
)
private async setFaucet() {
const faucet = await this.getData(faucetScheme, faucetHost, faucetPort)
faucet.version !== undefined && this.setState({ faucet })
} catch (error) {
!axios.isCancel(error) && Logger.error(error.message)
}
// 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(scheme: string, host: string, port: number | string) {
const { data } = await axios.get(`${scheme}://${host}:${port}`, {
headers: { Accept: 'application/json' },
cancelToken: this.signal.token
})
return data
try {
const response = await axios.get(`${scheme}://${host}:${port}`, {
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() {
@ -152,7 +198,7 @@ export default class VersionNumbers extends PureComponent<
return minimal ? (
<p className={styles.versionsMinimal}>
<a title={mimimalOutput} href={'/about'}>
v{commons.version} ({brizo.network})
v{commons.version} {brizo.network && `(${brizo.network})`}
</a>
</p>
) : (

View File

@ -0,0 +1,11 @@
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

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

View File

@ -11,7 +11,7 @@
},
{
"name": "brizo",
"version": "~0.3.6"
"version": "~0.3.9"
},
{
"name": "aquarius",
@ -23,7 +23,7 @@
},
{
"name": "faucet",
"version": "~0.2.0"
"version": "~0.2.4"
}
]
}