Skip to content

Commit 79f29c5

Browse files
authored
Yesod test add check for checkboxes (#1843)
* Create checkboxesField' - correct version of checkboxesField * Add checkByLabel to yesod-test for testing checkboxes
1 parent 7eb3c1e commit 79f29c5

7 files changed

Lines changed: 94 additions & 5 deletions

File tree

yesod-form/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ChangeLog for yesod-form
22

3+
## 1.7.9
4+
5+
* Added `checkboxesField'` for creating checkbox in more correct way than original `checkboxesField`
6+
Function `checkboxesField` marked as deprecated. [#1843](https://github.com/yesodweb/yesod/pull/1843)
37

48
## 1.7.8
59

yesod-form/Yesod/Form/Fields.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ module Yesod.Form.Fields
5252
, radioFieldList
5353
, withRadioField
5454
, checkboxesField
55+
, checkboxesField'
5556
, checkboxesFieldList
5657
, multiSelectField
5758
, multiSelectFieldList
@@ -125,6 +126,7 @@ import Data.Monoid
125126
import Data.Char (isHexDigit)
126127

127128
{-# DEPRECATED radioField "This function seems to have a bug (label could not be found with byLabel algorithm)" #-}
129+
{-# DEPRECATED checkboxesField "This function seems to have a bug (label could not be found with byLabel algorithm)" #-}
128130

129131
defaultFormMessage :: FormMessage -> Text
130132
defaultFormMessage = englishFormMessage
@@ -533,6 +535,26 @@ checkboxesField ioptlist = (multiSelectField ioptlist)
533535
|]
534536
}
535537

538+
-- | Creates an input with @type="checkbox"@ for selecting multiple options.
539+
checkboxesField' :: Eq a
540+
=> HandlerFor site (OptionList a)
541+
-> Field (HandlerFor site) [a]
542+
checkboxesField' ioptlist = (multiSelectField ioptlist)
543+
{ fieldView =
544+
\theId name attrs val _isReq -> do
545+
opts <- olOptions <$> handlerToWidget ioptlist
546+
let optselected (Left _) _ = False
547+
optselected (Right vals) opt = optionInternalValue opt `elem` vals
548+
[whamlet|
549+
<span ##{theId}>
550+
$forall opt <- opts
551+
<input id=#{theId}-#{optionExternalValue opt} type=checkbox name=#{name} value=#{optionExternalValue opt} *{attrs} :optselected val opt:checked>
552+
<label for=#{theId}-#{optionExternalValue opt}>
553+
#{optionDisplay opt}
554+
|]
555+
}
556+
557+
536558
-- | Creates an input with @type="radio"@ for selecting one option.
537559
radioField :: (Eq a, RenderMessage site FormMessage)
538560
=> HandlerFor site (OptionList a)

yesod-form/yesod-form.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: >= 1.10
22
name: yesod-form
3-
version: 1.7.8
3+
version: 1.7.9
44
license: MIT
55
license-file: LICENSE
66
author: Michael Snoyman <michael@snoyman.com>

yesod-test/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ChangeLog for yesod-test
22

3+
## 1.6.18
4+
5+
* Add `checkByLabel` to yesod-test. [#1843](https://github.com/yesodweb/yesod/pull/1843)
6+
37
## 1.6.17
48

59
* Add `chooseByLabel` to yesod-test. [#1842](https://github.com/yesodweb/yesod/pull/1842)

yesod-test/Yesod/Test.hs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ module Yesod.Test
178178
, fileByLabelPrefix
179179
, fileByLabelSuffix
180180
, chooseByLabel
181+
, checkByLabel
181182

182183
-- *** CSRF Tokens
183184
-- | In order to prevent CSRF exploits, yesod-form adds a hidden input
@@ -1716,6 +1717,40 @@ chooseByLabel label = do
17161717
value <- genericValueFromLabel (==) label
17171718
addPostParam name value
17181719

1720+
-- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then make this input checked.
1721+
-- It is assumed the @\<input>@ has @type=checkbox@.
1722+
--
1723+
-- ==== __Examples__
1724+
--
1725+
-- Given this HTML, we want to submit @f1=2@ and @f1=4@ (i.e. checked checkboxes are "Blue" and "Black") to the server:
1726+
--
1727+
-- > <form method="POST">
1728+
-- > <label for="hident2">Colors</label>
1729+
-- > <span id="hident2">
1730+
-- > <input id="hident2-1" type="checkbox" name="f1" value="1">
1731+
-- > <label for="hident2-1">Red</label>
1732+
-- > <input id="hident2-2" type="checkbox" name="f1" value="2" checked>
1733+
-- > <label for="hident2-2">Blue</label>
1734+
-- > <input id="hident2-3" type="checkbox" name="f1" value="3">
1735+
-- > <label for="hident2-3">Gray</label>
1736+
-- > <input id="hident2-4" type="checkbox" name="f1" value="4" checked>
1737+
-- > <label for="hident2-4">Black</label>
1738+
-- > </span>
1739+
-- > </form>
1740+
--
1741+
-- You can set this parameter like so:
1742+
--
1743+
-- > request $ do
1744+
-- > checkByLabel "Blue"
1745+
-- > checkByLabel "Black"
1746+
--
1747+
-- @since 1.6.18
1748+
checkByLabel :: T.Text -> RequestBuilder site ()
1749+
checkByLabel label = do
1750+
name <- genericNameFromLabel (==) label
1751+
value <- genericValueFromLabel (==) label
1752+
addPostParam name value
1753+
17191754
-- |
17201755
-- This looks up the value of a field based on the contents of the label pointing to it.
17211756
genericValueFromLabel :: HasCallStack => (T.Text -> T.Text -> Bool) -> T.Text -> RequestBuilder site T.Text

yesod-test/test/main.hs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,15 @@ main = hspec $ do
322322
chooseByLabel "Blue"
323323
addToken
324324
bodyContains "colorRadioButton = Just Blue"
325+
yit "can click check boxes" $ do
326+
get ("/labels-checkboxes" :: Text)
327+
request $ do
328+
setMethod "POST"
329+
setUrl ("/labels-checkboxes" :: Text)
330+
checkByLabel "Red"
331+
checkByLabel "Gray"
332+
addToken
333+
bodyContains "colorCheckBoxes = [Gray,Red]"
325334

326335
ydescribe "byLabel-related tests" $ do
327336
yit "fails with \"More than one label contained\" error" $ do
@@ -667,19 +676,34 @@ app = liteApp $ do
667676
onStatic "labels-radio-buttons" $ dispatchTo $ do
668677
((result, widget), _) <- runFormPost
669678
$ renderDivs
670-
$ ColorForm <$> aopt (radioField' optionsEnum) "Color" Nothing
679+
$ RadioButtonForm <$> aopt (radioField' optionsEnum) "Color" Nothing
671680
case result of
672681
FormSuccess color -> return $ toHtml $ show color
673682
_ -> defaultLayout [whamlet|$newline never
683+
<p>
684+
^{toHtml $ show result}
674685
<form method=post action="labels-radio-buttons">
675686
^{widget}
676687
|]
677688

689+
onStatic "labels-checkboxes" $ dispatchTo $ do
690+
((result, widget), _) <- runFormPost
691+
$ renderDivs
692+
$ CheckboxesForm <$> areq (checkboxesField' optionsEnum) "Checkboxes" (Just [Blue, Black])
693+
case result of
694+
FormSuccess color -> return $ toHtml $ show color
695+
_ -> defaultLayout [whamlet|$newline never
696+
<p>
697+
^{toHtml $ show result}
698+
<form method=post action="labels-checkboxes">
699+
^{widget}
700+
|]
701+
678702
data Color = Red | Blue | Gray | Black
679703
deriving (Show, Eq, Enum, Bounded)
680704

681-
newtype ColorForm = ColorForm { colorRadioButton :: Maybe Color }
682-
deriving Show
705+
newtype RadioButtonForm = RadioButtonForm { colorRadioButton :: Maybe Color } deriving Show
706+
newtype CheckboxesForm = CheckboxesForm { colorCheckBoxes :: [Color] } deriving Show
683707

684708
cookieApp :: LiteApp
685709
cookieApp = liteApp $ do

yesod-test/yesod-test.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: yesod-test
2-
version: 1.6.17
2+
version: 1.6.18
33
license: MIT
44
license-file: LICENSE
55
author: Nubis <nubis@woobiz.com.ar>

0 commit comments

Comments
 (0)