haskelltestingintegration-testingyesodyesod-test

Run db action in yesod test


In my yesod test I want to be able to modify a record in the db in the middle of the test.

Here is the code I came up with

        yit "post is created by authorized user" $ do
            request $ do
                addPostParam "ident" "dummy"
                setMethod "POST"
                setUrl ("http://localhost:3000/auth/page/dummy" :: Text)
            update 0 [UserAuthorized =. True]
            postBody PostR (encode $ object [
                "body" .= ("test post" :: Text),
                "title" .= ("test post" :: Text),
                "coverImage" .= ("test post" :: Text),
                "author" .= (0 :: Int)
                ])
            statusIs 200

This fails with the error

• Couldn't match expected type ‘IO a0’
              with actual type ‘ReaderT backend0 m0 ()’
• In the second argument of ‘($)’, namely
    ‘update 0 [UserAuthorized =. True]’

  In a stmt of a 'do' block:
    runIO $ update 0 [UserAuthorized =. True]
  In the expression:
    do { settings <- runIO
                     $ loadYamlSettings
                         ["config/test-settings.yml", "config/settings.yml"] [] useEnv;
         foundation <- runIO $ makeFoundation settings;
         yesodSpec foundation $ do { ydescribe "Auth" $ do { ... } };
         runIO $ update 0 [UserAuthorized =. True];
         .... }

I can tell this is because update returns m () instead of YesodExample site () like request, postBody and statusIs do.

How would I be able to do a db update inside of this test?


Solution

  • There were 2 problems in this, the first one as Sibi pointed out is I needed runDB the second one is you can't just look up a record with an integer.

    To get this working I used the following code

    runDB $ do
        (first :: Maybe (Entity User)) <- selectFirst [] []
        case first of
            Nothing -> pure () -- handle the case when the table is empty
            Just (Entity k _) -> update k [UserAuthorized =. True]
    

    This find's the record in the DB and then updates it. Modify (first :: Maybe (Entity User)) <- selectFirst [] [] to select the record you want to update.