simple.spec.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. import expect from 'expect';
  2. import { loadContractAndCallConstructor } from './setup';
  3. import crypto from 'crypto';
  4. import { BN } from '@coral-xyz/anchor';
  5. describe('Simple solang tests', function () {
  6. this.timeout(500000);
  7. it('flipper', async function () {
  8. let { program, storage } = await loadContractAndCallConstructor('flipper', [true]);
  9. // make sure we can't run the constructor twice
  10. await expect(program.methods.new(false)
  11. .accounts({ dataAccount: storage.publicKey })
  12. .rpc()).rejects.toThrow();
  13. let res = await program.methods.get().accounts({ dataAccount: storage.publicKey }).view();
  14. expect(res).toStrictEqual(true);
  15. await program.methods.flip().accounts({ dataAccount: storage.publicKey }).rpc();
  16. res = await program.methods.get().accounts({ dataAccount: storage.publicKey }).view();
  17. expect(res).toStrictEqual(false);
  18. });
  19. it('primitives', async function () {
  20. let { program, payer, storage } = await loadContractAndCallConstructor('primitives', []);
  21. // TEST Basic enums
  22. // in ethereum, an enum is described as an uint8 so can't use the enum
  23. // names programmatically. 0 = add, 1 = sub, 2 = mul, 3 = div, 4 = mod, 5 = pow, 6 = shl, 7 = shr
  24. let res = await program.methods.isMul({ mul: {} }).accounts({ dataAccount: storage.publicKey }).view();
  25. expect(res).toBe(true);
  26. res = await program.methods.returnDiv().accounts({ dataAccount: storage.publicKey }).view();
  27. expect(res.div).toBeDefined();
  28. // TEST uint and int types, and arithmetic/bitwise ops
  29. res = await program.methods.opI64({ add: {} }, new BN(1000), new BN(4100)).view();
  30. expect(Number(res)).toBe(5100);
  31. res = await program.methods.opI64({ sub: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  32. expect(Number(res)).toStrictEqual(-3100);
  33. res = await program.methods.opI64({ mul: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  34. expect(Number(res)).toBe(4100000);
  35. res = await program.methods.opI64({ div: {} }, new BN(1000), new BN(10)).accounts({ dataAccount: storage.publicKey }).view();
  36. expect(Number(res)).toBe(100);
  37. res = await program.methods.opI64({ mod: {} }, new BN(1000), new BN(99)).accounts({ dataAccount: storage.publicKey }).view();
  38. expect(Number(res)).toBe(10);
  39. res = await program.methods.opI64({ shl: {} }, new BN(-1000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  40. expect(Number(res)).toBe(-256000);
  41. res = await program.methods.opI64({ shr: {} }, new BN(-1000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  42. expect(Number(res)).toBe(-4);
  43. res = await program.methods.opU64({ add: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  44. expect(Number(res)).toBe(5100);
  45. res = await program.methods.opU64({ sub: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  46. expect(Number(res)).toBe(18446744073709548516); // (2^64)-18446744073709548516 = 3100
  47. res = await program.methods.opU64({ mul: {} }, new BN(123456789), new BN(123456789)).accounts({ dataAccount: storage.publicKey }).view();
  48. expect(Number(res)).toBe(15241578750190521);
  49. res = await program.methods.opU64({ div: {} }, new BN(123456789), new BN(100)).accounts({ dataAccount: storage.publicKey }).view();
  50. expect(Number(res)).toBe(1234567);
  51. res = await program.methods.opU64({ mod: {} }, new BN(123456789), new BN(100)).accounts({ dataAccount: storage.publicKey }).view();
  52. expect(Number(res)).toBe(89);
  53. res = await program.methods.opU64({ pow: {} }, new BN(3), new BN(7)).accounts({ dataAccount: storage.publicKey }).view();
  54. expect(Number(res)).toBe(2187);
  55. res = await program.methods.opI64({ shl: {} }, new BN(1000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  56. expect(Number(res)).toBe(256000);
  57. res = await program.methods.opI64({ shr: {} }, new BN(1000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  58. expect(Number(res)).toBe(3);
  59. // now for 256 bit operations
  60. res = await program.methods.opI256({ add: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  61. expect(Number(res)).toBe(5100);
  62. res = await program.methods.opI256({ sub: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  63. expect(res).toStrictEqual(new BN(-3100));
  64. res = await program.methods.opI256({ mul: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  65. expect(Number(res)).toBe(4100000);
  66. res = await program.methods.opI256({ div: {} }, new BN(1000), new BN(10)).accounts({ dataAccount: storage.publicKey }).view();
  67. expect(Number(res)).toBe(100);
  68. res = await program.methods.opI256({ mod: {} }, new BN(1000), new BN(99)).accounts({ dataAccount: storage.publicKey }).view();
  69. expect(Number(res)).toBe(10);
  70. res = await program.methods.opI256({ shl: {} }, new BN(-10000000000000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  71. expect(Number(res)).toBe(-2560000000000000);
  72. res = await program.methods.opI256({ shr: {} }, new BN(-10000000000000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  73. expect(Number(res)).toBe(-39062500000);
  74. res = await program.methods.opU256({ add: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  75. expect(Number(res)).toBe(5100);
  76. res = await program.methods.opU256({ sub: {} }, new BN(1000), new BN(4100)).accounts({ dataAccount: storage.publicKey }).view();
  77. expect(Number(res)).toBe(115792089237316195423570985008687907853269984665640564039457584007913129636836); // (2^64)-18446744073709548516 = 3100
  78. res = await program.methods.opU256({ mul: {} }, new BN(123456789), new BN(123456789)).accounts({ dataAccount: storage.publicKey }).view();
  79. expect(Number(res)).toBe(15241578750190521);
  80. res = await program.methods.opU256({ div: {} }, new BN(123456789), new BN(100)).accounts({ dataAccount: storage.publicKey }).view();
  81. expect(Number(res)).toBe(1234567);
  82. res = await program.methods.opU256({ mod: {} }, new BN(123456789), new BN(100)).accounts({ dataAccount: storage.publicKey }).view();
  83. expect(Number(res)).toBe(89);
  84. res = await program.methods.opU256({ pow: {} }, new BN(123456789), new BN(9)).accounts({ dataAccount: storage.publicKey }).view();
  85. expect(Number(res)).toBe(6662462759719942007440037531362779472290810125440036903063319585255179509);
  86. res = await program.methods.opU256({ shl: {} }, new BN(10000000000000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  87. expect(Number(res)).toBe(2560000000000000);
  88. res = await program.methods.opU256({ shr: {} }, new BN(10000000000000), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  89. expect(Number(res)).toBe(39062500000);
  90. // TEST bytesN
  91. res = await program.methods.returnU86().accounts({ dataAccount: storage.publicKey }).view();
  92. expect(res).toStrictEqual([0x41, 0x42, 0x43, 0x44, 0x45, 0x46]);
  93. // TEST bytes5
  94. res = await program.methods.opU85Shift({ shl: {} },
  95. Buffer.from("deadcafe59", "hex"), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  96. expect(res).toStrictEqual([0xad, 0xca, 0xfe, 0x59, 0x00]);
  97. res = await program.methods.opU85Shift({ shr: {} }, Buffer.from("deadcafe59", "hex"), new BN(8)).accounts({ dataAccount: storage.publicKey }).view();
  98. expect(res).toStrictEqual([0x00, 0xde, 0xad, 0xca, 0xfe]);
  99. res = await program.methods.opU85({ or: {} },
  100. Buffer.from("deadcafe59", "hex"),
  101. Buffer.from("0000000006", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  102. expect(res).toStrictEqual([0xde, 0xad, 0xca, 0xfe, 0x5f]);
  103. res = await program.methods.opU85({ and: {} },
  104. Buffer.from("deadcafe59", "hex"),
  105. Buffer.from("00000000ff", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  106. expect(res).toStrictEqual([0x00, 0x00, 0x00, 0x00, 0x59]);
  107. res = await program.methods.opU85({ xor: {} },
  108. Buffer.from("deadcafe59", "hex"),
  109. Buffer.from("00000000ff", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  110. expect(res).toStrictEqual([0xde, 0xad, 0xca, 0xfe, 0xa6]);
  111. // TEST bytes14
  112. res = await program.methods.opU814Shift({ shl: {} },
  113. Buffer.from("deadcafe123456789abcdefbeef7", "hex"), new BN(9))
  114. .accounts({ dataAccount: storage.publicKey }).view();
  115. expect(res).toStrictEqual([0x5b, 0x95, 0xfc, 0x24, 0x68, 0xac, 0xf1, 0x35, 0x79, 0xbd, 0xf7, 0xdd, 0xee, 0x00]);
  116. res = await program.methods.opU814Shift({ shr: {} },
  117. Buffer.from("deadcafe123456789abcdefbeef7", "hex"), new BN(9)).accounts({ dataAccount: storage.publicKey }).view();
  118. expect(res).toStrictEqual([0x00, 0x6f, 0x56, 0xe5, 0x7f, 0x09, 0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x7d, 0xf7]);
  119. res = await program.methods.opU814({ or: {} },
  120. Buffer.from("deadcafe123456789abcdefbeef7", "hex"),
  121. Buffer.from("0000060000000000000000000000", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  122. expect(res).toStrictEqual([0xde, 0xad, 0xce, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xfb, 0xee, 0xf7]);
  123. res = await program.methods.opU814({ and: {} },
  124. Buffer.from("deadcafe123456789abcdefbeef7", "hex"),
  125. Buffer.from("000000000000000000ff00000000", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  126. expect(res).toStrictEqual(
  127. [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00]);
  128. res = await program.methods.opU814({ xor: {} },
  129. Buffer.from("deadcafe123456789abcdefbeef7", "hex"),
  130. Buffer.from("ff00000000000000000000000000", "hex")).accounts({ dataAccount: storage.publicKey }).view();
  131. expect(res).toStrictEqual(
  132. [0x21, 0xad, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xfb, 0xee, 0xf7]);
  133. res = await program.methods.addressPassthrough(payer.publicKey).view();
  134. expect(res).toStrictEqual(payer.publicKey);
  135. });
  136. it('store', async function () {
  137. const { storage, program } = await loadContractAndCallConstructor('store', []);
  138. let res = await program.methods.getValues1().accounts({ dataAccount: storage.publicKey }).view();
  139. expect(Number(res.return0)).toEqual(0);
  140. expect(Number(res.return1)).toEqual(0);
  141. expect(Number(res.return2)).toEqual(0);
  142. expect(Number(res.return3)).toEqual(0);
  143. res = await program.methods.getValues2().accounts({ dataAccount: storage.publicKey }).view();
  144. expect(Number(res.return0)).toEqual(0);
  145. expect(res.return1).toEqual("");
  146. expect(res.return2).toEqual(Buffer.from("b00b1e", "hex"));
  147. expect(res.return3).toEqual([0, 0, 0, 0]);
  148. expect(Number(res.return4.bar1)).toBeDefined();
  149. await program.methods.setValues().accounts({ dataAccount: storage.publicKey }).rpc();
  150. res = await program.methods.getValues1().accounts({ dataAccount: storage.publicKey }).view();
  151. expect(BigInt(res.return0)).toEqual(18446744073709551615n);
  152. expect(Number(res.return1)).toEqual(0xdad0feef);
  153. expect(Number(res.return2)).toEqual(0x7ffe);
  154. expect(BigInt(res.return3)).toEqual(57896044618658097711785492504343953926634992332820282019728792003956564819967n);
  155. res = await program.methods.getValues2().accounts({ dataAccount: storage.publicKey }).view();
  156. expect(Number(res.return0)).toEqual(102);
  157. expect(res.return1).toEqual("the course of true love never did run smooth");
  158. expect(res.return2).toEqual(Buffer.from("b00b1e", "hex"));
  159. expect(res.return3).toEqual([0x41, 0x42, 0x43, 0x44]);
  160. expect(Number(res.return4.bar2)).toBeDefined();
  161. await program.methods.doOps().accounts({ dataAccount: storage.publicKey }).rpc();
  162. res = await program.methods.getValues1().accounts({ dataAccount: storage.publicKey }).view();
  163. expect(BigInt(res.return0)).toEqual(1n);
  164. expect(Number(res.return1)).toEqual(65263);
  165. expect(Number(res.return2)).toEqual(32767);
  166. expect(BigInt(res.return3)).toEqual(57896044618658097711785492504343953926634992332820282019728792003956564819966n);
  167. res = await program.methods.getValues2().accounts({ dataAccount: storage.publicKey }).view();
  168. expect(Number(res.return0)).toEqual(61200);
  169. expect(res.return1).toEqual("");
  170. expect(res.return2).toEqual(Buffer.from("b0ff1e", "hex"));
  171. expect(res.return3).toEqual([0x61, 0x62, 0x63, 0x64]);
  172. expect(Number(res.return4.bar3)).toBeDefined();
  173. await program.methods.pushZero().accounts({ dataAccount: storage.publicKey }).rpc();
  174. let bs = "0xb0ff1e00";
  175. for (let i = 0; i < 20; i++) {
  176. res = await program.methods.getBs().accounts({ dataAccount: storage.publicKey }).view();
  177. expect(res).toStrictEqual(Buffer.from(bs.substring(2), "hex"));
  178. if (bs.length <= 4 || Math.random() >= 0.5) {
  179. let val = ((Math.random() * 256) | 0);
  180. await program.methods.push([val]).accounts({ dataAccount: storage.publicKey }).rpc();
  181. let valStr = val.toString(16);
  182. valStr = valStr.length == 1 ? "0" + valStr : valStr;
  183. bs += valStr;
  184. } else {
  185. await program.methods.pop().accounts({ dataAccount: storage.publicKey }).rpc();
  186. let last = bs.slice(-2);
  187. // TODO: rpc calls cannot return anything; this should be fixed in Anchor, so that
  188. // this line can be uncommented.
  189. //expect(res).toStrictEqual(Buffer.from(last, "hex"));
  190. bs = bs.slice(0, -2);
  191. }
  192. }
  193. });
  194. it('structs', async function () {
  195. const { program, storage } = await loadContractAndCallConstructor('store', []);
  196. await program.methods.setFoo1().accounts({ dataAccount: storage.publicKey }).rpc();
  197. // get foo1
  198. let res = await program.methods.getBothFoos().accounts({ dataAccount: storage.publicKey }).view();
  199. expect(res.return0.f1.bar2).toBeDefined();
  200. expect(res.return0.f2).toEqual(Buffer.from("Don't count your chickens before they hatch", "utf-8"));
  201. expect(res.return0.f3).toEqual(new BN(-102));
  202. expect(res.return0.f4).toEqual([0xed, 0xae, 0xda]);
  203. expect(res.return0.f5).toEqual("You can't have your cake and eat it too");
  204. expect(res.return0.f6.in1).toEqual(true);
  205. expect(res.return0.f6.in2).toEqual("There are other fish in the sea");
  206. expect(res.return1.f1.bar1).toBeDefined();
  207. expect(res.return1.f2).toEqual(Buffer.from([]));
  208. expect(res.return1.f3).toEqual(new BN(0));
  209. expect(res.return1.f4).toEqual([0, 0, 0]);
  210. expect(res.return1.f5).toEqual("");
  211. expect(res.return1.f6.in1).toEqual(false);
  212. expect(res.return1.f6.in2).toEqual("");
  213. await program.methods.setFoo2(
  214. {
  215. f1: { bar2: {} },
  216. f2: Buffer.from("b52b073595ccb35eaebb87178227b779", "hex"),
  217. f3: new BN(-123112321),
  218. f4: [0x12, 0x34, 0x56],
  219. f5: "Barking up the wrong tree",
  220. f6: { in1: true, in2: "Drive someone up the wall" }
  221. },
  222. "nah"
  223. ).accounts({ dataAccount: storage.publicKey }).rpc();
  224. res = await program.methods.getBothFoos().accounts({ dataAccount: storage.publicKey }).view();
  225. expect(res.return0.f1.bar2).toBeDefined();
  226. expect(res.return0.f2).toEqual(Buffer.from("Don't count your chickens before they hatch", "utf-8"));
  227. expect(res.return0.f3).toEqual(new BN(-102));
  228. expect(res.return0.f4).toEqual([0xed, 0xae, 0xda]);
  229. expect(res.return0.f5).toEqual("You can't have your cake and eat it too");
  230. expect(res.return0.f6.in1).toEqual(true);
  231. expect(res.return0.f6.in2).toEqual("There are other fish in the sea");
  232. expect(res.return1.f1.bar2).toBeDefined();
  233. expect(res.return1.f2).toEqual(Buffer.from("b52b073595ccb35eaebb87178227b779", "hex"));
  234. expect(res.return1.f3).toEqual(new BN(-123112321));
  235. expect(res.return1.f4).toEqual([0x12, 0x34, 0x56]);
  236. expect(res.return1.f5).toEqual("Barking up the wrong tree");
  237. expect(res.return1.f6.in1).toEqual(true);
  238. expect(res.return1.f6.in2).toEqual("nah");
  239. await program.methods.deleteFoo(true).accounts({ dataAccount: storage.publicKey }).rpc();
  240. res = await program.methods.getFoo(false).accounts({ dataAccount: storage.publicKey }).view();
  241. expect(res.f1.bar2).toBeDefined();
  242. expect(res.f2).toEqual(Buffer.from("b52b073595ccb35eaebb87178227b779", "hex"));
  243. expect(res.f3).toEqual(new BN(-123112321));
  244. expect(res.f4).toEqual([0x12, 0x34, 0x56]);
  245. expect(res.f5).toEqual("Barking up the wrong tree");
  246. expect(res.f6.in1).toEqual(true);
  247. expect(res.f6.in2).toEqual("nah");
  248. res = await program.methods.getFoo(true).accounts({ dataAccount: storage.publicKey }).view();
  249. expect(res.f1.bar1).toBeDefined();
  250. expect(res.f2).toEqual(Buffer.from([]));
  251. expect(res.f3).toEqual(new BN(0));
  252. expect(res.f4).toEqual([0, 0, 0]);
  253. expect(res.f5).toEqual("");
  254. expect(res.f6.in1).toEqual(false);
  255. expect(res.f6.in2).toEqual("");
  256. await program.methods.deleteFoo(false).accounts({ dataAccount: storage.publicKey }).rpc();
  257. res = await program.methods.getBothFoos().accounts({ dataAccount: storage.publicKey }).view();
  258. expect(res.return0.f1.bar1).toBeDefined();
  259. expect(res.return0.f2).toEqual(Buffer.from([]));
  260. expect(res.return0.f3).toEqual(new BN(0));
  261. expect(res.return0.f4).toEqual([0, 0, 0]);
  262. expect(res.return0.f5).toEqual("");
  263. expect(res.return0.f6.in1).toEqual(false);
  264. expect(res.return0.f6.in2).toEqual("");
  265. expect(res.return1.f1.bar1).toBeDefined();
  266. expect(res.return1.f2).toEqual(Buffer.from([]));
  267. expect(res.return1.f3).toEqual(new BN(0));
  268. expect(res.return1.f4).toEqual([0, 0, 0]);
  269. expect(res.return1.f5).toEqual("");
  270. expect(res.return1.f6.in1).toEqual(false);
  271. expect(res.return1.f6.in2).toEqual("");
  272. await program.methods.structLiteral().accounts({ dataAccount: storage.publicKey }).rpc();
  273. res = await program.methods.getFoo(true).accounts({ dataAccount: storage.publicKey }).view();
  274. expect(res.f1.bar4).toBeDefined();
  275. expect(res.f2).toEqual(Buffer.from("537570657263616c6966726167696c697374696365787069616c69646f63696f7573", "hex"));
  276. expect(res.f3).toEqual(new BN(64927));
  277. expect(res.f4).toEqual([0xe2, 0x82, 0xac]);
  278. expect(res.f5).toEqual("Antidisestablishmentarianism");
  279. expect(res.f6.in1).toEqual(true);
  280. expect(res.f6.in2).toEqual("Pseudopseudohypoparathyroidism");
  281. });
  282. it('account storage too small constructor', async function () {
  283. await expect(loadContractAndCallConstructor('store', [], 100))
  284. .rejects
  285. .toThrowError(new Error('failed to send transaction: Transaction simulation failed: Error processing Instruction 0: account data too small for instruction'));
  286. });
  287. it('account storage too small dynamic alloc', async function () {
  288. const { program, storage } = await loadContractAndCallConstructor('store', [], 233);
  289. // storage.sol needs 168 bytes on constructor, more for string data
  290. // set a load of string which will overflow
  291. await expect(program.methods.setFoo1().accounts({ dataAccount: storage.publicKey }).rpc())
  292. .rejects
  293. .toThrowError(new Error('failed to send transaction: Transaction simulation failed: Error processing Instruction 0: account data too small for instruction'));
  294. });
  295. it('account storage too small dynamic realloc', async function () {
  296. const { program, storage } = await loadContractAndCallConstructor('store', [], 233);
  297. async function push_until_bang() {
  298. for (let i = 0; i < 100; i++) {
  299. await program.methods.push(new Uint8Array([1])).accounts({ dataAccount: storage.publicKey }).rpc();
  300. }
  301. }
  302. // do realloc until failure
  303. await expect(push_until_bang())
  304. .rejects
  305. .toThrowError(new Error('failed to send transaction: Transaction simulation failed: Error processing Instruction 0: account data too small for instruction'));
  306. });
  307. it('arrays in account storage', async function () {
  308. const { program, storage } = await loadContractAndCallConstructor('arrays', []);
  309. let users = [];
  310. for (let i = 0; i < 3; i++) {
  311. let addr = [...crypto.randomBytes(32)];
  312. let name = `name${i}`;
  313. let id = new BN(crypto.randomBytes(4).readUInt32BE(0));
  314. let perms = [];
  315. for (let j = 0; j < Math.random() * 3; j++) {
  316. let p = Math.floor(Math.random() * 8);
  317. let perm = { [`perm${p + 1}`]: {} };
  318. perms.push(perm);
  319. }
  320. await program.methods.addUser(id, addr, name, perms)
  321. .accounts({ dataAccount: storage.publicKey })
  322. .rpc();
  323. users.push([
  324. name, addr, id, perms
  325. ]);
  326. }
  327. let user = users[Math.floor(Math.random() * users.length)];
  328. let res = await program.methods.getUserById(user[2]).accounts({ dataAccount: storage.publicKey }).view();
  329. expect(res.name).toEqual(user[0]);
  330. expect(res.addr).toEqual(user[1]);
  331. expect(res.id.cmp(user[2])).toBe(0);
  332. expect(res.perms).toEqual(user[3]);
  333. // @ts-ignore
  334. const perms: string[] = user[3];
  335. if (perms.length > 0) {
  336. let p = perms[Math.floor(Math.random() * perms.length)];
  337. res = await program.methods.hasPermission(user[2], p).accounts({ dataAccount: storage.publicKey }).view();
  338. expect(res).toStrictEqual(true);
  339. }
  340. user = users[Math.floor(Math.random() * users.length)];
  341. res = await program.methods.getUserByAddress(user[1]).accounts({ dataAccount: storage.publicKey }).view();
  342. expect(res.name).toEqual(user[0]);
  343. expect(res.addr).toEqual(user[1]);
  344. expect(res.id.cmp(user[2])).toBe(0);
  345. expect(res.perms).toEqual(user[3]);
  346. await program.methods.removeUser(user[2]).accounts({ dataAccount: storage.publicKey }).rpc();
  347. res = await program.methods.userExists(user[2]).accounts({ dataAccount: storage.publicKey }).view();
  348. expect(res).toStrictEqual(false);
  349. });
  350. });