11import type { bytes , Contract } from '@algorandfoundation/algorand-typescript'
2+ import { OnCompleteAction } from '@algorandfoundation/algorand-typescript'
3+ import { getContractMethodAbiMetadata } from './abi-metadata'
24import type { ApplicationCallInnerTxnContext } from './impl/inner-transactions'
35import { methodSelector } from './impl/method-selector'
46import type { AnyFunction , ConstructorFor } from './typescript-helpers'
@@ -7,16 +9,16 @@ import { asNumber } from './util'
79export type AppSpyCb = ( itxnContext : ApplicationCallInnerTxnContext ) => void
810
911const predicates = {
10- bareCall : ( cb : AppSpyCb ) : AppSpyCb => {
12+ bareCall : ( cb : AppSpyCb , ocas : OnCompleteAction [ ] ) : AppSpyCb => {
1113 return ( ctx ) => {
12- if ( asNumber ( ctx . numAppArgs ) === 0 ) {
14+ if ( asNumber ( ctx . numAppArgs ) === 0 && ocas . includes ( ctx . onCompletion ) ) {
1315 cb ( ctx as ApplicationCallInnerTxnContext )
1416 }
1517 }
1618 } ,
17- methodSelector : ( cb : AppSpyCb , selectorBytes : bytes ) : AppSpyCb => {
19+ methodSelector : ( cb : AppSpyCb , selectorBytes : bytes , ocas : OnCompleteAction [ ] ) : AppSpyCb => {
1820 return ( ctx ) => {
19- if ( selectorBytes . equals ( ctx . appArgs ( 0 ) ) ) {
21+ if ( selectorBytes . equals ( ctx . appArgs ( 0 ) ) && ocas . includes ( ctx . onCompletion ) ) {
2022 cb ( ctx )
2123 }
2224 }
@@ -57,17 +59,36 @@ export class ApplicationSpy<TContract extends Contract = Contract> {
5759 * Registers a callback for a bare call (no arguments).
5860 * @param callback - The callback to be executed when a bare call is detected.
5961 */
60- onBareCall ( callback : AppSpyCb ) {
61- this . #spyFns. push ( predicates . bareCall ( callback ) )
62+ onBareCall ( callback : AppSpyCb ) : void
63+ onBareCall ( ocas : OnCompleteAction [ ] , callback : AppSpyCb ) : void
64+ onBareCall ( ...args : [ AppSpyCb ] | [ OnCompleteAction [ ] , AppSpyCb ] ) : void {
65+ let callback : AppSpyCb
66+ let ocas : OnCompleteAction [ ] = [ OnCompleteAction . NoOp ]
67+ if ( args . length === 2 ) {
68+ ; [ ocas , callback ] = args
69+ } else {
70+ ; [ callback ] = args
71+ }
72+ this . #spyFns. push ( predicates . bareCall ( callback , ocas ) )
6273 }
6374
6475 /**
6576 * Registers a callback for a specific method signature.
6677 * @param methodSignature
6778 * @param callback
6879 */
69- onAbiCall ( methodSignature : bytes , callback : AppSpyCb ) {
70- this . #spyFns. push ( predicates . methodSelector ( callback , methodSignature ) )
80+ onAbiCall ( methodSignature : bytes , callback : AppSpyCb ) : void
81+ onAbiCall ( methodSignature : bytes , ocas : OnCompleteAction [ ] , callback : AppSpyCb ) : void
82+ onAbiCall ( ...args : [ bytes , AppSpyCb ] | [ bytes , OnCompleteAction [ ] , AppSpyCb ] ) : void {
83+ let methodSignature : bytes
84+ let callback : AppSpyCb
85+ let ocas : OnCompleteAction [ ] = [ OnCompleteAction . NoOp ]
86+ if ( args . length === 3 ) {
87+ ; [ methodSignature , ocas , callback ] = args
88+ } else {
89+ ; [ methodSignature , callback ] = args
90+ }
91+ this . #spyFns. push ( predicates . methodSelector ( callback , methodSignature , ocas ) )
7192 }
7293
7394 private _tryGetMethod ( name : string | symbol ) {
@@ -85,8 +106,14 @@ export class ApplicationSpy<TContract extends Contract = Contract> {
85106 const fn = spy . _tryGetMethod ( methodName )
86107 if ( fn === undefined ) return fn
87108 return function ( callback : AppSpyCb ) {
109+ let ocas : OnCompleteAction [ ] = [ OnCompleteAction . NoOp ]
110+ if ( spy . contract !== undefined ) {
111+ const metadata = getContractMethodAbiMetadata ( spy . contract , methodName as string )
112+ ocas = metadata . allowActions ?. map ( ( action ) => OnCompleteAction [ action ] ) ?? [ OnCompleteAction . NoOp ]
113+ }
114+
88115 const selector = methodSelector ( fn , spy . contract )
89- spy . onAbiCall ( selector , callback )
116+ spy . onAbiCall ( selector , ocas , callback )
90117 }
91118 } ,
92119 } ) as _TypedApplicationSpyCallBacks < TContract >
0 commit comments