You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

backendTest.ts 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. import { Injector } from "../src/backend/Injector/Injector";
  2. import { FrontworkAdmin } from "../src/backend/Admin/Admin";
  3. import { T1 } from "../src/backend/Types/Items";
  4. import { RPCSocket } from "rpclibrary";
  5. import { FrontcraftIfc, Auth, User, FrontcraftFeatureIfc, Raid, Character, Rank, Class, Race, SRPriority, Spec, Signup } from "../src/backend/Types/Types";
  6. import { SpecT } from "../src/backend/Types/PlayerSpecs";
  7. type protoAccount<C extends Class = Class> = {
  8. name : string,
  9. rank : Rank,
  10. race: Race,
  11. class: C,
  12. spec: SpecT[C]
  13. }
  14. const trialsAndUp = {
  15. ADMIN: true,
  16. Guildmaster: true,
  17. Officer: true,
  18. Classleader: true,
  19. Raider: true,
  20. Trial: true,
  21. Social: false,
  22. Guest: false
  23. }
  24. const adminsOnly = {
  25. ADMIN: true,
  26. Guildmaster: true,
  27. Officer: true,
  28. Classleader: false,
  29. Raider: false,
  30. Trial: false,
  31. Social: false,
  32. Guest: false
  33. }
  34. const defaultPermissions = [
  35. { rpcname: 'signup', ...trialsAndUp
  36. },{ rpcname: 'reset', ...adminsOnly
  37. },{ rpcname: 'modifyPermissions', ...adminsOnly
  38. },{ rpcname: 'manageGuild', ...adminsOnly
  39. },{ rpcname: 'managePriorities', ...adminsOnly
  40. },{ rpcname: 'softreserveCurrency', ...adminsOnly
  41. },{ rpcname: 'manageRaid', ...adminsOnly
  42. }]
  43. const testAccounts : protoAccount[] = [
  44. {
  45. name: 'Rain',
  46. race: 'Human',
  47. class: 'Warrior',
  48. spec: 'Protection',
  49. rank: 'Guildmaster'
  50. },{
  51. name: 'Celinda',
  52. class: 'Warrior',
  53. race: 'Night Elf',
  54. spec: 'Protection',
  55. rank: 'Officer'
  56. },{
  57. name: 'Silver',
  58. class: 'Druid',
  59. race: 'Night Elf',
  60. spec: 'Restoration',
  61. rank: 'Raider'
  62. },{
  63. name: 'Dagger',
  64. race: 'Dwarf',
  65. class: 'Rogue',
  66. spec: 'Assassination',
  67. rank: 'Classleader'
  68. },{
  69. name: 'Hope',
  70. class: 'Paladin',
  71. race: 'Human',
  72. spec: 'Holy',
  73. rank: 'Classleader'
  74. },{
  75. name: 'Shrekd',
  76. class: 'Warrior',
  77. race: 'Dwarf',
  78. spec: 'Fury',
  79. rank: 'Classleader'
  80. },{
  81. name: 'Teeniweeni',
  82. class: 'Warlock',
  83. race: 'Gnome',
  84. spec: 'Demonology',
  85. rank: 'Classleader'
  86. },{
  87. name: 'Hagibaba',
  88. class: 'Priest',
  89. race: 'Human',
  90. spec: 'Discipline',
  91. rank: 'Classleader'
  92. },{
  93. name: 'Muffinbreak',
  94. class: 'Mage',
  95. race: 'Gnome',
  96. spec: 'Arcane',
  97. rank: 'Classleader'
  98. },
  99. ]
  100. describe('Frontcraft', () => {
  101. let auth: Auth,
  102. adminUser : User,
  103. server: FrontworkAdmin,
  104. client : RPCSocket & FrontcraftIfc,
  105. adminClient : RPCSocket & FrontcraftFeatureIfc,
  106. raids: Raid[] = [],
  107. users : {[username in string] : { account: User, character: Character, auth: Auth, signup?:Signup, item?:string }} = {}
  108. const createAccount = (user: User) => {
  109. return client.UserManager.createUser(user)
  110. }
  111. const createAccountAndUser = async (acc : protoAccount) => {
  112. const account = await createAccount({
  113. pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
  114. rank: acc.rank,
  115. username: acc.name,
  116. })
  117. const auth = await client.UserManager.login(acc.name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
  118. const id = await client.CharacterManager.getSpecId(acc.class, acc.spec)
  119. const char = await client.CharacterManager.createCharacter(auth.token.value, {
  120. charactername: acc.name,
  121. specid: id,
  122. userid: account.id!,
  123. race: acc.race
  124. })
  125. return {
  126. account: account,
  127. character: char,
  128. auth: auth
  129. }
  130. }
  131. before(function (done){
  132. this.timeout(10000);
  133. server = Injector.resolve<FrontworkAdmin>(FrontworkAdmin)
  134. server.start().then((_server) => {
  135. RPCSocket.makeSocket<FrontcraftIfc>(20000, 'localhost').then(_client => {
  136. client = _client
  137. createAccount({
  138. pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //hash("a")
  139. rank: 'ADMIN',
  140. username: 'a',
  141. MC: 2
  142. }).then(adminUser => {
  143. client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => {
  144. const sock = new RPCSocket(
  145. auth.port,
  146. "localhost"
  147. )
  148. sock.connect<any>(auth.token.value).then(cli => {
  149. adminClient = cli
  150. sock.hook('kick', () => {
  151. console.log("I got kicked");
  152. })
  153. sock.hook('getUserData', () => auth)
  154. sock.hook('navigate', (where:string) => {
  155. console.log("Nagivate client to "+where);
  156. })
  157. sock.on('error', (e) => {
  158. console.log('Socket error', e)
  159. })
  160. done()
  161. })
  162. })
  163. })
  164. })
  165. }).catch(done)
  166. })
  167. after(()=>{
  168. client.destroy()
  169. adminClient.destroy()
  170. server.stop()
  171. })
  172. it('create raids', (done) => {
  173. let insertRaid = <Raid>{
  174. description: "Test raid 1",
  175. title: 'MC',
  176. start: Date.now().toString(),
  177. tier: 'MC'
  178. }
  179. adminClient.manageRaid.createRaid(insertRaid).then(() => {
  180. client.RaidManager.getRaids().then((r)=>{
  181. if(r[0].title === insertRaid.title
  182. && r[0].description === insertRaid.description){
  183. raids.push(r[0])
  184. done()
  185. }
  186. }).catch(done)
  187. }).catch(done)
  188. })
  189. it('create users', (done)=>{
  190. Promise.all(testAccounts.map(acc => createAccountAndUser(acc))).then(accs => {
  191. if(accs.length === testAccounts.length){
  192. accs.forEach(acc => {
  193. users[acc.account.username] = acc
  194. })
  195. done()
  196. }
  197. }).catch(done)
  198. })
  199. it('should sign up', (done)=>{
  200. Promise.all(Object.values(users).map((user) =>
  201. adminClient.signup.sign(user.auth.token.value, user.character, raids[0], false).catch(done)
  202. )).then(x => {
  203. adminClient.signup.getSignups(raids[0]).then(s => {
  204. if(s.length == testAccounts.length){
  205. s.forEach(sign => {
  206. users[sign.username].signup = sign
  207. })
  208. done()
  209. }else{
  210. done("Unexpected number of signups: "+s.length)
  211. }
  212. })
  213. })
  214. })
  215. it('calculate priorities', (done)=>{
  216. const makePrio = async (itemname:string, spec?: Spec, race?:Race, mod:number = 0, description:string = "") => {
  217. let specid
  218. if(spec)
  219. specid = await client.CharacterManager.getSpecId(spec.class, <any>spec.specname)
  220. await adminClient.managePriorities.setPriority(itemname, {
  221. specid: specid,
  222. race: race,
  223. modifier: mod,
  224. description: description
  225. })
  226. }
  227. Promise.all([
  228. makePrio(
  229. 'Bracers of Arcane Accuracy',
  230. {class:'Warlock', specname:'Demonology'},
  231. undefined, 2, "hit bias"
  232. ),
  233. makePrio(
  234. 'Bracers of Arcane Accuracy',
  235. {class:'Warlock', specname:'Affliction'},
  236. undefined, 2, "hit bias"
  237. ),
  238. makePrio(
  239. 'Bracers of Arcane Accuracy',
  240. {class:'Warlock', specname:'Destruction'},
  241. undefined, 2, "hit bias"
  242. ),
  243. makePrio(
  244. 'Bracers of Arcane Accuracy',
  245. {class:'Mage', specname:'Arcane'},
  246. undefined, 1, "hit bias"
  247. ),
  248. makePrio(
  249. 'Bracers of Arcane Accuracy',
  250. {class:'Mage', specname:'Frost'},
  251. undefined, 1, "hit bias"
  252. ),
  253. makePrio(
  254. 'Bracers of Arcane Accuracy',
  255. {class:'Mage', specname:'Fire'},
  256. undefined, 1, "hit bias"
  257. ),
  258. makePrio(
  259. 'Maladath, Runed Blade of the Black Flight',
  260. undefined,
  261. "Human", -2, "(1) Non-Human"
  262. ),
  263. makePrio(
  264. 'Maladath, Runed Blade of the Black Flight',
  265. {class:'Rogue', specname:'Subtlety'},
  266. undefined, 2, "...Rogues (weapon skill bias)"
  267. ),
  268. makePrio(
  269. 'Maladath, Runed Blade of the Black Flight',
  270. {class:'Rogue', specname:'Combat'},
  271. undefined, 2, "...Rogues (weapon skill bias)"
  272. ),
  273. makePrio(
  274. 'Maladath, Runed Blade of the Black Flight',
  275. {class:'Rogue', specname:'Assassination'},
  276. undefined, 2, "...Rogues (weapon skill bias)"
  277. ),
  278. makePrio(
  279. 'Maladath, Runed Blade of the Black Flight',
  280. {class:'Warrior', specname:'Fury'},
  281. 'Human', 4, "+2 Fury Warrior (weapon skill bias), +2 to offset (1)"
  282. ),
  283. makePrio(
  284. 'Cloak of Firemaw',
  285. {class:'Rogue', specname:'Assassination'},
  286. undefined, 2, "agi-to-ap bias"
  287. ),
  288. makePrio(
  289. 'Cloak of Firemaw',
  290. {class:'Rogue', specname:'Combat'},
  291. undefined, 2, "agi-to-ap bias"
  292. ),
  293. makePrio(
  294. 'Cloak of Firemaw',
  295. {class:'Rogue', specname:'Subtlety'},
  296. undefined, 2, "agi-to-ap bias"
  297. ),
  298. makePrio(
  299. 'Band of Forced Concentration',
  300. {class:'Warlock', specname:'Demonology'},
  301. undefined, 2, "hit bias"
  302. ),
  303. makePrio(
  304. 'Band of Forced Concentration',
  305. {class:'Warlock', specname:'Affliction'},
  306. undefined, 2, "hit bias"
  307. ),
  308. makePrio(
  309. 'Band of Forced Concentration',
  310. {class:'Warlock', specname:'Destruction'},
  311. undefined, 2, "hit bias"
  312. ),
  313. makePrio(
  314. 'Band of Forced Concentration',
  315. {class:'Mage', specname:'Arcane'},
  316. undefined, 1, "hit bias"
  317. ),
  318. makePrio(
  319. 'Band of Forced Concentration',
  320. {class:'Mage', specname:'Frost'},
  321. undefined, 1, "hit bias"
  322. ),
  323. makePrio(
  324. 'Band of Forced Concentration',
  325. {class:'Mage', specname:'Fire'},
  326. undefined, 1, "hit bias"
  327. ),
  328. makePrio(
  329. 'Drake Fang Talisman',
  330. {class:'Rogue', specname:'Assassination'},
  331. undefined, 4, "hit bias"
  332. ),
  333. makePrio(
  334. 'Drake Fang Talisman',
  335. {class:'Rogue', specname:'Combat'},
  336. undefined, 4, "hit bias"
  337. ),
  338. makePrio(
  339. 'Drake Fang Talisman',
  340. {class:'Rogue', specname:'Subtlety'},
  341. undefined, 4, "hit bias"
  342. ),
  343. makePrio(
  344. 'Drake Fang Talisman',
  345. {class:'Warrior', specname:'Fury'},
  346. undefined, 2, "hit bias"
  347. ),
  348. makePrio(
  349. 'Drake Fang Talisman',
  350. {class:'Druid', specname:'Feral (DPS)'},
  351. undefined, 2, "hit bias"
  352. ),
  353. makePrio(
  354. 'Circle of Applied Force',
  355. {class:'Warrior', specname:'Fury'},
  356. undefined, 2, "str-to-ap bias"
  357. ),
  358. makePrio(
  359. 'Circle of Applied Force',
  360. {class:'Druid', specname:'Feral (DPS)'},
  361. undefined, 2, "str-to-ap bias"
  362. ),
  363. makePrio(
  364. 'Empowered Leggings',
  365. {class:'Paladin', specname:'Holy'},
  366. undefined, 2, "crit bias"
  367. ),
  368. makePrio(
  369. 'Empowered Leggings',
  370. {class:'Druid', specname:'Restoration'},
  371. undefined, 2, "crit bias"
  372. ),
  373. makePrio(
  374. 'Boots of the Shadow Flame',
  375. {class:'Rogue', specname:'Assassination'},
  376. undefined, 2, "hit bias"
  377. ),
  378. makePrio(
  379. 'Boots of the Shadow Flame',
  380. {class:'Rogue', specname:'Combat'},
  381. undefined, 2, "hit bias"
  382. ),
  383. makePrio(
  384. 'Boots of the Shadow Flame',
  385. {class:'Rogue', specname:'Subtlety'},
  386. undefined, 2, "hit bias"
  387. ),
  388. makePrio(
  389. 'Boots of the Shadow Flame',
  390. {class:'Druid', specname:'Feral (DPS)'},
  391. undefined, 2, "hit bias"
  392. ),
  393. makePrio(
  394. 'Neltharion\'s Tear',
  395. {class:'Warlock', specname:'Demonology'},
  396. undefined, 4, "hit bias"
  397. ),
  398. makePrio(
  399. 'Neltharion\'s Tear',
  400. {class:'Warlock', specname:'Affliction'},
  401. undefined, 4, "hit bias"
  402. ),
  403. makePrio(
  404. 'Neltharion\'s Tear',
  405. {class:'Warlock', specname:'Destruction'},
  406. undefined, 4, "hit bias"
  407. ),
  408. makePrio(
  409. 'Neltharion\'s Tear',
  410. {class:'Mage', specname:'Arcane'},
  411. undefined, 2, "hit bias"
  412. ),
  413. makePrio(
  414. 'Neltharion\'s Tear',
  415. {class:'Mage', specname:'Frost'},
  416. undefined, 2, "hit bias"
  417. ),
  418. makePrio(
  419. 'Neltharion\'s Tear',
  420. {class:'Mage', specname:'Fire'},
  421. undefined, 2, "hit bias"
  422. ),
  423. makePrio(
  424. 'Cloak of Draconic Might',
  425. {class:'Warrior', specname:'Fury'},
  426. undefined, 2, "str-to-ap bias"
  427. ),
  428. makePrio(
  429. 'Cloak of Draconic Might',
  430. {class:'Druid', specname:'Feral (DPS)'},
  431. undefined, 2, "str-to-ap bias"
  432. ),
  433. ])
  434. const user = Object.values(users)[0]
  435. adminClient.managePriorities.setPriority(T1[0], {
  436. race: user.character.race,
  437. specid: user.character.specid,
  438. modifier: 1,
  439. description:'AAA'
  440. }).then(() => {
  441. adminClient.managePriorities.setPriority(T1[0], {
  442. race: user.character.race,
  443. specid: undefined,
  444. modifier: 2,
  445. description:'BBB'
  446. }).then(()=>{
  447. adminClient.managePriorities.setPriority(T1[0], {
  448. race: undefined,
  449. specid: user.character.specid,
  450. modifier: 3,
  451. description:'CCC'
  452. }).then(()=>{
  453. client.ItemManager.calculatePriorities(T1[0], user.character).then(sum => {
  454. if(sum === 6)
  455. done()
  456. })
  457. })
  458. })
  459. })
  460. })
  461. it('buy token', (done)=>{
  462. Promise.all(Object.values(users).map(async (user) =>{
  463. const itemname = T1[0]//T1[Math.floor(T1.length*Math.random())]
  464. const modifier = await client.ItemManager.calculatePriorities(itemname, user.character)
  465. const token = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!)
  466. users[user.account.username].item = itemname
  467. if(!token) return false
  468. return modifier+1 === token.level
  469. })).then(success => {
  470. if(success.reduce((prev, curr)=>prev&&curr, true)) done()
  471. })
  472. })
  473. it('not buy token without currency', (done)=>{
  474. const user = Object.values(users)[0]
  475. const itemname = T1[0]
  476. client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!).then(token => {
  477. if(!token)
  478. done()
  479. else {
  480. console.log("Unexpected token", token);
  481. }
  482. })
  483. })
  484. it('upgrade token', (done)=>{
  485. const user = Object.values(users)[0]
  486. const itemname = T1[0]
  487. adminClient.softreserveCurrency.incrementCurrency(user.account, raids[0].tier, 2).then(async ()=>{
  488. const item = await client.ItemManager.getItem(itemname)
  489. const before = await client.ItemManager.getToken(user.character, item)
  490. if(!before || before.level !== 7) {
  491. console.log("expected level to be 7", before);
  492. return
  493. }
  494. await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!)
  495. const after = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!)
  496. if(!after || after.level !== 9) {
  497. console.log("expected level to be 9", after);
  498. return
  499. }
  500. done()
  501. })
  502. })
  503. it('should buy more tokens', (done) => {
  504. Promise.all(Object.values(users).map(async (user) => {
  505. await adminClient.softreserveCurrency.incrementCurrency(user.account,raids[0].tier, 1)
  506. return await client.ItemManager
  507. .buyToken(
  508. user.auth.token.value,
  509. user.character.charactername,
  510. T1[Math.floor(T1.length*Math.random())],
  511. user.signup!
  512. )
  513. })).then(_ => {
  514. done()
  515. })
  516. })
  517. it('can set permissions', (done) => {
  518. Promise.all(
  519. defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
  520. ).then(_ => {
  521. done()
  522. })
  523. })
  524. it('start raid', (done) => {
  525. client.RaidManager.getRaids().then((r)=>{
  526. adminClient.manageRaid.startRaid(raids[0]).then(async data => {
  527. const dbRaids = await client.RaidManager.getRaids()
  528. if(dbRaids.length === 0){
  529. await client.UserManager.getUser(testAccounts[0].name).then(dbUser => {
  530. if(dbUser && dbUser.MC === 1){
  531. adminClient.signup.getSignups(raids[0]).then(signups => {
  532. if(signups.length === 0){
  533. done()
  534. }else{
  535. console.log(signups);
  536. }
  537. })
  538. }
  539. else{
  540. console.log("Bad user currency", dbUser);
  541. }
  542. })
  543. }
  544. })
  545. })
  546. })
  547. it('reset system', (done) => {
  548. adminClient.reset.wipeCurrencyAndItems().then(() => {
  549. client.UserManager.getUser(testAccounts[0].name).then(user => {
  550. if(user && user.MC === 1){
  551. client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character, ['MC']).then(tokens => {
  552. if(tokens!.length === 0){
  553. done()
  554. }else{
  555. console.log(tokens);
  556. }
  557. })
  558. }else{
  559. console.log(user)
  560. }
  561. })
  562. })
  563. })
  564. })