import Test.HUnit import System.IO import System.Environment import Data.String.Utils import Network.Factual.API import Data.Factual.Query.ReadQuery import Data.Factual.Query.SchemaQuery import Data.Factual.Query.ResolveQuery import Data.Factual.Query.GeocodeQuery import Data.Factual.Query.MatchQuery import Data.Factual.Response import qualified Data.Factual.Query.DiffsQuery as D import qualified Data.Factual.Query as Q import qualified Data.Map as M import qualified Data.Factual.Write as W import qualified Data.Factual.Query.FacetsQuery as F import qualified Data.Factual.Query.GeopulseQuery as G import qualified Data.Factual.Write.Submit as S import qualified Data.Factual.Write.Insert as I import qualified Data.Factual.Write.Flag as L runUnitTests = runTestTT unitTests runIntegrationTests = do token <- getTokenFromCredentialsFile runTestTT $ integrationTests token getTokenFromCredentialsFile = do home <- getEnv "HOME" yaml <- readFile $ home ++ "/.factual/factual-auth.yaml" let lines = split "\n" yaml let lines' = filter (\x -> length (split ":" x) == 2) lines let pairs = map (map strip . split ":") lines' let key = last $ head $ filter (\x -> head x == "key") pairs let secret = last $ head $ filter (\x -> head x == "secret") pairs let token = generateToken key secret return token unitTests = TestList [ TestLabel "Place table test" placeTablePathTest , TestLabel "Restaurants table test" restaurantsTablePathTest , TestLabel "Hotels table test" hotelsTablePathTest , TestLabel "Global table test" globalTablePathTest , TestLabel "Crosswalk table test" crosswalkProductsTablePathTest , TestLabel "Healthcare table test" healthcareTablePathTest , TestLabel "World Geographies table test" worldGeographiesTablePathTest , TestLabel "CPG table test" cpgTablePathTest , TestLabel "Crosswalk Products table test" crosswalkProductsTablePathTest , TestLabel "Monetize table test" monetizeTablePathTest , TestLabel "Custom table test" customTablePathTest , TestLabel "Geopulse test" geopulseTest , TestLabel "Geocode test" geocodeTest , TestLabel "And search test" andSearchPathTest , TestLabel "Or search test" orSearchPathTest , TestLabel "Select test" selectTest , TestLabel "Limit test" limitTest , TestLabel "Offset test" offsetTest , TestLabel "Equal number filter test" equalNumFilterTest , TestLabel "Equal string filter test" equalStrFilterTest , TestLabel "Not equal number filter test" notEqualNumFilterTest , TestLabel "Not equal string filter test" notEqualStrFilterTest , TestLabel "In number list filter test" inNumListFilterTest , TestLabel "In string list filter test" inStrListFilterTest , TestLabel "Not in number list filter test" notInNumListFilterTest , TestLabel "Not in string list filter test" notInStrListFilterTest , TestLabel "Begins with filter test" beginsWithFilterTest , TestLabel "Not begins with filter test" notBeginsWithFilterTest , TestLabel "Begins with any filter test" beginsWithAnyFilterTest , TestLabel "Not begins with any filter test" notBeginsWithAnyFilterTest , TestLabel "Is blank filter test" isBlankFilterTest , TestLabel "Is not blank filter test" isNotBlankFilterTest , TestLabel "Greater than number filter test" greaterThanFilterTest , TestLabel "Greater than or equal to number filter test" greaterThanOrEqualToFilterTest , TestLabel "Less than number filter test" lessThanFilterTest , TestLabel "Less than or equal to number filter test" lessThanOrEqualToFilterTest , TestLabel "Search filter test" searchFilterTest , TestLabel "And filter test" andFilterTest , TestLabel "Or filter test" orFilterTest , TestLabel "Geo test" geoTest , TestLabel "Sort test" sortTest , TestLabel "Include count test" includeCountTest , TestLabel "Schema query test" schemaQueryTest , TestLabel "Resolve query test" resolveQueryTest , TestLabel "Match query test" matchQueryTest , TestLabel "Facets test" facetsTest , TestLabel "Diffs test" diffsTest , TestLabel "Submit path test" submitPathTest , TestLabel "Submit body test" submitBodyTest , TestLabel "Insert path test" insertPathTest , TestLabel "Insert body test" insertBodyTest , TestLabel "Flag path test" flagPathTest , TestLabel "Flag body test" flagBodyTest ] integrationTests token = TestList [ TestLabel "Read test" (readIntegrationTest token) , TestLabel "Unicode test" (unicodeIntegrationTest token) , TestLabel "Schema test" (schemaIntegrationTest token) , TestLabel "Resolve test" (resolveIntegrationTest token) , TestLabel "Match test" (matchIntegrationTest token) , TestLabel "Raw read test" (rawIntegrationTest token) , TestLabel "Facets test" (facetsIntegrationTest token) --, TestLabel "Diffs test" (diffsIntegrationTest token) , TestLabel "Geopulse test" (geopulseIntegrationTest token) , TestLabel "Geocode test" (geocodeIntegrationTest token) , TestLabel "Multi test" (multiIntegrationTest token) , TestLabel "Submit test" (submitIntegrationTest token) , TestLabel "Insert test" (insertIntegrationTest token) , TestLabel "Flag test" (flagIntegrationTest token) , TestLabel "Error test" (errorIntegrationTest token) ] placeTablePathTest = TestCase (do let expected = "/t/places" let queryPath = Q.path $ blankReadQuery { table = Places } assertEqual "Correct path for places table" expected queryPath) restaurantsTablePathTest = TestCase (do let expected = "/t/restaurants-us" let queryPath = Q.path $ blankReadQuery { table = RestaurantsUS } assertEqual "Correct path for us restaurants table" expected queryPath) hotelsTablePathTest = TestCase (do let expected = "/t/hotels-us" let queryPath = Q.path $ blankReadQuery { table = HotelsUS } assertEqual "Correct path for us hotels table" expected queryPath) globalTablePathTest = TestCase (do let expected = "/t/global" let queryPath = Q.path $ blankReadQuery { table = Global } assertEqual "Correct path for global table" expected queryPath) crosswalkTablePathTest = TestCase (do let expected = "/t/crosswalk" let queryPath = Q.path $ blankReadQuery { table = Crosswalk } assertEqual "Correct path for crosswalk table" expected queryPath) healthcareTablePathTest = TestCase (do let expected = "/t/health-care-providers-us" let queryPath = Q.path $ blankReadQuery { table = HealthCareProviders } assertEqual "Correct path for health care providers table" expected queryPath) worldGeographiesTablePathTest = TestCase (do let expected = "/t/world-geographies" let queryPath = Q.path $ blankReadQuery { table = WorldGeographies } assertEqual "Correct path for world geographies table" expected queryPath) cpgTablePathTest = TestCase (do let expected = "/t/products-cpg" let queryPath = Q.path $ blankReadQuery { table = ProductsCPG } assertEqual "Correct path for products CPG table" expected queryPath) crosswalkProductsTablePathTest = TestCase (do let expected = "/t/products-crosswalk" let queryPath = Q.path $ blankReadQuery { table = ProductsCrosswalk } assertEqual "Correct path for products crosswalk table" expected queryPath) monetizeTablePathTest = TestCase (do let expected = "/places/monetize" let queryPath = Q.path $ blankReadQuery { table = Monetize } assertEqual "Correct path for monetize table" expected queryPath) customTablePathTest = TestCase (do let expected = "/t/foo" let queryPath = Q.path $ blankReadQuery { table = Custom "foo" } assertEqual "Correct path for custom table" expected queryPath) geopulseTest = TestCase (do let query = G.GeopulseQuery { G.geo = Point 34.06021 (-118.41828) , G.select = ["commercial_density"] } let queryPath = Q.path query let queryParams = Q.params query assertEqual "Correct path for geopulse" queryPath "/places/geopulse" assertEqual "Correct geo param" (queryParams M.! "geo") "{\"$point\":[34.06021,-118.41828]}" assertEqual "Correct select param" (queryParams M.! "select") "commercial_density") geocodeTest = TestCase (do let query = GeocodeQuery $ Point 34.06021 (-118.41828) let queryPath = Q.path query let queryParams = Q.params query assertEqual "Correct path for geocode" queryPath "/places/geocode" assertEqual "Correct geo param" (queryParams M.! "geo") "{\"$point\":[34.06021,-118.41828]}") andSearchPathTest = TestCase (do let query = blankReadQuery { search = AndSearch ["foo", "bar"] } let queryParams = Q.params query assertEqual "Correct query value" (queryParams M.! "q") "foo bar") orSearchPathTest = TestCase (do let query = blankReadQuery { search = OrSearch ["foo", "bar"] } let queryParams = Q.params query assertEqual "Correct query value" (queryParams M.! "q") "foo,bar") selectTest = TestCase (do let query = blankReadQuery { select = ["foo", "bar"] } let queryParams = Q.params query assertEqual "Correct select value" (queryParams M.! "select") "foo,bar") limitTest = TestCase (do let query = blankReadQuery { limit = Just 321 } let queryParams = Q.params query assertEqual "Correct limit value" (queryParams M.! "limit") "321") offsetTest = TestCase (do let query = blankReadQuery { offset = Just 321 } let queryParams = Q.params query assertEqual "Correct offset value" (queryParams M.! "offset") "321") equalNumFilterTest = TestCase (do let query = blankReadQuery { filters = [EqualNum "field" 123.4] } let queryParams = Q.params query assertEqual "Correct filters value" (queryParams M.! "filters") "{\"field\":123.4}") equalStrFilterTest = TestCase (do let query = blankReadQuery { filters = [EqualStr "field" "value"] } let queryParams = Q.params query assertEqual "Correct filters value" (queryParams M.! "filters") "{\"field\":\"value\"}") notEqualNumFilterTest = TestCase (do let query = blankReadQuery { filters = [NotEqualNum "field" 123.4] } let queryParams = Q.params query assertEqual "Correct filters value" (queryParams M.! "filters") "{\"field\":{\"$neq\":123.4}}") notEqualStrFilterTest = TestCase (do let query = blankReadQuery { filters = [NotEqualStr "field" "value"] } let queryParams = Q.params query let expected = "{\"field\":{\"$neq\":\"value\"}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) inNumListFilterTest = TestCase (do let query = blankReadQuery { filters = [InNumList "field" [123.4, 5432.1]] } let queryParams = Q.params query let expected = "{\"field\":{\"$in\":[123.4,5432.1]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) inStrListFilterTest = TestCase (do let query = blankReadQuery { filters = [InStrList "field" ["value","other"]] } let queryParams = Q.params query let expected = "{\"field\":{\"$in\":[\"value\",\"other\"]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) notInNumListFilterTest = TestCase (do let query = blankReadQuery { filters = [NotInNumList "field" [123.4, 5432.1]] } let queryParams = Q.params query let expected = "{\"field\":{\"$nin\":[123.4,5432.1]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) notInStrListFilterTest = TestCase (do let query = blankReadQuery { filters = [NotInStrList "field" ["value","other"]] } let queryParams = Q.params query let expected = "{\"field\":{\"$nin\":[\"value\",\"other\"]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) beginsWithFilterTest = TestCase (do let query = blankReadQuery { filters = [BeginsWith "field" "val"] } let queryParams = Q.params query let expected = "{\"field\":{\"$bw\":\"val\"}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) notBeginsWithFilterTest = TestCase (do let query = blankReadQuery { filters = [NotBeginsWith "field" "val"] } let queryParams = Q.params query let expected = "{\"field\":{\"$nbw\":\"val\"}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) beginsWithAnyFilterTest = TestCase (do let query = blankReadQuery { filters = [BeginsWithAny "field" ["val","ot"]] } let queryParams = Q.params query let expected = "{\"field\":{\"$bwin\":[\"val\",\"ot\"]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) notBeginsWithAnyFilterTest = TestCase (do let query = blankReadQuery { filters = [NotBeginsWithAny "field" ["val","ot"]] } let queryParams = Q.params query let expected = "{\"field\":{\"$nbwin\":[\"val\",\"ot\"]}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) isBlankFilterTest = TestCase (do let query = blankReadQuery { filters = [IsBlank "field"] } let queryParams = Q.params query let expected = "{\"field\":{\"$blank\":true}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) isNotBlankFilterTest = TestCase (do let query = blankReadQuery { filters = [IsNotBlank "field"] } let queryParams = Q.params query let expected = "{\"field\":{\"$blank\":false}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) greaterThanFilterTest = TestCase (do let query = blankReadQuery { filters = [GreaterThan "field" 10.0] } let queryParams = Q.params query let expected = "{\"field\":{\"$gt\":10.0}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) greaterThanOrEqualToFilterTest = TestCase (do let query = blankReadQuery { filters = [GreaterThanOrEqualTo "field" 10.0] } let queryParams = Q.params query let expected = "{\"field\":{\"$gte\":10.0}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) lessThanFilterTest = TestCase (do let query = blankReadQuery { filters = [LessThan "field" 10.0] } let queryParams = Q.params query let expected = "{\"field\":{\"$lt\":10.0}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) lessThanOrEqualToFilterTest = TestCase (do let query = blankReadQuery { filters = [LessThanOrEqualTo "field" 10.0] } let queryParams = Q.params query let expected = "{\"field\":{\"$lte\":10.0}}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) searchFilterTest = TestCase (do let query = blankReadQuery { filters = [SearchFilter "field" "value"] } let queryParams = Q.params query assertEqual "Correct filters value" (queryParams M.! "filters") "{\"field\":{\"$search\":\"value\"}}") andFilterTest = TestCase (do let query = blankReadQuery { filters = [And [IsBlank "field1", IsNotBlank "field2"]] } let queryParams = Q.params query let expected = "{\"$and\":[{\"field1\":{\"$blank\":true}},{\"field2\":{\"$blank\":false}}]}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) orFilterTest = TestCase (do let query = blankReadQuery { filters = [Or [IsBlank "field1", IsNotBlank "field2"]] } let queryParams = Q.params query let expected = "{\"$or\":[{\"field1\":{\"$blank\":true}},{\"field2\":{\"$blank\":false}}]}" assertEqual "Correct filters value" (queryParams M.! "filters") expected) geoTest = TestCase (do let query = blankReadQuery { geo = Just (Circle 300.1 200.3 100.5) } let queryParams = Q.params query let expected = "{\"$circle\":{\"$center\":[300.1, 200.3],\"$meters\":100.5}}" assertEqual "Correct geo value" (queryParams M.! "geo") expected) sortTest = TestCase (do let query = blankReadQuery { sort = [Asc "name", Desc "country"] } let queryParams = Q.params query let expected = "name:asc,country:desc" assertEqual "Correct sort value" (queryParams M.! "sort") expected) includeCountTest = TestCase (do let query = blankReadQuery { includeCount = True } let queryParams = Q.params query assertEqual "Correct include_count value" (queryParams M.! "include_count") "true") schemaQueryTest = TestCase (do let queryPath = Q.path $ SchemaQuery Places let expected = "/t/places/schema" assertEqual "Correct path for a schema query" queryPath expected) resolveQueryTest = TestCase (do let query = ResolveQuery { values = [ResolveStr "field1" "value1", ResolveNum "field2" 32.1], debug = False } let queryPath = Q.path query let queryParams = Q.params query let expectedValues = "{\"field1\":\"value1\",\"field2\":32.1}" assertEqual "Correct path" queryPath "/places/resolve" assertEqual "Correct values" (queryParams M.! "values") expectedValues assertEqual "Correct debug" (queryParams M.! "debug") "false") matchQueryTest = TestCase (do let query = MatchQuery [MatchStr "field1" "value1", MatchNum "field2" 32.1] let queryPath = Q.path query let queryParams = Q.params query let expectedValues = "{\"field1\":\"value1\",\"field2\":32.1}" assertEqual "Correct path" queryPath "/places/match" assertEqual "Correct values" (queryParams M.! "values") expectedValues) facetsTest = TestCase (do let query = F.FacetsQuery { F.table = Places , F.search = AndSearch ["starbucks"] , F.select = ["locality", "region"] , F.filters = [EqualStr "country" "US"] , F.geo = Nothing , F.limit = Just 10 , F.minCount = Just 2 , F.includeCount = False } let queryPath = Q.path query let queryParams = Q.params query assertEqual "Correct path for a facets query" queryPath "/t/places/facets" assertEqual "Correct q" (queryParams M.! "q") "starbucks" assertEqual "Correct select" (queryParams M.! "select") "locality,region" assertEqual "Correct filters" (queryParams M.! "filters") "{\"country\":\"US\"}" assertEqual "Correct limit" (queryParams M.! "limit") "10" assertEqual "Correct min count" (queryParams M.! "min_count") "2" assertEqual "Correct include count" (queryParams M.! "include_count") "false") diffsTest = TestCase (do let query = D.DiffsQuery { D.table = Places, D.start = 1318890505254, D.end = 1318890516892 } let queryPath = Q.path query let queryParams = Q.params query assertEqual "Correct path for a diffs query" queryPath "/t/places/diffs" assertEqual "Correct start" (queryParams M.! "start") "1318890505254" assertEqual "Correct end" (queryParams M.! "end") "1318890516892") submitPathTest = TestCase (do let expected = "/t/places/foobar/submit" let writePath = W.path submitWrite assertEqual "Correct path for submit" expected writePath) submitBodyTest = TestCase (do let expected = "user=user123&values={\"key\":\"val\"}" let bodyParams = W.body submitWrite assertEqual "Correct user" (bodyParams M.! "user") "user123" assertEqual "Correct values" (bodyParams M.! "values") "{\"key\":\"val\"}") insertPathTest = TestCase (do let expected = "/t/places/foobar/insert" let writePath = W.path insertWrite assertEqual "Correct path for insert" expected writePath) insertBodyTest = TestCase (do let expected = "user=user123&values={\"key\":\"val\"}" let bodyParams = W.body insertWrite assertEqual "Correct user" (bodyParams M.! "user") "user123" assertEqual "Correct values" (bodyParams M.! "values") "{\"key\":\"val\"}") flagPathTest = TestCase (do let expected = "/t/places/foobar/flag" let path = W.path flagWrite assertEqual "Correct path for flag" expected path) flagBodyTest = TestCase (do let bodyParams = W.body flagWrite assertEqual "Correct problem" (bodyParams M.! "problem") "Duplicate" assertEqual "Correct user" (bodyParams M.! "user") "user123" assertEqual "Correct comment" (bodyParams M.! "comment") "There was a problem") readIntegrationTest :: Token -> Test readIntegrationTest token = TestCase (do let query = ReadQuery { table = Places , search = AndSearch ["McDonalds", "Burger King"] , select = ["name"] , limit = Just 50 , offset = Just 10 , includeCount = True , geo = Just (Circle 34.06021 (-118.41828) 5000.0) , sort = [] , filters = [EqualStr "name" "Stand"] } result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid read query" "ok" (status result)) unicodeIntegrationTest :: Token -> Test unicodeIntegrationTest token = TestCase (do let query = ReadQuery { table = Global , search = NoSearch , select = [] , limit = Nothing , offset = Nothing , includeCount = False , geo = Nothing , sort = [] , filters = [EqualStr "locality" "בני ברק"] } result <- executeQuery (Options { token = token, timeout = Nothing }) query let resp = response result let dat = lookupValue "data" resp let row = (toList dat) !! 0 let loc = lookupString "locality" row assertEqual "Correctly encoded locality" loc "בני ברק") schemaIntegrationTest :: Token -> Test schemaIntegrationTest token = TestCase (do let query = SchemaQuery Places result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid schema query" "ok" (status result)) resolveIntegrationTest :: Token -> Test resolveIntegrationTest token = TestCase (do let query = ResolveQuery { values = [ResolveStr "name" "McDonalds"], debug = False } result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid resolve query" "ok" (status result)) matchIntegrationTest :: Token -> Test matchIntegrationTest token = TestCase (do let query = MatchQuery [MatchStr "name" "McDonalds"] result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid match query" "ok" (status result)) rawIntegrationTest :: Token -> Test rawIntegrationTest token = TestCase (do result <- get (Options { token = token, timeout = Nothing }) "/t/places" (M.fromList [("q", "starbucks")]) assertEqual "Valid read query" "ok" (status result)) facetsIntegrationTest token = TestCase (do let query = F.FacetsQuery { F.table = Places , F.search = AndSearch ["Starbucks"] , F.select = ["country"] , F.filters = [] , F.geo = Nothing , F.limit = Just 100 , F.minCount = Just 1 , F.includeCount = False } result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid facets query" "ok" (status result)) diffsIntegrationTest token = TestCase (do let query = D.DiffsQuery { D.table = Custom "t7RSEV", D.start = 1339123455775, D.end = 1339124455775 } result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid diffs query" "ok" (status result)) geopulseIntegrationTest token = TestCase (do let query = G.GeopulseQuery { G.geo = Point 34.06021 (-118.41828) , G.select = [] } result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid geopulse query" "ok" (status result)) geocodeIntegrationTest token = TestCase (do let query = GeocodeQuery $ Point 34.06021 (-118.41828) result <- executeQuery (Options { token = token, timeout = Nothing }) query assertEqual "Valid geopulse query" "ok" (status result)) multiIntegrationTest :: Token -> Test multiIntegrationTest token = TestCase (do let query1 = ReadQuery { table = Places , search = AndSearch ["McDonalds", "Burger King"] , select = ["name"] , limit = Just 50 , offset = Just 10 , includeCount = True , geo = Just (Circle 34.06021 (-118.41828) 5000.0) , sort = [] , filters = [EqualStr "name" "Stand"] } let query2 = query1 { filters = [EqualStr "name" "Xerox"] } results <- executeMultiQuery (Options { token = token, timeout = Nothing }) $ M.fromList [("query1", query1), ("query2", query2)] let result1 = results M.! "query1" let result2 = results M.! "query2" assertEqual "Valid multi query" ["ok","ok"] [status result1, status result2]) submitIntegrationTest :: Token -> Test submitIntegrationTest token = TestCase (do let newValues = M.fromList [ ("name","Factual") , ("address","1801 Avenue of the Stars, Suite 1450") , ("country","USA") , ("locality","Los Angeles") ] let write = S.Submit { S.table = Custom "t7RSEV" , S.user = "drivertest" , S.factualId = Nothing , S.reference = Nothing , S.comment = Nothing , S.values = newValues } result <- executeWrite (Options { token = token, timeout = Nothing }) write assertEqual "Valid submit" "ok" (status result)) insertIntegrationTest :: Token -> Test insertIntegrationTest token = TestCase (do let newValues = M.fromList [ ("name","Factual") , ("address","1801 Avenue of the Stars, Suite 1450") , ("country","USA") , ("locality","Los Angeles") ] let write = I.Insert { I.table = Custom "t7RSEV" , I.user = "drivertest" , I.factualId = Nothing , I.values = newValues } result <- executeWrite (Options { token = token, timeout = Nothing }) write assertEqual "Valid insert" "ok" (status result)) flagIntegrationTest :: Token -> Test flagIntegrationTest token = TestCase (do let write = L.Flag { L.table = Custom "t7RSEV" , L.user = "drivertest" , L.factualId = "97a38c06-cde1-402d-ad5a-4ae408530386" , L.problem = L.Inaccurate , L.comment = Nothing , L.dataJSON = Nothing , L.fields = Nothing , L.reference = Nothing } result <- executeWrite (Options { token = token, timeout = Nothing }) write assertEqual "Valid flag" "ok" (status result)) errorIntegrationTest :: Token -> Test errorIntegrationTest token = TestCase (do result <- get (Options { token = token, timeout = Nothing }) "/t/foobarbaz" (M.empty) assertEqual "Invalud read query" "error" (status result)) blankReadQuery :: ReadQuery blankReadQuery = ReadQuery { table = Places , search = AndSearch [] , select = [] , limit = Nothing , offset = Nothing , filters = [] , geo = Nothing , sort = [] , includeCount = False } submitWrite :: S.Submit submitWrite = S.Submit { S.table = Places , S.user = "user123" , S.factualId = Just "foobar" , S.reference = Nothing , S.comment = Nothing , S.values = M.fromList [("key", "val")] } insertWrite :: I.Insert insertWrite = I.Insert { I.table = Places , I.user = "user123" , I.factualId = Just "foobar" , I.values = M.fromList [("key", "val")] } flagWrite :: L.Flag flagWrite = L.Flag { L.table = Places , L.factualId = "foobar" , L.problem = L.Duplicate , L.user = "user123" , L.comment = Just "There was a problem" , L.dataJSON = Nothing , L.fields = Nothing , L.reference = Nothing }