-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactoring/NR-65 Refactoring game identifier #207
refactoring/NR-65 Refactoring game identifier #207
Conversation
cb0a73e
to
c88d72a
Compare
fixed missing argument in method bug
# removed unused code # fixed bugs in updateGamesWithoutDetails and updateGamesWithoutReleaseDates tests
# updated tests
# fixed small true/false logic bug # removed isGame method from steamApp # updated tests to reflect change
c88d72a
to
7a79a0d
Compare
# renamed functions # fixed test descriptions # adjusted tests # slight refactor/final PR adjustments
@@ -34,102 +34,63 @@ export class GameIdentifier { | |||
this.#options = options; | |||
} | |||
|
|||
tryViaSteamWeb = async () => { | |||
this.#logger.debugc("identifying games via steam web"); | |||
tryIfGameViaSource = async (source) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to checkIfGameViaSource
# moved steamAppsIsEmpty functionality to it # added instantiation to steamApps repo get method # added tests
0fbe661
to
ccbc45a
Compare
# renamed aggregator # added tests
# passed in logger through the games repository into aggregator # removed fdescribe # added tests
# adjusted test to reflect code
# added tests
# improved test descriptions
# changed getter into normal method # adjusted tests, fixed some typos
# adjusted/fixed some tests
# improved test descriptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job man! You did a lot and a lot correct. I added some comments and ideas. You decide what to tackle or not. You can merge if you want.
@@ -11,6 +11,20 @@ export class Game { | |||
imageUrl; | |||
playerHistory; | |||
|
|||
copy() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have cloneDeep
for that. It's used in the game class in line 93 also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using cloneDeep for the use cases in the app. Ran across a problem. From what I discovered, it seems like cloning private properties of an instance of a class is impossible through clone deep, and some suggestions said to just create your own method for doing this in the class. I'm not sure what to do at this point, but in 30 minutes of searching I couldn't find a better solution. Let me know if it's okay to just leave it how it is, or if I should search more/you have a different suggestion.
The error was: "TypeError: Receiver must be an instance of class SteamApp".
References:
lodash/lodash#5589
lodash/lodash#5247
https://stackoverflow.com/questions/57542052/deep-clone-class-instance-javascript
backend/src/core/models/game.spec.js
Outdated
import { PlayerHistory } from "./player.history.js"; | ||
import { getXSampleSteamApps } from "./steam.app.mocks.js"; | ||
|
||
describe("game.js", function () { | ||
describe("Game", function () { | ||
describe(".copy", function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove once switched to deepCopy
@@ -23,32 +21,20 @@ export class SteamApp { | |||
return copy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when you're at it, use deepCopy
here also
@@ -12,4 +12,13 @@ export class ValidDataSources { | |||
} | |||
return Object.freeze(enumObject); | |||
} | |||
|
|||
static getSourceUrl(id, source) { | |||
if (source === ValidDataSources.validDataSources.steamWeb) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use switch/case
@@ -12,4 +12,13 @@ export class ValidDataSources { | |||
} | |||
return Object.freeze(enumObject); | |||
} | |||
|
|||
static getSourceUrl(id, source) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would leave in steam.client.js as a method. Its not the responsibility of the data model to know the exact URLs. Ideally we would have those URLs provide externally via Env Vars like all other external things (think DB connection url) so that we can set it to something else if we need to without changing the code. BUT we did not get to that yet, so I would just move it out here an into the steam client.
This will go away anyway because you will switch to the API, right?
export class SteamAppsAggregate { | ||
apps; | ||
|
||
static manyFromDbEntries(steamApps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use normal constructor
return steamAppsAggregate; | ||
} | ||
|
||
isEmpty() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getter
this.apps = this.apps.map((app) => { | ||
const appCopy = app.copy(); | ||
|
||
const page = this.#findSteamAppHtmlDetailsPage(htmlDetailsPages, appCopy); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in app.appid
}); | ||
|
||
describe(".isEmpty", function () { | ||
describe("when the steamApps array is empty", function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above...update text..in the tests below also
this.steamAppsRepository = createSteamAppsRepositoryMock([], undefined); | ||
this.gamesRepository = createGamesRepositoryMock(); | ||
this.historyChecksRepository = createHistoryChecksRepositoryMock(); | ||
describe(".checkIfGameViaSource.", function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could heavily simplify the tests. No need to check for the calling or not calling of all methods of the mocks, it would be enough to check for the flow of the logic, e.g. when isEmpty is true => just check that nothing is persisted. And if isEmpty is false check only for the expected result to be persisted. Do you know what I mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will skip this for now since API/logic will change heavily. Opened ticket to do it after: #212
# removed todo # fixed test using steamApps aggregate instead of games aggregate
# removed old test
# udpated tests
# encapsulated methods, made them private
# applicaiton now uses .content to access the content in games aggregate # modified tests to reflect new code
# renamed private mathod # changed argument of private method into game's id only
# removed unused methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good bro! Thanks for taking the time to add the changes.
See comments below. Only the copy
one is a one I would recommend you add in your next branch if the code will be used further.
|
||
try { | ||
return (await this.#httpClient.get(url)).data; | ||
} catch (err) { | ||
return ""; | ||
} | ||
} | ||
|
||
getSourceUrl(id, source) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use private methods (encapsulation) if no client needs access
|
||
return gamesAggregate; | ||
get content() { | ||
return this.#games; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always return or copy, because JS uses "pass by reference" of objects (and arrays which is an object). If you don't use a copy the returned value can be modified and by that the GamesAggregate instance also and you did not intended that.
isEmpty() { | ||
if (this.games.length > 0) return false; | ||
get isEmpty() { | ||
if (this.#games.length > 0) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return this.#games.length > 0
|
||
return gameCopy; | ||
}); | ||
} | ||
|
||
#findGamesHtmlDetailsPage(htmlDetailsPages, game) { | ||
return htmlDetailsPages.find((page) => game.id === page.id).page; | ||
findPageForGameById(htmlDetailsPages, gameId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private
|
||
return steamAppsAggregate; | ||
get content() { | ||
return this.#apps; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return a copy
expect(this.steamAppsArray.apps[0].triedVia).toEqual(["steamWeb"]); | ||
expect(this.steamAppsArray.apps[0].failedVia).toEqual(["steamWeb"]); | ||
expect(this.steamAppsArray.apps[0].type).toBe("unknown"); | ||
expect(this.steamAppsArray.content[0].appid).toBe(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use just toEqual
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried using toEqual, but the object I compare it to has to be an instance of same class, seems like it would be unnecessarily extra work for no real benefit? Let me know if I should do it anyway, and I will do in the future.
Related Issue: #213