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

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