import { Injector } from "../src/backend/Injector/Injector"; import { FrontworkAdmin } from "../src/backend/Admin/Admin"; import { T1 } from "../src/backend/Types/Items"; import { RPCSocket } from "rpclibrary"; import { FrontcraftIfc, Auth, User, FrontcraftFeatureIfc, Raid, Character, Rank, Class, Race, SRPriority, Spec, Signup } from "../src/backend/Types/Types"; import { SpecT } from "../src/backend/Types/PlayerSpecs"; type protoAccount = { name : string, rank : Rank, race: Race, class: C, spec: SpecT[C] } const trialsAndUp = { ADMIN: true, Guildmaster: true, Officer: true, Classleader: true, Raider: true, Trial: true, Social: false, Guest: false } const adminsOnly = { ADMIN: true, Guildmaster: true, Officer: true, Classleader: false, Raider: false, Trial: false, Social: false, Guest: false } const defaultPermissions = [ { rpcname: 'signup', ...trialsAndUp },{ rpcname: 'reset', ...adminsOnly },{ rpcname: 'modifyPermissions', ...adminsOnly },{ rpcname: 'manageGuild', ...adminsOnly },{ rpcname: 'managePriorities', ...adminsOnly },{ rpcname: 'softreserveCurrency', ...adminsOnly },{ rpcname: 'manageRaid', ...adminsOnly }] const testAccounts : protoAccount[] = [ { name: 'Rain', race: 'Human', class: 'Warrior', spec: 'Protection', rank: 'Guildmaster' },{ name: 'Celinda', class: 'Warrior', race: 'Night Elf', spec: 'Protection', rank: 'Officer' },{ name: 'Dagger', race: 'Dwarf', class: 'Rogue', spec: 'Assassination', rank: 'Classleader' },{ name: 'Hope', class: 'Paladin', race: 'Human', spec: 'Holy', rank: 'Classleader' },{ name: 'Shrekd', class: 'Warrior', race: 'Dwarf', spec: 'Fury', rank: 'Classleader' },{ name: 'Teeniweeni', class: 'Warlock', race: 'Gnome', spec: 'Demonology', rank: 'Classleader' },{ name: 'Hagibaba', class: 'Priest', race: 'Human', spec: 'Discipline', rank: 'Classleader' },{ name: 'Muffinbreak', class: 'Mage', race: 'Gnome', spec: 'Arcane', rank: 'Classleader' }, ] describe('Frontcraft', () => { let auth: Auth, adminUser : User, server: FrontworkAdmin, client : RPCSocket & FrontcraftIfc, adminClient : RPCSocket & FrontcraftFeatureIfc, raids: Raid[] = [], users : {[username in string] : { account: User, character: Character, auth: Auth, signup?:Signup, item?:string }} = {} const createAccount = (user: User) => { return client.UserManager.createUser(user) } const createAccountAndUser = async (acc : protoAccount) => { const account = await createAccount({ pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a") rank: acc.rank, username: acc.name }) const auth = await client.UserManager.login(acc.name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb') const id = await client.CharacterManager.getSpecId(acc.class, acc.spec) const char = await client.CharacterManager.createCharacter(auth.token.value, { charactername: acc.name, specid: id, userid: account.id!, race: acc.race }) return { account: account, character: char, auth: auth } } before(function (done){ this.timeout(10000); server = Injector.resolve(FrontworkAdmin) server.start().then((_server) => { RPCSocket.makeSocket(20000, 'localhost').then(_client => { client = _client createAccount({ pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //hash("a") rank: 'ADMIN', username: 'a', currency: 2 }).then(adminUser => { client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => { const sock = new RPCSocket( auth.port, "localhost" ) sock.connect(auth.token.value).then(cli => { adminClient = cli sock.hook('kick', () => { console.log("I got kicked"); }) sock.hook('getUserData', () => auth) sock.hook('navigate', (where:string) => { console.log("Nagivate client to "+where); }) sock.on('error', (e) => { console.log('Socket error', e) }) done() }) }) }) }) }).catch(done) }) after(()=>{ client.destroy() adminClient.destroy() server.stop() }) it('create raids', (done) => { let insertRaid = { description: "Test raid 1", title: 'MC', start: Date.now().toString() } adminClient.manageRaid.createRaid(insertRaid).then(() => { client.RaidManager.getRaids().then((r)=>{ if(r[0].title === insertRaid.title && r[0].description === insertRaid.description){ raids.push(r[0]) done() } }).catch(done) }).catch(done) }) it('create users', (done)=>{ Promise.all(testAccounts.map(acc => createAccountAndUser(acc))).then(accs => { if(accs.length === testAccounts.length){ accs.forEach(acc => { users[acc.account.username] = acc }) done() } }).catch(done) }) it('should sign up', (done)=>{ Promise.all(Object.values(users).map((user) => adminClient.signup.sign(user.auth.token.value, user.character, raids[0], false).catch(done) )).then(x => { adminClient.signup.getSignups(raids[0]).then(s => { if(s.length == testAccounts.length){ s.forEach(sign => { users[sign.username].signup = sign }) done() }else{ done("Unexpected number of signups: "+s.length) } }) }) }) it('calculate priorities', (done)=>{ const makePrio = async (itemname:string, spec?: Spec, race?:Race, mod:number = 0, description:string = "") => { let specid if(spec) specid = await client.CharacterManager.getSpecId(spec.class, spec.specname) await adminClient.managePriorities.setPriority(itemname, { specid: specid, race: race, modifier: mod, description: description }) } Promise.all([ makePrio( 'Bracers of Arcane Accuracy', {class:'Warlock', specname:'Demonology'}, undefined, 2, "hit bias" ), makePrio( 'Bracers of Arcane Accuracy', {class:'Warlock', specname:'Affliction'}, undefined, 2, "hit bias" ), makePrio( 'Bracers of Arcane Accuracy', {class:'Warlock', specname:'Destruction'}, undefined, 2, "hit bias" ), makePrio( 'Bracers of Arcane Accuracy', {class:'Mage', specname:'Arcane'}, undefined, 1, "hit bias" ), makePrio( 'Bracers of Arcane Accuracy', {class:'Mage', specname:'Frost'}, undefined, 1, "hit bias" ), makePrio( 'Bracers of Arcane Accuracy', {class:'Mage', specname:'Fire'}, undefined, 1, "hit bias" ), makePrio( 'Maladath, Runed Blade of the Black Flight', undefined, "Human", -2, "(1) Non-Human" ), makePrio( 'Maladath, Runed Blade of the Black Flight', {class:'Rogue', specname:'Subtlety'}, undefined, 2, "...Rogues (weapon skill bias)" ), makePrio( 'Maladath, Runed Blade of the Black Flight', {class:'Rogue', specname:'Combat'}, undefined, 2, "...Rogues (weapon skill bias)" ), makePrio( 'Maladath, Runed Blade of the Black Flight', {class:'Rogue', specname:'Assassination'}, undefined, 2, "...Rogues (weapon skill bias)" ), makePrio( 'Maladath, Runed Blade of the Black Flight', {class:'Warrior', specname:'Fury'}, 'Human', 4, "+2 Fury Warrior (weapon skill bias), +2 to offset (1)" ), makePrio( 'Cloak of Firemaw', {class:'Rogue', specname:'Assassination'}, undefined, 2, "agi-to-ap bias" ), makePrio( 'Cloak of Firemaw', {class:'Rogue', specname:'Combat'}, undefined, 2, "agi-to-ap bias" ), makePrio( 'Cloak of Firemaw', {class:'Rogue', specname:'Subtlety'}, undefined, 2, "agi-to-ap bias" ), makePrio( 'Band of Forced Concentration', {class:'Warlock', specname:'Demonology'}, undefined, 2, "hit bias" ), makePrio( 'Band of Forced Concentration', {class:'Warlock', specname:'Affliction'}, undefined, 2, "hit bias" ), makePrio( 'Band of Forced Concentration', {class:'Warlock', specname:'Destruction'}, undefined, 2, "hit bias" ), makePrio( 'Band of Forced Concentration', {class:'Mage', specname:'Arcane'}, undefined, 1, "hit bias" ), makePrio( 'Band of Forced Concentration', {class:'Mage', specname:'Frost'}, undefined, 1, "hit bias" ), makePrio( 'Band of Forced Concentration', {class:'Mage', specname:'Fire'}, undefined, 1, "hit bias" ), makePrio( 'Drake Fang Talisman', {class:'Rogue', specname:'Assassination'}, undefined, 4, "hit bias" ), makePrio( 'Drake Fang Talisman', {class:'Rogue', specname:'Combat'}, undefined, 4, "hit bias" ), makePrio( 'Drake Fang Talisman', {class:'Rogue', specname:'Subtlety'}, undefined, 4, "hit bias" ), makePrio( 'Drake Fang Talisman', {class:'Warrior', specname:'Fury'}, undefined, 2, "hit bias" ), makePrio( 'Drake Fang Talisman', {class:'Druid', specname:'Feral (DPS)'}, undefined, 2, "hit bias" ), makePrio( 'Circle of Applied Force', {class:'Warrior', specname:'Fury'}, undefined, 2, "str-to-ap bias" ), makePrio( 'Circle of Applied Force', {class:'Druid', specname:'Feral (DPS)'}, undefined, 2, "str-to-ap bias" ), makePrio( 'Empowered Leggings', {class:'Paladin', specname:'Holy'}, undefined, 2, "crit bias" ), makePrio( 'Boots of the Shadow Flame', {class:'Rogue', specname:'Assassination'}, undefined, 2, "hit bias" ), makePrio( 'Boots of the Shadow Flame', {class:'Rogue', specname:'Combat'}, undefined, 2, "hit bias" ), makePrio( 'Boots of the Shadow Flame', {class:'Rogue', specname:'Subtlety'}, undefined, 2, "hit bias" ), makePrio( 'Boots of the Shadow Flame', {class:'Druid', specname:'Feral (DPS)'}, undefined, 2, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Warlock', specname:'Demonology'}, undefined, 4, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Warlock', specname:'Affliction'}, undefined, 4, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Warlock', specname:'Destruction'}, undefined, 4, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Mage', specname:'Arcane'}, undefined, 2, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Mage', specname:'Frost'}, undefined, 2, "hit bias" ), makePrio( 'Neltharion\'s Tear', {class:'Mage', specname:'Fire'}, undefined, 2, "hit bias" ), makePrio( 'Cloak of Draconic Might', {class:'Warrior', specname:'Fury'}, undefined, 2, "str-to-ap bias" ), makePrio( 'Cloak of Draconic Might', {class:'Druid', specname:'Feral (DPS)'}, undefined, 2, "str-to-ap bias" ), ]) const user = Object.values(users)[0] adminClient.managePriorities.setPriority(T1[0], { race: user.character.race, specid: user.character.specid, modifier: 1, description:'AAA' }).then(() => { adminClient.managePriorities.setPriority(T1[0], { race: user.character.race, specid: undefined, modifier: 2, description:'BBB' }).then(()=>{ adminClient.managePriorities.setPriority(T1[0], { race: undefined, specid: user.character.specid, modifier: 3, description:'CCC' }).then(()=>{ client.ItemManager.calculatePriorities(T1[0], user.character).then(sum => { if(sum === 6) done() }) }) }) }) }) it('buy token', (done)=>{ Promise.all(Object.values(users).map(async (user) =>{ const itemname = T1[0]//T1[Math.floor(T1.length*Math.random())] const modifier = await client.ItemManager.calculatePriorities(itemname, user.character) const token = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!) users[user.account.username].item = itemname if(!token) return false return modifier+1 === token.level })).then(success => { if(success.reduce((prev, curr)=>prev&&curr, true)) done() }) }) it('not buy token without currency', (done)=>{ const user = Object.values(users)[0] const itemname = T1[0] client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!).then(token => { if(!token) done() else { console.log("Unexpected token", token); } }) }) it('upgrade token', (done)=>{ const user = Object.values(users)[0] const itemname = T1[0] adminClient.softreserveCurrency.incrementCurrency(user.account, 2).then(async ()=>{ const item = await client.ItemManager.getItem(itemname) const before = await client.ItemManager.getToken(user.character, item) if(!before || before.level !== 7) { console.log("expected level to be 7", before); return } await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!) const after = await client.ItemManager.buyToken(user.auth.token.value, user.character.charactername, itemname, user.signup!) if(!after || after.level !== 9) { console.log("expected level to be 9", after); return } done() }) }) it('should buy more tokens', (done) => { Promise.all(Object.values(users).map(async (user) => { await adminClient.softreserveCurrency.incrementCurrency(user.account, 1) return await client.ItemManager .buyToken( user.auth.token.value, user.character.charactername, T1[Math.floor(T1.length*Math.random())], user.signup! ) })).then(_ => { done() }) }) it('can set permissions', (done) => { Promise.all( defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)), ).then(_ => { done() }) }) it('start raid', (done) => { client.RaidManager.getRaids().then((r)=>{ adminClient.manageRaid.startRaid(raids[0]).then(async data => { const dbRaids = await client.RaidManager.getRaids() if(dbRaids.length === 0){ await client.UserManager.getUser(testAccounts[0].name).then(dbUser => { if(dbUser && dbUser.currency === 1){ adminClient.signup.getSignups(raids[0]).then(signups => { if(signups.length === 0){ done() }else{ console.log(signups); } }) } else{ console.log("Bad user currency", dbUser); } }) } }) }) }) it('reset system', (done) => { adminClient.reset.wipeCurrencyAndItems().then(() => { client.UserManager.getUser(testAccounts[0].name).then(user => { if(user && user.currency === 0){ client.ItemManager.getTokens(users[testAccounts[0].name.toLowerCase()].character).then(tokens => { if(tokens.length === 0){ done() }else{ console.log(tokens); } }) }else{ console.log(user) } }) }) }) })