From 15e4ee21e636b10ab4dce7fe5ad1f39c5fc3dbfa Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 10 Sep 2024 13:11:39 +0200 Subject: [PATCH 01/14] API tests - Update trigger - Auto Sell - Spark --- .../autoSell/spark/autoSellSparkAdd.spec.ts | 10 + .../spark/autoSellSparkUpdate.spec.ts | 441 ++++++++++++++++++ 2 files changed, 451 insertions(+) create mode 100644 tests/api/automations/autoSell/spark/autoSellSparkUpdate.spec.ts diff --git a/tests/api/automations/autoSell/spark/autoSellSparkAdd.spec.ts b/tests/api/automations/autoSell/spark/autoSellSparkAdd.spec.ts index 34044c41..2e5964e2 100644 --- a/tests/api/automations/autoSell/spark/autoSellSparkAdd.spec.ts +++ b/tests/api/automations/autoSell/spark/autoSellSparkAdd.spec.ts @@ -344,4 +344,14 @@ test.describe('API tests - Auto-Sell - Spark - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongUseMinSellPrice); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloadsSpark.autoSell.updateMinSellPrice, action: 'add' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoSellAlreadyExists); + }); }); diff --git a/tests/api/automations/autoSell/spark/autoSellSparkUpdate.spec.ts b/tests/api/automations/autoSell/spark/autoSellSparkUpdate.spec.ts new file mode 100644 index 00000000..b552e3fc --- /dev/null +++ b/tests/api/automations/autoSell/spark/autoSellSparkUpdate.spec.ts @@ -0,0 +1,441 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsSpark, + responses, + autoSellWithoutMinSellPriceResponse, +} from 'utils/testData_APIs'; + +const autoSellEndpoint = '/api/triggers/1/spark/auto-sell'; + +const validPayloads = validPayloadsSpark.autoSell.updateMinSellPrice; + +const validResponse = autoSellWithoutMinSellPriceResponse({ + dpm: '0xB2F1349068c1Cb6a596A22A3531b8062778c9Da4', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }, + // hasStablecoinDebt: true, --> Morpho bug (?) - Waiting for confirmation + hasStablecoinDebt: true, + executionLTV: '6000', + targetLTV: '5000', + targetLTVWithDeviation: ['4900', '5100'], +}); + +test.describe('API tests - Auto-Sell - Aave V3 - Base', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/spark/multiply/WSTETH-DAI/2584#protection + + test('Update existing automation - minSellPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + warnings: [], + }); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '6500', + minSellPrice: '40000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { ...validResponse.simulation, executionLTV: '6500' }, + warnings: [], + }); + }); + + test('Update existing automation - targetLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + targetLTV: '5200', + minSellPrice: '40000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { + ...validResponse.simulation, + targetLTV: '5200', + targetLTVWithDeviation: ['5100', '5300'], + }, + warnings: [], + }); + }); + + test('Update existing automation - Set No threshold - Valid payload data', async ({ + request, + }) => { + const { minSellPrice, ...triggerdataWithoutminSellPrice } = validPayloads.triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...triggerdataWithoutminSellPrice, + useMinSellPrice: false, + }, + }, + }); + + const respJSON = await response.json(); + + // No warning for Morpho - Minor bug + // https://app.shortcut.com/oazo-apps/story/15553/bug-auto-buy-missing-warning-when-selecting-set-no-threshold + expect(respJSON).toMatchObject({ + ...validResponse, + // warnings: [], + }); + }); + + test('Update existing automation - executionLTV, targetLTV & minSellPrice - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '6200', + targetLTV: '4700', + minSellPrice: '30000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { + ...validResponse.simulation, + executionLTV: '6200', + targetLTV: '4700', + targetLTVWithDeviation: ['4600', '4800'], + }, + warnings: [], + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloadsSpark.autoSell.addWithoutMinSellPrice, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoSellDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: 'string', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update automation - Without "maxBaseFee (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { maxBaseFee, ...triggerDataWithoutMaxBaseFee } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutMaxBaseFee }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongMaxBaseFee); + }); + + test('Update automation - Without "targetLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { targetLTV, ...triggerDataWithoutTargetLTV } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutTargetLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTargetLTV); + }); + + test('Update automation - Without "useMinSellPrice (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { minSellPrice, useMinSellPrice, ...triggerDataWithoutUseMinSellPrice } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutUseMinSellPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongUseMinSellPrice); + }); +}); From 8a540b6dc8c830cef153f869012eecebe5362c75 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 10 Sep 2024 13:27:11 +0200 Subject: [PATCH 02/14] API tests - Update trigger - Stop-Loss - Aave v3 Ethereum --- .../ethereum/stopLossAv3EthereumAdd.spec.ts | 12 +- .../stopLossAv3EthereumUpdate.spec.ts | 343 ++++++++++++++++++ utils/testData_APIs.ts | 26 ++ 3 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts diff --git a/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumAdd.spec.ts b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumAdd.spec.ts index 155db889..3ff487bb 100644 --- a/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumAdd.spec.ts +++ b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumAdd.spec.ts @@ -4,7 +4,7 @@ import { validPayloadsAaveV3Ethereum, responses } from 'utils/testData_APIs'; const stopLossEndpoint = '/api/triggers/1/aave3/dma-stop-loss'; const validPayloads = validPayloadsAaveV3Ethereum.stopLoss.closeToDebt; -test.describe('API tests - Stop-Loss - Aave V3 - Ethereum', async () => { +test.describe('API tests - Stop-Loss - Add - Aave V3 - Ethereum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1218 @@ -279,4 +279,14 @@ test.describe('API tests - Stop-Loss - Aave V3 - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloadsAaveV3Ethereum.stopLoss.updateCloseToCollateral, action: 'add' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossAlreadyExist); + }); }); diff --git a/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts new file mode 100644 index 00000000..b8f5ed16 --- /dev/null +++ b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts @@ -0,0 +1,343 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsAaveV3Ethereum, responses } from 'utils/testData_APIs'; + +const stopLossEndpoint = '/api/triggers/1/aave3/dma-stop-loss'; +const validPayloads = validPayloadsAaveV3Ethereum.stopLoss.updateCloseToCollateral; + +test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => { + // Very old test wallet: 0x10649c79428d718621821Cf6299e91920284743F + // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/RETH-DAI/1276#protection + + test('Update automation - Close to collateral - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x6Bb713b56e73A115164b4B56ea1f5A76640c4D19', + }, + }); + }); + + test('Update automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { executionLTV: '7000', token: '0x6b175474e89094c44da98b954eedeac495271d0f' }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x6Bb713b56e73A115164b4B56ea1f5A76640c4D19', + }, + }); + }); + + test('Update automation - Close to collateral & executionLTV - Valid payload data', async ({ + request, + }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { executionLTV: '7100', token: '0x6b175474e89094c44da98b954eedeac495271d0f' }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x6Bb713b56e73A115164b4B56ea1f5A76640c4D19', + }, + }); + }); + + test('Update automation - Close to debt - Valid payload data', async ({ request }) => { + // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 + // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1586#protection + const response = await request.post(stopLossEndpoint, { + data: validPayloadsAaveV3Ethereum.stopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xB727afF37C480a0FDbA8a6c97fC4FcF3A19f2ac7', + }, + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloadsAaveV3Ethereum.stopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, collateral: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 6ecf6a89..f29ff00f 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1487,6 +1487,32 @@ export const validPayloadsAaveV3Ethereum = { token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', }, }, + updateCloseToCollateral: { + dpm: '0x6bb713b56e73a115164b4b56ea1f5a76640c4d19', + protocol: 'aavev3', + position: { + collateral: '0xae78736cd615f374d3085123a210448e74fc6393', + debt: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + triggerData: { + executionLTV: '6500', + token: '0xae78736cd615f374d3085123a210448e74fc6393', + }, + }, + updateCloseToDebt: { + dpm: '0xb727aff37c480a0fdba8a6c97fc4fcf3a19f2ac7', + protocol: 'aavev3', + position: { + collateral: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + debt: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + triggerData: { + executionLTV: '7700', + token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + }, }, trailingStopLoss: { closeToDebt: { From 4c5f85907a62fd6005bfc18a7932341e947b4040 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 10 Sep 2024 15:36:45 +0200 Subject: [PATCH 03/14] API tests - Update trigger - Stop-Loss - Aave v3 Optimism --- .../stopLossAv3ArbitrumUpdate.spec.ts | 2 +- .../aaveV3/base/stopLossAv3BaseUpdate.spec.ts | 2 +- .../stopLossAv3EthereumUpdate.spec.ts | 2 +- .../optimism/stopLossAv3OptimismAdd.spec.ts | 12 +- .../stopLossAv3OptimismUpdate.spec.ts | 343 +++++++++++++++++ .../morphoBlue/stopLossMorphoAdd.spec.ts | 12 +- .../morphoBlue/stopLossMorphoUpdate.spec.ts | 350 ++++++++++++++++++ utils/testData_APIs.ts | 40 ++ 8 files changed, 758 insertions(+), 5 deletions(-) create mode 100644 tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismUpdate.spec.ts create mode 100644 tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts diff --git a/tests/api/automations/stopLoss/aaveV3/arbitrum/stopLossAv3ArbitrumUpdate.spec.ts b/tests/api/automations/stopLoss/aaveV3/arbitrum/stopLossAv3ArbitrumUpdate.spec.ts index 937065b5..b2d6f60a 100644 --- a/tests/api/automations/stopLoss/aaveV3/arbitrum/stopLossAv3ArbitrumUpdate.spec.ts +++ b/tests/api/automations/stopLoss/aaveV3/arbitrum/stopLossAv3ArbitrumUpdate.spec.ts @@ -49,7 +49,7 @@ test.describe('API tests - Stop-Loss - Update - Aave V3 - Arbitrum', async () => const response = await request.post(stopLossEndpoint, { data: { ...validPayloads, - triggerData: { executionLTV: '7100', token: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1' }, + triggerData: { ...validPayloads.triggerData, executionLTV: '7100' }, }, }); diff --git a/tests/api/automations/stopLoss/aaveV3/base/stopLossAv3BaseUpdate.spec.ts b/tests/api/automations/stopLoss/aaveV3/base/stopLossAv3BaseUpdate.spec.ts index 624690d1..ab438d7a 100644 --- a/tests/api/automations/stopLoss/aaveV3/base/stopLossAv3BaseUpdate.spec.ts +++ b/tests/api/automations/stopLoss/aaveV3/base/stopLossAv3BaseUpdate.spec.ts @@ -49,7 +49,7 @@ test.describe('API tests - Stop-Loss - Update - Aave V3 - Base', async () => { const response = await request.post(stopLossEndpoint, { data: { ...validPayloads, - triggerData: { executionLTV: '6800', token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913' }, + triggerData: { ...validPayloads.triggerData, executionLTV: '6800' }, }, }); diff --git a/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts index b8f5ed16..172f0fd2 100644 --- a/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts +++ b/tests/api/automations/stopLoss/aaveV3/ethereum/stopLossAv3EthereumUpdate.spec.ts @@ -49,7 +49,7 @@ test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => const response = await request.post(stopLossEndpoint, { data: { ...validPayloads, - triggerData: { executionLTV: '7100', token: '0x6b175474e89094c44da98b954eedeac495271d0f' }, + triggerData: { ...validPayloads.triggerData, executionLTV: '7100' }, }, }); diff --git a/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismAdd.spec.ts b/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismAdd.spec.ts index cecceca1..20e8aa30 100644 --- a/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismAdd.spec.ts +++ b/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismAdd.spec.ts @@ -4,7 +4,7 @@ import { validPayloadsAaveV3Optimism, responses } from 'utils/testData_APIs'; const stopLossEndpoint = '/api/triggers/10/aave3/dma-stop-loss'; const validPayloads = validPayloadsAaveV3Optimism.stopLoss.closeToDebt; -test.describe('API tests - Stop-Loss - Aave V3 - Optimism', async () => { +test.describe('API tests - Stop-Loss - Add - Aave V3 - Optimism', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-USDC.E/2 @@ -291,4 +291,14 @@ test.describe('API tests - Stop-Loss - Aave V3 - Optimism', async () => { expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloadsAaveV3Optimism.stopLoss.updateCloseToCollateral, action: 'add' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossAlreadyExist); + }); }); diff --git a/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismUpdate.spec.ts b/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismUpdate.spec.ts new file mode 100644 index 00000000..4099bb0f --- /dev/null +++ b/tests/api/automations/stopLoss/aaveV3/optimism/stopLossAv3OptimismUpdate.spec.ts @@ -0,0 +1,343 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsAaveV3Optimism, responses } from 'utils/testData_APIs'; + +const stopLossEndpoint = '/api/triggers/10/aave3/dma-stop-loss'; +const validPayloads = validPayloadsAaveV3Optimism.stopLoss.updateCloseToCollateral; + +test.describe('API tests - Stop-Loss - Update - Aave V3 - Optimism', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-USDC/355#protection + + test('Update automation - Close to collateral - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xc4CfF680A409Ebbd1A73a57f1FaC92065e2262d8', + }, + }); + }); + + test('Update automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { executionLTV: '7000', token: '0x0b2c639c533813f4aa9d7837caf62653d097ff85' }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xc4CfF680A409Ebbd1A73a57f1FaC92065e2262d8', + }, + }); + }); + + test('Update automation - Close to collateral & executionLTV - Valid payload data', async ({ + request, + }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { ...validPayloads.triggerData, executionLTV: '6800' }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xc4CfF680A409Ebbd1A73a57f1FaC92065e2262d8', + }, + }); + }); + + test('Update automation - Close to debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-DAI/385#protection + const response = await request.post(stopLossEndpoint, { + data: validPayloadsAaveV3Optimism.stopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xDfBEb6d4E160aAfa441690f11a5F2257021882b1', + }, + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloadsAaveV3Optimism.stopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, collateral: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); +}); diff --git a/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoAdd.spec.ts b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoAdd.spec.ts index 644f23a4..1f79fb88 100644 --- a/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoAdd.spec.ts +++ b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoAdd.spec.ts @@ -4,7 +4,7 @@ import { validPayloadsMorpho, responses } from 'utils/testData_APIs'; const stopLossEndpoint = '/api/triggers/1/morphoblue/dma-stop-loss'; const validPayloads = validPayloadsMorpho.stopLoss.closeToDebt; -test.describe('API tests - Stop-Loss - Morpho Blue - Ethereum', async () => { +test.describe('API tests - Stop-Loss - Add - Morpho Blue - Ethereum', async () => { // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WSTETH-ETH-1/1467 @@ -291,4 +291,14 @@ test.describe('API tests - Stop-Loss - Morpho Blue - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongToken); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloadsMorpho.stopLoss.updateCloseToCollateral, action: 'add' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossAlreadyExist); + }); }); diff --git a/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts new file mode 100644 index 00000000..a83500c9 --- /dev/null +++ b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts @@ -0,0 +1,350 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsMorpho, responses } from 'utils/testData_APIs'; + +const stopLossEndpoint = '/api/triggers/1/morphoblue/dma-stop-loss'; +const validPayloads = validPayloadsMorpho.stopLoss.updateCloseToCollateral; + +test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/morphoblue/borrow/WSTETH-ETH-1/2545#protection + + test('Update automation - Close to collateral - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + }, + }); + }); + + test('Update automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '7000', + token: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + }, + }); + }); + + test('Update automation - Close to collateral & executionLTV - Valid payload data', async ({ + request, + }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '7100', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + }, + }); + }); + + test.skip('Update automation - Close to debt - Valid payload data', async ({ request }) => { + // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 + // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1586#protection + const response = await request.post(stopLossEndpoint, { + data: validPayloadsMorpho.stopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xB727afF37C480a0FDbA8a6c97fC4FcF3A19f2ac7', + }, + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloadsMorpho.stopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, collateral: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongToken); + }); +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index f29ff00f..4711596a 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1641,6 +1641,20 @@ export const validPayloadsMorpho = { token: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, }, + updateCloseToCollateral: { + dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', + protocol: 'morphoblue', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + }, + action: 'update', + triggerData: { + executionLTV: '9300', + poolId: '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', + token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + }, + }, }, trailingStopLoss: { closeToDebt: { @@ -2188,6 +2202,32 @@ export const validPayloadsAaveV3Optimism = { token: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', }, }, + updateCloseToCollateral: { + dpm: '0xc4cff680a409ebbd1a73a57f1fac92065e2262d8', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + }, + action: 'update', + triggerData: { + executionLTV: '7887', + token: '0x4200000000000000000000000000000000000006', + }, + }, + updateCloseToDebt: { + dpm: '0xdfbeb6d4e160aafa441690f11a5f2257021882b1', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + triggerData: { + executionLTV: '7801', + token: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + }, }, trailingStopLoss: { closeToDebt: { From 6d6cd4627f88c0c8758b6806563ac372408e5753 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 10 Sep 2024 15:55:24 +0200 Subject: [PATCH 04/14] API tests - Update trigger - Auto Take Profit - fixes --- .../autoTakeProfitAv3ArbitrumAdd.spec.ts | 2 +- .../base/autoTakeProfitAv3BaseAdd.spec.ts | 2 +- .../autoTakeProfitAv3EthereumAdd.spec.ts | 2 +- .../autoTakeProfitAv3OptimismAdd.spec.ts | 2 +- .../autoTakeProfitMorphoAdd.spec.ts | 2 +- .../spark/autoTakeProfitSpark.spec.ts | 2 +- utils/testData_APIs.ts | 27 ++++++++++++++----- 7 files changed, 27 insertions(+), 12 deletions(-) diff --git a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts index ba439292..808b0ca3 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts @@ -7,7 +7,7 @@ import { const autoTakeProfit = '/api/triggers/42161/aave3/dma-partial-take-profit'; -const validPayloads = validPayloadsAaveV3Arbitrum.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsAaveV3Arbitrum.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0xF0464Ef55705e5B5cb3b865d92BE5341fe85fBB8', diff --git a/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts index 90f96625..1829adb9 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts @@ -3,7 +3,7 @@ import { validPayloadsAaveV3Base, responses, autoTakeProfitResponse } from 'util const autoTakeProfit = '/api/triggers/8453/aave3/dma-partial-take-profit'; -const validPayloads = validPayloadsAaveV3Base.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsAaveV3Base.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0xf71dA0973121d949E1CEe818eb519BA364406309', diff --git a/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts index 2cb842c1..469e6fea 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts @@ -7,7 +7,7 @@ import { const autoTakeProfit = '/api/triggers/1/aave3/dma-partial-take-profit'; -const validPayloads = validPayloadsAaveV3Ethereum.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsAaveV3Ethereum.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0x16F2C35E062C14F57475dE0A466F7E08b03A9C7D', diff --git a/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts index 98f725df..aa85d409 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts @@ -7,7 +7,7 @@ import { const autoTakeProfit = '/api/triggers/10/aave3/dma-partial-take-profit'; -const validPayloads = validPayloadsAaveV3Optimism.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsAaveV3Optimism.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0x2047E97451955c98bF8378f6ac2f04D95578990C', diff --git a/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts index 37460335..ea64dd37 100644 --- a/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts @@ -3,7 +3,7 @@ import { validPayloadsMorpho, responses, autoTakeProfitResponse } from 'utils/te const autoTakeProfit = '/api/triggers/1/morphoblue/dma-partial-take-profit'; -const validPayloads = validPayloadsMorpho.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsMorpho.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', diff --git a/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts index 22c1dc20..1be42dff 100644 --- a/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts +++ b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts @@ -3,7 +3,7 @@ import { validPayloadsSpark, responses, autoTakeProfitResponse } from 'utils/tes const autoTakeProfit = '/api/triggers/1/spark/dma-partial-take-profit'; -const validPayloads = validPayloadsSpark.autoTakeProfit.closeToDebt; +const validPayloads = validPayloadsSpark.autoTakeProfit.profitInDebt; const validResponse = autoTakeProfitResponse({ dpm: '0x6be31243E0FfA8F42D1F64834ECa2AB6DC8F7498', diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 4711596a..d0aa6019 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1530,7 +1530,7 @@ export const validPayloadsAaveV3Ethereum = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0x16f2c35e062c14f57475de0a466f7e08b03a9c7d', protocol: 'aavev3', position: { @@ -1673,7 +1673,7 @@ export const validPayloadsMorpho = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', protocol: 'morphoblue', position: { @@ -1798,7 +1798,7 @@ export const validPayloadsSpark = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0x6be31243e0ffa8f42d1f64834eca2ab6dc8f7498', protocol: 'sparkv3', position: { @@ -1947,7 +1947,7 @@ export const validPayloadsAaveV3Arbitrum = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0xf0464ef55705e5b5cb3b865d92be5341fe85fbb8', protocol: 'aavev3', position: { @@ -1969,6 +1969,21 @@ export const validPayloadsAaveV3Arbitrum = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0x849c16eb8bdeca1cb1bc7e83f1b92b1926b427ca', + protocol: 'aavev3', + position: { + collateral: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + debt: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + }, + action: 'update', + triggerData: { + executionLTV: '1600', + executionPrice: '9000000000000', + withdrawToken: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + withdrawStep: '500', + }, + }, }, }; @@ -2096,7 +2111,7 @@ export const validPayloadsAaveV3Base = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0xf71da0973121d949e1cee818eb519ba364406309', protocol: 'aavev3', position: { @@ -2245,7 +2260,7 @@ export const validPayloadsAaveV3Optimism = { }, }, autoTakeProfit: { - closeToDebt: { + profitInDebt: { dpm: '0x2047e97451955c98bf8378f6ac2f04d95578990c', protocol: 'aavev3', position: { From ee5ccc893222e7740001be6977bc79c3833e2e89 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 10 Sep 2024 16:52:11 +0200 Subject: [PATCH 05/14] API tests - Update trigger - Auto Take Profit - Arbitrum --- .../autoTakeProfitAv3ArbitrumAdd.spec.ts | 29 +- .../autoTakeProfitAv3ArbitrumUpdate.spec.ts | 449 ++++++++++++++++++ utils/testData_APIs.ts | 44 ++ 3 files changed, 514 insertions(+), 8 deletions(-) create mode 100644 tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts diff --git a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts index 808b0ca3..437e0c35 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumAdd.spec.ts @@ -23,7 +23,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Aave V3 - Arbitrum', async () => { +test.describe('API tests - Auto Take Profit - Add - Aave V3 - Arbitrum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/ETH-DAI/1 @@ -41,16 +41,16 @@ test.describe('API tests - Auto Take Profit - Aave V3 - Arbitrum', async () => { const response = await request.post(autoTakeProfit, { data: { ...validPayloads, - stopLoss: { - ...validPayloads.triggerData.stopLoss, - triggerData: { - ...validPayloads.triggerData.stopLoss.triggerData, - token: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', - }, - }, triggerData: { ...validPayloads.triggerData, withdrawToken: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + stopLoss: { + ...validPayloads.triggerData.stopLoss, + triggerData: { + ...validPayloads.triggerData.stopLoss.triggerData, + token: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + }, + }, }, }, }); @@ -355,5 +355,18 @@ test.describe('API tests - Auto Take Profit - Aave V3 - Arbitrum', async () => { expect(respJSON).toMatchObject(responses.wrongStopLossTriggerData); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Arbitrum.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts new file mode 100644 index 00000000..7ec56e38 --- /dev/null +++ b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts @@ -0,0 +1,449 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsAaveV3Arbitrum, + responses, + autoTakeProfitResponse, +} from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/42161/aave3/dma-partial-take-profit'; + +const validPayloads = validPayloadsAaveV3Arbitrum.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0x849c16eb8BDeCA1cB1Bc7e83F1B92b1926B427Ca', + collateral: { + decimals: 8, + symbol: 'WBTC', + address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Aave V3 - Arbitrum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/WBTC-USDC/370#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/ETH-DAI/352#optimization + + const response = await request.post(autoTakeProfit, { + data: validPayloadsAaveV3Arbitrum.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0x5658E378371809d1aEF8749eBAD8D161CD90D33c', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + executionPrice: '8000000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + executionLTV: '1000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '9500000000000', + executionLTV: '1100', + withdrawStep: '6000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Arbitrum.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index d0aa6019..6d7dd492 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1382,6 +1382,28 @@ export const responses = { ], warnings: [], }, + autoTakeProfitDoesNotExist: { + message: 'Validation Errors', + errors: [ + { + message: 'Trigger does not exist', + code: 'trigger-does-not-exist', + path: [], + }, + ], + warnings: [], + }, + autoTakeProfitAlreadyExists: { + message: 'Validation Errors', + errors: [ + { + message: 'Trigger already exists', + code: 'trigger-already-exists', + path: [], + }, + ], + warnings: [], + }, stopLossDoesNotExist: { message: 'Validation Errors', errors: [ @@ -1984,6 +2006,28 @@ export const validPayloadsAaveV3Arbitrum = { withdrawStep: '500', }, }, + updateProfitInDebt: { + dpm: '0x5658e378371809d1aef8749ebad8d161cd90d33c', + protocol: 'aavev3', + position: { + collateral: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + debt: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + triggerData: { + executionLTV: '1000', + executionPrice: '600000000000', + stopLoss: { + triggerData: { + executionLTV: '8140', + token: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + }, + withdrawToken: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + withdrawStep: '500', + }, + }, }, }; From e12dcfffa9fdc95dee928e34ad55ca42a84d779f Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 09:22:33 +0200 Subject: [PATCH 06/14] API tests - Update trigger - Auto Take Profit - Base --- .../autoTakeProfitAv3ArbitrumUpdate.spec.ts | 2 +- .../base/autoTakeProfitAv3BaseAdd.spec.ts | 15 +- .../base/autoTakeProfitAv3BaseUpdate.spec.ts | 445 ++++++++++++++++++ utils/testData_APIs.ts | 66 +++ 4 files changed, 526 insertions(+), 2 deletions(-) create mode 100644 tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseUpdate.spec.ts diff --git a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts index 7ec56e38..3cc437a0 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/arbitrum/autoTakeProfitAv3ArbitrumUpdate.spec.ts @@ -127,7 +127,7 @@ test.describe('API tests - Auto Take Profit - Update - Aave V3 - Arbitrum', asyn ...validPayloads.triggerData, executionPrice: '9500000000000', executionLTV: '1100', - withdrawStep: '6000', + withdrawStep: '600', }, }, }); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts index 1829adb9..9e12fb80 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseAdd.spec.ts @@ -19,7 +19,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Aave V3 - Base', async () => { +test.describe('API tests - Auto Take Profit - Add - Aave V3 - Base', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/base/aave/v3/multiply/ETH-USDC/435 @@ -351,5 +351,18 @@ test.describe('API tests - Auto Take Profit - Aave V3 - Base', async () => { expect(respJSON).toMatchObject(responses.wrongStopLossTriggerData); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Base.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseUpdate.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseUpdate.spec.ts new file mode 100644 index 00000000..9c9c1854 --- /dev/null +++ b/tests/api/automations/autoTakeProfit/aaveV3/base/autoTakeProfitAv3BaseUpdate.spec.ts @@ -0,0 +1,445 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsAaveV3Base, responses, autoTakeProfitResponse } from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/8453/aave3/dma-partial-take-profit'; + +const validPayloads = validPayloadsAaveV3Base.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0xb3287c2890Ed7EA99Cb4d5D899434bB64997a609', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Aave V3 - Base', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/base/aave/v3/borrow/ETH-USDC/677#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/base/aave/v3/multiply/ETH-USDC/500#protection + + const response = await request.post(autoTakeProfit, { + data: validPayloadsAaveV3Base.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0x20e74013d82fea853AfCa3b4CB1Fd9C2B105F55a', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + executionPrice: '8000000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + executionLTV: '2000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '9500000000000', + executionLTV: '1100', + withdrawStep: '600', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Base.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 6d7dd492..0b3d0cec 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -2177,6 +2177,50 @@ export const validPayloadsAaveV3Base = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0xb3287c2890ed7ea99cb4d5d899434bb64997a609', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }, + action: 'update', + triggerData: { + executionLTV: '5400', + executionPrice: '600000000000', + stopLoss: { + triggerData: { + executionLTV: '7855', + token: '0x4200000000000000000000000000000000000006', + }, + action: 'update', + }, + withdrawToken: '0x4200000000000000000000000000000000000006', + withdrawStep: '500', + }, + }, + updateProfitInDebt: { + dpm: '0x20e74013d82fea853afca3b4cb1fd9c2b105f55a', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }, + action: 'update', + triggerData: { + executionLTV: '1400', + executionPrice: '600000000000', + stopLoss: { + triggerData: { + executionLTV: '7721', + token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }, + action: 'update', + }, + withdrawToken: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + withdrawStep: '500', + }, + }, }, }; @@ -2326,5 +2370,27 @@ export const validPayloadsAaveV3Optimism = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0xc4cff680a409ebbd1a73a57f1fac92065e2262d8', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + }, + action: 'update', + triggerData: { + executionLTV: '800', + executionPrice: '860000000000', + stopLoss: { + triggerData: { + executionLTV: '7887', + token: '0x4200000000000000000000000000000000000006', + }, + action: 'update', + }, + withdrawToken: '0x4200000000000000000000000000000000000006', + withdrawStep: '500', + }, + }, }, }; From e5ede9e322501945e595eee6ea19f0a0b57ece03 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 09:57:49 +0200 Subject: [PATCH 07/14] API tests - Update trigger - Auto Take Profit - Ethereum --- .../morphoBlue/autoSellMorphoAdd.spec.ts | 2 +- .../morphoBlue/autoSellMorphoUpdate.spec.ts | 441 +++++++++++++++++ .../autoTakeProfitAv3EthereumAdd.spec.ts | 15 +- .../autoTakeProfitAvEthereumUpdate.spec.ts | 449 ++++++++++++++++++ utils/testData_APIs.ts | 44 ++ 5 files changed, 949 insertions(+), 2 deletions(-) create mode 100644 tests/api/automations/autoSell/morphoBlue/autoSellMorphoUpdate.spec.ts create mode 100644 tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAvEthereumUpdate.spec.ts diff --git a/tests/api/automations/autoSell/morphoBlue/autoSellMorphoAdd.spec.ts b/tests/api/automations/autoSell/morphoBlue/autoSellMorphoAdd.spec.ts index 802c1dda..9f8bd5fe 100644 --- a/tests/api/automations/autoSell/morphoBlue/autoSellMorphoAdd.spec.ts +++ b/tests/api/automations/autoSell/morphoBlue/autoSellMorphoAdd.spec.ts @@ -27,7 +27,7 @@ const validResponse = autoSellWithoutMinSellPriceResponse({ targetLTVWithDeviation: ['9200', '9400'], }); -test.describe('API tests - Auto-Sell - Morpho Blue - Ethereum', async () => { +test.describe('API tests - Auto-Sell - Add - Morpho Blue - Ethereum', async () => { // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WSTETH-ETH-1/1467 diff --git a/tests/api/automations/autoSell/morphoBlue/autoSellMorphoUpdate.spec.ts b/tests/api/automations/autoSell/morphoBlue/autoSellMorphoUpdate.spec.ts new file mode 100644 index 00000000..9521ba3c --- /dev/null +++ b/tests/api/automations/autoSell/morphoBlue/autoSellMorphoUpdate.spec.ts @@ -0,0 +1,441 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsMorpho, + responses, + autoSellWithoutMinSellPriceResponse, +} from 'utils/testData_APIs'; + +const autoSellEndpoint = '/api/triggers/1/morphoblue/auto-sell'; + +const validPayloads = validPayloadsMorpho.autoSell.updateMinSellPrice; + +const validResponse = autoSellWithoutMinSellPriceResponse({ + dpm: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + collateral: { + decimals: 8, + symbol: 'WBTC', + address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, + // hasStablecoinDebt: true, --> Morpho bug (?) - Waiting for confirmation + hasStablecoinDebt: false, + executionLTV: '8000', + targetLTV: '7300', + targetLTVWithDeviation: ['7200', '7400'], +}); + +test.describe('API tests - Auto-Sell - Update - Morpho Blue - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WBTC-USDC/2545#protection + + test('Update existing automation - minSellPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + warnings: [], + }); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '8100', + minSellPrice: '500000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { ...validResponse.simulation, executionLTV: '8100' }, + warnings: [], + }); + }); + + test('Update existing automation - targetLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + targetLTV: '7200', + minSellPrice: '500000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { + ...validResponse.simulation, + targetLTV: '7200', + targetLTVWithDeviation: ['7100', '7300'], + }, + warnings: [], + }); + }); + + test('Update existing automation - Set No threshold - Valid payload data', async ({ + request, + }) => { + const { minSellPrice, ...triggerdataWithoutminSellPrice } = validPayloads.triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...triggerdataWithoutminSellPrice, + useMinSellPrice: false, + }, + }, + }); + + const respJSON = await response.json(); + + // No warning for Morpho - Minor bug + // https://app.shortcut.com/oazo-apps/story/15553/bug-auto-buy-missing-warning-when-selecting-set-no-threshold + expect(respJSON).toMatchObject({ + ...validResponse, + warnings: [], + }); + }); + + test('Update existing automation - executionLTV, targetLTV & minSellPrice - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '7800', + targetLTV: '6700', + minSellPrice: '300000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...validResponse, + simulation: { + ...validResponse.simulation, + executionLTV: '7800', + targetLTV: '6700', + targetLTVWithDeviation: ['6600', '6800'], + }, + warnings: [], + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloadsMorpho.autoSell.addWithoutMinSellPrice, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoSellDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoSellEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { + ...validPayloads, + triggerData: 'string', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(autoSellEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update automation - Without "maxBaseFee (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { maxBaseFee, ...triggerDataWithoutMaxBaseFee } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutMaxBaseFee }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongMaxBaseFee); + }); + + test('Update automation - Without "targetLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { targetLTV, ...triggerDataWithoutTargetLTV } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutTargetLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTargetLTV); + }); + + test('Update automation - Without "useMinSellPrice (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { minSellPrice, useMinSellPrice, ...triggerDataWithoutUseMinSellPrice } = triggerData; + + const response = await request.post(autoSellEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutUseMinSellPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongUseMinSellPrice); + }); +}); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts index 469e6fea..ccef0083 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAv3EthereumAdd.spec.ts @@ -23,7 +23,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Aave V3 - Ethereum', async () => { +test.describe('API tests - Auto Take Profit - Add - Aave V3 - Ethereum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1218 @@ -355,5 +355,18 @@ test.describe('API tests - Auto Take Profit - Aave V3 - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongStopLossTriggerData); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Ethereum.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAvEthereumUpdate.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAvEthereumUpdate.spec.ts new file mode 100644 index 00000000..b07cc66d --- /dev/null +++ b/tests/api/automations/autoTakeProfit/aaveV3/ethereum/autoTakeProfitAvEthereumUpdate.spec.ts @@ -0,0 +1,449 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsAaveV3Ethereum, + responses, + autoTakeProfitResponse, +} from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/1/aave3/dma-partial-take-profit'; + +const validPayloads = validPayloadsAaveV3Ethereum.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Aave V3 - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/WSTETH-USDC/2545#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 + // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1586#optimization + + const response = await request.post(autoTakeProfit, { + data: validPayloadsAaveV3Ethereum.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0xB727afF37C480a0FDbA8a6c97fC4FcF3A19f2ac7', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + executionPrice: '8000000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + executionLTV: '2000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '9500000000000', + executionLTV: '1100', + withdrawStep: '600', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Ethereum.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 0b3d0cec..8d86bfa4 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1574,6 +1574,50 @@ export const validPayloadsAaveV3Ethereum = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', + protocol: 'aavev3', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + triggerData: { + executionLTV: '3010', + executionPrice: '700000000000', + stopLoss: { + triggerData: { + executionLTV: '7740', + token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + }, + action: 'update', + }, + withdrawToken: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + withdrawStep: '500', + }, + }, + updateProfitInDebt: { + dpm: '0xb727aff37c480a0fdba8a6c97fc4fcf3a19f2ac7', + protocol: 'aavev3', + position: { + collateral: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + debt: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + triggerData: { + executionLTV: '2220', + executionPrice: '514130825283', + stopLoss: { + triggerData: { + executionLTV: '7700', + token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + }, + withdrawToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + withdrawStep: '500', + }, + }, }, }; From f53100463191fd78b3392baf57a3eeae339ca20d Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 10:39:09 +0200 Subject: [PATCH 08/14] API tests - Update trigger - Auto Take Profit - Morpho --- .../autoTakeProfitMorphoAdd.spec.ts | 15 +- .../autoTakeProfitMorphoUpdate.spec.ts | 445 ++++++++++++++++++ utils/testData_APIs.ts | 48 ++ 3 files changed, 507 insertions(+), 1 deletion(-) create mode 100644 tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoUpdate.spec.ts diff --git a/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts index ea64dd37..731f8525 100644 --- a/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoAdd.spec.ts @@ -19,7 +19,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Morpho Blue - Ethereum', async () => { +test.describe('API tests - Auto Take Profit - Add - Morpho Blue - Ethereum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/ethereum/morphoblue/borrow/WBTC-USDC/2545 @@ -351,5 +351,18 @@ test.describe('API tests - Auto Take Profit - Morpho Blue - Ethereum', async () expect(respJSON).toMatchObject(responses.wrongStopLossTriggerDataMorpho); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsMorpho.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoUpdate.spec.ts b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoUpdate.spec.ts new file mode 100644 index 00000000..4d3bb6be --- /dev/null +++ b/tests/api/automations/autoTakeProfit/morphoBlue/autoTakeProfitMorphoUpdate.spec.ts @@ -0,0 +1,445 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsMorpho, responses, autoTakeProfitResponse } from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/1/morphoblue/dma-partial-take-profit'; + +const validPayloads = validPayloadsMorpho.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 18, + symbol: 'WETH', + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Morpho Blue - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WSTETH-ETH-1/2545#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WSTETH-USDC/2545#optimization + + const response = await request.post(autoTakeProfit, { + data: validPayloadsMorpho.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + executionPrice: '400000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + executionLTV: '3200', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '450000000', + executionLTV: '3100', + withdrawStep: '600', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsMorpho.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 8d86bfa4..b908ef11 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1763,6 +1763,54 @@ export const validPayloadsMorpho = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', + protocol: 'morphoblue', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + }, + action: 'update', + triggerData: { + executionLTV: '3580', + executionPrice: '350000000', + poolId: '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', + stopLoss: { + triggerData: { + executionLTV: '9300', + token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + poolId: '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', + }, + action: 'update', + }, + withdrawToken: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + withdrawStep: '500', + }, + }, + updateProfitInDebt: { + dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', + protocol: 'morphoblue', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + triggerData: { + executionLTV: '1740', + executionPrice: '600000000000', + poolId: '0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc', + stopLoss: { + triggerData: { + executionLTV: '8490', + token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + poolId: '0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc', + }, + action: 'update', + }, + withdrawToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + withdrawStep: '500', + }, + }, }, }; From 235937e6eadeb99a5694ae0a4dde4ec596c0e4ed Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 11:30:16 +0200 Subject: [PATCH 09/14] API tests - Update trigger - Auto Take Profit - Spark --- ...spec.ts => autoTakeProfitSparkAdd.spec.ts} | 15 +- .../spark/autoTakeProfitSparkUpdate.spec.ts | 445 ++++++++++++++++++ utils/testData_APIs.ts | 44 ++ 3 files changed, 503 insertions(+), 1 deletion(-) rename tests/api/automations/autoTakeProfit/spark/{autoTakeProfitSpark.spec.ts => autoTakeProfitSparkAdd.spec.ts} (96%) create mode 100644 tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkUpdate.spec.ts diff --git a/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkAdd.spec.ts similarity index 96% rename from tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts rename to tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkAdd.spec.ts index 1be42dff..fb1d073a 100644 --- a/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSpark.spec.ts +++ b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkAdd.spec.ts @@ -19,7 +19,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Spark - Ethereum', async () => { +test.describe('API tests - Auto Take Profit - Add - Spark - Ethereum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/ethereum/spark/earn/WSTETH-ETH/1417 @@ -351,5 +351,18 @@ test.describe('API tests - Auto Take Profit - Spark - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongStopLossTriggerData); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsSpark.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkUpdate.spec.ts b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkUpdate.spec.ts new file mode 100644 index 00000000..debc6695 --- /dev/null +++ b/tests/api/automations/autoTakeProfit/spark/autoTakeProfitSparkUpdate.spec.ts @@ -0,0 +1,445 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsSpark, responses, autoTakeProfitResponse } from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/1/spark/dma-partial-take-profit'; + +const validPayloads = validPayloadsSpark.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0xce049ff57d4146d5bE3a55E60Ef4523bB70798b6', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Spark - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/spark/multiply/WSTETH-DAI/2637#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/spark/multiply/WSTETH-DAI/2737#optimization + + const response = await request.post(autoTakeProfit, { + data: validPayloadsSpark.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0xB42D970a6424583618D0013E0D6eBB039dd1c945', + collateral: { + decimals: 18, + symbol: 'wstETH', + address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + executionPrice: '750000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + executionLTV: '1800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '800000000000', + executionLTV: '1500', + withdrawStep: '600', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsSpark.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index b908ef11..d026ba63 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1934,6 +1934,50 @@ export const validPayloadsSpark = { withdrawStep: '500', }, }, + updateProfitInCollateral: { + dpm: '0xce049ff57d4146d5be3a55e60ef4523bb70798b6', + protocol: 'sparkv3', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + triggerData: { + executionLTV: '2000', + executionPrice: '650000000000', + stopLoss: { + triggerData: { + executionLTV: '7790', + token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + }, + action: 'update', + }, + withdrawToken: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + withdrawStep: '500', + }, + }, + updateProfitInDebt: { + dpm: '0xb42d970a6424583618d0013e0d6ebb039dd1c945', + protocol: 'sparkv3', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + triggerData: { + executionLTV: '2000', + executionPrice: '600000000000', + stopLoss: { + triggerData: { + executionLTV: '7790', + token: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + }, + withdrawToken: '0x6b175474e89094c44da98b954eedeac495271d0f', + withdrawStep: '500', + }, + }, }, }; From ad0d6a1cff91a31c81d0b10d2d8b84fb6340f92c Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 11:38:49 +0200 Subject: [PATCH 10/14] API tests - Update trigger - Stop-Loss - Morpho --- .../morphoBlue/stopLossMorphoUpdate.spec.ts | 8 ++++---- utils/testData_APIs.ts | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts index a83500c9..0d62630f 100644 --- a/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts +++ b/tests/api/automations/stopLoss/morphoBlue/stopLossMorphoUpdate.spec.ts @@ -71,9 +71,9 @@ test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => }); }); - test.skip('Update automation - Close to debt - Valid payload data', async ({ request }) => { - // Old test wallet: 0xbEf4befb4F230F43905313077e3824d7386E09F8 - // Position link: https://staging.summer.fi/ethereum/aave/v3/multiply/ETH-USDC/1586#protection + test('Update automation - Close to debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/morphoblue/multiply/WSTETH-USDC/2545#protection const response = await request.post(stopLossEndpoint, { data: validPayloadsMorpho.stopLoss.updateCloseToDebt, }); @@ -84,7 +84,7 @@ test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => ...responses.stopLoss, transaction: { ...responses.stopLoss.transaction, - to: '0xB727afF37C480a0FDbA8a6c97fC4FcF3A19f2ac7', + to: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', }, }); }); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index d026ba63..fd6edce8 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1721,6 +1721,20 @@ export const validPayloadsMorpho = { token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', }, }, + updateCloseToDebt: { + dpm: '0x2e0515d7a3ea0276f28c94c426c5d2d1d85fd4d5', + protocol: 'morphoblue', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + action: 'update', + triggerData: { + executionLTV: '8490', + poolId: '0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc', + token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + }, }, trailingStopLoss: { closeToDebt: { From 8baffd6d5b38d6b373cf5c41d8aff4e061e2b7a5 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 11:57:38 +0200 Subject: [PATCH 11/14] API tests - Update trigger - Stop-Loss - Spark --- .../stopLoss/spark/stopLossSparkAdd.spec.ts | 12 +- .../spark/stopLossSparkUpdate.spec.ts | 350 ++++++++++++++++++ 2 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 tests/api/automations/stopLoss/spark/stopLossSparkUpdate.spec.ts diff --git a/tests/api/automations/stopLoss/spark/stopLossSparkAdd.spec.ts b/tests/api/automations/stopLoss/spark/stopLossSparkAdd.spec.ts index dd9ec36e..f1161aa8 100644 --- a/tests/api/automations/stopLoss/spark/stopLossSparkAdd.spec.ts +++ b/tests/api/automations/stopLoss/spark/stopLossSparkAdd.spec.ts @@ -4,7 +4,7 @@ import { validPayloadsSpark, responses } from 'utils/testData_APIs'; const stopLossEndpoint = '/api/triggers/1/spark/dma-stop-loss'; const validPayloads = validPayloadsSpark.stopLoss.closeToDebt; -test.describe('API tests - Stop-Loss - Spark - Ethereum', async () => { +test.describe('API tests - Stop-Loss - Add - Spark - Ethereum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/ethereum/spark/earn/WSTETH-ETH/1417 @@ -291,4 +291,14 @@ test.describe('API tests - Stop-Loss - Spark - Ethereum', async () => { expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloadsSpark.stopLoss.updateCloseToCollateral, action: 'add' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossAlreadyExist); + }); }); diff --git a/tests/api/automations/stopLoss/spark/stopLossSparkUpdate.spec.ts b/tests/api/automations/stopLoss/spark/stopLossSparkUpdate.spec.ts new file mode 100644 index 00000000..0a00ad64 --- /dev/null +++ b/tests/api/automations/stopLoss/spark/stopLossSparkUpdate.spec.ts @@ -0,0 +1,350 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsSpark, responses } from 'utils/testData_APIs'; + +const stopLossEndpoint = '/api/triggers/1/spark/dma-stop-loss'; +const validPayloads = validPayloadsSpark.stopLoss.updateCloseToCollateral; + +test.describe('API tests - Stop-Loss - Update - Aave V3 - Ethereum', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/spark/multiply/WSTETH-DAI/2843#protection + + test('Update automation - Close to collateral - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x9ae9e1FcccB4934F29565121f9982a43A00F53EC', + }, + }); + }); + + test('Update automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '7000', + token: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x9ae9e1FcccB4934F29565121f9982a43A00F53EC', + }, + }); + }); + + test('Update automation - Close to collateral & executionLTV - Valid payload data', async ({ + request, + }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionLTV: '7100', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0x9ae9e1FcccB4934F29565121f9982a43A00F53EC', + }, + }); + }); + + test('Update automation - Close to debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/ethereum/spark/multiply/WSTETH-DAI/2637#protection + const response = await request.post(stopLossEndpoint, { + data: validPayloadsSpark.stopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject({ + ...responses.stopLoss, + transaction: { + ...responses.stopLoss.transaction, + to: '0xce049ff57d4146d5bE3a55E60Ef4523bB70798b6', + }, + }); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloadsSpark.stopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + test('Update automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update automation - Wrong data type - "position" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update automation - Wrong data type - "position" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong data type - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, collateral: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Wrong value - "collateral (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(stopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - string', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - number', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - array', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Wrong data type - "triggerData" - null', async ({ request }) => { + const response = await request.post(stopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); + + test('Update automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(stopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerDataStopLoss); + }); +}); From a50d502afa24e6fe270f493551378352ccfe39d5 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 15:48:58 +0200 Subject: [PATCH 12/14] API tests - Update trigger - Auto Take Profit - Optimism --- .../autoTakeProfitAv3OptimismAdd.spec.ts | 14 +- .../autoTakeProfitAv3OptimismUpdate.spec.ts | 449 ++++++++++++++++++ .../trailingStopLossAv3ArbitrumAdd.spec.ts | 13 +- .../trailingStopLossAv3ArbitrumUpdate.spec.ts | 396 +++++++++++++++ utils/testData_APIs.ts | 74 +++ 5 files changed, 944 insertions(+), 2 deletions(-) create mode 100644 tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismUpdate.spec.ts create mode 100644 tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts diff --git a/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts index aa85d409..132edd63 100644 --- a/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts +++ b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismAdd.spec.ts @@ -23,7 +23,7 @@ const validResponse = autoTakeProfitResponse({ }, }); -test.describe('API tests - Auto Take Profit - Aave V3 - Optimism', async () => { +test.describe('API tests - Auto Take Profit - Add - Aave V3 - Optimism', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-USDC.E/2 @@ -355,5 +355,17 @@ test.describe('API tests - Auto Take Profit - Aave V3 - Optimism', async () => { expect(respJSON).toMatchObject(responses.wrongStopLossTriggerData); }); + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Optimism.autoTakeProfit.updateProfitInCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitAlreadyExists); + }); // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' }); diff --git a/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismUpdate.spec.ts b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismUpdate.spec.ts new file mode 100644 index 00000000..b35bb6ed --- /dev/null +++ b/tests/api/automations/autoTakeProfit/aaveV3/optimism/autoTakeProfitAv3OptimismUpdate.spec.ts @@ -0,0 +1,449 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsAaveV3Optimism, + responses, + autoTakeProfitResponse, +} from 'utils/testData_APIs'; + +const autoTakeProfit = '/api/triggers/10/aave3/dma-partial-take-profit'; + +const validPayloads = validPayloadsAaveV3Optimism.autoTakeProfit.updateProfitInCollateral; + +const validResponse = autoTakeProfitResponse({ + dpm: '0xc4CfF680A409Ebbd1A73a57f1FaC92065e2262d8', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', + }, +}); + +test.describe('API tests - Auto Take Profit - Update - Aave V3 - Optimism', async () => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-USDC/355#optimization + + test('Update existing automation - Profit in collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Profit in debt - Valid payload data', async ({ request }) => { + // New test wallet: 0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA + // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-DAI/385#optimization + + const response = await request.post(autoTakeProfit, { + data: validPayloadsAaveV3Optimism.autoTakeProfit.updateProfitInDebt, + }); + + const respJSON = await response.json(); + + const debtResponse = autoTakeProfitResponse({ + dpm: '0xDfBEb6d4E160aAfa441690f11a5F2257021882b1', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + }, + }); + + expect(respJSON).toMatchObject(debtResponse); + }); + + test('Update existing automation - executionPrice - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + executionPrice: '870000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - executionLTV - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + executionLTV: '700', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - withdrawStep - Valid payload data', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + withdrawToken: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + withdrawStep: '800', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - profit in collateral, executionPrice, executionLTV and withdrawStep - Valid payload data', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + executionPrice: '900000000000', + executionLTV: '600', + withdrawStep: '600', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloadsAaveV3Optimism.autoTakeProfit.profitInDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.autoTakeProfitDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { ...validPayloads.position, debt: 11 }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(autoTakeProfit, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(autoTakeProfit, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(autoTakeProfit, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "executionLTV (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionLTV, ...triggerDataWithoutExecutionLTV } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionLTV }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionLTV); + }); + + test('Update existing automation - Without "executionPrice (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { executionPrice, ...triggerDataWithoutExecutionPrice } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutExecutionPrice }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongExecutionPrice); + }); + + test('Update existing automation - Without "withdrawToken (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawToken, ...triggerDataWithoutWithdrawToken } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawToken); + }); + + test('Update existing automation - Without "withdrawStep (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { withdrawStep, ...triggerDataWithoutWithdrawStep } = triggerData; + + const response = await request.post(autoTakeProfit, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutWithdrawStep }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongWithdrawStep); + }); + + // TO BE DONE - More negative scenarios for missing attribues in 'triggerData > StopLoss' +}); diff --git a/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumAdd.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumAdd.spec.ts index 06e40da9..c1387ad3 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumAdd.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumAdd.spec.ts @@ -26,7 +26,7 @@ const validResponse = trailingStopLossResponse({ hasStablecoinDebt: true, }); -test.describe('API tests - Trailing Stop-Loss - Aave V3 - Arbitrum', async () => { +test.describe('API tests - Trailing Stop-Loss - Add - Aave V3 - Arbitrum', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/ETH-DAI/1 @@ -307,4 +307,15 @@ test.describe('API tests - Trailing Stop-Loss - Aave V3 - Arbitrum', async () => expect(respJSON).toMatchObject(responses.wrongToken); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloadsAaveV3Arbitrum.trailingStopLoss.updateCloseToCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + }); }); diff --git a/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts new file mode 100644 index 00000000..79edc03f --- /dev/null +++ b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts @@ -0,0 +1,396 @@ +import { expect, test } from '@playwright/test'; +import { + validPayloadsAaveV3Arbitrum, + responses, + trailingStopLossResponse, +} from 'utils/testData_APIs'; + +const trailingStopLossEndpoint = '/api/triggers/42161/aave3/dma-trailing-stop-loss'; + +const validPayloads = validPayloadsAaveV3Arbitrum.trailingStopLoss.updateCloseToCollateral; + +const validResponse = trailingStopLossResponse({ + dpm: '0x9a8999d48499743B5CA481210dc568018a3B417a', + collateral: { + decimals: 8, + symbol: 'WBTC', + address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + oraclesAddress: '0x6ce185860a4963106506c203335a2910413708e9', + }, + debt: { + decimals: 18, + symbol: 'DAI', + address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + oraclesAddress: '0xc5c8e77b397e531b8ec06bfb0048328b30e9ecfb', + }, + hasStablecoinDebt: true, +}); + +test.describe('API tests - Trailing Stop-Loss - Update - Aave V3 - Arbitrum', async () => { + // New test wallet: 0x10649c79428d718621821Cf6299e91920284743F + // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/WBTC-DAI/560#protection + + test('Update existing automation - Close to collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Close to debt - Valid payload data', async ({ request }) => { + // New test wallet: 0x10649c79428d718621821Cf6299e91920284743F + // Position link: https://staging.summer.fi/arbitrum/aave/v3/multiply/WBTC-USDC/370#protection + + const response = await request.post(trailingStopLossEndpoint, { + data: validPayloadsAaveV3Arbitrum.trailingStopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + const updateCloseToDebtResponse = trailingStopLossResponse({ + dpm: '0x849c16eb8BDeCA1cB1Bc7e83F1B92b1926B427Ca', + collateral: { + decimals: 8, + symbol: 'WBTC', + address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + oraclesAddress: '0x6ce185860a4963106506c203335a2910413708e9', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + oraclesAddress: '0x50834f3163758fcc1df9973b6e91f0f0f0434ad3', + }, + hasStablecoinDebt: true, + }); + + expect(respJSON).toMatchObject(updateCloseToDebtResponse); + }); + + test('Update existing automation - Trailing distance - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + trailingDistance: '3700000000000', + token: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Close to collateral and trailing distance - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + trailingDistance: '3750000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloadsAaveV3Arbitrum.trailingStopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + // ------------------- + // ------------------- + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "trailingDistance (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { trailingDistance, ...triggerDataWithoutTrailingDistance } = triggerData; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutTrailingDistance }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTrailingDistance); + }); + + test('Update existing automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongToken); + }); +}); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index fd6edce8..4908a183 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -1909,6 +1909,32 @@ export const validPayloadsSpark = { token: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, }, + updateCloseToCollateral: { + dpm: '0x9ae9e1fcccb4934f29565121f9982a43a00f53ec', + protocol: 'sparkv3', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + triggerData: { + executionLTV: '7760', + token: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + }, + }, + updateCloseToDebt: { + dpm: '0xce049ff57d4146d5be3a55e60ef4523bb70798b6', + protocol: 'sparkv3', + position: { + collateral: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + debt: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + action: 'update', + triggerData: { + executionLTV: '7790', + token: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, + }, }, trailingStopLoss: { closeToDebt: { @@ -2117,6 +2143,32 @@ export const validPayloadsAaveV3Arbitrum = { token: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', }, }, + updateCloseToCollateral: { + dpm: '0x9a8999d48499743b5ca481210dc568018a3b417a', + protocol: 'aavev3', + position: { + collateral: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + debt: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + triggerData: { + trailingDistance: '3670000000000', + token: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + }, + }, + updateCloseToDebt: { + dpm: '0x849c16eb8bdeca1cb1bc7e83f1b92b1926b427ca', + protocol: 'aavev3', + position: { + collateral: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + debt: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + }, + action: 'update', + triggerData: { + trailingDistance: '4080000000000', + token: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + }, + }, }, autoTakeProfit: { profitInDebt: { @@ -2542,5 +2594,27 @@ export const validPayloadsAaveV3Optimism = { withdrawStep: '500', }, }, + updateProfitInDebt: { + dpm: '0xdfbeb6d4e160aafa441690f11a5f2257021882b1', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + triggerData: { + executionLTV: '1500', + executionPrice: '700000000000', + stopLoss: { + triggerData: { + executionLTV: '7801', + token: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + action: 'update', + }, + withdrawToken: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + withdrawStep: '500', + }, + }, }, }; From 85e07092d93c440e7a3357ba642657cd0f012c96 Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 16:44:56 +0200 Subject: [PATCH 13/14] API tests - Update trigger - Trailing Stop-Loss - Base --- .../trailingStopLossAv3ArbitrumUpdate.spec.ts | 3 - .../base/trailingStopLossAv3BaseAdd.spec.ts | 13 +- .../trailingStopLossAv3BaseUpdate.spec.ts | 390 ++++++++++++++++++ .../trailingStopLossAv3OptimismAdd.spec.ts | 2 +- utils/testData_APIs.ts | 39 +- 5 files changed, 437 insertions(+), 10 deletions(-) create mode 100644 tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts diff --git a/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts index 79edc03f..e009e99b 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/arbitrum/trailingStopLossAv3ArbitrumUpdate.spec.ts @@ -121,9 +121,6 @@ test.describe('API tests - Trailing Stop-Loss - Update - Aave V3 - Arbitrum', as expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); }); - // ------------------- - // ------------------- - test('Update existing automation - Without "dpm"', async ({ request }) => { const { dpm, ...payloadWithoutDpm } = validPayloads; diff --git a/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseAdd.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseAdd.spec.ts index 13de5cfc..8325507e 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseAdd.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseAdd.spec.ts @@ -22,7 +22,7 @@ const validResponse = trailingStopLossResponse({ hasStablecoinDebt: true, }); -test.describe('API tests - Trailing Stop-Loss - Aave V3 - Base', async () => { +test.describe('API tests - Trailing Stop-Loss - Add - Aave V3 - Base', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/base/aave/v3/multiply/ETH-USDC/435 @@ -303,4 +303,15 @@ test.describe('API tests - Trailing Stop-Loss - Aave V3 - Base', async () => { expect(respJSON).toMatchObject(responses.wrongToken); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloadsAaveV3Base.trailingStopLoss.updateCloseToCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + }); }); diff --git a/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts new file mode 100644 index 00000000..d7d5b776 --- /dev/null +++ b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts @@ -0,0 +1,390 @@ +import { expect, test } from '@playwright/test'; +import { validPayloadsAaveV3Base, responses, trailingStopLossResponse } from 'utils/testData_APIs'; + +const trailingStopLossEndpoint = '/api/triggers/8453/aave3/dma-trailing-stop-loss'; + +const validPayloads = validPayloadsAaveV3Base.trailingStopLoss.updateCloseToCollateral; + +const validResponse = trailingStopLossResponse({ + dpm: '0xe70c8069627a9C7933362e25F033Ec0771F0f06e', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + oraclesAddress: '0x71041dddad3595f9ced3dccfbe3d1f4b0a16bb70', + }, + debt: { + decimals: 6, + symbol: 'USDbC', + address: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', + oraclesAddress: '0x7e860098f58bbfc8648a4311b374b1d669a2bc6b', + usdcVariant: 'usdbcBase', + }, + hasStablecoinDebt: true, +}); + +test.describe('API tests - Trailing Stop-Loss - Update - Aave V3 - Base', async () => { + // New test wallet: 0x10649c79428d718621821Cf6299e91920284743F + // Position link: https://staging.summer.fi/base/aave/v3/multiply/ETH-USDBC/815#protection + + test('Update existing automation - Close to collateral - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: validPayloads, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Close to debt - Valid payload data', async ({ request }) => { + // New test wallet: 0x10649c79428d718621821Cf6299e91920284743F + // Position link: ??? + + const response = await request.post(trailingStopLossEndpoint, { + data: validPayloadsAaveV3Base.trailingStopLoss.updateCloseToDebt, + }); + + const respJSON = await response.json(); + + const updateCloseToDebtResponse = trailingStopLossResponse({ + dpm: '0xaE294A81D5015D8De3eC55973F207857bd6b1Fb4', + collateral: { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + oraclesAddress: '0x71041dddad3595f9ced3dccfbe3d1f4b0a16bb70', + }, + debt: { + decimals: 6, + symbol: 'USDC', + address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + oraclesAddress: '0x7e860098f58bbfc8648a4311b374b1d669a2bc6b', + }, + hasStablecoinDebt: true, + }); + + expect(respJSON).toMatchObject(updateCloseToDebtResponse); + }); + + test('Update existing automation - Trailing distance - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + trailingDistance: '140000000000', + token: '0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update existing automation - Close to collateral and trailing distance - Valid payload data', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + triggerData: { + ...validPayloads.triggerData, + trailingDistance: '130000000000', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(validResponse); + }); + + test('Update non-existing automation', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloadsAaveV3Base.trailingStopLoss.closeToDebt, + action: 'update', + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.stopLossDoesNotExist); + }); + + test('Update existing automation - Without "dpm"', async ({ request }) => { + const { dpm, ...payloadWithoutDpm } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutDpm, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong data type - "dpm"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, dpm: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Wrong value - "dpm"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, dpm: '0xwrong' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDpm); + }); + + test('Update existing automation - Without "position"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutPosition, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingPosition); + }); + + test('Update existing automation - Wrong data type - "position" - string', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_string); + }); + + test('Update existing automation - Wrong data type - "position" - number', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_number); + }); + + test('Update existing automation - Wrong data type - "position" - array', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_array); + }); + + test('Update existing automation - Wrong data type - "position" - null', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, position: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongPosition_null); + }); + + test('Update existing automation - Without "collateral (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { collateral, ...positionWithoutCollateral } = position; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutCollateral }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong data type - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Wrong value - "collateral (position)"', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + collateral: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongCollateral); + }); + + test('Update existing automation - Without "debt (position)"', async ({ request }) => { + const { position, ...payloadWithoutPosition } = validPayloads; + const { debt, ...positionWithoutDebt } = position; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutPosition, position: positionWithoutDebt }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong data type - "debt (position)"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: 11, + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Wrong value - "debt (position)"', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloads, + position: { + ...validPayloads.position, + debt: '0xwrong', + }, + }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongDebt); + }); + + test('Update existing automation - Without "triggerData"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + + const response = await request.post(trailingStopLossEndpoint, { + data: payloadWithoutTriggerData, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.missingTriggerData); + }); + + test('Update existing automation - Wrong data type - "triggerData" - string', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: 'string' }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_string); + }); + + test('Update existing automation - Wrong data type - "triggerData" - number', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: 1 }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_number); + }); + + test('Update existing automation - Wrong data type - "triggerData" - array', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: [] }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_array); + }); + + test('Update existing automation - Wrong data type - "triggerData" - null', async ({ + request, + }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { ...validPayloads, triggerData: null }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTriggerData_null); + }); + + test('Update existing automation - Without "trailingDistance (triggerData)"', async ({ + request, + }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { trailingDistance, ...triggerDataWithoutTrailingDistance } = triggerData; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutTrailingDistance }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongTrailingDistance); + }); + + test('Update existing automation - Without "token (triggerData)"', async ({ request }) => { + const { triggerData, ...payloadWithoutTriggerData } = validPayloads; + const { token, ...triggerDataWithoutToken } = triggerData; + + const response = await request.post(trailingStopLossEndpoint, { + data: { ...payloadWithoutTriggerData, triggerData: triggerDataWithoutToken }, + }); + + const respJSON = await response.json(); + + expect(respJSON).toMatchObject(responses.wrongToken); + }); +}); diff --git a/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts index 97a58784..2da18f88 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts @@ -22,7 +22,7 @@ const validResponse = trailingStopLossResponse({ symbol: 'USDC', address: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607', oraclesAddress: '0x16a9fa2fda030272ce99b29cf780dfa30361e0f3', - usd_cOptimism: true, + usdcVariant: 'usdceOptimism', }, hasStablecoinDebt: true, }); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index 4908a183..a44942b0 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -967,10 +967,15 @@ export const trailingStopLossResponse = ({ symbol: string; address: string; oraclesAddress: string; - usd_cOptimism?: boolean; + usdcVariant?: 'usdceOptimism' | 'usdbcBase'; }; hasStablecoinDebt: boolean; }) => { + const usdcVariantId = { + usdceOptimism: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + usdbcBase: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }; + const response = { simulation: { latestPrice: { @@ -986,10 +991,8 @@ export const trailingStopLossResponse = ({ ], }, denomination: { - id: debt.usd_cOptimism - ? '0x0b2c639c533813f4aa9d7837caf62653d097ff85' - : debt.address.toLocaleLowerCase(), - symbol: debt.symbol, + id: debt.usdcVariant ? usdcVariantId[debt.usdcVariant] : debt.address.toLocaleLowerCase(), + symbol: debt.usdcVariant && debt.usdcVariant === 'usdbcBase' ? 'USDC' : debt.symbol, oraclesToken: [ { address: debt.oraclesAddress, @@ -2355,6 +2358,32 @@ export const validPayloadsAaveV3Base = { token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', }, }, + updateCloseToCollateral: { + dpm: '0xe70c8069627a9c7933362e25f033ec0771f0f06e', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca', + }, + action: 'update', + triggerData: { + trailingDistance: '152000000000', + token: '0x4200000000000000000000000000000000000006', + }, + }, + updateCloseToDebt: { + dpm: '0xae294a81d5015d8de3ec55973f207857bd6b1fb4', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }, + action: 'update', + triggerData: { + trailingDistance: '144000000000', + token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + }, + }, }, autoTakeProfit: { profitInDebt: { From 99486f8037b737ec255bdce54bed39fcde2de3af Mon Sep 17 00:00:00 2001 From: juan-langa Date: Wed, 11 Sep 2024 17:01:21 +0200 Subject: [PATCH 14/14] API tests - Update trigger - Trailing Stop-Loss - Base - 2 --- .../base/trailingStopLossAv3BaseUpdate.spec.ts | 2 +- .../optimism/trailingStopLossAv3OptimismAdd.spec.ts | 13 ++++++++++++- utils/testData_APIs.ts | 13 +++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts index d7d5b776..fea9df90 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/base/trailingStopLossAv3BaseUpdate.spec.ts @@ -41,7 +41,7 @@ test.describe('API tests - Trailing Stop-Loss - Update - Aave V3 - Base', async test('Update existing automation - Close to debt - Valid payload data', async ({ request }) => { // New test wallet: 0x10649c79428d718621821Cf6299e91920284743F - // Position link: ??? + // Position link: https://staging.summer.fi/base/aave/v3/multiply/ETH-USDC/816#protection const response = await request.post(trailingStopLossEndpoint, { data: validPayloadsAaveV3Base.trailingStopLoss.updateCloseToDebt, diff --git a/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts b/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts index 2da18f88..a0b3830a 100644 --- a/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts +++ b/tests/api/automations/trailingStopLoss/aaveV3/optimism/trailingStopLossAv3OptimismAdd.spec.ts @@ -27,7 +27,7 @@ const validResponse = trailingStopLossResponse({ hasStablecoinDebt: true, }); -test.describe('API tests - Trailing Stop-Loss - Aave V3 - Optimism', async () => { +test.describe('API tests - Trailing Stop-Loss - Add - Aave V3 - Optimism', async () => { // Old test wallet: 0x10649c79428d718621821Cf6299e91920284743F // Position link: https://staging.summer.fi/optimism/aave/v3/multiply/ETH-USDC.E/2 @@ -308,4 +308,15 @@ test.describe('API tests - Trailing Stop-Loss - Aave V3 - Optimism', async () => expect(respJSON).toMatchObject(responses.wrongToken); }); + + test('Add automation - Trigger already exists', async ({ request }) => { + const response = await request.post(trailingStopLossEndpoint, { + data: { + ...validPayloadsAaveV3Optimism.trailingStopLoss.updateCloseToCollateral, + action: 'add', + }, + }); + + const respJSON = await response.json(); + }); }); diff --git a/utils/testData_APIs.ts b/utils/testData_APIs.ts index a44942b0..cf97fb0d 100644 --- a/utils/testData_APIs.ts +++ b/utils/testData_APIs.ts @@ -2577,6 +2577,19 @@ export const validPayloadsAaveV3Optimism = { token: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', }, }, + updateCloseToCollateral: { + dpm: '0xc213d697c81e15a2422701c653dc4b9bcad47530', + protocol: 'aavev3', + position: { + collateral: '0x4200000000000000000000000000000000000006', + debt: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', + }, + action: 'update', + triggerData: { + trailingDistance: '151000000000', + token: '0x4200000000000000000000000000000000000006', + }, + }, }, autoTakeProfit: { profitInDebt: {