Skip to content

Commit

Permalink
Add tests for JsonRpcCondition.
Browse files Browse the repository at this point in the history
  • Loading branch information
derekpierre committed Dec 18, 2024
1 parent fee055d commit 23a026e
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest';

import {
JsonApiCondition,
JsonApiConditionProps,
jsonApiConditionSchema,
JsonApiConditionType,
} from '../../../src/conditions/base/json-api';
Expand Down Expand Up @@ -88,7 +89,7 @@ describe('JsonApiCondition', () => {
});

it('accepts conditions without parameters', () => {
const { query, ...noParamsObj } = testJsonApiConditionObj;
const { parameters, ...noParamsObj } = testJsonApiConditionObj;
const result = JsonApiCondition.validate(
jsonApiConditionSchema,
noParamsObj,
Expand All @@ -101,7 +102,7 @@ describe('JsonApiCondition', () => {

describe('context variables', () => {
it('allow context variables for various values including as substring', () => {
const jsonApiConditionObj = {
const jsonApiConditionObj: JsonApiConditionProps = {
conditionType: JsonApiConditionType,
endpoint:
'https://api.coingecko.com/api/:version/simple/:endpointPath',
Expand All @@ -116,6 +117,7 @@ describe('JsonApiCondition', () => {
value: ':expectedPrice',
},
};

const result = JsonApiCondition.validate(
jsonApiConditionSchema,
jsonApiConditionObj,
Expand Down
147 changes: 147 additions & 0 deletions packages/taco/test/conditions/base/json-rpc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { describe, expect, it } from 'vitest';

import {
JsonRpcCondition,
JsonRpcConditionProps,
jsonRpcConditionSchema,
JsonRpcConditionType,
} from '../../../src/conditions/base/json-rpc';
import { testJsonRpcConditionObj } from '../../test-utils';

describe('JsonRpcCondition', () => {
describe('validation', () => {
it('accepts a valid schema', () => {
const result = JsonRpcCondition.validate(
jsonRpcConditionSchema,
testJsonRpcConditionObj,
);
expect(result.error).toBeUndefined();
expect(result.data).toEqual(testJsonRpcConditionObj);
});

it.each(['unsafe-url', 'http://http-url.com'])(
'rejects an invalid schema',
() => {
const badJsonRpcObj = {
...testJsonRpcConditionObj,
endpoint: 'unsafe-url',
};

const result = JsonRpcCondition.validate(
jsonRpcConditionSchema,
badJsonRpcObj,
);

expect(result.error).toBeDefined();
expect(result.data).toBeUndefined();
const errorMessages = result.error?.errors.map((err) => err.message);
expect(
errorMessages?.includes('Invalid url - must start with https://'),
).toBeTruthy();
},
);

describe('authorizationToken', () => {
it('accepts context variable', () => {
const result = JsonRpcCondition.validate(jsonRpcConditionSchema, {
...testJsonRpcConditionObj,
authorizationToken: ':authToken',
});
expect(result.error).toBeUndefined();
expect(result.data).toEqual({
...testJsonRpcConditionObj,
authorizationToken: ':authToken',
});
});
it.each([
'authToken',
'ABCDEF1234567890',
':authToken?',
'$:authToken',
':auth-Token',
])('rejects invalid context variable', (contextVar) => {
const result = JsonRpcCondition.validate(jsonRpcConditionSchema, {
...testJsonRpcConditionObj,
authorizationToken: `${contextVar}`,
});
expect(result.error).toBeDefined();
expect(result.data).toBeUndefined();
expect(result.error?.format()).toMatchObject({
authorizationToken: {
_errors: ['Invalid'],
},
});
});
});

describe('properties', () => {
it('accepts conditions without query path', () => {
const { query, ...noQueryObj } = testJsonRpcConditionObj;
const result = JsonRpcCondition.validate(
jsonRpcConditionSchema,
noQueryObj,
);

expect(result.error).toBeUndefined();
expect(result.data).toEqual(noQueryObj);
});

it('accepts conditions without params', () => {
const { params, ...noParamsObj } = testJsonRpcConditionObj;
const result = JsonRpcCondition.validate(
jsonRpcConditionSchema,
noParamsObj,
);

expect(result.error).toBeUndefined();
expect(result.data).toEqual(noParamsObj);
});

it('accepts conditions with params as dictionary', () => {
const result = JsonRpcCondition.validate(jsonRpcConditionSchema, {
...testJsonRpcConditionObj,
params: {
value1: 42,
value2: 23,
},
});
expect(result.error).toBeUndefined();
expect(result.data).toEqual({
...testJsonRpcConditionObj,
params: {
value1: 42,
value2: 23,
},
});
});
});

describe('context variables', () => {
it('allow context variables for various values including as substring', () => {
const testJsonRpcConditionObjWithContextVars: JsonRpcConditionProps = {
conditionType: JsonRpcConditionType,
endpoint: 'https://math.example.com/:version/simple',
method: ':methodContextVar',
params: {
value1: 42,
value2: ':value2',
},
query: '$.:queryKey',
authorizationToken: ':authToken',
returnValueTest: {
comparator: '==',
value: ':expectedResult',
},
};

const result = JsonRpcCondition.validate(
jsonRpcConditionSchema,
testJsonRpcConditionObjWithContextVars,
);
expect(result.error).toBeUndefined();
expect(result.data).toEqual(testJsonRpcConditionObjWithContextVars);
});
});
});
});
25 changes: 25 additions & 0 deletions packages/taco/test/conditions/condition-expr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ContractConditionProps,
} from '../../src/conditions/base/contract';
import { JsonApiCondition } from '../../src/conditions/base/json-api';
import { JsonRpcCondition } from '../../src/conditions/base/json-rpc';
import { RpcCondition, RpcConditionType } from '../../src/conditions/base/rpc';
import {
TimeCondition,
Expand All @@ -22,6 +23,7 @@ import {
testContractConditionObj,
testFunctionAbi,
testJsonApiConditionObj,
testJsonRpcConditionObj,
testReturnValueTest,
testRpcConditionObj,
testTimeConditionObj,
Expand Down Expand Up @@ -59,6 +61,7 @@ describe('condition set', () => {
const rpcCondition = new RpcCondition(testRpcConditionObj);
const timeCondition = new TimeCondition(testTimeConditionObj);
const jsonApiCondition = new JsonApiCondition(testJsonApiConditionObj);
const jsonRpcCondition = new JsonRpcCondition(testJsonRpcConditionObj);
const compoundCondition = new CompoundCondition({
operator: 'and',
operands: [
Expand Down Expand Up @@ -424,6 +427,28 @@ describe('condition set', () => {
expect(conditionExprFromJson.condition).toBeInstanceOf(JsonApiCondition);
});

it('json rpc condition serialization', () => {
const conditionExpr = new ConditionExpression(jsonRpcCondition);

const conditionExprJson = conditionExpr.toJson();
expect(conditionExprJson).toBeDefined();
expect(conditionExprJson).toContain('endpoint');
expect(conditionExprJson).toContain('https://math.example.com/');
expect(conditionExprJson).toContain('method');
expect(conditionExprJson).toContain('subtract');
expect(conditionExprJson).toContain('params');
expect(conditionExprJson).toContain('[42,23]');

expect(conditionExprJson).toContain('query');
expect(conditionExprJson).toContain('$.mathresult');
expect(conditionExprJson).toContain('returnValueTest');

const conditionExprFromJson =
ConditionExpression.fromJSON(conditionExprJson);
expect(conditionExprFromJson).toBeDefined();
expect(conditionExprFromJson.condition).toBeInstanceOf(JsonRpcCondition);
});

it('compound condition serialization', () => {
const conditionExpr = new ConditionExpression(compoundCondition);
const compoundConditionObj = compoundCondition.toObj();
Expand Down
14 changes: 13 additions & 1 deletion packages/taco/test/conditions/lingo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ describe('check that valid lingo in python is valid in typescript', () => {
value: 2,
},
};
const jsonRpcConditionProps = {
conditionType: 'json-rpc',
endpoint: 'https://math.example.com/',
method: 'subtract',
params: [42, 23],
query: '$.value',
returnValueTest: {
comparator: '==',
value: 2,
},
};
const sequentialConditionProps = {
conditionType: 'sequential',
conditionVariables: [
Expand All @@ -81,7 +92,7 @@ describe('check that valid lingo in python is valid in typescript', () => {
};
const ifThenElseConditionProps = {
conditionType: 'if-then-else',
ifCondition: rpcConditionProps,
ifCondition: jsonRpcConditionProps,
thenCondition: jsonApiConditionProps,
elseCondition: timeConditionProps,
};
Expand All @@ -107,6 +118,7 @@ describe('check that valid lingo in python is valid in typescript', () => {
timeConditionProps,
contractConditionProps,
jsonApiConditionProps,
jsonRpcConditionProps,
compoundConditionProps,
sequentialConditionProps,
ifThenElseConditionProps,
Expand Down
47 changes: 47 additions & 0 deletions packages/taco/test/taco.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,51 @@ describe('taco', () => {
new Set([':userId', ':userAddress', ':authToken']),
);
});
// test json api condition exposes requested parameters
it('jsonrpc condition exposes requested parameters', async () => {
const mockedDkg = fakeDkgFlow(FerveoVariant.precomputed, 0, 4, 4);
const mockedDkgRitual = fakeDkgRitual(mockedDkg);
const provider = fakeProvider(aliceSecretKeyBytes);
const signer = provider.getSigner();
const getFinalizedRitualSpy = mockGetActiveRitual(mockedDkgRitual);

const jsonRpcCondition = new conditions.base.jsonRpc.JsonRpcCondition({
endpoint: 'https://math.example.com/:version/simple',
method: ':methodContextVar',
params: {
value1: 42,
value2: ':value2',
},
query: '$.:queryKey',
authorizationToken: ':authToken',
returnValueTest: {
comparator: '==',
value: ':expectedResult',
},
});
const messageKit = await taco.encrypt(
provider,
domains.DEVNET,
message,
jsonRpcCondition,
mockedDkg.ritualId,
signer,
);
expect(getFinalizedRitualSpy).toHaveBeenCalled();

const conditionContext = ConditionContext.fromMessageKit(messageKit);
const requestedParameters = conditionContext.requestedContextParameters;

// Verify all context parameters are detected
expect(requestedParameters).toEqual(
new Set([
':version',
':methodContextVar',
':value2',
':queryKey',
':authToken',
':expectedResult',
]),
);
});
});
20 changes: 18 additions & 2 deletions packages/taco/test/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ import {
ContractConditionType,
FunctionAbiProps,
} from '../src/conditions/base/contract';
import { JsonApiConditionType } from '../src/conditions/base/json-api';
import {
JsonApiConditionProps,
JsonApiConditionType,
} from '../src/conditions/base/json-api';
import {
RpcConditionProps,
RpcConditionType,
Expand All @@ -55,6 +58,10 @@ import {
} from '../src/conditions/compound-condition';
import { ConditionExpression } from '../src/conditions/condition-expr';
import { ERC721Balance } from '../src/conditions/predefined/erc721';
import {
JsonRpcConditionProps,
JsonRpcConditionType,
} from '../src/conditions/schemas/json-rpc';
import {
SequentialConditionProps,
SequentialConditionType,
Expand Down Expand Up @@ -232,7 +239,7 @@ export const testTimeConditionObj: TimeConditionProps = {
chain: TEST_CHAIN_ID,
};

export const testJsonApiConditionObj = {
export const testJsonApiConditionObj: JsonApiConditionProps = {
conditionType: JsonApiConditionType,
endpoint: 'https://_this_would_totally_fail.com',
parameters: {
Expand All @@ -243,6 +250,15 @@ export const testJsonApiConditionObj = {
returnValueTest: testReturnValueTest,
};

export const testJsonRpcConditionObj: JsonRpcConditionProps = {
conditionType: JsonRpcConditionType,
endpoint: 'https://math.example.com/',
method: 'subtract',
params: [42, 23],
query: '$.mathresult',
returnValueTest: testReturnValueTest,
};

export const testRpcConditionObj: RpcConditionProps = {
conditionType: RpcConditionType,
chain: TEST_CHAIN_ID,
Expand Down

0 comments on commit 23a026e

Please sign in to comment.