From 32d4b9aee8cc58b486103709237cead50eb419a1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 19 Dec 2024 10:06:11 -0500 Subject: [PATCH] Add specific tests for checking whether context variables are extracted appropriately from conditions. --- packages/taco/test/conditions/context.test.ts | 241 ++++++++++++++++++ packages/taco/test/taco.test.ts | 83 ------ 2 files changed, 241 insertions(+), 83 deletions(-) diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index e893766a..baa0f6bb 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -12,16 +12,21 @@ import { ethers } from 'ethers'; import { beforeAll, describe, expect, it, vi } from 'vitest'; import { toBytes, toHexString } from '../../src'; +import { ConditionFactory } from '../../src/conditions'; import { ContractCondition, ContractConditionProps, + ContractConditionType, } from '../../src/conditions/base/contract'; import { RpcCondition } from '../../src/conditions/base/rpc'; +import { CompoundConditionType } from '../../src/conditions/compound-condition'; import { ConditionContext, CustomContextParam, } from '../../src/conditions/context'; import { RESERVED_CONTEXT_PARAMS } from '../../src/conditions/context/context'; +import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; +import { SequentialConditionType } from '../../src/conditions/sequential'; import { paramOrContextParamSchema, ReturnValueTestProps, @@ -29,8 +34,11 @@ import { import { testContractConditionObj, testFunctionAbi, + testJsonApiConditionObj, + testJsonRpcConditionObj, testReturnValueTest, testRpcConditionObj, + testTimeConditionObj, } from '../test-utils'; describe('context', () => { @@ -621,3 +629,236 @@ describe('param or context param schema', () => { expect(paramOrContextParamSchema.safeParse(() => {}).success).toBe(false); }); }); + +describe('recognition of context variables in conditions', () => { + const rvt = { + comparator: '>=', + value: ':expectedResult', + }; + + const rpcCondition = { + ...testRpcConditionObj, + parameters: [':userAddress', ':blockNumber'], + returnValueTest: rvt, + }; + + const timeCondition = { + ...testTimeConditionObj, + returnValueTest: rvt, + }; + + const contractCondition = { + conditionType: ContractConditionType, + contractAddress: '0x0000000000000000000000000000000000000000', + chain: 1, + method: 'balanceOf', + functionAbi: testFunctionAbi, + parameters: [':userAddress'], + returnValueTest: rvt, + }; + + const jsonApiCondition = { + ...testJsonApiConditionObj, + endpoint: 'https://api.example.com/:userId/:endpoint', + parameters: { + value1: ':value1', + value2: 2, + }, + query: '$.data[?(@.owner == :query)].value', + authorizationToken: ':authToken', + returnValueTest: rvt, + }; + + const jsonRpcConditionParamsDict = { + ...testJsonRpcConditionObj, + endpoint: 'https://math.example.com/:version/simple', + method: 'subtract', + params: { + value1: 42, + value2: ':value2', + }, + query: '$.:queryKey', + authorizationToken: ':authToken', + returnValueTest: rvt, + }; + + const jsonRpcConditionParamsArray = { + ...testJsonRpcConditionObj, + endpoint: 'https://math.example.com/:version/simple', + method: 'subtract', + params: [':value1', ':value2'], + query: '$.:queryKey', + authorizationToken: ':authToken', + returnValueTest: rvt, + }; + + it('handles context params for rpc condition', () => { + const condition = ConditionFactory.conditionFromProps(rpcCondition); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([':userAddress', ':blockNumber', ':expectedResult']), + ); + }); + it('handles context params for time condition', () => { + const condition = ConditionFactory.conditionFromProps(timeCondition); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([':expectedResult']), + ); + }); + it('handles context params for contract condition', () => { + const condition = ConditionFactory.conditionFromProps(contractCondition); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([':userAddress', ':expectedResult']), + ); + }); + it('handles context params for json api condition', () => { + const condition = ConditionFactory.conditionFromProps(jsonApiCondition); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([ + ':userId', + ':endpoint', + ':value1', + ':query', + ':authToken', + ':expectedResult', + ]), + ); + }); + it('handles context params for json rpc condition (params dict)', () => { + const condition = ConditionFactory.conditionFromProps( + jsonRpcConditionParamsDict, + ); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([ + ':version', + ':value2', + ':queryKey', + ':authToken', + ':expectedResult', + ]), + ); + }); + it('handles context params for json rpc condition (params array)', () => { + const condition = ConditionFactory.conditionFromProps( + jsonRpcConditionParamsArray, + ); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([ + ':version', + ':value1', + ':value2', + ':queryKey', + ':authToken', + ':expectedResult', + ]), + ); + }); + it.each([ + { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'rpc', + condition: rpcCondition, + }, + { + varName: 'time', + condition: timeCondition, + }, + { + varName: 'contract', + condition: contractCondition, + }, + { + varName: 'jsonApi', + condition: jsonApiCondition, + }, + { + varName: 'sequential', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'jsonRpcParamsDict', + condition: jsonRpcConditionParamsDict, + }, + { + varName: 'jsonRpcParamsArray', + condition: jsonRpcConditionParamsArray, + }, + ], + }, + }, + ], + }, + { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + jsonApiCondition, + jsonRpcConditionParamsDict, + { + conditionType: CompoundConditionType, + operator: 'and', + operands: [jsonRpcConditionParamsArray, rpcCondition, timeCondition], + }, + { + conditionType: CompoundConditionType, + operator: 'not', + operands: [contractCondition], + }, + ], + }, + { + conditionType: IfThenElseConditionType, + ifCondition: rpcCondition, + thenCondition: jsonRpcConditionParamsArray, + elseCondition: { + conditionType: CompoundConditionType, + operator: 'and', + operands: [ + timeCondition, + contractCondition, + jsonApiCondition, + jsonRpcConditionParamsDict, + ], + }, + }, + ])('handles context params for logical conditions', (logicalCondition) => { + const condition = ConditionFactory.conditionFromProps(logicalCondition); + const conditionContext = new ConditionContext(condition); + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([ + ':version', + ':userAddress', + ':blockNumber', + ':userId', + ':endpoint', + ':value1', + ':value2', + ':query', + ':queryKey', + ':authToken', + ':expectedResult', + ]), + ); + }); +}); diff --git a/packages/taco/test/taco.test.ts b/packages/taco/test/taco.test.ts index e3527264..5f8b59f3 100644 --- a/packages/taco/test/taco.test.ts +++ b/packages/taco/test/taco.test.ts @@ -136,87 +136,4 @@ describe('taco', () => { new Set([customParamKey, USER_ADDRESS_PARAM_DEFAULT]), ); }); - // test json api condition exposes requested parameters - it('jsonapi 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 jsonApiCondition = new conditions.base.jsonApi.JsonApiCondition({ - endpoint: 'https://api.example.com/:userId/data', - query: '$.data[?(@.owner == :userAddress)].value', - authorizationToken: ':authToken', - returnValueTest: { - comparator: '==', - value: true, - }, - }); - - const messageKit = await taco.encrypt( - provider, - domains.DEVNET, - message, - jsonApiCondition, - mockedDkg.ritualId, - signer, - ); - expect(getFinalizedRitualSpy).toHaveBeenCalled(); - - const conditionContext = ConditionContext.fromMessageKit(messageKit); - const requestedParameters = conditionContext.requestedContextParameters; - - // Verify all context parameters from endpoint, query and authToken are detected - expect(requestedParameters).toEqual( - 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', - ]), - ); - }); });