mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Alternate (embedded) code versioning scheme; start to fix up tests
This commit is contained in:
@@ -142,7 +142,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA%3D%3D.CwBhCYzBGW9qCTSqs5xA.&bn=Test%20My%20Ship');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=A4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04----0303326b.AwRj4zNLZI%3D%3D.CwBhCYzBGW9qCTSq15xA.&bn=Test%20My%20Ship');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('catches an invalid build', function() {
|
it('catches an invalid build', function() {
|
||||||
@@ -167,7 +167,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA%3D%3D.CwBhCYzBGW9qCTSqs5xA.H4sIAAAAAAAAA2P8xwAEf0GE2AtmBob%2F%2FwFvM%2BjKEgAAAA%3D%3D&bn=Test%20My%20Ship');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=A4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04----0303326b.AwRj4zNLZI%3D%3D.CwBhCYzBGW9qCTSq15xA.H4sIAAAAAAAAA2MUe8HMwPD%2FPwMcAABTINwTEgAAAA%3D%3D&bn=Test%20My%20Ship');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/asp?code=0pftiFflfddsnf5------020202033c044002v62f2i.AwRj4yvI.CwRgDBldHnJA.H4sIAAAAAAAAA2P858DAwPCXEUhwHPvx%2F78YG5AltB7I%2F8%2F0TwImJboDSPJ%2F%2B%2Ff%2Fv%2FKlX%2F%2F%2Fi3AwMTBIfARK%2FGf%2BJwVSxArStVAYqOjvz%2F%2F%2FJVo5GRhE2IBc4SKQSSz%2FDGEmCa398P8%2F%2F2%2BgTf%2F%2FAwDFxwtofAAAAA%3D%3D&bn=Multi-purpose%20Asp%20Explorer');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/asp?code=A0pftiFflfddsnf5------020202033c044002v62f2i.AwRj4yvI.CwRgDBldHnJA.H4sIAAAAAAAAA2P858DAwPCXEUhwHPvx%2F78YG5AltB7I%2F8%2F0TwImJboDSPJ%2F%2B%2Ff%2Fv%2FKlX%2F%2F%2Fi3AwMTBIfARK%2FGf%2BJwVSxArStVAYqOjvz%2F%2F%2FJVo5GRhE2IBc4SKQSSz%2FDGEmCa398P8%2F%2F2%2BgTf%2F%2FAwDFxwtofAAAAA%3D%3D&bn=Multi-purpose%20Asp%20Explorer');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports a valid v4 build with modifications', function() {
|
it('imports a valid v4 build with modifications', function() {
|
||||||
@@ -196,7 +196,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/imperial_courier?code=0patzF5l0das8f31a1a270202000e402t0101-2f.AwRj4zKA.CwRgDBldLiQ%3D.H4sIAAAAAAAAA12OP0tCYRjFj9fuVbvF1du9ekkT8s%2FkIg4NElyIBBd321yaGvwUQTS3N7UFfYygIT9EoyQUJA36ns47XJCWA%2B%2Fz%2Bz3Pe3ImBbDNKaqNPSBoGrL4ngfomKpFGiJ%2BLgHteR1IPjxJT5pF11uSeXNsJVcRfgdC92syWUuK0iMdKZqrjJ%2F0aoA71lJ5oKf38knWcCiptCPdhJIerdS00vlK0qktlqoj983UmqqHjQ33VsW8eazFmaTyULP2hQ4lX8LBme6g%2F6v0TTdbxJ2KhdEIaCw15MF%2FNB0L%2BS2hwEwyFM8KgP%2BqEpWWA3Qu9Z3z9kPWHzakt7Dt%2BAeD7ghSTgEAAA%3D%3D&bn=Multi-purpose%20Imperial%20Courier');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/imperial_courier?code=A0patzF5l0das8f31a1a270202000e402t0101-2f.AwRj4zKA.CwRgDBldLiQ%3D.H4sIAAAAAAAAA12OP0tCYRjFj9fuVbvF1du9ekkT8s%2FkIg4NElyIBBd321yaGvwUQTS3N7UFfYygIT9EoyQUJA36ns47XJCWA%2B%2Fz%2Bz3Pe3ImBbDNKaqNPSBoGrL4ngfomKpFGiJ%2BLgHteR1IPjxJT5pF11uSeXNsJVcRfgdC92syWUuK0iMdKZqrjJ%2F0aoA71lJ5oKf38knWcCiptCPdhJIerdS00vlK0qktlqoj983UmqqHjQ33VsW8eazFmaTyULP2hQ4lX8LBme6g%2F6v0TTdbxJ2KhdEIaCw15MF%2FNB0L%2BS2hwEwyFM8KgP%2BqEpWWA3Qu9Z3z9kPWHzakt7Dt%2BAeD7ghSTgEAAA%3D%3D&bn=Multi-purpose%20Imperial%20Courier');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifrv66g2f.AwRj4zNaKA%3D%3D.CwRgDBldUExuBiQqA%3D%3D%3D.H4sIAAAAAAAAA02Svy9DURTHT1vvtfoat30eXlvV0ufXQmLAIDHSRDcJAzHV1PgDDAaJpVbxF0gYKhFiEFuXTgbCIsKfYJCItHWP75E83vLNue%2F7Od977zs3pBeJ6DsE6TcNIlVn5lgFSw7rfrEikL6mSVS0HSL3MgxoqM3sTGtm%2BxA2R3RGSLSTfWzD32kxu043kVNFDxt6wU8ajVpEY7coh5uARrYR0n3aYY4%2FY6lmkc4xveafqZOHpHejRMb9J7NZQqN9Ascto4fjet0P7iQgRhV7mo5LlLtAUnIe34rVDaKBF9AThUJhla3%2FHqMRB76XBV7v8vEvOOoGx%2BJEgKz9BgvZEHJOyHNUakYujUuSW8KxWOkl%2F%2BzuMsR6QpkS8URUTYKTAagNta4EEvFE1INAqQD0IdCdQCKeiOoBk9%2BPYU87QL7i2tajkITKk0odSFxvAJrClawX%2BCkRT0RZYNjV5b%2BRbyLaOpMkafJa%2BBgufjFnjxBnvgFxKvgBnNYlP7jwiXcRnYQ%2F%2FoRlqCnTHAz41xha9F78CNahGXk8eZ3z%2FcyWjJcg7goeU%2BJdZsw%2FFW2pAaMCAAA%3D&bn=Imported%20Federal%20Corvette');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=A2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifr------.AwRj4zNapI%3D%3D.CwRgDBldUExuBiZA.H4sIAAAAAAAAA02SP0vDUBTFb1qTtE3xtTFqav0Tbfy3KHRQB8FRO7gJOuioU%2FEDODgILrqKn0DQQUEUB3Hr0smhYhcp%2BiEEEVvf9VwhmuVw3zu%2Fe959eTH0EhF9G5A%2ByyRSl8yc2saSE7pPrCSkt24RlVyPyL9JABpuM3uzmtk9hs1JPSAk2sk9deHvfjH7XprIq6KHTb0YJY3bDtHEA8rROqCxHYSkzzvMmRcs1RzSOaXXo5k6I5DCnk1kNj6YrQoa3TM4%2Fip6OKM3ouBOFmJWcabl%2BURD10jKLWCvVN0k6m%2BBngqCYI2d%2Fx6zlgG%2BXwR%2B2RXhn3DUPcbibIw8%2Bg0WsibkvJBXqFRZLo1Lkl%2FBWKz0cjS7vwJxmijzIqGIOpLgXAxqQ51bgURCEfUkUD4GvQv0KJBIKKK6wYwcpHCmGyNfcW3nWUhCFUqlDiWuJwbN4EpOC35eJBRRDhj29erfk28h2rmQJGkKv7CZKH0yF08QZ70B8bbxAbigK1Fw8IH%2Fwp6GP9nE0qjLaw7G%2FDs8mt0QP4m1UZafh38AuKZDe4MCAAA%3D&bn=Imported%20Federal%20Corvette');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports a valid v4 build', function() {
|
it('imports a valid v4 build', function() {
|
||||||
@@ -250,7 +250,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/beluga?code=0pktsFplCdpsnf70t0t2727270004040404043c4fmimlmm04mc0iv62i2f.AwRj4yukg%3D%3D%3D.CwRgDBldHi8IUA%3D%3D.H4sIAAAAAAAAA2P8Z8%2FAwPCXEUiIKTMxMPCv%2F%2Ff%2FP8cFIPGf6Z8YTEr0GjMDg%2FJWICERBOTzn%2Fn7%2F7%2FIO5Ai5n9SIEWsQEIoSxAolfbt%2F3%2BJPk4GBhE7YQYGYVmgcuVnf4Aq%2FwMAIrEcGGsAAAA%3D&bn=Imported%20Beluga%20Liner');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/beluga?code=A0pktsFplCdpsnf70t0t2727270004040404043c4fmimlmm04mc0iv62i2f.AwRj4yukg%3D%3D%3D.CwRgDBldHi8IUA%3D%3D.H4sIAAAAAAAAA2P8Z8%2FAwPCXEUiIKTMxMPCv%2F%2Ff%2FP8cFIPGf6Z8YTEr0GjMDg%2FJWICERBOTzn%2Fn7%2F7%2FIO5Ai5n9SIEWsQEIoSxAolfbt%2F3%2BJPk4GBhE7YQYGYVmgcuVnf4Aq%2FwMAIrEcGGsAAAA%3D&bn=Imported%20Beluga%20Liner');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ export default class OutfittingPage extends Page {
|
|||||||
let params = context.route.params;
|
let params = context.route.params;
|
||||||
let shipId = params.ship;
|
let shipId = params.ship;
|
||||||
let code = params.code;
|
let code = params.code;
|
||||||
let version = params.ver;
|
|
||||||
let buildName = params.bn;
|
let buildName = params.bn;
|
||||||
let data = Ships[shipId]; // Retrieve the basic ship properties, slots and defaults
|
let data = Ships[shipId]; // Retrieve the basic ship properties, slots and defaults
|
||||||
let savedCode = Persist.getBuild(shipId, buildName);
|
let savedCode = Persist.getBuild(shipId, buildName);
|
||||||
@@ -73,7 +72,7 @@ export default class OutfittingPage extends Page {
|
|||||||
let ship = new Ship(shipId, data.properties, data.slots); // Create a new Ship instance
|
let ship = new Ship(shipId, data.properties, data.slots); // Create a new Ship instance
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
ship.buildFrom(code, version); // Populate modules from serialized 'code' URL param
|
ship.buildFrom(code); // Populate modules from serialized 'code' URL param
|
||||||
} else {
|
} else {
|
||||||
ship.buildWith(data.defaults); // Populate with default components
|
ship.buildWith(data.defaults); // Populate with default components
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,74 +127,23 @@ export function toDetailedBuild(buildName, ship) {
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates a ship from a ship-loadout object
|
|
||||||
* @param {Object} detailedBuild ship-loadout object
|
|
||||||
* @return {Ship} Ship instance
|
|
||||||
*/
|
|
||||||
export function fromDetailedBuild(detailedBuild) {
|
export function fromDetailedBuild(detailedBuild) {
|
||||||
let shipId = Object.keys(Ships).find((shipId) => Ships[shipId].properties.name.toLowerCase() == detailedBuild.ship.toLowerCase());
|
let shipId = Object.keys(Ships).find((shipId) => Ships[shipId].properties.name.toLowerCase() == detailedBuild.ship.toLowerCase());
|
||||||
|
|
||||||
if (!shipId) {
|
if (!shipId) {
|
||||||
throw 'No such ship: ' + detailedBuild.ship;
|
throw 'No such ship: ' + detailedBuild.ship;
|
||||||
}
|
}
|
||||||
|
|
||||||
let comps = detailedBuild.components;
|
|
||||||
let stn = comps.standard;
|
|
||||||
let priorities = [stn.cargoHatch && stn.cargoHatch.priority !== undefined ? stn.cargoHatch.priority - 1 : 0];
|
|
||||||
let enabled = [stn.cargoHatch && stn.cargoHatch.enabled !== undefined ? stn.cargoHatch.enabled : true];
|
|
||||||
let shipData = Ships[shipId];
|
let shipData = Ships[shipId];
|
||||||
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
||||||
let bulkheads = ModuleUtils.bulkheadIndex(stn.bulkheads);
|
|
||||||
let modifications = new Array(stn.bulkheads.modifications);
|
|
||||||
let blueprints = new Array(stn.bulkheads.blueprint);
|
|
||||||
|
|
||||||
if (bulkheads < 0) {
|
if (!detailedBuild.references[0] || !detailedBuild.references[0].code) {
|
||||||
throw 'Invalid bulkheads: ' + stn.bulkheads;
|
throw 'Missing reference code';
|
||||||
}
|
}
|
||||||
|
|
||||||
let standard = STANDARD.map((c) => {
|
ship.buildFrom(detailedBuild.references[0].code);
|
||||||
if (!stn[c].class || !stn[c].rating) {
|
|
||||||
throw 'Invalid value for ' + c;
|
|
||||||
}
|
|
||||||
priorities.push(stn[c].priority === undefined ? 0 : stn[c].priority - 1);
|
|
||||||
enabled.push(stn[c].enabled === undefined ? true : stn[c].enabled);
|
|
||||||
modifications.push(stn[c].modifications);
|
|
||||||
blueprints.push(stn[c].blueprint);
|
|
||||||
return ModuleUtils.findStandardId(STANDARD_GROUPS[c], stn[c].class, stn[c].rating, stn[c].name);
|
|
||||||
});
|
|
||||||
|
|
||||||
let internal = comps.internal.map(c => c ? ModuleUtils.findInternalId(c.group, c.class, c.rating, c.name) : 0);
|
|
||||||
|
|
||||||
let hardpoints = comps.hardpoints.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount], c.missile) : 0)
|
|
||||||
.concat(comps.utility.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount]) : 0));
|
|
||||||
|
|
||||||
// The ordering of these arrays must match the order in which they are read in Ship.buildWith
|
|
||||||
priorities = priorities.concat(
|
|
||||||
comps.hardpoints.map(c => (!c || c.priority === undefined) ? 0 : c.priority - 1),
|
|
||||||
comps.utility.map(c => (!c || c.priority === undefined) ? 0 : c.priority - 1),
|
|
||||||
comps.internal.map(c => (!c || c.priority === undefined) ? 0 : c.priority - 1)
|
|
||||||
);
|
|
||||||
enabled = enabled.concat(
|
|
||||||
comps.hardpoints.map(c => (!c || c.enabled === undefined) ? true : c.enabled * 1),
|
|
||||||
comps.utility.map(c => (!c || c.enabled === undefined) ? true : c.enabled * 1),
|
|
||||||
comps.internal.map(c => (!c || c.enabled === undefined) ? true : c.enabled * 1)
|
|
||||||
);
|
|
||||||
modifications = modifications.concat(
|
|
||||||
comps.hardpoints.map(c => (c ? c.modifications : null)),
|
|
||||||
comps.utility.map(c => (c ? c.modifications : null)),
|
|
||||||
comps.internal.map(c => (c ? c.modifications : null))
|
|
||||||
);
|
|
||||||
blueprints = blueprints.concat(
|
|
||||||
comps.hardpoints.map(c => (c ? c.blueprint : null)),
|
|
||||||
comps.utility.map(c => (c ? c.blueprint : null)),
|
|
||||||
comps.internal.map(c => (c ? c.blueprint : null))
|
|
||||||
);
|
|
||||||
|
|
||||||
ship.buildWith({ bulkheads, standard, hardpoints, internal }, priorities, enabled, modifications, blueprints);
|
|
||||||
|
|
||||||
return ship;
|
return ship;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an array of ship-loadout JSON Schema object for export
|
* Generates an array of ship-loadout JSON Schema object for export
|
||||||
|
|||||||
@@ -301,6 +301,7 @@ export default class Ship {
|
|||||||
*/
|
*/
|
||||||
toString() {
|
toString() {
|
||||||
return [
|
return [
|
||||||
|
'A',
|
||||||
this.getStandardString(),
|
this.getStandardString(),
|
||||||
this.getHardpointsString(),
|
this.getHardpointsString(),
|
||||||
this.getInternalString(),
|
this.getInternalString(),
|
||||||
@@ -610,7 +611,7 @@ export default class Ship {
|
|||||||
* @param {String} serializedString The string to deserialize
|
* @param {String} serializedString The string to deserialize
|
||||||
* @return {this} The current ship instance for chaining
|
* @return {this} The current ship instance for chaining
|
||||||
*/
|
*/
|
||||||
buildFrom(serializedString, version = 1) {
|
buildFrom(serializedString) {
|
||||||
let standard = new Array(this.standard.length),
|
let standard = new Array(this.standard.length),
|
||||||
hardpoints = new Array(this.hardpoints.length),
|
hardpoints = new Array(this.hardpoints.length),
|
||||||
internal = new Array(this.internal.length),
|
internal = new Array(this.internal.length),
|
||||||
@@ -621,6 +622,19 @@ export default class Ship {
|
|||||||
enabled = null,
|
enabled = null,
|
||||||
code = parts[0];
|
code = parts[0];
|
||||||
|
|
||||||
|
// Code has a version ID embedded as the first character (if it is alphabetic)
|
||||||
|
let version;
|
||||||
|
if (code && code.match(/^[0-4]/)) {
|
||||||
|
// Starting with bulkhead number is version 1
|
||||||
|
version = 1;
|
||||||
|
} else {
|
||||||
|
// Version 2 (current version)
|
||||||
|
version = 2;
|
||||||
|
if (code) {
|
||||||
|
code = code.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parts[1]) {
|
if (parts[1]) {
|
||||||
enabled = LZString.decompressFromBase64(Utils.fromUrlSafe(parts[1])).split('');
|
enabled = LZString.decompressFromBase64(Utils.fromUrlSafe(parts[1])).split('');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export function outfitURL(shipId, code, buildName) {
|
|||||||
let sepChar = '?';
|
let sepChar = '?';
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
path = path + sepChar + 'code=' + encodeURIComponent(code) + '&ver=2';
|
path = path + sepChar + 'code=' + encodeURIComponent(code);
|
||||||
sepChar = '&';
|
sepChar = '&';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user