Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
volodyaeleks committed Jun 14, 2021
1 parent 2addf56 commit 5d56a5f
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 29 deletions.
27 changes: 16 additions & 11 deletions eleks/nft/src/Contracts/NFT/OffChain.hs
Expand Up @@ -87,28 +87,26 @@ data CreateParams = CreateParams

-- | Parameters for the @sell@-endpoint, which creates a new NFT.
data SellParams = SellParams
{ spTokenSymbol :: String
, spSellPrice :: Integer
{ spTokenSymbol :: String -- ^ Token symbol to sell
, spSellPrice :: Integer -- ^ Sell price
} deriving (Show, Generic, ToJSON, FromJSON, ToSchema)

-- | Parameters for the @cancel-sell@-endpoint, which creates a new NFT.
data CancelSellParams = CancelSellParams
{ cspTokenSymbol :: String
{ cspTokenSymbol :: String -- ^ Token symbol to cancell sell
} deriving (Show, Generic, ToJSON, FromJSON, ToSchema)

-- | Parameters for the @buy@-endpoint, which creates a new NFT.
data BuyParams = BuyParams
{ bpTokenSymbol :: String
{ bpTokenSymbol :: String -- ^ Token symbol to buy
} deriving (Show, Generic, ToJSON, FromJSON, ToSchema)

-- | Parameters for the @transfer@-endpoint, which creates a new NFT.
data TransferParams = TransferParams
{ tpTokenSymbol :: String
, tpReceiverWallet :: Integer
{ tpTokenSymbol :: String -- ^ Token symbol to buy
, tpReceiverWallet :: Integer -- ^ Wallet id to receive payment
} deriving (Show, Generic, ToJSON, FromJSON, ToSchema)



nftMetadataToDto:: NFTMetadata -> NFTMetadataDto
nftMetadataToDto nftMeta = NFTMetadataDto
{ nftDtoTokenName = read.show $ nftTokenName nftMeta
Expand Down Expand Up @@ -217,6 +215,7 @@ sell market SellParams{..} = do
pkh <- pubKeyHash <$> ownPubKey
let tokenSymbol = CurrencySymbol $ dtoStrToByteStr spTokenSymbol
(_, (oref, o, nftMetadata)) <- findMarketFactoryAndNftMeta market tokenSymbol
when (spSellPrice <= 0) $ throwError "sell price should be greater than zero"
let marketInst = marketInstance market
nftMetadata' = nftMetadata { nftSeller = Just pkh, nftSellPrice = spSellPrice }
nftMetadataDatum = NFTMeta nftMetadata'
Expand Down Expand Up @@ -282,7 +281,7 @@ buy market BuyParams{..} = do
let tokenSymbol = CurrencySymbol $ dtoStrToByteStr bpTokenSymbol
(_, (oref, o, nftMetadata)) <- findMarketFactoryAndNftMeta market tokenSymbol
when (PlutusTx.Prelude.isNothing $ nftSeller nftMetadata) $
throwError $ pack $ printf "NFT is not on sale"
throwError $ pack $ printf "NFT token is not on sale"
let marketInst = marketInstance market
nftMetadata' = nftMetadata { nftSeller = Nothing, nftSellPrice = 0 }
nftSeller' = fromMaybe "" $ nftSeller nftMetadata
Expand Down Expand Up @@ -447,7 +446,7 @@ userNftTokens market = do
result = map nftMetadataToDto $ ownUserTokens <> sellingUserTokens
return result

-- | Gets the caller's NFTs.
-- | Gets the selling NFT's
sellingTokens ::
HasBlockchainActions s
=> NFTMarket
Expand All @@ -458,7 +457,6 @@ sellingTokens market = do
let result = map nftMetadataToDto $ filter (PlutusTx.Prelude.isJust . nftSeller) nftMetas
return result


ownerEndpoint ::
(TokenName
-> PubKeyHash
Expand Down Expand Up @@ -507,6 +505,13 @@ data MarketContractState =
-- | Provides the following endpoints for users of a NFT marketplace instance:
--
-- [@create@]: Creates an nft token.
-- [@sell@]: Put token on sale
-- [@cancelSell@]: Cancel token selling.
-- [@buy@]: Buy token on sale.
-- [@transfer@]: Transfer NFT token to other wallet.
-- [@userNftTokens@]: Get all NFT tokens of the current wallet.
-- [@sellingTokens@]: Get all selling NFT tokens.
-- [@userPubKeyHash@]: Get user pubkeyhash.
userEndpoints ::
(TokenName
-> PubKeyHash
Expand Down
4 changes: 1 addition & 3 deletions eleks/nft/src/Contracts/NFT/OnChain.hs
Expand Up @@ -138,7 +138,7 @@ validateCancelSell NFTMarket{..} nftMeta@NFTMetadata{nftMetaTokenSymbol, nftMeta
traceIfFalse "nft metadata token missing from input" (valueOf inVal nftMetaTokenSymbol nftMetaTokenName == 1) &&
traceIfFalse "nft token missing from input" (valueOf inVal nftTokenSymbol nftTokenName == 1) &&
traceIfFalse "ouptut nftMetadata should be same" (nftMeta == outDatum) &&
traceIfFalse "price should be grater 0" (nftSellPrice outDatum == 0) &&
traceIfFalse "price should be emptied" (nftSellPrice outDatum == 0) &&
traceIfFalse "seller should be emptied" (PlutusTx.Prelude.isNothing $ nftSeller outDatum)
where
info :: TxInfo
Expand Down Expand Up @@ -177,8 +177,6 @@ validateBuy ::
-> ScriptContext
-> Bool
validateBuy NFTMarket{..} nftMeta@NFTMetadata{nftMetaTokenSymbol, nftMetaTokenName, nftTokenSymbol, nftTokenName} buyer ctx =

traceIfFalse "price should be greater 0" True &&
traceIfFalse "nft metadata token missing from input" (valueOf inVal nftMetaTokenSymbol nftMetaTokenName == 1) &&
traceIfFalse "ouptut nftMetadata should be same" (nftMeta == outDatum) &&
traceIfFalse "expected seller to get money" (getsValue (nftSeller nftMeta) $ Ada.lovelaceValueOf (nftSellPrice nftMeta)) &&
Expand Down
84 changes: 69 additions & 15 deletions eleks/nft/src/test/Spec/NFT.hs
Expand Up @@ -80,7 +80,7 @@ tests = testGroup "nft"
-- )
-- createDuplicateNftTokenFailureTrace
-- ,
checkPredicate "Should sell NFT token"
checkPredicate "Should start sell NFT token"
(
assertNoFailedTransactions
.&&. valueAtAddress (marketAddress nftMarketMock)
Expand All @@ -92,7 +92,7 @@ tests = testGroup "nft"
.&&. assertAccumState userContract t1
(\case Last (Just (Right (NFTMarket.Selling meta))) ->
meta == (nftMetadataToDto $ nftTestMeta
{nftSellPrice = 1000, nftSeller = Just $ pubKeyHash $ walletPubKey w1 });
{nftSellPrice = nftMaketSellPrice, nftSeller = Just $ pubKeyHash $ walletPubKey w1 });
_ -> False)
"should create sell NFT state"
)
Expand All @@ -109,6 +109,17 @@ tests = testGroup "nft"
)
sellNonMarketNFTFailureTrace
,
checkPredicate "Should fail start selling if price less than 0"
(
assertNoFailedTransactions
.&&. assertAccumState userContract t1
(\case Last (Just (Left errText)) ->
errText Prelude.== pack "sell price should be greater than zero";
_ -> False)
"should have failed state"
)
sellFailureOnLessThanZeroPriceTrace
,
checkPredicate "Should cancel NFT token selling"
(
assertNoFailedTransactions
Expand All @@ -132,21 +143,38 @@ tests = testGroup "nft"
(\case Last (Just (Left errText)) ->
errText Prelude.== pack "NFT token is not on sale";
_ -> False)
"should have failed state "
"should have failed state"
)
cancelSellFailureIfNotSale
cancelSellFailureIfNotSaleTrace
,
-- checkPredicate "Should fail cancel sell if not token owner"
-- (
-- assertFailedTransaction (\_ err _ -> case err of {ScriptFailure (EvaluationError ["owner should sign"]) -> True; _ -> False })
-- )
-- cancelSellFailureIfNotOwnerTrace
-- ,
checkPredicate "Should buy NFT token"
(
assertNoFailedTransactions
.&&. valueAtAddress (marketAddress nftMarketMock) (== (assetClassValue nftTestTokenMetadata 1 <> assetClassValue (marketId nftMarketMock) 1))
.&&. walletFundsChange w1 (Ada.lovelaceValueOf 1000)
  .&&. walletFundsChange w2 (Ada.lovelaceValueOf (-1000) <> assetClassValue nftTestToken 1)
.&&. walletFundsChange w1 (Ada.lovelaceValueOf nftMaketSellPrice)
  .&&. walletFundsChange w2 (Ada.lovelaceValueOf (negate nftMaketSellPrice) <> assetClassValue nftTestToken 1)
.&&. assertAccumState userContract t2
(\case Last (Just (Right (NFTMarket.Buyed meta))) -> meta == nftTestTokenMeta; _ -> False)
"should create buy NFT state"
)
buyNftTokenFlowTrace
,
checkPredicate "Should not buy NFT token if not on sale"
(
assertNoFailedTransactions
.&&. assertAccumState userContract t2
(\case Last (Just (Left errText)) ->
errText Prelude.== pack "NFT token is not on sale";
_ -> False)
"should have failed state"
)
buyNftNotOnSaleFailureFlowTrace
]

initialise :: EmulatorTrace ()
Expand Down Expand Up @@ -175,7 +203,7 @@ sellNftTokenFlowTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
sellNftTokenTrace user1Hdl nftTokenMeta
sellNftTokenTrace user1Hdl nftTokenMeta nftMaketSellPrice

sellNonMarketNFTFailureTrace :: EmulatorTrace ()
sellNonMarketNFTFailureTrace = do
Expand All @@ -186,30 +214,55 @@ sellNonMarketNFTFailureTrace = do
-- https://github.com/input-output-hk/plutus/issues/3359
_ <- Trace.payToWallet w2 w1 $ Value.singleton (currencySymbol nonNftCur) nftNonMarketTokenName 1
user1Hdl <- Trace.activateContractWallet w1 userContract
sellNftTokenTrace user1Hdl nonMarketNftMeta
sellNftTokenTrace user1Hdl nonMarketNftMeta nftMaketSellPrice

sellFailureOnLessThanZeroPriceTrace :: EmulatorTrace ()
sellFailureOnLessThanZeroPriceTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
forgeCurrencyHdl <- Trace.activateContractWallet w1 NFTCurrency.forgeNftToken
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
sellNftTokenTrace user1Hdl nftTokenMeta 0

cancelSellNftTokenFlowTrace :: EmulatorTrace ()
cancelSellNftTokenFlowTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
sellNftTokenTrace user1Hdl nftTokenMeta
sellNftTokenTrace user1Hdl nftTokenMeta nftMaketSellPrice
cancelSellNftTokenTrace user1Hdl nftTokenMeta

cancelSellFailureIfNotSale :: EmulatorTrace ()
cancelSellFailureIfNotSale= do
cancelSellFailureIfNotSaleTrace :: EmulatorTrace ()
cancelSellFailureIfNotSaleTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
cancelSellNftTokenTrace user1Hdl nftTokenMeta

cancelSellFailureIfNotOwnerTrace :: EmulatorTrace ()
cancelSellFailureIfNotOwnerTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
user2Hdl <- Trace.activateContractWallet w2 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
sellNftTokenTrace user1Hdl nftTokenMeta nftMaketSellPrice
cancelSellNftTokenTrace user2Hdl nftTokenMeta

buyNftTokenFlowTrace :: EmulatorTrace ()
buyNftTokenFlowTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
user2Hdl <- Trace.activateContractWallet w2 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
sellNftTokenTrace user1Hdl nftTokenMeta
sellNftTokenTrace user1Hdl nftTokenMeta nftMaketSellPrice
buyNftTokenTrace user2Hdl nftTokenMeta

buyNftNotOnSaleFailureFlowTrace :: EmulatorTrace ()
buyNftNotOnSaleFailureFlowTrace = do
initialise
user1Hdl <- Trace.activateContractWallet w1 userContract
user2Hdl <- Trace.activateContractWallet w2 userContract
nftTokenMeta <- createNftTokenTrace user1Hdl nftTestTokenName
buyNftTokenTrace user2Hdl nftTokenMeta

forgeMockNftToken::
Expand Down Expand Up @@ -252,10 +305,11 @@ createNonMarketNftTokenTrace hdl tokenName = do

sellNftTokenTrace ::
Trace.ContractHandle (Last(Either Text MarketContractState)) MarketUserSchema Void
-> NFTMetadataDto
-> NFTMetadataDto
-> Integer
-> EmulatorTrace ()
sellNftTokenTrace hdl nftTokenMeta = do
let nftTokenSellParams = NFTMarket.SellParams { spTokenSymbol = nftDtoTokenSymbol nftTokenMeta, spSellPrice = 1000}
sellNftTokenTrace hdl nftTokenMeta sellPrice = do
let nftTokenSellParams = NFTMarket.SellParams { spTokenSymbol = nftDtoTokenSymbol nftTokenMeta, spSellPrice = sellPrice}
Trace.callEndpoint @"sell" hdl nftTokenSellParams
void $ Trace.waitNSlots 5

Expand Down
3 changes: 3 additions & 0 deletions eleks/nft/src/test/Spec/Types.hs
Expand Up @@ -53,6 +53,9 @@ getNFTTokenSymbol tokenName = NFTCurrency.currencySymbol $ TestNFTCurrency token
createNFTTokenMock:: TokenName -> AssetClass
createNFTTokenMock tokenName = AssetClass (getNFTTokenSymbol tokenName, tokenName)

nftMaketSellPrice:: Integer
nftMaketSellPrice = 1000

createNftMeta:: TokenName -> CurrencySymbol -> NFTMetadata
createNftMeta tokenName currency = NFTMetadata
{ nftTokenName = tokenName
Expand Down

0 comments on commit 5d56a5f

Please sign in to comment.