-
Notifications
You must be signed in to change notification settings - Fork 0
/
BehaviorGraph.ts
187 lines (153 loc) · 6.46 KB
/
BehaviorGraph.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import { time, loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import '@nomicfoundation/hardhat-chai-matchers';
import { anyValue } from '@nomicfoundation/hardhat-chai-matchers/withArgs';
import { expect } from 'chai';
import '@nomiclabs/hardhat-ethers';
import { BehaviorGraph__factory } from '../typechain-types';
import { ethers } from 'hardhat';
import { BigNumber, Signer } from 'ethers';
import { BehaviorGraph, NodeStruct, TokenGateRuleStruct } from '../typechain-types/contracts/BehaviorGraph';
import { Token } from '../typechain-types/contracts/Token';
import { token } from '../typechain-types/@openzeppelin/contracts';
describe('BehaviorGraph', function () {
// We define a fixture to reuse the same setup in every test.
// We use loadFixture to run this setup once, snapshot that state,
// and reset Hardhat Network to that snapshot in every test.
async function deployFixture() {
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount, anotherAccount] = await ethers.getSigners();
const BehaviorGraph = (await ethers.getContractFactory('BehaviorGraph')) as BehaviorGraph__factory;
const behaviorGraph = await BehaviorGraph.deploy();
return { behaviorGraph, owner, otherAccount, anotherAccount };
}
describe('safeMint', () => {
it('does not raise an erroor if the caller is not the owner', async () => {
const { behaviorGraph, otherAccount } = await loadFixture(deployFixture);
const ipfsHash = 'asdfasdfasfda';
const nodesToCreate: NodeStruct[] = [];
await expect(behaviorGraph.connect(otherAccount).safeMint(ipfsHash, nodesToCreate)).to.not.be.rejected;
});
it('creates a token with the list of node onto the list of nodes', async () => {
const { behaviorGraph, otherAccount } = await loadFixture(deployFixture);
const ipfsHash = 'asdfasdfasfda';
const nodesToCreate: NodeStruct[] = [
{
nodeType: 0,
id: '0',
tokenGateRule: {
active: false,
tokenContract: otherAccount.address,
},
},
{
nodeType: 1,
id: '5',
tokenGateRule: {
active: true,
tokenContract: behaviorGraph.address,
},
},
];
const tx = await behaviorGraph.safeMint(ipfsHash, nodesToCreate);
await tx.wait();
const tokenId = 0;
const node = await behaviorGraph.getNode(tokenId, '5');
expect(node.nodeType).to.eql(nodesToCreate[1].nodeType);
});
});
describe('executeAction', () => {
let nodesToCreate: NodeStruct[] = [];
let contract: BehaviorGraph;
let otherTokenContract: Token;
let otherAccount: Signer;
beforeEach(async () => {
const { behaviorGraph, otherAccount: _otherAccount } = await deployFixture();
const TokenContract = await ethers.getContractFactory('Token');
const tokenContract = (await TokenContract.deploy()) as Token;
contract = behaviorGraph;
otherTokenContract = tokenContract;
otherAccount = _otherAccount;
});
describe('when the action is not token gated', () => {
it('can successfully execute that action and emits an event with the count', async () => {
const actionId = '5';
const nodesToCreate = [
{
nodeType: 0,
id: actionId,
tokenGateRule: {
active: false,
tokenContract: contract.address,
},
},
];
const ipfsHash = 'asdfasfda';
const tx = await contract.safeMint(ipfsHash, nodesToCreate);
await tx.wait();
const tokenId = 0;
const executerAddress = otherAccount;
const actionCount = 1;
await expect(contract.connect(executerAddress).executeAction(tokenId, actionId))
.to.emit(contract, 'ActionExecuted')
.withArgs(await executerAddress.getAddress(), tokenId, actionId, actionCount);
await expect(contract.connect(executerAddress).executeAction(tokenId, actionId))
.to.emit(contract, 'ActionExecuted')
.withArgs(await executerAddress.getAddress(), tokenId, actionId, actionCount + 1);
});
});
describe('when the action is token gated', () => {
beforeEach(async () => {
const nodesToCreate = [
{
nodeType: 0,
id: '10',
tokenGateRule: {
active: false,
tokenContract: contract.address,
},
},
{
nodeType: 0,
id: '1',
// this rule requires you to have a token from another contract
tokenGateRule: {
active: true,
tokenContract: otherTokenContract.address,
},
},
];
// mint 2 tokens
await contract.safeMint('0asdfasfd', []);
const tx = await contract.safeMint('asdfasdfasfd', nodesToCreate);
await tx.wait();
});
describe('when the user does not have a token of that acollection', () => {
it('cannot successfully execute that action', async () => {
// user does not have a token of that other account, so this fails.
const tokenId = 1;
const actionId = '1';
await expect(contract.connect(otherAccount).executeAction(tokenId, actionId)).to.be.reverted;
});
});
describe('when the user has a token of that collection', () => {
it('can successfully execute that action and emits the result', async () => {
const executerAccount = otherAccount;
const executerAccountAddress = await executerAccount.getAddress();
const tokenId = 1;
const actionId = '1';
const actionCount = 1;
// mint a token on the other contract the balance should be good now
const tx = await otherTokenContract.connect(executerAccount).safeMint('asdfasdfafs');
await tx.wait();
// verify that we have a token in the other contract
const balance = await otherTokenContract.balanceOf(executerAccountAddress);
expect(balance).to.eql(BigNumber.from(1));
// successfully call eecute the other action
await expect(contract.connect(otherAccount).executeAction(tokenId, actionId))
.to.emit(contract, 'ActionExecuted')
.withArgs(await executerAccountAddress, tokenId, actionId, actionCount); // We accept any value as `when` arg
});
});
});
});
});