summaryrefslogtreecommitdiff
path: root/Hledger/Web/Test.hs
blob: 6a5e3c55a5ad9e1105cc295546f10b8ce3673e4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
{-# LANGUAGE OverloadedStrings #-}

module Hledger.Web.Test (
  hledgerWebTest
) where

import qualified Data.Text as T
import Test.Hspec (hspec)
import Yesod.Default.Config
import Yesod.Test

import Hledger.Web.Application ( makeFoundationWith )
import Hledger.Web.WebOptions ( WebOpts(cliopts_), defwebopts, prognameandversion )
import Hledger.Web.Import hiding (get, j)
import Hledger.Cli hiding (prognameandversion, tests)


runHspecTestsWith :: AppConfig DefaultEnv Extra -> WebOpts -> Journal -> YesodSpec App -> IO ()
runHspecTestsWith yesodconf hledgerwebopts j specs = do
  app <- makeFoundationWith j yesodconf hledgerwebopts
  hspec $ yesodSpec app specs

-- Run hledger-web's built-in tests using the hspec test runner.
hledgerWebTest :: IO ()
hledgerWebTest = do
  putStrLn $ "Running tests for " ++ prognameandversion -- ++ " (--test --help for options)"

  -- loadConfig fails without ./config/settings.yml; use a hard-coded one
  let conf = AppConfig{
               appEnv = Testing
              ,appPort = 3000  -- will it clash with a production instance ? doesn't seem to
              ,appRoot = "http://localhost:3000"
              ,appHost = "*4"
              ,appExtra = Extra
                          { extraCopyright  = ""
                          , extraAnalytics  = Nothing
                          , extraStaticRoot = Nothing
                          }
                  }

  -- http://hspec.github.io/writing-specs.html
  -- https://hackage.haskell.org/package/yesod-test-1.6.10/docs/Yesod-Test.html
  -- "The best way to see an example project using yesod-test is to create a scaffolded Yesod project:
  -- stack new projectname yesodweb/sqlite
  -- (See https://github.com/commercialhaskell/stack-templates/wiki#yesod for the full list of Yesod templates)"

  -- Since these tests use makeFoundation, the startup code in Hledger.Web.Main is not tested. XXX
  --
  -- Be aware that unusual combinations of opts/files here could cause problems,
  -- eg if cliopts{file_} is left empty journalReload might reload the user's default journal.

  -- basic tests
  runHspecTestsWith conf defwebopts nulljournal $ do
    ydescribe "hledger-web" $ do

      yit "serves a reasonable-looking journal page" $ do
        get JournalR
        statusIs 200
        bodyContains "Add a transaction"

      yit "serves a reasonable-looking register page" $ do
        get RegisterR
        statusIs 200
        bodyContains "accounts"

      -- WIP
      -- yit "shows the add form" $ do
      --   get JournalR
      --   -- printBody
      --   -- let addbutton = "button:contains('add')"
      --   -- bodyContains addbutton
      --   -- htmlAnyContain "button:visible" "add"
      --   printMatches "div#addmodal:visible"
      --   htmlCount "div#addmodal:visible" 0

      --   -- clickOn "a#addformlink"
      --   -- printBody
      --   -- bodyContains addbutton

      -- yit "can add transactions" $ do

  -- test with forecasted transactions
  d <- getCurrentDay
  let
    ropts = defreportopts{forecast_=Just nulldatespan}
    rspec = case reportOptsToSpec d ropts of
            Left e   -> error $ "failed to set up report options for tests, shouldn't happen: " ++ show e
            Right rs -> rs
    copts = defcliopts{reportspec_=rspec, file_=[""]}  -- non-empty, see file_ note above
    wopts = defwebopts{cliopts_=copts}
  j <- fmap (journalTransform copts) $ readJournal' (T.pack $ unlines  -- PARTIAL: readJournal' should not fail
    ["~ monthly"
    ,"    assets    10"
    ,"    income"
    ])
  runHspecTestsWith conf wopts j $ do
    ydescribe "hledger-web --forecast" $ do

      yit "serves a journal page showing forecasted transactions" $ do
        get JournalR
        statusIs 200
        bodyContains "id=\"transaction-0-1\""  -- 0 indicates a fileless (forecasted) txn
        bodyContains "id=\"transaction-0-2\""  -- etc.