import { OpenChannel } from '@statechannels/wallet-core' ; import { testKnex as knex } from '../../../jest/knex-setup-teardown' ; import { seedAlicesSigningWallet } from '../../db/seeds/1_signing_wallet_seeds' ; import { WaitingFor as ChannelOpenerWaitingFor } from '../../protocols/channel-opener' ; import { Nothing } from '../../objectives/objective-manager' ; import { Channel } from '../channel' ; import { ObjectiveModel , ObjectiveChannelModel } from '../objective' ; import { channel } from './fixtures/channel' ; const c = channel ( ) ; const objective = { type : 'OpenChannel' , participants : [ ] , data : { targetChannelId : c . channelId , fundingStrategy : 'Direct' , role : 'app' , } , } ; beforeEach ( async ( ) => { await seedAlicesSigningWallet ( knex ) ; } ) ; describe ( 'Objective > insert' , ( ) => { it ( 'returns an objective with Date types for timestamps' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; const inserted = await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; expect ( inserted . createdAt instanceof Date ) . toBe ( true ) ; expect ( inserted . progressLastMadeAt instanceof Date ) . toBe ( true ) ; } ) ; it ( 'fails to insert / associate an objective when it references a channel that does not exist' , async ( ) => { await expect ( ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ) . rejects . toThrow ( ) ; expect ( await ObjectiveModel . query ( knex ) . select ( ) ) . toMatchObject ( [ ] ) ; expect ( await ObjectiveChannelModel . query ( knex ) . select ( ) ) . toMatchObject ( [ ] ) ; } ) ; it ( 'inserts and associates an objective with all channels that it references (channels exist)' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; expect ( await ObjectiveModel . query ( knex ) . select ( ) ) . toMatchObject ( [ { objectiveId : `OpenChannel-${ c . channelId }` } , ] ) ; expect ( await ObjectiveChannelModel . query ( knex ) . select ( ) ) . toMatchObject ( [ { objectiveId : `OpenChannel-${ c . channelId }` , channelId : c . channelId } , ] ) ; } ) ; it ( 'inserts an objective with a createdAt timestamp' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; const before = Date . now ( ) - 1000 ; const { createdAt } = await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; const after = Date . now ( ) + 1000 ; expect ( createdAt . getTime ( ) > before ) . toBe ( true ) ; expect ( createdAt . getTime ( ) < after ) . toBe ( true ) ; } ) ; it ( 'updates the progressLastMadeAt timestamp on an objective when updateWaitingFor is called' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; const { objectiveId } = await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; const before = Date . now ( ) - 1000 ; const { progressLastMadeAt } = await ObjectiveModel . updateWaitingFor ( objectiveId , ChannelOpenerWaitingFor . theirPostFundState , knex ) ; const after = Date . now ( ) + 1000 ; expect ( progressLastMadeAt . getTime ( ) > before ) . toBe ( true ) ; expect ( progressLastMadeAt . getTime ( ) < after ) . toBe ( true ) ; } ) ; } ) ; describe ( 'Objective > forId' , ( ) => { it ( 'returns an objective with Date types for timestamps' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; const fetchedObjective = await ObjectiveModel . forId ( `OpenChannel-${ c . channelId }` , knex ) ; expect ( fetchedObjective . createdAt instanceof Date ) . toBe ( true ) ; expect ( fetchedObjective . progressLastMadeAt instanceof Date ) . toBe ( true ) ; } ) ; } ) ; describe ( 'Objective > forChannelIds' , ( ) => { it ( 'retrieves objectives associated with a given channelId' , async ( ) => { await Channel . query ( knex ) . withGraphFetched ( 'signingWallet' ) . insert ( c ) ; await ObjectiveModel . insert ( objective , knex , undefined , ChannelOpenerWaitingFor . theirPreFundSetup ) ; expect ( await ObjectiveModel . forChannelIds ( [ c . channelId ] , knex ) ) . toMatchObject ( [ { objectiveId : `OpenChannel-${ c . channelId }` } , ] ) ; } ) ; } ) ; describe ( 'Default value for waitingFor' , ( ) => { it ( 'Is an empty string' , async ( ) => { const returnedRow = await ObjectiveModel . query ( knex ) . insert ( { objectiveId : 'doesNotMatter' , status : 'pending' , type : objective . type , data : objective . data , createdAt : new Date ( ) , progressLastMadeAt : new Date ( ) , } ) . returning ( '*' ) . first ( ) ; expect ( returnedRow . waitingFor ) . toEqual ( '' ) ; } ) ; it ( 'Exists in the app code type system' , async ( ) => { let waitFor = ChannelOpenerWaitingFor . theirPreFundSetup ; waitFor = Nothing . ToWaitFor ; expect ( waitFor ) . toEqual ( '' ) ; } ) ; } ) ;