From eacaa0c78fa340d176541b9bf310bcb7dd79a47b Mon Sep 17 00:00:00 2001 From: Lucy Cifferello <12953208+elvece@users.noreply.github.com> Date: Mon, 22 Nov 2021 13:06:05 -0700 Subject: [PATCH] rename all references from services to packages --- src/Handler/Marketplace.hs | 180 +++++++++++++++++++------------------ src/Lib/PkgRepository.hs | 4 +- src/Lib/Types/AppIndex.hs | 70 ++++++++------- test/Handler/AppSpec.hs | 32 +++---- 4 files changed, 148 insertions(+), 138 deletions(-) diff --git a/src/Handler/Marketplace.hs b/src/Handler/Marketplace.hs index 0c5c54b..0da92bc 100644 --- a/src/Handler/Marketplace.hs +++ b/src/Handler/Marketplace.hs @@ -96,8 +96,8 @@ import Lib.Error ( S9Error(..) ) import Lib.PkgRepository ( getManifest ) import Lib.Types.AppIndex ( PkgId(PkgId) - , ServiceDependencyInfo(serviceDependencyInfoVersion) - , ServiceManifest(serviceManifestDependencies) + , PackageDependency(packageDependencyVersion) + , PackageManifest(packageManifestDependencies) , VersionInfo(..) ) import Lib.Types.AppIndex ( ) @@ -168,14 +168,14 @@ instance ToContent CategoryRes where toContent = toContent . toJSON instance ToTypedContent CategoryRes where toTypedContent = toTypedContent . toJSON -data ServiceRes = ServiceRes - { serviceResIcon :: URL - , serviceResManifest :: Data.Aeson.Value -- ServiceManifest - , serviceResCategories :: [CategoryTitle] - , serviceResInstructions :: URL - , serviceResLicense :: URL - , serviceResVersions :: [Version] - , serviceResDependencyInfo :: HM.HashMap PkgId DependencyInfo +data PackageRes = PackageRes + { packageResIcon :: URL + , packageResManifest :: Data.Aeson.Value -- PackageManifest + , packageResCategories :: [CategoryTitle] + , packageResInstructions :: URL + , packageResLicense :: URL + , packageResVersions :: [Version] + , packageResDependencies :: HM.HashMap PkgId DependencyRes } deriving (Show, Generic) newtype ReleaseNotes = ReleaseNotes { unReleaseNotes :: HM.HashMap Version Text } @@ -186,44 +186,44 @@ instance ToContent ReleaseNotes where toContent = toContent . toJSON instance ToTypedContent ReleaseNotes where toTypedContent = toTypedContent . toJSON -instance ToJSON ServiceRes where - toJSON ServiceRes {..} = object - [ "icon" .= serviceResIcon - , "license" .= serviceResLicense - , "instructions" .= serviceResInstructions - , "manifest" .= serviceResManifest - , "categories" .= serviceResCategories - , "versions" .= serviceResVersions - , "dependency-metadata" .= serviceResDependencyInfo +instance ToJSON PackageRes where + toJSON PackageRes {..} = object + [ "icon" .= packageResIcon + , "license" .= packageResLicense + , "instructions" .= packageResInstructions + , "manifest" .= packageResManifest + , "categories" .= packageResCategories + , "versions" .= packageResVersions + , "dependency-metadata" .= packageResDependencies ] -instance FromJSON ServiceRes where - parseJSON = withObject "ServiceRes" $ \o -> do - serviceResIcon <- o .: "icon" - serviceResLicense <- o .: "license" - serviceResInstructions <- o .: "instructions" - serviceResManifest <- o .: "manifest" - serviceResCategories <- o .: "categories" - serviceResVersions <- o .: "versions" - serviceResDependencyInfo <- o .: "dependency-metadata" - pure ServiceRes { .. } -data DependencyInfo = DependencyInfo - { dependencyInfoTitle :: PkgId - , dependencyInfoIcon :: URL +instance FromJSON PackageRes where + parseJSON = withObject "PackageRes" $ \o -> do + packageResIcon <- o .: "icon" + packageResLicense <- o .: "license" + packageResInstructions <- o .: "instructions" + packageResManifest <- o .: "manifest" + packageResCategories <- o .: "categories" + packageResVersions <- o .: "versions" + packageResDependencies <- o .: "dependency-metadata" + pure PackageRes { .. } +data DependencyRes = DependencyRes + { dependencyResTitle :: PkgId + , dependencyResIcon :: URL } deriving (Eq, Show) -instance ToJSON DependencyInfo where - toJSON DependencyInfo {..} = object ["icon" .= dependencyInfoIcon, "title" .= dependencyInfoTitle] -instance FromJSON DependencyInfo where - parseJSON = withObject "DependencyInfo" $ \o -> do - dependencyInfoIcon <- o .: "icon" - dependencyInfoTitle <- o .: "title" - pure DependencyInfo { .. } -newtype ServiceAvailableRes = ServiceAvailableRes [ServiceRes] +instance ToJSON DependencyRes where + toJSON DependencyRes {..} = object ["icon" .= dependencyResIcon, "title" .= dependencyResTitle] +instance FromJSON DependencyRes where + parseJSON = withObject "DependencyRes" $ \o -> do + dependencyResIcon <- o .: "icon" + dependencyResTitle <- o .: "title" + pure DependencyRes { .. } +newtype PackageListRes = PackageListRes [PackageRes] deriving (Generic) -instance ToJSON ServiceAvailableRes -instance ToContent ServiceAvailableRes where +instance ToJSON PackageListRes +instance ToContent PackageListRes where toContent = toContent . toJSON -instance ToTypedContent ServiceAvailableRes where +instance ToTypedContent PackageListRes where toTypedContent = toTypedContent . toJSON newtype VersionLatestRes = VersionLatestRes (HM.HashMap PkgId (Maybe Version)) @@ -235,12 +235,12 @@ instance ToTypedContent VersionLatestRes where toTypedContent = toTypedContent . toJSON data OrderArrangement = ASC | DESC deriving (Eq, Show, Read) -data ServiceListDefaults = ServiceListDefaults - { serviceListOrder :: OrderArrangement - , serviceListPageLimit :: Int -- the number of items per page - , serviceListPageNumber :: Int -- the page you are on - , serviceListCategory :: Maybe CategoryTitle - , serviceListQuery :: Text +data PackageListDefaults = PackageListDefaults + { packageListOrder :: OrderArrangement + , packageListPageLimit :: Int -- the number of items per page + , packageListPageNumber :: Int -- the page you are on + , packageListCategory :: Maybe CategoryTitle + , packageListQuery :: Text } deriving (Eq, Show, Read) data EosRes = EosRes @@ -257,16 +257,16 @@ instance ToContent EosRes where instance ToTypedContent EosRes where toTypedContent = toTypedContent . toJSON -data PackageVersion = PackageVersion - { packageVersionId :: PkgId - , packageVersionVersion :: VersionRange +data PackageReq = PackageReq + { packageReqId :: PkgId + , packageReqVersion :: VersionRange } deriving Show -instance FromJSON PackageVersion where +instance FromJSON PackageReq where parseJSON = withObject "package version" $ \o -> do - packageVersionId <- o .: "id" - packageVersionVersion <- o .: "version" - pure PackageVersion { .. } + packageReqId <- o .: "id" + packageReqVersion <- o .: "version" + pure PackageReq { .. } getCategoriesR :: Handler CategoryRes getCategoriesR = do @@ -353,19 +353,26 @@ getVersionLatestR = do ) $ HM.fromList packageList -getPackageListR :: Handler ServiceAvailableRes +getPackageListR :: Handler PackageListRes getPackageListR = do osPredicate <- getOsVersionQuery <&> \case Nothing -> const True Just v -> flip satisfies v pkgIds <- getPkgIdsQuery + -- deep info + -- generate data from db + -- filter os + -- filter from request + -- shallow info - generate get deps + -- transformations + -- assemble api response filteredPackages <- case pkgIds of Nothing -> do -- query for all category <- getCategoryQuery page <- getPageQuery limit' <- getLimitQuery - query <- T.strip . fromMaybe (serviceListQuery defaults) <$> lookupGetParam "query" + query <- T.strip . fromMaybe (packageListQuery defaults) <$> lookupGetParam "query" runDB $ runConduit $ searchServices category query @@ -377,10 +384,10 @@ getPackageListR = do .| sinkList Just packages' -> do -- for each item in list get best available from version range - let vMap = (packageVersionId &&& packageVersionVersion) <$> packages' + let vMap = (packageReqId &&& packageReqVersion) <$> packages' runDB . runConduit - $ getPkgData (packageVersionId <$> packages') + $ getPkgData (packageReqId <$> packages') .| zipVersions .| mapC (\(a, vs) -> @@ -398,16 +405,16 @@ getPackageListR = do -- log all errors but just throw first error until Validation implemented - TODO https://hackage.haskell.org/package/validation for_ xs (\e -> $logWarn [i|Get package list errors: #{e}|]) sendResponseStatus (toStatus x) x - [] -> pure $ ServiceAvailableRes res + [] -> pure $ PackageListRes res where - defaults = ServiceListDefaults { serviceListOrder = DESC - , serviceListPageLimit = 20 - , serviceListPageNumber = 1 - , serviceListCategory = Nothing - , serviceListQuery = "" + defaults = PackageListDefaults { packageListOrder = DESC + , packageListPageLimit = 20 + , packageListPageNumber = 1 + , packageListCategory = Nothing + , packageListQuery = "" } - getPkgIdsQuery :: Handler (Maybe [PackageVersion]) + getPkgIdsQuery :: Handler (Maybe [PackageReq]) getPkgIdsQuery = lookupGetParam "ids" >>= \case Nothing -> pure Nothing Just ids -> case eitherDecodeStrict (encodeUtf8 ids) of @@ -427,7 +434,7 @@ getPackageListR = do Just t -> pure $ Just t getPageQuery :: Handler Int getPageQuery = lookupGetParam "page" >>= \case - Nothing -> pure $ serviceListPageNumber defaults + Nothing -> pure $ packageListPageNumber defaults Just p -> case readMaybe p of Nothing -> do let e = InvalidParamsE "get:page" p @@ -438,7 +445,7 @@ getPackageListR = do _ -> t getLimitQuery :: Handler Int getLimitQuery = lookupGetParam "per-page" >>= \case - Nothing -> pure $ serviceListPageLimit defaults + Nothing -> pure $ packageListPageLimit defaults Just pp -> case readMaybe pp of Nothing -> do let e = InvalidParamsE "get:per-page" pp @@ -475,12 +482,12 @@ createPackageMetadata pkgs = do & HM.fromListWith mergeDupes pure $ (keys, HM.intersectionWith (,) vers (categoryName <<$>> cats)) -getServiceDetails :: (MonadIO m, MonadResource m, MonadReader r m, MonadLogger m, Has AppSettings r, MonadUnliftIO m) +getServiceDetails :: (MonadResource m, MonadReader r m, MonadLogger m, Has AppSettings r, MonadUnliftIO m) => (Version -> Bool) -> ConnectionPool -> (HM.HashMap PkgId (([Version], VersionRange), [CategoryTitle])) -> PkgId - -> m (Either S9Error ServiceRes) + -> m (Either S9Error PackageRes) getServiceDetails osPredicate appConnPool metadata pkg = runExceptT $ do settings <- ask packageMetadata <- case HM.lookup pkg metadata of @@ -502,23 +509,22 @@ getServiceDetails osPredicate appConnPool metadata pkg = runExceptT $ do case eitherDecode manifest of Left _ -> liftEither . Left $ AssetParseE [i|#{pkg}:manifest|] (decodeUtf8 $ BS.toStrict manifest) Right m -> do - let depVerList = - (fst &&& (serviceDependencyInfoVersion . snd)) <$> (HM.toList $ serviceManifestDependencies m) + let depVerList = (fst &&& (packageDependencyVersion . snd)) <$> (HM.toList $ packageManifestDependencies m) (_, depMetadata) <- lift $ runSqlPool (createPackageMetadata =<< getDependencies depVerList) appConnPool let (errors, deps) = partitionEithers $ parMap rpar (mapDependencyMetadata domain $ (HM.union depMetadata metadata)) - (HM.toList $ serviceManifestDependencies m) + (HM.toList $ packageManifestDependencies m) case errors of _ : xs -> liftEither . Left $ DepMetadataE xs - [] -> pure $ ServiceRes { serviceResIcon = [i|https://#{domain}/package/icon/#{pkg}|] + [] -> pure $ PackageRes { packageResIcon = [i|https://#{domain}/package/icon/#{pkg}|] -- pass through raw JSON Value, we have checked its correct parsing above - , serviceResManifest = unsafeFromJust . decode $ manifest - , serviceResCategories = snd packageMetadata - , serviceResInstructions = [i|https://#{domain}/package/instructions/#{pkg}|] - , serviceResLicense = [i|https://#{domain}/package/license/#{pkg}|] - , serviceResVersions = fst . fst $ packageMetadata - , serviceResDependencyInfo = HM.fromList deps + , packageResManifest = unsafeFromJust . decode $ manifest + , packageResCategories = snd packageMetadata + , packageResInstructions = [i|https://#{domain}/package/instructions/#{pkg}|] + , packageResLicense = [i|https://#{domain}/package/license/#{pkg}|] + , packageResVersions = fst . fst $ packageMetadata + , packageResDependencies = HM.fromList deps } where getDependencies :: (MonadResource m, MonadUnliftIO m) @@ -538,23 +544,23 @@ getServiceDetails osPredicate appConnPool metadata pkg = runExceptT $ do mapDependencyMetadata :: Text -> HM.HashMap PkgId (([Version], VersionRange), [CategoryTitle]) - -> (PkgId, ServiceDependencyInfo) - -> Either Text (PkgId, DependencyInfo) + -> (PkgId, PackageDependency) + -> Either Text (PkgId, DependencyRes) mapDependencyMetadata domain metadata (appId, depInfo) = do depMetadata <- case HM.lookup appId metadata of Nothing -> Left [i|dependency metadata for #{appId} not found.|] Just m -> pure m -- get best version from VersionRange of dependency - let satisfactory = filter (<|| serviceDependencyInfoVersion depInfo) (fst . fst $ depMetadata) + let satisfactory = filter (<|| packageDependencyVersion depInfo) (fst . fst $ depMetadata) let best = getMax <$> foldMap (Just . Max) satisfactory version <- case best of Nothing -> Left [i|No satisfactory version for dependent package #{appId}|] Just v -> pure v pure ( appId - , DependencyInfo { dependencyInfoTitle = appId - , dependencyInfoIcon = [i|https://#{domain}/package/icon/#{appId}?spec==#{version}|] - } + , DependencyRes { dependencyResTitle = appId + , dependencyResIcon = [i|https://#{domain}/package/icon/#{appId}?spec==#{version}|] + } ) fetchAllAppVersions :: PkgId -> Handler ([VersionInfo], ReleaseNotes) diff --git a/src/Lib/PkgRepository.hs b/src/Lib/PkgRepository.hs index fc4db82..e826228 100644 --- a/src/Lib/PkgRepository.hs +++ b/src/Lib/PkgRepository.hs @@ -37,7 +37,7 @@ import qualified Data.Text as T import Lib.Error ( S9Error(NotFoundE) ) import qualified Lib.External.AppMgr as AppMgr import Lib.Types.AppIndex ( PkgId(..) - , ServiceManifest(serviceManifestIcon) + , PackageManifest(packageManifestIcon) ) import Lib.Types.Emver ( Version , VersionRange @@ -163,7 +163,7 @@ extractPkg fp = handle @_ @SomeException cleanup $ do liftIO . throwIO $ ManifestParseException (pkgRoot "manifest.json") Right manifest -> do wait iconTask - let iconDest = "icon" <.> case serviceManifestIcon manifest of + let iconDest = "icon" <.> case packageManifestIcon manifest of Nothing -> "png" Just x -> case takeExtension (T.unpack x) of "" -> "png" diff --git a/src/Lib/Types/AppIndex.hs b/src/Lib/Types/AppIndex.hs index 7ffdd62..a12f296 100644 --- a/src/Lib/Types/AppIndex.hs +++ b/src/Lib/Types/AppIndex.hs @@ -8,6 +8,7 @@ module Lib.Types.AppIndex where import Startlude +-- NOTE: leave eitherDecode for inline test evaluation below import Control.Monad ( fail ) import Data.Aeson ( (.:) , (.:?) @@ -16,6 +17,7 @@ import Data.Aeson ( (.:) , ToJSON(..) , ToJSONKey(..) , withObject + , eitherDecode ) import qualified Data.ByteString.Lazy as BS import Data.Functor.Contravariant ( contramap ) @@ -76,43 +78,43 @@ data VersionInfo = VersionInfo deriving (Eq, Show) -- TODO rename to PackageDependencyInfo -data ServiceDependencyInfo = ServiceDependencyInfo - { serviceDependencyInfoOptional :: Maybe Text - , serviceDependencyInfoVersion :: VersionRange - , serviceDependencyInfoDescription :: Maybe Text - , serviceDependencyInfoCritical :: Bool +data PackageDependency = PackageDependency + { packageDependencyOptional :: Maybe Text + , packageDependencyVersion :: VersionRange + , packageDependencyDescription :: Maybe Text + , packageDependencyCritical :: Bool } deriving Show -instance FromJSON ServiceDependencyInfo where +instance FromJSON PackageDependency where parseJSON = withObject "service dependency info" $ \o -> do - serviceDependencyInfoOptional <- o .:? "optional" - serviceDependencyInfoVersion <- o .: "version" - serviceDependencyInfoDescription <- o .:? "description" - serviceDependencyInfoCritical <- o .: "critical" - pure ServiceDependencyInfo { .. } + packageDependencyOptional <- o .:? "optional" + packageDependencyVersion <- o .: "version" + packageDependencyDescription <- o .:? "description" + packageDependencyCritical <- o .: "critical" + pure PackageDependency { .. } data ServiceAlert = INSTALL | UNINSTALL | RESTORE | START | STOP deriving (Show, Eq, Generic, Hashable, Read) -data ServiceManifest = ServiceManifest - { serviceManifestId :: !PkgId - , serviceManifestTitle :: !Text - , serviceManifestVersion :: !Version - , serviceManifestDescriptionLong :: !Text - , serviceManifestDescriptionShort :: !Text - , serviceManifestReleaseNotes :: !Text - , serviceManifestIcon :: !(Maybe Text) - , serviceManifestAlerts :: !(HM.HashMap ServiceAlert (Maybe Text)) - , serviceManifestDependencies :: !(HM.HashMap PkgId ServiceDependencyInfo) +data PackageManifest = PackageManifest + { packageManifestId :: !PkgId + , packageManifestTitle :: !Text + , packageManifestVersion :: !Version + , packageManifestDescriptionLong :: !Text + , packageManifestDescriptionShort :: !Text + , packageManifestReleaseNotes :: !Text + , packageManifestIcon :: !(Maybe Text) + , packageManifestAlerts :: !(HM.HashMap ServiceAlert (Maybe Text)) + , packageManifestDependencies :: !(HM.HashMap PkgId PackageDependency) } deriving Show -instance FromJSON ServiceManifest where +instance FromJSON PackageManifest where parseJSON = withObject "service manifest" $ \o -> do - serviceManifestId <- o .: "id" - serviceManifestTitle <- o .: "title" - serviceManifestVersion <- o .: "version" - serviceManifestDescriptionLong <- o .: "description" >>= (.: "long") - serviceManifestDescriptionShort <- o .: "description" >>= (.: "short") - serviceManifestIcon <- o .: "assets" >>= (.: "icon") - serviceManifestReleaseNotes <- o .: "release-notes" + packageManifestId <- o .: "id" + packageManifestTitle <- o .: "title" + packageManifestVersion <- o .: "version" + packageManifestDescriptionLong <- o .: "description" >>= (.: "long") + packageManifestDescriptionShort <- o .: "description" >>= (.: "short") + packageManifestIcon <- o .: "assets" >>= (.: "icon") + packageManifestReleaseNotes <- o .: "release-notes" alerts <- o .: "alerts" a <- for (HM.toList alerts) $ \(key, value) -> do alertType <- case readMaybe $ T.toUpper key of @@ -120,12 +122,12 @@ instance FromJSON ServiceManifest where Just t -> pure t alertDesc <- parseJSON value pure (alertType, alertDesc) - let serviceManifestAlerts = HM.fromList a - serviceManifestDependencies <- o .: "dependencies" - pure ServiceManifest { .. } + let packageManifestAlerts = HM.fromList a + packageManifestDependencies <- o .: "dependencies" + pure PackageManifest { .. } --- >>> eitherDecode testManifest :: Either String ServiceManifest --- Right (ServiceManifest {serviceManifestId = embassy-pages, serviceManifestTitle = "Embassy Pages", serviceManifestVersion = 0.1.3, serviceManifestDescriptionLong = "Embassy Pages is a simple web server that uses directories inside File Browser to serve Tor websites.", serviceManifestDescriptionShort = "Create Tor websites, hosted on your Embassy.", serviceManifestReleaseNotes = "Upgrade to EmbassyOS v0.3.0", serviceManifestIcon = Just "icon.png", serviceManifestAlerts = fromList [(INSTALL,Nothing),(UNINSTALL,Nothing),(STOP,Nothing),(RESTORE,Nothing),(START,Nothing)], serviceManifestDependencies = fromList [(filebrowser,ServiceDependencyInfo {serviceDependencyInfoOptional = Nothing, serviceDependencyInfoVersion = >=2.14.1.1 <3.0.0, serviceDependencyInfoDescription = Just "Used to upload files to serve.", serviceDependencyInfoCritical = False})]}) +-- >>> eitherDecode testManifest :: Either String PackageManifest +-- Right (PackageManifest {packageManifestId = embassy-pages, packageManifestTitle = "Embassy Pages", packageManifestVersion = 0.1.3, packageManifestDescriptionLong = "Embassy Pages is a simple web server that uses directories inside File Browser to serve Tor websites.", packageManifestDescriptionShort = "Create Tor websites, hosted on your Embassy.", packageManifestReleaseNotes = "Upgrade to EmbassyOS v0.3.0", packageManifestIcon = Just "icon.png", packageManifestAlerts = fromList [(INSTALL,Nothing),(UNINSTALL,Nothing),(STOP,Nothing),(RESTORE,Nothing),(START,Nothing)], packageManifestDependencies = fromList [(filebrowser,PackageDependency {packageDependencyOptional = Nothing, packageDependencyVersion = >=2.14.1.1 <3.0.0, packageDependencyDescription = Just "Used to upload files to serve.", packageDependencyCritical = False})]}) testManifest :: BS.ByteString testManifest = [i|{ "id": "embassy-pages", diff --git a/test/Handler/AppSpec.hs b/test/Handler/AppSpec.hs index 1f7c4e5..b3431d6 100644 --- a/test/Handler/AppSpec.hs +++ b/test/Handler/AppSpec.hs @@ -17,6 +17,8 @@ import Seed import Lib.Types.AppIndex import Data.Aeson import Data.Either.Extra +import Handler.Marketplace ( PackageListRes ) + spec :: Spec spec = do describe "GET /package/index" $ withApp $ it "returns list of packages" $ do @@ -25,7 +27,7 @@ spec = do setMethod "GET" setUrl ("/package/index" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have two packages" (length res) 3 describe "GET /package/index?ids" $ withApp $ it "returns list of packages at specified version" $ do _ <- seedBitcoinLndStack @@ -33,11 +35,11 @@ spec = do setMethod "GET" setUrl ("/package/index?ids=[{\"id\":\"bitcoind\",\"version\":\"=0.21.1.2\"}]" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have one package" (length res) 1 let pkg = fromJust $ head res - let (manifest :: ServiceManifest) = fromRight' $ eitherDecode $ encode $ serviceResManifest pkg - assertEq "manifest id should be bitcoind" (serviceManifestId manifest) "bitcoind" + let (manifest :: PackageManifest) = fromRight' $ eitherDecode $ encode $ packageResManifest pkg + assertEq "manifest id should be bitcoind" (packageManifestId manifest) "bitcoind" describe "GET /package/index?ids" $ withApp $ it "returns list of packages and dependencies at specified version" @@ -47,43 +49,43 @@ spec = do setMethod "GET" setUrl ("/package/index?ids=[{\"id\":\"lnd\",\"version\":\"=0.13.3.1\"}]" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have one package" (length res) 1 let pkg = fromJust $ head res - assertEq "package dependency metadata should not be empty" (null $ serviceResDependencyInfo pkg) False + assertEq "package dependency metadata should not be empty" (null $ packageResDependencyInfo pkg) False describe "GET /package/index?ids" $ withApp $ it "returns list of packages at exactly specified version" $ do _ <- seedBitcoinLndStack request $ do setMethod "GET" setUrl ("/package/index?ids=[{\"id\":\"bitcoind\",\"version\":\"=0.21.1.1\"}]" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have one package" (length res) 1 let pkg = fromJust $ head res - let (manifest :: ServiceManifest) = fromRight' $ eitherDecode $ encode $ serviceResManifest pkg - assertEq "manifest version should be 0.21.1.1" (serviceManifestVersion manifest) "0.21.1.1" + let (manifest :: PackageManifest) = fromRight' $ eitherDecode $ encode $ packageResManifest pkg + assertEq "manifest version should be 0.21.1.1" (packageManifestVersion manifest) "0.21.1.1" describe "GET /package/index?ids" $ withApp $ it "returns list of packages at specified version or greater" $ do _ <- seedBitcoinLndStack request $ do setMethod "GET" setUrl ("/package/index?ids=[{\"id\":\"bitcoind\",\"version\":\">=0.21.1.1\"}]" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have one package" (length res) 1 let pkg = fromJust $ head res - let (manifest :: ServiceManifest) = fromRight' $ eitherDecode $ encode $ serviceResManifest pkg - assertEq "manifest version should be 0.21.1.2" (serviceManifestVersion manifest) "0.21.1.2" + let (manifest :: PackageManifest) = fromRight' $ eitherDecode $ encode $ packageResManifest pkg + assertEq "manifest version should be 0.21.1.2" (packageManifestVersion manifest) "0.21.1.2" describe "GET /package/index?ids" $ withApp $ it "returns list of packages at specified version or greater" $ do _ <- seedBitcoinLndStack request $ do setMethod "GET" setUrl ("/package/index?ids=[{\"id\":\"bitcoind\",\"version\":\">=0.21.1.2\"}]" :: Text) statusIs 200 - (res :: [ServiceRes]) <- requireJSONResponse + (res :: PackageListRes) <- requireJSONResponse assertEq "response should have one package" (length res) 1 let pkg = fromJust $ head res - let (manifest :: ServiceManifest) = fromRight' $ eitherDecode $ encode $ serviceResManifest pkg - assertEq "manifest version should be 0.21.1.2" (serviceManifestVersion manifest) "0.21.1.2" + let (manifest :: PackageManifest) = fromRight' $ eitherDecode $ encode $ packageResManifest pkg + assertEq "manifest version should be 0.21.1.2" (packageManifestVersion manifest) "0.21.1.2" describe "GET /package/:pkgId with unknown version spec for bitcoind" $ withApp $ it "fails to get unknown app" $ do _ <- seedBitcoinLndStack request $ do