Skip to content
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

Merged
merged 78 commits into from
Apr 11, 2024

Conversation

lukatarman
Copy link
Owner

@lukatarman lukatarman commented Dec 18, 2023

Related Issue: #213

@lukatarman lukatarman self-assigned this Dec 18, 2023
@lukatarman lukatarman linked an issue Dec 18, 2023 that may be closed by this pull request
5 tasks
@lukatarman lukatarman force-pushed the refactoring/NR-65-refactoring-game-identifier branch from cb0a73e to c88d72a Compare January 16, 2024 15:09
@lukatarman lukatarman force-pushed the refactoring/NR-65-refactoring-game-identifier branch from c88d72a to 7a79a0d Compare January 19, 2024 13:24
# 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) => {
Copy link
Owner Author

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
@lukatarman lukatarman force-pushed the refactoring/NR-65-refactoring-game-identifier branch from 0fbe661 to ccbc45a Compare February 15, 2024 14:45
# renamed aggregator
# added tests
# passed in logger through the games repository into aggregator
# removed fdescribe
# added tests
# adjusted test to reflect code
Copy link
Collaborator

@stas-at-ibm stas-at-ibm left a 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() {
Copy link
Collaborator

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.

Copy link
Owner Author

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

import { PlayerHistory } from "./player.history.js";
import { getXSampleSteamApps } from "./steam.app.mocks.js";

describe("game.js", function () {
describe("Game", function () {
describe(".copy", function () {
Copy link
Collaborator

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;
Copy link
Collaborator

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)
Copy link
Collaborator

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) {
Copy link
Collaborator

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) {
Copy link
Collaborator

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() {
Copy link
Collaborator

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);
Copy link
Collaborator

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 () {
Copy link
Collaborator

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 () {
Copy link
Collaborator

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?

Copy link
Owner Author

@lukatarman lukatarman Apr 10, 2024

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

@lukatarman lukatarman linked an issue Apr 11, 2024 that may be closed by this pull request
6 tasks
@lukatarman lukatarman merged commit d2e77db into master Apr 11, 2024
2 checks passed
Copy link
Collaborator

@stas-at-ibm stas-at-ibm left a 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) {
Copy link
Collaborator

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;
Copy link
Collaborator

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;
Copy link
Collaborator

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) {
Copy link
Collaborator

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;
Copy link
Collaborator

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);
Copy link
Collaborator

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?

Copy link
Owner Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor game identifier
2 participants