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

Refactor GithubUser model to no longer encapsulate assignee role #379

Closed
wants to merge 4 commits into from

Conversation

kokerinks
Copy link
Contributor

@kokerinks kokerinks commented Jul 1, 2024

Summary:

This PR is in preparation for the enhancement proposed in the issue #342

Before this PR, the GithubUser model was responsible for storing information for both the authentication as well as details of assignees in each issue/PR. This PR turns them into two separate classes, keeping GitHubUser for authentication and moving the details of assignees to a new class Assignee.

This is done to ensure separation of roles between models. This will also improve code quality for future PRs related to the role of Assignees.

Type of change:

  • 🎨 Code Refactoring

Changes Made:

  • Created a new model Assignee
    • Similar in structure to the existing Milestone model
  • Replaced all instances where GithubUser is used as an assignee with Assignee
    • Significant changes were in assignee-grouping-strategy, where GithubUser is used heavily as an assignee

Proposed Commit Message:

Refactor GithubUser model to no longer encapsulate assignee role

Currently, GithubUser is responsible for two roles. One, it holds data
for the current user during and after Github authentication. Second, it
stores data for assignees of issues and PRs in the Github repository.

This commit refactors GithubUser to no longer encapsulate the assignee
role. Instead, it introduces a new class, Assignee, to encapsulate
assignee data. 

This change is important to support better cohesion of the components,
and facilitates easier maintenance and further development in both 
functions.

Checklist:

  • I have tested my changes thoroughly.
  • I have created tests for any new code files created in this PR or provided a link to a issue/PR that addresses this.
  • I have added or modified code comments to improve code readability where necessary.
  • I have updated the project's documentation as necessary.

@kokerinks kokerinks changed the title Kl/assignee filter Refactor Assignee model to no longer rely on GithubUser model Jul 1, 2024
@kokerinks kokerinks changed the title Refactor Assignee model to no longer rely on GithubUser model Refactor GithubUser model to no longer encapsulate assignee role Jul 1, 2024
@kokerinks kokerinks marked this pull request as ready for review July 1, 2024 14:19
Copy link
Contributor

@NereusWB922 NereusWB922 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kokerinks, l left some comments, pls lmk if you have any questions.

Comment on lines -23 to 29
getDataForGroup(issues: Issue[], key: GithubUser): Issue[] {
if (key === GithubUser.NO_ASSIGNEE) {
return this.getUnassignedData(issues);
}

return this.getDataAssignedToUser(issues, key);
getDataForGroup(issues: Issue[], key: Assignee): Issue[] {
return issues.filter(
(issue) => issue.assignees.includes(key.login) || (key === Assignee.WithoutAssignee && issue.assignees.length === 0)
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In WATcher, the issue model can represent either a GitHub Issue or a GitHub Pull Request. Therefore, in getDataAssignedToUser, we use different filtering logic: for GitHub Issues, we retrieve those assigned to the target; for GitHub Pull Requests, we retrieve those created by the target.

Comment on lines +1 to +22
import { Group } from './github/group.interface';

/**
* Represents an assignee and its attributes fetched from Github.
*/
export class Assignee implements Group {
static WithoutAssignee: Assignee = new Assignee({ login: 'Issues/PRs without an assignee', avatar_url: null });
login: string;
avatarUrl: string;

constructor(assignee: { login: string; avatar_url: string }) {
this.login = assignee.login;
this.avatarUrl = assignee.avatar_url;
}

public equals(other: any) {
if (!(other instanceof Assignee)) {
return false;
}
return this.login === other.login;
}
}
Copy link
Contributor

@NereusWB922 NereusWB922 Jul 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the need for a new class to represent an assignee since an assignee can only be a GitHub User. Unless the assignee has different behaviors or fields from a GitHub user, creating a new class seems unnecessary. Additionally, you created a new service for the assignee, which just parses data from the GitHub user.

If the concern is about methods that only require the "login" and "avatarUrl" fields shouldn't have access to other fields of Github User, a simpler solution would be to create an interface called Assignee with these fields and have the GitHub user implement this interface. This way, methods requiring an assignee can use the Assignee type, ensuring only the assignee-specific fields are accessed.

I might be wrong about this, so please feel free to discuss further if you have different considerations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NereusWB922 okay, after working deeper on the filter PR I think i have a better understanding of the role of each of the models and services.. will try to incorporate the new filter without using a new assignee model

that said, having a new service for assignee is fine right? I'll just rewrite it so that it uses githubUsers instead of the new assignee model class

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kokerinks, then in this case, you can just use the method getUsersAssignable from github service right? New service seems unnecessary also.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i think it would make the code less easy to understand though. i intentionally designed assignee.service.ts to be similar in structure to milestone.service.ts, since they both have a similar purpose of handling logic for their respective filters.assignee.service.ts currently also "caches" the assignees taken from getUsersAssignable, which will help to reduce calls to github APIs.

There are some options i see here:

  1. Use getUsersAssignable to retrieve each time and without any caching
  • will cause structure of assignee filter implementation to differ from milestone
  • will result in more github api calls
  1. Implement caching in github.service.ts
  • code structure would not be consistent with milestone.service.ts, where the milestones are "cached" at
  1. Implement caching in a new assignee.service.ts
  • will result in a new file, but will align better with the current milestone filter implementation in terms of code structure

Personally, I think having the new file is necessary.. i understand the potential concern of having too many service files, but maybe we can reorganise the services into new folders to declutter the services folder.

bit of a read, let me know what you think!

Copy link
Contributor

@NereusWB922 NereusWB922 Jul 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kokerinks, thanks for the detailed explanation. I can see where you are coming from and agree that having the logic related to filtering in the GitHub service would make it too complicated. Please go ahead with your idea but just remove the Assignee model. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just let me know when this pr is ready for review again. Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, will be closing this PR and reimplementing it in #381 alongside the assignee filter implementation. will tag you in it for review once its ready

@kokerinks
Copy link
Contributor Author

Reimplementing it in #381 alongside the assignee filter implementation

@kokerinks kokerinks closed this Jul 8, 2024
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.

3 participants