packages feed

launchdarkly-server-sdk-redis-hedis-1.0.0: test/Spec/Upsert.hs

module Spec.Upsert (allTests) where

import Data.ByteString (isInfixOf)
import Data.ByteString.Char8 (pack)
import Data.Char (toLower)
import GHC.Natural (Natural)
import qualified LaunchDarkly.Server.Store as Store
import Test.HUnit
import Text.Printf
import Util (defaultPrefix, emptyData, makeDefaultRedisBackend)

createTestFlag :: Natural -> Bool -> Store.SerializedItemDescriptor
createTestFlag version deleted =
    Store.SerializedItemDescriptor
        { Store.item = Just $ pack $ printf "{\"deleted\":%s,\"version\":%d}" (map toLower $ show deleted) version
        , Store.version = version
        , Store.deleted = deleted
        }

testHandlesVersionsAppropriately :: Natural -> Natural -> Natural -> Test
testHandlesVersionsAppropriately initialVersion secondVersion expectedVersion = TestCase $ do
    backend <- makeDefaultRedisBackend defaultPrefix
    _ <- Store.persistentDataStoreInitialize backend emptyData
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag initialVersion False
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag secondVersion False
    flag <- Store.persistentDataStoreGetFeature backend "features" "first-flag"

    assertEqual "" (Right $ Just expectedFlag) flag
  where
    expectedFlag = (createTestFlag expectedVersion False) {Store.version = 0, Store.deleted = False}

testUpsertionAfterDeletionHandlesVersionsAppropriately :: Natural -> Natural -> Natural -> Bool -> Test
testUpsertionAfterDeletionHandlesVersionsAppropriately initialVersion secondVersion expectedVersion expectedDeletionStatus = TestCase $ do
    backend <- makeDefaultRedisBackend defaultPrefix
    _ <- Store.persistentDataStoreInitialize backend emptyData
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag initialVersion True
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag secondVersion False
    flag <- Store.persistentDataStoreGetFeature backend "features" "first-flag"

    case flag of
        Right (Just Store.SerializedItemDescriptor {Store.item = Just item, Store.version = 0, Store.deleted = False}) -> do
            assertBool "" (expectedVersionString `isInfixOf` item)
            assertBool "" (expectedDeletionString `isInfixOf` item)
        _ -> assertFailure "failed to restore deleted file"
  where
    expectedVersionString = pack $ printf "\"version\":%d" expectedVersion
    expectedDeletionString = pack $ printf "\"deleted\":%s" (map toLower $ show expectedDeletionStatus)

testUpsertionToADeletionHandlesVersionsAppropriately :: Natural -> Natural -> Natural -> Bool -> Test
testUpsertionToADeletionHandlesVersionsAppropriately initialVersion secondVersion expectedVersion expectedDeletionStatus = TestCase $ do
    backend <- makeDefaultRedisBackend defaultPrefix
    _ <- Store.persistentDataStoreInitialize backend emptyData
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag initialVersion False
    _ <- Store.persistentDataStoreUpsertFeature backend "features" "first-flag" $ createTestFlag secondVersion True
    flag <- Store.persistentDataStoreGetFeature backend "features" "first-flag"

    case flag of
        Right (Just Store.SerializedItemDescriptor {Store.item = Just item, Store.version = 0, Store.deleted = False}) -> do
            assertBool "" (expectedVersionString `isInfixOf` item)
            assertBool "" (expectedDeletionString `isInfixOf` item)
        _ -> assertFailure "failed to restore deleted file"
  where
    expectedVersionString = pack $ printf "\"version\":%d" expectedVersion
    expectedDeletionString = pack $ printf "\"deleted\":%s" (map toLower $ show expectedDeletionStatus)

allTests :: Test
allTests =
    TestList
        [ TestLabel "Newer versions replace older" $ testHandlesVersionsAppropriately 1 2 2
        , TestLabel "Older versions do not replace newer" $ testHandlesVersionsAppropriately 2 1 2
        , TestLabel "Newer versions replace older" $ testUpsertionAfterDeletionHandlesVersionsAppropriately 1 2 2 False
        , TestLabel "Older versions do not replace newer" $ testUpsertionAfterDeletionHandlesVersionsAppropriately 2 1 2 True
        , TestLabel "Newer versions replace older" $ testUpsertionToADeletionHandlesVersionsAppropriately 1 2 2 True
        , TestLabel "Older versions do not replace newer" $ testUpsertionToADeletionHandlesVersionsAppropriately 2 1 2 False
        ]