diff --git a/.idea/dictionaries/marley.xml b/.idea/dictionaries/marley.xml new file mode 100644 index 0000000..709fb63 --- /dev/null +++ b/.idea/dictionaries/marley.xml @@ -0,0 +1,7 @@ + + + + edsm + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 4ed2ac0..d40e675 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,6 +1,12 @@ \ No newline at end of file diff --git a/src/models/EDSM.ts b/src/models/EDSM.ts index ada8a86..c32fd7b 100755 --- a/src/models/EDSM.ts +++ b/src/models/EDSM.ts @@ -1,51 +1,56 @@ -import type { systemEstimatedValue } from '../@types/edsmResponses'; +import type {systemEstimatedValue} from '../@types/edsmResponses'; const EventEmitter = require('node:events'); -import { Log } from './Log'; -import { System } from './System'; +import {Log} from './Log'; +import {System} from './System'; export class EDSM extends EventEmitter { - static #instance: EDSM; + static #instance: EDSM; - private constructor() { - super(); + private constructor() { + super(); + } + + static connect(): EDSM { + if (!EDSM.#instance) { + EDSM.#instance = new EDSM(); } - static connect(): EDSM { - if (!EDSM.#instance) { - EDSM.#instance = new EDSM(); - } + return EDSM.#instance; + } - return EDSM.#instance; + /* ---------------------------------------------------------------------------- #request ---- */ + + // Submit a request to EDSM and return the response as an object + static async #request( + url: string, + options: { [x: string]: string }, + ): Promise { + let data: object | undefined = undefined; + + try { + const response = await fetch(url + '?' + new URLSearchParams(options)); + + if (!response.ok) { + throw new Error(`Network error - ${response}`); + } + + data = await response.json(); + } catch (err) { + Log.write(`ERROR - EDSM.request(): ${err}`); } - /* ---------------------------------------------------------------------------- #request ---- */ + return data; + } - // Submit a request to EDSM and return the response as an object - static async #request(url: string, options: {[x: string]: string}): Promise { - let data: object|undefined = undefined; + /* ---------------------------------------------------------------------- getSystemValue ---- */ - try { - const response = await fetch(url + '?' + new URLSearchParams(options)); - - if (!response.ok) { - throw new Error(`Network error - ${response}`); - } - - data = await response.json(); - } catch (err) { - Log.write(`ERROR - EDSM.request(): ${err}`); - } - - return data; - } - - /* ---------------------------------------------------------------------- getSystemValue ---- */ - - static async getSystemValue(system: System): Promise { - const url = 'https://www.edsm.net/api-system-v1/estimated-value'; - const response = await EDSM.#request(url, {systemName: system.name}); - return (response as systemEstimatedValue); - } -} \ No newline at end of file + static async getSystemValue(system: System): Promise { + const url = 'https://www.edsm.net/api-system-v1/estimated-value'; + const response = await EDSM.#request(url, {systemName: system.name}); + return ( + response as systemEstimatedValue + ); + } +} diff --git a/src/models/System.ts b/src/models/System.ts index 52cff9d..04ac4a8 100755 --- a/src/models/System.ts +++ b/src/models/System.ts @@ -1,81 +1,79 @@ -import type { completeFsdJump, location, navRouteSystem } from '../@types/journalLines'; +import type {completeFsdJump, location, navRouteSystem} from '../@types/journalLines'; import * as _ from 'lodash-es'; -import { Body } from './Body'; -import { EDSM } from './EDSM'; +import {Body} from './Body'; +import {EDSM} from './EDSM'; export class System { - name: string; - SystemAddress?: number; - StarClass?: string; - charted: boolean; - bodies: Body[]; + name: string; + SystemAddress?: number; + StarClass?: string; + charted: boolean; + bodies: Body[]; - // ESDM data - estimatedValue?: number; - estimatedValueMapped?: number; - valuableBodies?: Body[]; + // EDSM data + estimatedValue?: number; + estimatedValueMapped?: number; + valuableBodies?: Body[]; - constructor(line?: navRouteSystem|completeFsdJump|location) { - // In future, this is where we preform EDSM lookup + constructor(line?: navRouteSystem | completeFsdJump | location) { + if (!line) { + this.name = 'Unknown'; + } else { + this.name = line.StarSystem; + this.SystemAddress = line.SystemAddress; - if (!line) { - this.name = 'Unknown'; - } else { - this.name = line.StarSystem; - this.SystemAddress = line.SystemAddress; + if ('StarClass' in line) { + this.StarClass = line.StarClass; + } - if ('StarClass' in line) { - this.StarClass = line.StarClass; - } - - } - - // Set this to true initially, since it likely is and the system is technically inserted - // into the UI before it's appraised. - this.charted = true; - this.bodies = []; - - if (this.name !== 'Unknown') { - this.#getValue(); - } } - /* --------------------------------------------------------------------------- #getValue ---- */ + // Set this to true initially, since it likely is and the system is technically inserted + // into the UI before it's appraised. + this.charted = true; + this.bodies = []; - async #getValue() { - // display estimatedValueMapped - const data = await EDSM.getSystemValue(this); - - if (data) { - this.estimatedValue = data.estimatedValue; - this.estimatedValueMapped = data.estimatedValueMapped; - - // If EDSM doesn't have an estimate, then it's likely undiscovered. - this.charted = this.estimatedValue > 0; - - // Save valuable bodies in system, if any. - if (data.valuableBodies.length > 0) { - this.valuableBodies = []; - - data.valuableBodies.forEach((body) => { - this.valuableBodies?.push(new Body(body)); - }); - } - - // Let the UI know it needs to update. - EDSM.connect().emit('SYSTEM_APPRAISED', this); - } + if (this.name !== 'Unknown') { + this.#getValue(); } + } - /* -------------------------------------------------------------------------- sortBodies ---- */ + /* --------------------------------------------------------------------------- #getValue ---- */ - sortBodies(): void { - this.bodies = _.orderBy( - this.bodies, - ['mappedValue', 'DistanceFromArrivalLS'], - ['desc', 'desc'], - ); + async #getValue() { + // display estimatedValueMapped + const data = await EDSM.getSystemValue(this); + + if (data) { + this.estimatedValue = data.estimatedValue; + this.estimatedValueMapped = data.estimatedValueMapped; + + // If EDSM doesn't have an estimate, then it's likely undiscovered. + this.charted = this.estimatedValue > 0; + + // Save valuable bodies in system, if any. + if (data.valuableBodies.length > 0) { + this.valuableBodies = []; + + data.valuableBodies.forEach((body) => { + this.valuableBodies?.push(new Body(body)); + }); + } + + // Let the UI know it needs to update. + EDSM.connect().emit('SYSTEM_APPRAISED', this); } -} \ No newline at end of file + } + + /* -------------------------------------------------------------------------- sortBodies ---- */ + + sortBodies(): void { + this.bodies = _.orderBy( + this.bodies, + ['mappedValue', 'DistanceFromArrivalLS'], + ['desc', 'desc'], + ); + } +} diff --git a/test/EDSM.test.ts b/test/EDSM.test.ts new file mode 100644 index 0000000..91a9bc7 --- /dev/null +++ b/test/EDSM.test.ts @@ -0,0 +1,72 @@ +import {expect, jest} from '@jest/globals'; +import {EDSM} from '../src/models/EDSM'; +import {System} from '../src/models/System'; + +describe('EDSM', () => { + describe('connect()', () => { + it('should create new instance', () => { + expect(EDSM.connect()).toBeInstanceOf(EDSM); + }); + + it('should get previously created instance', () => { + const edsm = EDSM.connect(); + expect(EDSM.connect()).toBeInstanceOf(EDSM); + }); + }); + + describe('getSystemValue()', () => { + const mockFetch = (data?: {[i: string]: any}, ok: boolean = true) => { + global.fetch = jest.fn(() => + Promise.resolve({ + ok: ok, + json: () => Promise.resolve(data), + } as Response), + ); + }; + + it('should get system info', async () => { + const system = new System({ "StarSystem":"LHS 3447", "SystemAddress":0, "StarPos":[0,0,0], "StarClass":"M" }); + const data = { + "id": 13153, + "id64": 5306465653474, + "name": "LHS 3447", + "url": "https://www.edsm.net/en/system/bodies/id/13153/name/LHS+3447", + "estimatedValue": 353968, + "estimatedValueMapped": 1164029, + "valuableBodies": [ + { + "bodyId": 3195879, + "bodyName": "LHS 3447 A 5", + "distance": 92282, + "valueMax": 879114 + } + ] + }; + mockFetch(data); + + const result = await EDSM.getSystemValue(system); + expect(result).toEqual(data); + }); + + it('should not get system info if system name is invalid', async () => { + const system = new System(); + const data = {}; + mockFetch({}); + + const result = await EDSM.getSystemValue(system); + expect(result).toEqual(data); + }); + + it('should return undefined if response is not ok', async () => { + const system = new System(); + mockFetch({}, false); + + const result = await EDSM.getSystemValue(system); + expect(result).toBeUndefined(); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + }); +});