Trying to test the `autoReply` trigger in the "gsg-trigger" template but cannot see the created answer

What am I doing wrong?

Also, I couldn’t find in the docs what the second argument with [Party] types is in the testRule function so I just put in both the allocated parties.

module ChatBot where

import qualified Daml.Trigger as T
import qualified User
import qualified DA.List.Total as List
import DA.Action (when)
import DA.Optional (whenSome)

import Daml.Script
import DA.Map qualified as Maps
import Daml.Trigger.Assert

autoReply : T.Trigger ()
autoReply = T.Trigger
  { initialize = pure ()
  , updateState = \_ -> pure ()
  , rule = \p -> do
      message_contracts <- T.query @User.Message
      let messages = map snd message_contracts
      debug $ "Messages so far: " <> show (length messages)
      let lastMessage = List.maximumOn (.receivedAt) messages
      debug $ "Last message: " <> show lastMessage
      whenSome lastMessage $ \m ->
        when (m.receiver == p) $ do
          users <- T.query @User.User
          debug $ "users: " <> show users
          let isSender = (\user -> user.username == m.sender)
          let replyTo = List.head $ filter (\(_, user) -> isSender user) users
          whenSome replyTo $ \(sender, _) ->
            T.dedupExercise sender (User.SendMessage p "Please, tell me more about that.")
  , registeredTemplates = T.AllInDar
  , heartbeat = None
  }

test : Script ()
test = do 
  alice <- allocateParty "Alice" 
  bob <- allocateParty "Bob" 

  aliceUserCid <- submit alice $ Daml.Script.createCmd User.User with username = alice, following = [bob]
  bobUserCid <- submit bob $ Daml.Script.createCmd User.User with username = bob, following = [alice]

  bobMsgCid <- submit bob $ Daml.Script.exerciseCmd aliceUserCid User.SendMessage with sender = bob, content = "Hello Alice"
  
  let acsBuilder = toACS aliceUserCid <> toACS bobUserCid <> toACS bobMsgCid

  testRule autoReply alice [alice, bob] acsBuilder Maps.empty ()

  return ()

The second argument is the parties passed via --ledger-readas, i.e., parties your trigger can read but not act as.

You’re not doing anything wrong unless you mean the call to your test. testRule doesn’t modify anything so discarding the result makes it relatively useless, it just gives you back the commands that would be executed.

You can assert on them like this:

((), cmds) <- testRule autoReply alice [alice, bob] acsBuilder Maps.empty ()

  assertExerciseCmd (flattenCommands cmds) $ \(cid, choiceArg) -> do
    cid === bobUserCid
    choiceArg === User.SendMessage with
      sender = alice
      content = "Please, tell me more about that."
1 Like

Thank you!

For other damlers interested in this topic, this is the trigger and the full test. You can get the original package like this:

daml new --template=gsg-trigger gsg-trigger

module ChatBot where

import qualified Daml.Trigger as T
import qualified User
import qualified DA.List.Total as List
import DA.Action (when)
import DA.Optional (whenSome)

import Daml.Script
import DA.Map qualified as Maps
import Daml.Trigger.Assert
import DA.Assert

autoReply : T.Trigger ()
autoReply = T.Trigger
  { initialize = pure ()
  , updateState = \_ -> pure ()
  , rule = \p -> do
      message_contracts <- T.query @User.Message
      let messages = map snd message_contracts
      debug $ "Messages so far: " <> show (length messages)
      let lastMessage = List.maximumOn (.receivedAt) messages
      debug $ "Last message: " <> show lastMessage
      whenSome lastMessage $ \m ->
        when (m.receiver == p) $ do
          users <- T.query @User.User
          debug $ "users: " <> show users
          let isSender = (\user -> user.username == m.sender)
          let replyTo = List.head $ filter (\(_, user) -> isSender user) users
          whenSome replyTo $ \(sender, _) ->
            T.dedupExercise sender (User.SendMessage p "Please, tell me more about that.")
  , registeredTemplates = T.AllInDar
  , heartbeat = None
  }

test : Script ()
test = do 
  alice <- allocateParty "Alice" 
  bob <- allocateParty "Bob" 

  aliceUserCid <- submit alice $ Daml.Script.createCmd User.User with username = alice, following = [bob]
  bobUserCid <- submit bob $ Daml.Script.createCmd User.User with username = bob, following = [alice]

  bobMsgCid <- submit bob $ Daml.Script.exerciseCmd aliceUserCid User.SendMessage with sender = bob, content = "Hello Alice"
  
  let acsBuilder = toACS aliceUserCid <> toACS bobUserCid <> toACS bobMsgCid

  ((), cmds) <- testRule autoReply alice [] acsBuilder Maps.empty ()
  
  assertExerciseCmd (flattenCommands cmds) $ \(cid, choiceArg) -> do
    cid === bobUserCid
    debug choiceArg
    choiceArg === User.SendMessage with
      sender = alice
      content = "Please, tell me more about that."
2 Likes