Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
3036649
added base entities
heklly Nov 10, 2025
0758001
Merge pull request #2 from heklly/create_base_entities
DevR0912 Nov 10, 2025
e1f042b
Update README.md
heklly Nov 15, 2025
2f32758
Update pom.xml, spotify api
heklly Nov 15, 2025
eab6668
Update README.md
heklly Nov 15, 2025
e48ea81
Update README.md
heklly Nov 15, 2025
855e09b
usecase for use story 3, untested, on Nov 16
Nov 17, 2025
75ce015
framework for loyalty scoring, interfaces, JSONParser and scoring alg…
heklly Nov 17, 2025
a2f1a83
Added Spotify OAuth authentication with loopback server (CallbackServ…
c0ffeec0des Nov 17, 2025
7946a4c
Create Group use case
samiwal1a Nov 17, 2025
f7c0d53
Updated Group Entity to include Owner, and maximum
samiwal1a Nov 17, 2025
cf13b39
Create Group Interface Adapters
samiwal1a Nov 17, 2025
a7efb9c
simplifying, getting rid of track loyalty score
heklly Nov 17, 2025
b462e59
Current Progress
heathanderrr Nov 17, 2025
91752fa
Revert "Current Progress"
heathanderrr Nov 17, 2025
6634508
Fleshed out UCI and started working on shared song presenter and cont…
heathanderrr Nov 18, 2025
ef5291f
Merge pull request #9 from heklly/create_group
2790125751tbh-oss Nov 18, 2025
6ea5d05
Some basic outline for the group analytics
DevR0912 Nov 19, 2025
887629e
Revert "Some basic outline for the group analytics"
heathanderrr Nov 19, 2025
10ec6ec
Refactored some
heathanderrr Nov 19, 2025
de6b5f0
Finetuned the login flow and changed authorization flow to PKCE.
c0ffeec0des Nov 20, 2025
6b2b948
Added Group getUsers method
heathanderrr Nov 20, 2025
66d4648
noticed that Jennifer and I's implementation are a bit conflicting. N…
heklly Nov 20, 2025
33a3542
fix Actiontype meaning, complete DataAccess through API request, unTe…
Nov 21, 2025
5594a59
Added placeholder files for implementing GUI. Also, renames are consi…
heklly Nov 21, 2025
e7434a9
Merge pull request #7 from heklly/loyalty
SYzhao666 Nov 22, 2025
f5db17a
Fixed Group.getUsers to avoid conflict
heathanderrr Nov 23, 2025
c940356
Merge remote-tracking branch 'origin/main' into SharedSongUseCaseCurr…
heathanderrr Nov 23, 2025
6c06f19
Merge branch 'main' into spotify-auth-and-loyalty-score
heklly Nov 23, 2025
826d5ee
Merge pull request #13 from heklly/spotify-auth-and-loyalty-score
heklly Nov 23, 2025
e2559fc
made the file structure cleaner
Nov 24, 2025
523eb8b
implemented DataAccessObject using JSON + test. Also, tiny changes to…
heklly Nov 24, 2025
5531d35
some progress in interface_adapter and use_case3
Nov 24, 2025
5d47523
implemented UI, interactor, and LoyaltyDataAccessInterface. implement…
heklly Nov 24, 2025
76b4521
finish daily mix part
SYzhao666 Nov 24, 2025
83e2919
Merge pull request #15 from heklly/fix_structure
samiwal1a Nov 24, 2025
b220466
Merge branch 'main' into loyalty
heklly Nov 24, 2025
aeb4c11
Merge remote-tracking branch 'origin/main' into use_case3
Nov 24, 2025
b57640e
made the file structure cleaner
Nov 24, 2025
e1c62a4
got rid of date in user
Nov 24, 2025
3ea1e00
set up leave group files
heathanderrr Nov 24, 2025
988b635
Merge branch 'fix_structure' into use_case3
Nov 24, 2025
5c3f47f
pause
heathanderrr Nov 24, 2025
0eaf74f
Merge remote-tracking branch 'origin/main' into SharedSongUseCaseCurr…
heathanderrr Nov 24, 2025
52b246a
Refactor
heathanderrr Nov 24, 2025
d22e606
refactored... everything to use SpotifyUser instead of User. Also, de…
heklly Nov 24, 2025
5f0167e
Merge pull request #12 from heklly/SharedSongUseCaseCurrentProgress
DevR0912 Nov 24, 2025
9c72846
Merge pull request #18 from heklly/merge-User-to-SpotifyUser
DevR0912 Nov 24, 2025
bcdc960
Added group analytics features
DevR0912 Nov 24, 2025
c160cce
fix adapter_interface and usecase
Nov 24, 2025
453dcd4
fix adapter_interface and usecase
Nov 24, 2025
abedd16
git rid of user, use SpotifyUser instead
Nov 24, 2025
d55ab5e
git rid of user, use SpotifyUser instead
Nov 24, 2025
7a41b56
Merge remote-tracking branch 'origin/main' into use_case3
Nov 24, 2025
f42ad11
Merge branch 'main' into final-daily-mix
heklly Nov 24, 2025
a5d937c
Merging daily-mix into main
heklly Nov 24, 2025
7e328f6
finished use_case3 DAO
Nov 25, 2025
15e1aaa
Merge remote-tracking branch 'origin/main' into use_case3
Nov 25, 2025
8926f99
got userstory3 view, app done, renamed songs to TopItems, CAUTION: so…
Nov 25, 2025
4de2556
Fleshed out more and made more progress
heathanderrr Nov 25, 2025
29bb51e
structure of getTopItemInteractorTest
Nov 25, 2025
d571762
finalizing changes to view, presenter. minor changes to use cases. Us…
heklly Nov 25, 2025
b25a7a2
Merge pull request #25 from heklly/finalize-view-loyalty
2790125751tbh-oss Nov 25, 2025
d84b764
Merge remote-tracking branch 'origin/main' into use_case3
Nov 25, 2025
244f9e6
finished getTopItemInteractorTest and added into AppBuilder
Nov 26, 2025
437168b
Merge pull request #5 from heklly/use_case3
2790125751tbh-oss Nov 26, 2025
1a9e700
Test case fails but it compiles. Most things should be fixed. Still w…
heathanderrr Nov 26, 2025
ba0fad5
minor changes to LoyaltyScoreView
heklly Nov 26, 2025
50f5b17
minor changes to view
heklly Nov 26, 2025
b878315
Merge branch 'main' into finalize-view-loyalty
heklly Nov 26, 2025
04feb28
LeaveGroup + views. Not done yet. Needs test etc.
heathanderrr Nov 26, 2025
ffcb537
LeaveGroup + views. Not done yet. Needs test etc.
heathanderrr Nov 26, 2025
eb3ec22
Merge branch 'main' into groupAnalytics
samiwal1a Nov 26, 2025
743d836
Merge pull request #19 from heklly/groupAnalytics
samiwal1a Nov 26, 2025
4074d6e
Merge remote-tracking branch 'origin/main' into LeaveGroup
heathanderrr Nov 27, 2025
9153fb4
forgot to commit b/4 push...
heklly Nov 30, 2025
097babb
Merge branch 'main' into finalize-view-loyalty
heklly Nov 30, 2025
a3a9197
undoing broken files, so project merges AGAIN.
heklly Nov 30, 2025
077d6dc
Merge branch 'main' into finalize-view-loyalty
heklly Nov 30, 2025
8099d19
Merge pull request #27 from heklly/finalize-view-loyalty
heklly Nov 30, 2025
c491cde
Revert "Merge pull request #27 from heklly/finalize-view-loyalty"
heklly Nov 30, 2025
7533acc
small changes to make sure things compile
heklly Nov 30, 2025
6706094
making view a bit nicer
heklly Nov 30, 2025
f9a2f96
Merge pull request #28 from heklly/finalize_view_loyalty
heklly Nov 30, 2025
a817239
fixed up logged in view and hooked up loyalty scores to it. Added a c…
heklly Nov 30, 2025
6c94c31
Merge pull request #29 from heklly/logged_in_view
2790125751tbh-oss Nov 30, 2025
8b9af1a
LeaveGroup + Group views.
heathanderrr Nov 30, 2025
1578e59
readd in generate top items button
heklly Nov 30, 2025
8e85961
Merge pull request #30 from heklly/logged_in_view
2790125751tbh-oss Nov 30, 2025
3f0e525
Merged in main updates and resolved conflicts
heathanderrr Dec 1, 2025
cd1ef26
Merged in main updates and resolved conflicts. Fixed some stuff that …
heathanderrr Dec 1, 2025
fd82553
Merge remote-tracking branch 'origin/main' into sharedsong-fixes-and-…
heathanderrr Dec 1, 2025
31be187
Merge branch 'LeaveGroup' into sharedsong-fixes-and-test
heathanderrr Dec 1, 2025
5cdad7b
Merged in main updates and resolved conflicts. Fixed some stuff that …
heathanderrr Dec 1, 2025
a76ca01
minor changes
DevR0912 Dec 1, 2025
47b7aca
Final changes
DevR0912 Dec 1, 2025
640f8be
Merge remote-tracking branch 'origin/main' into LeaveGroup
heathanderrr Dec 2, 2025
c246072
Merge pull request #34 from heklly/LeaveGroup
samiwal1a Dec 2, 2025
1c5ebdc
Merge remote-tracking branch 'origin/main' into LeaveGroup
heathanderrr Dec 2, 2025
932e438
Merge branch 'main' into groupAnalytics
DevR0912 Dec 2, 2025
1fd9786
Merge pull request #35 from heklly/groupAnalytics
DevR0912 Dec 2, 2025
5718bfe
Fixed issues group implementation caused.
c0ffeec0des Dec 2, 2025
56b01ac
deleting unnecessary use cases from template code
heklly Dec 2, 2025
ca17c45
Merge branch 'main' into logged_in_view
heklly Dec 2, 2025
9027bbc
Merge pull request #37 from heklly/logged_in_view
heklly Dec 2, 2025
2170832
Forgot to commit these quickly. Fixed a compile error.
heathanderrr Dec 2, 2025
9ca9948
Removed duplicated methods; added some defaulting logic so code compiles
heklly Dec 2, 2025
6ee3dbf
Merge pull request #38 from heklly/fix_compile
heklly Dec 2, 2025
48b91cc
Forgot to commit these quickly. Fixed a compile error.
heathanderrr Dec 2, 2025
8729f69
Merge remote-tracking branch 'origin/main' into LeaveGroup
heathanderrr Dec 2, 2025
31e6471
test
samiwal1a Dec 2, 2025
bd01516
Forgot to commit these quickly. Fixed a compile error.
heathanderrr Dec 2, 2025
d7e065b
Merge pull request #39 from heklly/LeaveGroup
samiwal1a Dec 2, 2025
35a709a
added SpotifyUserDataAccessObject
samiwal1a Dec 2, 2025
0c9d708
added GroupDataAccessObject
samiwal1a Dec 2, 2025
15a69dc
added GroupDataAccessInterface and cleaned up some things
samiwal1a Dec 2, 2025
457e6e2
trying to clean up group entity
samiwal1a Dec 2, 2025
cac41f5
trying to clean up CreateGroupInteractor
samiwal1a Dec 2, 2025
baec3db
trying to clean up some things in input data (adding getusers, deleti…
samiwal1a Dec 2, 2025
969c75d
cleaned up some things in LeaveGroupController
samiwal1a Dec 2, 2025
4db584e
tried to fix an issue in inputs for leave group in group view
samiwal1a Dec 2, 2025
73661c6
fixed CreateGroupOutputData so it doesnt use owner, changed group ent…
samiwal1a Dec 2, 2025
bbbf133
working on loggedinview 1
samiwal1a Dec 2, 2025
5a24e5d
working on loggedinview 2
samiwal1a Dec 2, 2025
8576e54
initialize creategroupcontroller
samiwal1a Dec 2, 2025
01cf751
grouptabbutton
samiwal1a Dec 2, 2025
55988e2
Group tab button listeners
samiwal1a Dec 2, 2025
86cd489
Go to Group View Button
samiwal1a Dec 2, 2025
da59059
adding grouppanel to top wrapper
samiwal1a Dec 2, 2025
370bf89
adding groupbuttonspanel
samiwal1a Dec 2, 2025
fa23e33
go to group setenabled
samiwal1a Dec 2, 2025
75a0ed6
Merge remote-tracking branch 'origin/main' into spotify-auth-and-loya…
c0ffeec0des Dec 2, 2025
37e87db
group helpers
samiwal1a Dec 2, 2025
d0810a5
setting creategroupcontroller
samiwal1a Dec 2, 2025
6c5de8d
updating SpotifyUser
samiwal1a Dec 2, 2025
a5743dd
updates to help compile
samiwal1a Dec 2, 2025
12edf71
Fixed issues group implementation caused.
c0ffeec0des Dec 2, 2025
4c2aee3
Merge pull request #36 from heklly/spotify-auth-and-loyalty-score
c0ffeec0des Dec 2, 2025
b20b54e
Fixed SpotifyUserDataAccessObject so it actually stores spotifyusers …
samiwal1a Dec 2, 2025
c8eedd1
Fixed SpotifyUserDataAccessObject so it actually stores spotifyusers …
samiwal1a Dec 2, 2025
19a373f
Merge branch 'main' of github.com:heklly/BetterWrapped-team3project
samiwal1a Dec 3, 2025
0e2899b
Merge remote-tracking branch 'origin/main' into sharedsong-fixes-and-…
heathanderrr Dec 3, 2025
5da64ad
Created tests for full coverage
samiwal1a Dec 3, 2025
c9afb05
Merge pull request #41 from heklly/finaledits
samiwal1a Dec 3, 2025
63e3459
Merge remote-tracking branch 'refs/remotes/origin/main' into sharedso…
heathanderrr Dec 3, 2025
2a5e089
Forgot to commit these quickly. Fixed a compile error.
heathanderrr Dec 3, 2025
eed4c70
Merge pull request #42 from heklly/sharedsong-fixes-and-test
heathanderrr Dec 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,14 @@ build/
.DS_Store

### other files ###
users.csv
users.csv

# Environment variables
.env
.env.local
.env.development
.env.production

# Configuration files with secrets
config.properties
*.config
254 changes: 6 additions & 248 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,252 +1,10 @@
# Clean Architecture Team Lab Activity: Login and Logout
Cleaned out this readme. Add stuff here

In this team lab activity, your team will:
- explore an existing use case (login)
- add a new use case (logout).
Original readme from here:
https://github.com/CSC207-2025F-UofT/ca-lab/blob/main/README.md

To earn credit:
- your team must demo your working `logout` use case.
Also, Spotify WebAPi Java wrapper in case we want to use it.
https://github.com/spotify-web-api-java/spotify-web-api-java?tab=readme-ov-file

Your demo should be similar to the below example:
> import se.michaelthelin.spotify.SpotifyApi; to access the api

![](images/sample-logout.gif)

---

## Task 0: Fork this repo on GitHub
**To get started, one team member should fork this repo on GitHub and share it with the team.
All team members should then clone it.**


**Suggested logistics:** One of you should invite the others to collaborate on their fork of the original repo on GitHub. You can do this in your repo on GitHub under `Settings -> Collaborators`. This will allow you to push branches to a common repo and then use pull requests to contribute your code and review. To prevent others from pushing directly to the main branch, we recommend that you set branch protection rules on GitHub. Below are how the settings might look if you add branch protection rules:

![image of branch protection rules for main with a requirement of two approvers to merge in pull requests.](images/branch_protection_rules.png)

---

## Task 1: Understanding the Program

Open the project in IntelliJ. Open `app.Main` and read it as a team.
- What are the currently implemented Views and Use Cases in the program?
- Which Use Cases are triggered from each View?
- Which version of the DAO is `app.Main` using?

> Observe that the main method makes use of the `app.AppBuilder` class which
is responsible for constructing our CA engine for each use case of the application. To answer the last two questions above, you will need to look inside the details of the `app.AppBuilder` class.

**Make sure that each member of your team can successfully run `app/Main.java`.**
- Ensure that you are each able to create a new user and log in using the username and password.

> Note: you may need to set the Project SDK in the `Project Structure...` menu, and possibly
> also manually link the Maven project if the app won't run when you try to run Main.

### Task 1.1: Exploring the login use case

Let's take a tour of the login use case code:

- In IntelliJ, find the `LoginController` class and open it.

- Set a breakpoint inside its `execute` method.

- Run the program in debug mode.

- On the login page, attempt to log in with an existing account. When you click the button, the breakpoint that you set will be triggered.

- **Step through the code to trace the execution of the login use case.**
Importantly, pay extra close attention to what the Presenter does to ensure that the LoggedInView gets displayed after the user successfully gets logged into the application.

The code is designed based on our CA Engine that was introduced in the reading this week. For reference, here is our CA Engine diagram:

![The Clean Architecture Engine diagram](images/CA-Engine.png)

> Pay attention to the classes involved and the flow of execution. When your team implements the logout use case next, your code will need to have a very similar structure.

To better understand how the view gets updated, your team may find it useful to review the [Extra Advice about the Presenters, Views, and ViewModels](#extra-advice-about-the-presenters-views-and-viewmodels) section at the end of this README.

## Task 2: Implementing the Logout Use Case

Currently, you'll notice that the "Log Out" button in the `LoggedInView` still doesn't actually log you out of the program. Let's fix this.

We have created all the classes for your team, but some of the code is missing. **As a team, your task is to fill in the missing code so that the logout use case is functional.**

> The next part of the readme describes how your team will do this.

Your team will know when you are done when:

- Clicking the "Log Out" button takes the user back to the Login View when you use the program.
- On the Login View, the username of the logged-out user is filled in.
- The provided `LogoutInteractorTest` test passes.

### Task 2.1: Dividing up the work

There are `TODO` comments left in the files.

> Recall that you can use the TODO tool window to conveniently pull up a complete list.

Once all TODOs are complete, the "Log Out" button _should_ work!

**As a team, split up the TODOs (see below) between the members of your team.**

> Optionally, your team can make GitHub Issues and assign them to each team member.

Make sure that each member has at least one TODO that they will be responsible for completing.
If your team prefers to work in pairs, that is fine too.

The TODOs are summarized below (by file) to help your team decide how to split them up:

---

- `Main.java` (tip: look at how other use cases have been added)
-[ ] TODO: add the logout use case to the app

---

- `LoggedInView.java` (tip: refer to the other views for similar code)
-[ ] TODO: save the logout controller in the instance variable.
-[ ] TODO: execute the logout use case through the Controller

---

- `LogoutController.java` (tip: refer to the other controllers for similar code)
-[ ] TODO: Save the interactor in the instance variable.
-[ ] TODO: run the use case interactor for the logout use case

> Note: there is no input data necessary for this use case.

---

- `LogoutInteractor.java` (tip: refer to `ChangePasswordInteractor.java` for similar code)
-[ ] TODO: save the DAO and Presenter in the instance variables.
-[ ] TODO: implement the logic of the Logout Use Case

> Note: there is no input data necessary for this use case.

---

- `LogoutPresenter.java` (tip: refer to `SignupPresenter.java` for similar code)
-[ ] TODO: assign to the three instance variables.
-[ ] TODO: have prepareSuccessView update the LoggedInState
-[ ] TODO: have prepareSuccessView update the LoginState

---

### Task 2.2: Complete your TODOs!
With the work divided up, your team should complete the TODOs through a sequence of PRs.

1. Make a branch for your work.

> Make sure that you switch to your new branch!

2. Complete your assigned TODO and make a pull request on GitHub. In your pull request,
briefly describe what your TODO was and how you implemented it. If you aren't sure
about part of it, include this in your pull request so that everyone knows what to look
for when reviewing — or you can of course discuss with your team before making your
pull request.

3. Review all pull requests to ensure each TODO is correctly implemented.

4. Once all TODOs are completed, your team should debug as needed to ensure the
correctness of the code. Setting a breakpoint where the logout use case
interactor starts its work will likely be a great place to start when debugging.

And that's it; your team should now have a working logout use case!

**Demo your working code to your TA to earn credit.**

---

# Extra Advice about the Presenters, Views, and ViewModels

One of the trickiest parts of the code will be the flow of information between these pieces of the program. Below briefly explains how these pieces fit together and work in the context of the login use case.

## ViewModels and States

In the design of this program, `ViewModel` is written using generics to allow
for different "state" objects to be stored. For a `LoginViewModel`, the state is an instance of class `LoginState`. Each state object will just contain a basic constructor, getters, and setters to store the data of the view model.

## A View and its ViewModel

In the constructor of `LoginView`, the following line of code connects this instance of `LoginView` to its associated `LoginViewModel`:

```java
this.loginViewModel.addPropertyChangeListener(this);
```

This should remind you of the code we write when adding an action listener to a button. The code is following the same structure.

> We'll talk more about this "pattern" of _events_ and _listeners_ in our next module.

When the presenter updates the view model later, an event will be triggered — resulting in the view's `propertyChange` method getting called, with a `PropertyChangeEvent` object being passed through as the argument to the call.

For example, the `LoginView.propertyChange` method looks like:

```java
public void propertyChange(PropertyChangeEvent evt) {
final LoginState state = (LoginState) evt.getNewValue();
setFields(state);
usernameErrorField.setText(state.getLoginError());
}
```

The `LoginView` gets the `LoginState` object stored in the `LoginViewModel` and updates itself with that information.

## A Presenter and its ViewModel(s)

A presenter may have one or more view models associated with it. For example, the login use case's presenter has a reference to a `LoginViewModel` and a `LoggedInViewModel`, since it will need to update both view models. Additionally, our implementation makes use of a `ViewManager` and `ViewManagerModel` to keep track of which view
the user should currently see.

Let's take a look at the `LoginPresenter.prepareSuccessView` method as an example:

```java
public void prepareSuccessView(LoginOutputData response) {
// On success, update the loggedInViewModel's state
final LoggedInState loggedInState = loggedInViewModel.getState();
loggedInState.setUsername(response.getUsername());
this.loggedInViewModel.firePropertyChanged();

// and clear everything from the LoginViewModel's state
this.loginViewModel.setState(new LoginState());
this.loginViewModel.firePropertyChanged();

// switch to the logged in view
this.viewManagerModel.setState(loggedInViewModel.getViewName());
this.viewManagerModel.firePropertyChanged();
}
```

The first part of the code updates the view model for the logged-in view so that the newly logged-in username will be displayed. Once the state is updated, the `firePropertyChanged` method is called, which is what will trigger the call to the view's `propertyChange` method which will update the view based on the updated view model.

This can be visualized as a sequence diagram as follows:

> Note: this diagram has been simplified to focus on the high-level flow of information; the actual stack trace includes some additional intermediate calls which you can see if you step through the code in the debugger or manually click through the code.

![sequence diagram of the LoginPresenter code](images/login_presenter_sequence_diagram.png)

We then do the same, but for the login view model whose state we want to clear.

Lastly, we update the state of the `viewManagerModel`, and alert the viewManager that it should switch to displaying the logged-in view.

> Setting a breakpoint in the code and stepping through can help you see how the information flows through the system. Pay attention to the contents of the call stack to help you track where you are in the execution of the use case.

## The ViewManager

This class may stand out as a bit unclear about how it fits into our architecture, as it isn't in the CA Engine diagram at all. Remember that the CA Engine is representing a single use case in our program. Once our program has _multiple_ use cases, we naturally need some kind of additional code to connect them together. As we have seen, one use case can lead to a change in which view is presented to the user. To facilitate this, our implementation used a `ViewManager` and associated `ViewManagerModel` to take care of this switching for us. The state of a `ViewManagerModel` object is simply a string that indicates the name of the currently visible view (`JPanel` in this implementation). The `ViewManager` uses a `CardLayout` to conveniently display only the currently active view at a given time.

When the `ViewManager` is alerted of a change to its associated `ViewManagerModel`, its `propertyChange` method is executed:

```java
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("state")) {
final String viewModelName = (String) evt.getNewValue();
cardLayout.show(views, viewModelName);
}
}
```

This code will update the application to display the view corresponding to the `viewModelName` string.

> In the `AppBuilder` code, you can see how the views are originally added to the `cardLayout`.

> Thought Question: Can you think of any alternatives to our `ViewManager` implementation for managing multiple views?

---
Loading