feat: add ui for internal data sources, add unit test
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import {
|
||||
ConditionOperator,
|
||||
ConditionOperatorMapping,
|
||||
} from '@vegaprotocol/types';
|
||||
import { DataSourceProof } from './market-info-panels';
|
||||
|
||||
describe('DataSourceProof', () => {
|
||||
const ORACLE_PUBKEY =
|
||||
'69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f';
|
||||
it('renders correct proof for external data sources', () => {
|
||||
const props = {
|
||||
data: {
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal' as const,
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration' as const,
|
||||
signers: [
|
||||
{
|
||||
__typename: 'Signer' as const,
|
||||
signer: {
|
||||
__typename: 'PubKey' as const,
|
||||
key: ORACLE_PUBKEY,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
providers: [
|
||||
{
|
||||
name: 'Another oracle',
|
||||
url: 'https://zombo.com',
|
||||
description_markdown:
|
||||
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
|
||||
oracle: {
|
||||
status: 'GOOD' as const,
|
||||
status_reason: '',
|
||||
first_verified: '2022-01-01T00:00:00.000Z',
|
||||
last_verified: '2022-12-31T00:00:00.000Z',
|
||||
type: 'public_key' as const,
|
||||
public_key: ORACLE_PUBKEY,
|
||||
},
|
||||
proofs: [
|
||||
{
|
||||
format: 'signed_message' as const,
|
||||
available: true,
|
||||
type: 'public_key' as const,
|
||||
public_key: ORACLE_PUBKEY,
|
||||
message: 'SOMEHEX',
|
||||
},
|
||||
],
|
||||
github_link: `https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/PubKey-${ORACLE_PUBKEY}.toml`,
|
||||
},
|
||||
],
|
||||
linkText: 'Termination proof',
|
||||
};
|
||||
render(<DataSourceProof {...props} />);
|
||||
expect(screen.getByRole('link')).toHaveAttribute(
|
||||
'href',
|
||||
props.providers[0].github_link
|
||||
);
|
||||
});
|
||||
|
||||
it('renders message if no matching proof is found', () => {
|
||||
const props = {
|
||||
data: {
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal' as const,
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration' as const,
|
||||
signers: [
|
||||
{
|
||||
__typename: 'Signer' as const,
|
||||
signer: {
|
||||
__typename: 'PubKey' as const,
|
||||
key: ORACLE_PUBKEY,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
providers: [],
|
||||
linkText: 'Termination proof',
|
||||
};
|
||||
render(<DataSourceProof {...props} />);
|
||||
expect(
|
||||
screen.getByText('No oracle proof for data source')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders message if no data source on market', () => {
|
||||
const props = {
|
||||
data: {
|
||||
sourceType: {
|
||||
__typename: 'Invalid',
|
||||
},
|
||||
},
|
||||
providers: [],
|
||||
linkText: 'Termination proof',
|
||||
};
|
||||
// @ts-ignore types are invalid
|
||||
render(<DataSourceProof {...props} />);
|
||||
expect(screen.getByText('Invalid data source')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders conditions for internal data sources', () => {
|
||||
const condition = {
|
||||
__typename: 'Condition' as const,
|
||||
operator: ConditionOperator.OPERATOR_GREATER_THAN,
|
||||
value: '100',
|
||||
};
|
||||
const props = {
|
||||
data: {
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionInternal' as const,
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfigurationTime' as const,
|
||||
conditions: [condition],
|
||||
},
|
||||
},
|
||||
},
|
||||
providers: [],
|
||||
linkText: 'Termination proof',
|
||||
};
|
||||
render(<DataSourceProof {...props} />);
|
||||
expect(screen.getByText('Internal conditions')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
`${ConditionOperatorMapping[condition.operator]} ${condition.value}`
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -22,6 +22,7 @@ import type {
|
||||
} from './market-info-data-provider';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { DataSourceDefinition, SignerKind } from '@vegaprotocol/types';
|
||||
import { ConditionOperatorMapping } from '@vegaprotocol/types';
|
||||
import { MarketTradingModeMapping } from '@vegaprotocol/types';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import type { Provider } from '@vegaprotocol/oracles';
|
||||
@@ -418,10 +419,12 @@ export const OracleInfoPanel = ({
|
||||
const product = market.tradableInstrument.instrument.product;
|
||||
const { VEGA_EXPLORER_URL, ORACLE_PROOFS_URL } = useEnvironment();
|
||||
const { data } = useOracleProofs(ORACLE_PROOFS_URL);
|
||||
console.log(data);
|
||||
return (
|
||||
<MarketInfoTable data={product.dataSourceSpecBinding} {...props}>
|
||||
<div className="flex flex-col gap-2 mt-4">
|
||||
<div
|
||||
className="flex flex-col gap-2 mt-4"
|
||||
data-testid="oracle-proof-links"
|
||||
>
|
||||
<DataSourceProof
|
||||
data={product.dataSourceSpecForSettlementData.data}
|
||||
providers={data}
|
||||
@@ -449,7 +452,7 @@ export const OracleInfoPanel = ({
|
||||
);
|
||||
};
|
||||
|
||||
const DataSourceProof = ({
|
||||
export const DataSourceProof = ({
|
||||
data,
|
||||
providers,
|
||||
linkText,
|
||||
@@ -458,19 +461,25 @@ const DataSourceProof = ({
|
||||
providers: Provider[] | undefined;
|
||||
linkText: string;
|
||||
}) => {
|
||||
if (!providers) return null;
|
||||
|
||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
||||
const signers = data.sourceType.sourceType.signers || [];
|
||||
|
||||
if (!providers) {
|
||||
return <p>{t('No oracle proofs found')}</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2" data-testid="oracle-proof-links">
|
||||
<div className="flex flex-col gap-2">
|
||||
{signers.map(({ signer }, i) => {
|
||||
return (
|
||||
<OracleLink
|
||||
key={i}
|
||||
providers={providers}
|
||||
signer={signer}
|
||||
linkText={linkText}
|
||||
// render link text with a number for the signer eg "View termination proof (1)"
|
||||
linkText={
|
||||
signers.length > 1 ? `${linkText} (${i + 1})` : linkText
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -479,10 +488,22 @@ const DataSourceProof = ({
|
||||
}
|
||||
|
||||
if (data.sourceType.__typename === 'DataSourceDefinitionInternal') {
|
||||
return <div>{data.sourceType.__typename}: Render internal conditions</div>;
|
||||
return (
|
||||
<div>
|
||||
<h3>{t('Internal conditions')}</h3>
|
||||
{data.sourceType.sourceType.conditions.map((condition, i) => {
|
||||
if (!condition) return null;
|
||||
return (
|
||||
<p key={i}>
|
||||
{ConditionOperatorMapping[condition.operator]} {condition.value}
|
||||
</p>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <div>{t('No data sources')}</div>;
|
||||
return <div>{t('Invalid data source')}</div>;
|
||||
};
|
||||
|
||||
const OracleLink = ({
|
||||
@@ -517,8 +538,12 @@ const OracleLink = ({
|
||||
});
|
||||
|
||||
if (!provider) {
|
||||
return <p>{t('No oracle found for data source')}</p>;
|
||||
return <p>{t('No oracle proof for data source')}</p>;
|
||||
}
|
||||
|
||||
return <ExternalLink href={provider.github_link}>{linkText}</ExternalLink>;
|
||||
return (
|
||||
<p>
|
||||
<ExternalLink href={provider.github_link}>{linkText}</ExternalLink>
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ConditionOperator } from './__generated__/types';
|
||||
import type {
|
||||
AccountType,
|
||||
AuctionTrigger,
|
||||
@@ -22,6 +23,7 @@ import type {
|
||||
VoteValue,
|
||||
WithdrawalStatus,
|
||||
DispatchMetric,
|
||||
Condition,
|
||||
} from './__generated__/types';
|
||||
|
||||
export const AccountTypeMapping: {
|
||||
@@ -458,3 +460,11 @@ export const PositionStatusMapping: {
|
||||
POSITION_STATUS_ORDERS_CLOSED: 'Maintained by network',
|
||||
POSITION_STATUS_UNSPECIFIED: 'Normal',
|
||||
};
|
||||
|
||||
export const ConditionOperatorMapping: { [C in ConditionOperator]: string } = {
|
||||
OPERATOR_EQUALS: 'Equals',
|
||||
OPERATOR_GREATER_THAN: 'Greater than',
|
||||
OPERATOR_GREATER_THAN_OR_EQUAL: 'Greater than or equal to',
|
||||
OPERATOR_LESS_THAN: 'Less than',
|
||||
OPERATOR_LESS_THAN_OR_EQUAL: 'Less than or equal to',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user