Skip to content
Discussions/App Development/Trying to test the `autoReply` trigger in the "gsg-trigger" template but cannot see the created answerForum ↗

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

App Development4 posts341 views3 likesLast activity May 2022
GY
gyorgybalazsiOP
Apr 2022

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 ()
CO
cocreature
Apr 2022

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."
GY
gyorgybalazsi
Apr 2022

Thank you!

GY
gyorgybalazsi
May 2022
cocreature:
assertExerciseCmd (flattenCommands cmds) $ \(cid, choiceArg) -> do
    cid === bobUserCid
    choiceArg === User.SendMessage with
      sender = alice
      content = "Please, tell me more about that."

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."
← Back to Discussions