import { utils } from 'ethers' ; import { Channel } from '../../../models/channel' ; import { defaultTestEngineConfig , Engine } from '../..' ; import { updateChannelArgs } from '../fixtures/update-channel' ; import { seedAlicesSigningWallet } from '../../../db/seeds/1_signing_wallet_seeds' ; import { stateWithHashSignedBy } from '../fixtures/states' ; import { alice , bob } from '../fixtures/signing-wallets' ; import { channel } from '../../../models/__test__/fixtures/channel' ; import { defaultTestWalletConfig } from '../../../config' ; import { testKnex as knex } from '../../../../jest/knex-setup-teardown' ; import { AppBytecode } from '../../../models/app-bytecode' ; import { appBytecode , COUNTING_APP_DEFINITION } from '../../../models/__test__/fixtures/app-bytecode' ; import { DBAdmin } from '../../../db-admin/db-admin' ; import { createLogger } from '../../../logger' ; let w ; afterEach ( async ( ) => { await w . destroy ( ) ; } ) ; const appData1 = utils . defaultAbiCoder . encode ( [ 'uint256' ] , [ 1 ] ) ; const appData2 = utils . defaultAbiCoder . encode ( [ 'uint256' ] , [ 2 ] ) ; beforeEach ( async ( ) => { const logger = createLogger ( defaultTestWalletConfig ( ) ) ; w = await Engine . create ( defaultTestEngineConfig ( { skipEvmValidation : false } ) , logger ) ; await DBAdmin . truncateDataBaseFromKnex ( knex ) ; await seedAlicesSigningWallet ( knex ) ; await AppBytecode . query ( knex ) . insert ( [ appBytecode ( ) ] ) ; } ) ; it ( 'updates a channel' , async ( ) => { const c = channel ( { appDefinition : COUNTING_APP_DEFINITION , vars : [ stateWithHashSignedBy ( [ alice ( ) , bob ( ) ] ) ( { turnNum : 5 , appDefinition : COUNTING_APP_DEFINITION , appData : appData1 , } ) , ] , } ) ; await Channel . query ( w . knex ) . insert ( c ) ; const channelId = c . channelId ; const current = await Channel . forId ( channelId , knex ) ; expect ( current . latest ) . toMatchObject ( { turnNum : 5 , appData : appData1 } ) ; await expect ( w . updateChannel ( updateChannelArgs ( { appData : appData2 } ) ) ) . resolves . toMatchObject ( { outbox : [ { params : { recipient : 'bob' , sender : 'alice' , data : { signedStates : [ { turnNum : 6 , appData : appData2 } ] } , } , } , ] , channelResult : { channelId , turnNum : 6 , appData : appData2 } , } ) ; const updated = await Channel . forId ( channelId , knex ) ; expect ( updated . latest ) . toMatchObject ( { turnNum : 6 , appData : appData2 } ) ; } ) ; describe ( 'error cases' , ( ) => { it ( 'throws when it is not my turn' , async ( ) => { const c = channel ( { vars : [ stateWithHashSignedBy ( [ alice ( ) , bob ( ) ] ) ( { turnNum : 4 } ) ] } ) ; await Channel . query ( w . knex ) . insert ( c ) ; await expect ( w . updateChannel ( updateChannelArgs ( ) ) ) . rejects . toMatchObject ( Error ( 'it is not my turn' ) ) ; } ) ; it ( "throws when the channel isn't found" , async ( ) => { await expect ( w . updateChannel ( updateChannelArgs ( ) ) ) . rejects . toMatchObject ( Error ( 'channel not found' ) ) ; } ) ; it ( 'throws when it is an invalid app transition' , async ( ) => { const c = channel ( { appDefinition : COUNTING_APP_DEFINITION , vars : [ stateWithHashSignedBy ( [ alice ( ) , bob ( ) ] ) ( { turnNum : 5 , appDefinition : COUNTING_APP_DEFINITION , appData : appData2 , } ) , ] , } ) ; await Channel . query ( w . knex ) . insert ( c ) ; await expect ( w . updateChannel ( updateChannelArgs ( { appData : appData1 } ) ) ) . rejects . toMatchObject ( Error ( 'Invalid state transition' ) ) ; } ) ; } ) ;