module PhotoGrooveTest exposing (..) import Expect import Fuzz exposing (Fuzzer) import Html.Attributes as Attr import Json.Decode as J import Json.Encode as Encode import PhotoGroove.Internal as Testee exposing (FilterType(..), FilterValues, Message(..), Photo, filterTypeToName, initialModel) import Test exposing (..) import Test.Html.Event as Event import Test.Html.Query as Query import Test.Html.Selector exposing (attribute, tag) suite : Test suite = concat [ describe "photoDecoder" [ fuzz2 Fuzz.string Fuzz.int "title always defaults to '(untitled)'" <| \url size -> [ ( "url", Encode.string url ) , ( "size", Encode.int size ) ] |> Encode.object |> J.decodeValue Testee.photoDecoder |> Result.map .title |> Expect.equal (Ok "(untitled)") ] , describe "update" [ describe "slider event sets filter value" [ sliderTest Hue .hue , sliderTest Ripple .ripple , sliderTest Noise .noise ] , test "when photos are loaded, the first one gets selected" <| \_ -> Testee.initialModel |> Testee.update (GotPhotos (Ok <| [ photoFromUrl "1.jpg" ])) |> Tuple.first |> .status |> selectedUrl |> Expect.equal (Just "1.jpg") ] , describe "view" [ test "no photos, no thumbnails" <| \_ -> Testee.initialModel |> Testee.view |> Query.fromHtml |> Query.findAll [ tag "img" ] |> Query.count (Expect.equal 0) , fuzz (Fuzz.intRange 1 5) "URLs render as thumbnails" <| \count -> let urls : List String urls = List.range 1 count |> List.map (\num -> String.fromInt num ++ ".png") photos = List.map photoFromUrl urls checks = List.map thumbnailRendered urls in { initialModel | status = Testee.Loaded photos "" } |> Testee.view |> Query.fromHtml |> Expect.all checks ] ] sliderTest : FilterType -> (FilterValues -> Int) -> Test sliderTest filterType value = fuzz Fuzz.int (filterTypeToName filterType) <| \amount -> Testee.initialModel |> Testee.update (ChangedFilter filterType amount) |> Tuple.first |> .filterValues |> value |> Expect.equal amount thumbnailRendered : String -> Query.Single msg -> Expect.Expectation thumbnailRendered url query = query |> Query.findAll [ tag "img", attribute (Attr.src (Testee.urlPrefix ++ url)) ] |> Query.count (Expect.atLeast 1) clickThumbnail : Test clickThumbnail = fuzz3 urlFuzzer Fuzz.string urlFuzzer "clicking a thumbnail selects it" <| \urlsBefore urlSelected urlsAfter -> let url = urlSelected ++ ".jpeg" photos = (urlsBefore ++ url :: urlsAfter) |> List.map photoFromUrl srcToClick = Testee.urlPrefix ++ url in { initialModel | status = Testee.Loaded photos "" } |> Testee.view |> Query.fromHtml |> Query.find [ tag "img", attribute (Attr.src srcToClick) ] |> Event.simulate Event.click |> Event.expect (Testee.ClickedThumbnail url) photoFromUrl : String -> Photo photoFromUrl url = { url = url, size = 0, title = "" } selectedUrl : Testee.Status -> Maybe String selectedUrl status = case status of Testee.Loading -> Nothing Testee.Loaded _ url -> Just url Testee.Errored _ -> Nothing urlFuzzer : Fuzzer (List String) urlFuzzer = Fuzz.intRange 1 5 |> Fuzz.map urlsFromCount urlsFromCount : Int -> List String urlsFromCount count = List.range 1 count |> List.map (\num -> String.fromInt num ++ ".jpg")