During testing my Graph Project I receive the following error:
nft-lottery
Player entity
(assert.fieldEquals) Expected field 'lotteries' to equal '[0x1]', but was '[]' instead.
Mapping aborted at ~lib/matchstick-as/assembly/assert.ts, line 13, column 7, with message: Assertion Error
wasm backtrace:
0: 0x387c - <unknown>!~lib/matchstick-as/assembly/assert/assert.fieldEquals
1: 0x38fa - <unknown>!start:tests/nft-lottery.test~anonymous|0~anonymous|3
If I log the results after calling handleNftLotteryEnter()
function I get (i.e., the lottery.id has not been stored even though it should have as it is derivedFrom the NftLottery - see below):
"Player": {
"0xdb...a7bf": {
"lotteries": {
"type": "List",
"data": []
}
}
},
...
If I try to mock firing three subsequent events, the first two players has got values stored but the last one has not, i.e.:
"Player": {
"0x5a...3ca1": {
"lotteries": {
"type": "List",
"data": [
{
"type": "String",
"data": "0x1"
}
]
}
},
"0xd1...6575": {
"lotteries": {
"type": "List",
"data": []
}
},
"0xdb...a7bf": {
"lotteries": {
"type": "List",
"data": [
{
"type": "String",
"data": "0x1"
}
]
}
}
},
What could be the reason thereof? Thank you in advance!
Test file
import {
assert,
describe,
test,
clearStore,
beforeAll,
afterAll,
logStore,
} from "matchstick-as/assembly/index"
import { BigInt, Address } from "@graphprotocol/graph-ts"
import { handleNftLotteryEnter } from "../src/nft-lottery"
import { createNftLotteryEnterEvent } from "./nft-lottery-utils"
describe("Enter the NFT Lottery 1x", () => {
beforeAll(() => {
let lotteryCounter = BigInt.fromI32(1)
let player_one = Address.fromString("0xDB...a7bf")
let entranceFee = BigInt.fromI32(1)
let newNftLotteryEnterEvent = createNftLotteryEnterEvent(
lotteryCounter,
player_one,
entranceFee
)
handleNftLotteryEnter(newNftLotteryEnterEvent)
logStore()
})
afterAll(() => {
clearStore()
})
test("Player entity", () => {
assert.fieldEquals("Player", "0xdb...a7bf", "lotteries", "[0x1]")
})
})
describe("Enter the NFT Lottery 3x", () => {
beforeAll(() => {
let lotteryCounter = BigInt.fromI32(1)
let entranceFee = BigInt.fromI32(1)
let player_one = Address.fromString("0xDB...a7bf")
let player_two = Address.fromString("0x5a...3cA1")
let player_three = Address.fromString("0xd1...6575")
// the first event
let oneNftLotteryEnterEvent = createNftLotteryEnterEvent(
lotteryCounter,
player_one,
entranceFee
)
handleNftLotteryEnter(oneNftLotteryEnterEvent)
// the second event
let twoNftLotteryEnterEvent = createNftLotteryEnterEvent(
lotteryCounter,
player_two,
entranceFee
)
// the third event
handleNftLotteryEnter(twoNftLotteryEnterEvent)
let threeNftLotteryEnterEvent = createNftLotteryEnterEvent(
lotteryCounter,
player_three,
entranceFee
)
handleNftLotteryEnter(threeNftLotteryEnterEvent)
logStore()
})
afterAll(() => {
clearStore()
})
test("Counts", () => {
assert.entityCount("NftLottery", 1)
assert.entityCount("Player", 3)
})
test("Player Entity 3x", () => {
assert.fieldEquals("Player", "0xdb...a7bf", "lotteries", "[0x1]")
})
})
Schema.graphql
type NftLottery @entity {
id: ID!
openAtTimestamp: BigInt!
closeAtTimestamp: BigInt!
prize: BigInt!
players: [Player!]!
winners: [Player!]
requestId: BigInt
updatedAtTimestamp: BigInt
}
type Player @entity {
id: ID! # address
lotteries: [NftLottery!]! @derivedFrom(field: "players")
}
# events
type NftLotteryEnter @entity {
id: ID! # Set lotteryCounter + playerAddress
lotteryCounter: BigInt!
player: Bytes!
numberOfEntrances: [BigInt!]!
updatedAtTimestamp: BigInt
}
Handlers
import { BigInt, Address } from "@graphprotocol/graph-ts"
import {
NftLotteryEnter as NftLotteryEnterEvent
} from "../generated/NftLottery/NftLottery"
import { NftLottery, Player, NftLotteryEnter } from "../generated/schema"
export function handleNftLotteryEnter(event: NftLotteryEnterEvent): void {
/* Event params */
const playerId = event.params.player.toHexString()
const lotteryId = event.params.lotteryCounter.toHexString()
const entranceFee = event.params.entranceFee.toString()
const lotteryPlayerId = lotteryId + playerId
/* NftLottery: if a lottery does not exist, create it */
let nftLottery = NftLottery.load(lotteryId)
if (!nftLottery) {
nftLottery = new NftLottery(lotteryId)
nftLottery.openAtTimestamp = event.block.timestamp
nftLottery.closeAtTimestamp = BigInt.fromString("000000000000")
nftLottery.requestId = BigInt.fromString("0")
nftLottery.prize = BigInt.fromString("0")
nftLottery.players = new Array<string>()
nftLottery.winners = new Array<string>()
}
// update lottery data
let currentPrize = nftLottery.prize
nftLottery.prize = currentPrize.plus(BigInt.fromString(entranceFee))
// update players
let arrPlayers = nftLottery.players
arrPlayers.push(playerId)
nftLottery.players = arrPlayers
nftLottery.updatedAtTimestamp = event.block.timestamp
nftLottery.save()
/* Player: if a player does not exist, create them */
let player = Player.load(playerId)
if (!player) {
player = new Player(playerId)
player.save()
}
/* NftLotteryEnter */
let nftLotteryEnter = NftLotteryEnter.load((lotteryPlayerId))
if (!nftLotteryEnter) {
nftLotteryEnter = new NftLotteryEnter(lotteryPlayerId)
nftLotteryEnter.lotteryCounter = BigInt.fromString(event.params.lotteryCounter.toString())
nftLotteryEnter.player = Address.fromHexString(playerId)
nftLotteryEnter.numberOfEntrances = BigInt.fromString("0")
}
// update entrances
const entrances = nftLotteryEnter.numberOfEntrances
nftLotteryEnter.numberOfEntrances = entrances.plus(BigInt.fromString("1"))
nftLotteryEnter.save()
}