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 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  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 } 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: 'Teenieweenie',
  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, 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. done()
  199. else{
  200. done("Unexpected number of signups: "+s.length)
  201. }
  202. })
  203. })
  204. })
  205. it('calculate priorities', (done)=>{
  206. const makePrio = async (itemname:string, spec?: Spec, race?:Race, mod:number = 0, description:string = "") => {
  207. let specid
  208. if(spec)
  209. specid = await client.CharacterManager.getSpecId(spec.class, <any>spec.specname)
  210. await adminClient.managePriorities.setPriority(itemname, {
  211. specid: specid,
  212. race: race,
  213. modifier: mod,
  214. description: description
  215. })
  216. }
  217. Promise.all([
  218. makePrio(
  219. 'Bracers of Arcane Accuracy',
  220. {class:'Warlock', specname:'Demonology'},
  221. undefined, 2, "hit bias"
  222. ),
  223. makePrio(
  224. 'Bracers of Arcane Accuracy',
  225. {class:'Warlock', specname:'Affliction'},
  226. undefined, 2, "hit bias"
  227. ),
  228. makePrio(
  229. 'Bracers of Arcane Accuracy',
  230. {class:'Warlock', specname:'Destruction'},
  231. undefined, 2, "hit bias"
  232. ),
  233. makePrio(
  234. 'Bracers of Arcane Accuracy',
  235. {class:'Mage', specname:'Arcane'},
  236. undefined, 1, "hit bias"
  237. ),
  238. makePrio(
  239. 'Bracers of Arcane Accuracy',
  240. {class:'Mage', specname:'Frost'},
  241. undefined, 1, "hit bias"
  242. ),
  243. makePrio(
  244. 'Bracers of Arcane Accuracy',
  245. {class:'Mage', specname:'Fire'},
  246. undefined, 1, "hit bias"
  247. ),
  248. makePrio(
  249. 'Maladath, Runed Blade of the Black Flight',
  250. {class:'Warrior', specname:'Fury'},
  251. 'Human', 2, "weapon skill bias"
  252. ),
  253. makePrio(
  254. 'Cloak of Firemaw',
  255. {class:'Rogue', specname:'Assassination'},
  256. undefined, 2, "agi-to-ap bias"
  257. ),
  258. makePrio(
  259. 'Cloak of Firemaw',
  260. {class:'Rogue', specname:'Combat'},
  261. undefined, 2, "agi-to-ap bias"
  262. ),
  263. makePrio(
  264. 'Cloak of Firemaw',
  265. {class:'Rogue', specname:'Subtlety'},
  266. undefined, 2, "agi-to-ap bias"
  267. ),
  268. makePrio(
  269. 'Band of Forced Concentration',
  270. {class:'Warlock', specname:'Demonology'},
  271. undefined, 2, "hit bias"
  272. ),
  273. makePrio(
  274. 'Band of Forced Concentration',
  275. {class:'Warlock', specname:'Affliction'},
  276. undefined, 2, "hit bias"
  277. ),
  278. makePrio(
  279. 'Band of Forced Concentration',
  280. {class:'Warlock', specname:'Destruction'},
  281. undefined, 2, "hit bias"
  282. ),
  283. makePrio(
  284. 'Band of Forced Concentration',
  285. {class:'Mage', specname:'Arcane'},
  286. undefined, 1, "hit bias"
  287. ),
  288. makePrio(
  289. 'Band of Forced Concentration',
  290. {class:'Mage', specname:'Frost'},
  291. undefined, 1, "hit bias"
  292. ),
  293. makePrio(
  294. 'Band of Forced Concentration',
  295. {class:'Mage', specname:'Fire'},
  296. undefined, 1, "hit bias"
  297. ),
  298. makePrio(
  299. 'Drake Fang Talisman',
  300. {class:'Rogue', specname:'Assassination'},
  301. undefined, 4, "hit bias"
  302. ),
  303. makePrio(
  304. 'Drake Fang Talisman',
  305. {class:'Rogue', specname:'Combat'},
  306. undefined, 4, "hit bias"
  307. ),
  308. makePrio(
  309. 'Drake Fang Talisman',
  310. {class:'Rogue', specname:'Subtlety'},
  311. undefined, 4, "hit bias"
  312. ),
  313. makePrio(
  314. 'Drake Fang Talisman',
  315. {class:'Warrior', specname:'Fury'},
  316. undefined, 2, "hit bias"
  317. ),
  318. makePrio(
  319. 'Drake Fang Talisman',
  320. {class:'Druid', specname:'Feral (DPS)'},
  321. undefined, 2, "hit bias"
  322. ),
  323. makePrio(
  324. 'Circle of Applied Force',
  325. {class:'Warrior', specname:'Fury'},
  326. undefined, 2, "str-to-ap bias"
  327. ),
  328. makePrio(
  329. 'Circle of Applied Force',
  330. {class:'Druid', specname:'Feral (DPS)'},
  331. undefined, 2, "str-to-ap bias"
  332. ),
  333. makePrio(
  334. 'Empowered Leggings',
  335. {class:'Paladin', specname:'Holy'},
  336. undefined, 2, "crit bias"
  337. ),
  338. makePrio(
  339. 'Boots of the Shadow Flame',
  340. {class:'Rogue', specname:'Assassination'},
  341. undefined, 2, "hit bias"
  342. ),
  343. makePrio(
  344. 'Boots of the Shadow Flame',
  345. {class:'Rogue', specname:'Combat'},
  346. undefined, 2, "hit bias"
  347. ),
  348. makePrio(
  349. 'Boots of the Shadow Flame',
  350. {class:'Rogue', specname:'Subtlety'},
  351. undefined, 2, "hit bias"
  352. ),
  353. makePrio(
  354. 'Boots of the Shadow Flame',
  355. {class:'Druid', specname:'Feral (DPS)'},
  356. undefined, 2, "hit bias"
  357. ),
  358. makePrio(
  359. 'Neltharion\'s Tear',
  360. {class:'Warlock', specname:'Demonology'},
  361. undefined, 4, "hit bias"
  362. ),
  363. makePrio(
  364. 'Neltharion\'s Tear',
  365. {class:'Warlock', specname:'Affliction'},
  366. undefined, 4, "hit bias"
  367. ),
  368. makePrio(
  369. 'Neltharion\'s Tear',
  370. {class:'Warlock', specname:'Destruction'},
  371. undefined, 4, "hit bias"
  372. ),
  373. makePrio(
  374. 'Neltharion\'s Tear',
  375. {class:'Mage', specname:'Arcane'},
  376. undefined, 2, "hit bias"
  377. ),
  378. makePrio(
  379. 'Neltharion\'s Tear',
  380. {class:'Mage', specname:'Frost'},
  381. undefined, 2, "hit bias"
  382. ),
  383. makePrio(
  384. 'Neltharion\'s Tear',
  385. {class:'Mage', specname:'Fire'},
  386. undefined, 2, "hit bias"
  387. ),
  388. makePrio(
  389. 'Cloak of Draconic Might',
  390. {class:'Warrior', specname:'Fury'},
  391. undefined, 2, "str-to-ap bias"
  392. ),
  393. makePrio(
  394. 'Cloak of Draconic Might',
  395. {class:'Druid', specname:'Feral (DPS)'},
  396. undefined, 2, "str-to-ap bias"
  397. ),
  398. ])
  399. const user = Object.values(users)[0]
  400. adminClient.managePriorities.setPriority(T1[0], {
  401. race: user.character.race,
  402. specid: user.character.specid,
  403. modifier: 1,
  404. description:'AAA'
  405. }).then(() => {
  406. adminClient.managePriorities.setPriority(T1[0], {
  407. race: user.character.race,
  408. specid: undefined,
  409. modifier: 2,
  410. description:'BBB'
  411. }).then(()=>{
  412. adminClient.managePriorities.setPriority(T1[0], {
  413. race: undefined,
  414. specid: user.character.specid,
  415. modifier: 3,
  416. description:'CCC'
  417. }).then(()=>{
  418. client.ItemManager.calculatePriorities(T1[0], user.character).then(sum => {
  419. if(sum === 6)
  420. done()
  421. })
  422. })
  423. })
  424. })
  425. })
  426. it('buy token', (done)=>{
  427. Promise.all(Object.values(users).map(async (user) =>{
  428. const itemname = T1[0]//T1[Math.floor(T1.length*Math.random())]
  429. const modifier = await client.ItemManager.calculatePriorities(itemname, user.character)
  430. const token = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname)
  431. users[user.account.username].item = itemname
  432. if(!token) return false
  433. return modifier+1 === token.level
  434. })).then(success => {
  435. if(success.reduce((prev, curr)=>prev&&curr, true)) done()
  436. })
  437. })
  438. it('not buy token without currency', (done)=>{
  439. const user = Object.values(users)[0]
  440. const itemname = T1[0]
  441. client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname).then(token => {
  442. if(!token)
  443. done()
  444. else {
  445. console.log("Unexpected token", token);
  446. }
  447. })
  448. })
  449. it('upgrade token', (done)=>{
  450. const user = Object.values(users)[0]
  451. const itemname = T1[0]
  452. adminClient.softreserveCurrency.incrementCurrency(user.account, 2).then(async ()=>{
  453. const item = await client.ItemManager.getItem(itemname)
  454. const before = await client.ItemManager.getToken(user.character, item)
  455. if(!before || before.level !== 7) return
  456. await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname)
  457. const after = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname)
  458. if(!after || after.level !== 9) return
  459. done()
  460. })
  461. })
  462. it('should buy more tokens', (done) => {
  463. Promise.all(Object.values(users).map(async (user) => {
  464. await adminClient.softreserveCurrency.incrementCurrency(user.account, 1)
  465. await client.ItemManager
  466. .buyToken(
  467. user.auth.token.value,
  468. user.character.charactername,
  469. T1[Math.floor(T1.length*Math.random())]
  470. )
  471. })).then(_ => {
  472. done()
  473. })
  474. })
  475. it('can set permissions', (done) => {
  476. Promise.all(
  477. defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
  478. ).then(_ => {
  479. done()
  480. })
  481. })
  482. it('start raid', (done) => {
  483. client.RaidManager.getRaids().then((r)=>{
  484. adminClient.manageRaid.startRaid(raids[0]).then(async data => {
  485. const dbRaids = await client.RaidManager.getRaids()
  486. if(dbRaids.length === 0){
  487. await client.UserManager.getUser(testAccounts[0].name).then(dbUser => {
  488. if(dbUser && dbUser.currency === 1){
  489. adminClient.signup.getSignups(raids[0]).then(signups => {
  490. if(signups.length === 0){
  491. done()
  492. }else{
  493. console.log(signups);
  494. }
  495. })
  496. }
  497. else{
  498. console.log("Bad user currency", dbUser);
  499. }
  500. })
  501. }
  502. })
  503. })
  504. })
  505. it('reset system', (done) => {
  506. adminClient.reset.wipeCurrencyAndItems().then(() => {
  507. client.UserManager.getUser(testAccounts[0].name).then(user => {
  508. if(user && user.currency === 0){
  509. client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character).then(tokens => {
  510. if(tokens.length === 0){
  511. done()
  512. }else{
  513. console.log(tokens);
  514. }
  515. })
  516. }else{
  517. console.log(user)
  518. }
  519. })
  520. })
  521. })
  522. })