Repository: Mithrandir21/game-deals-android-app
Pull request #11: Add MODULES.md and update documentation
Author: login: Mithrandir21
Labels: name: documentation
description: Improvements or additions to documentation
Created: 2025-04-06T12:46:52Z | Merged: 2025-04-06T12:55:42Z

This pull request includes significant updates to the documentation and minor changes to the test files. The most important changes are the addition of a new section on module separation in `MODULES.md`, updates to the `README.md` file to include app explanations and usage, and a minor test code update in the `GameScreenTest` class.

Documentation updates:

* [`MODULES.md`](diffhunk://#diff-78287d98f6dd190df45b54fc6db0fa0c21bd8a20d88625b29511ad414b1b0f0aR1-R62): Added a comprehensive section on module separation, detailing its benefits, concerns, and existing issues with modularization in Android development.
* [`README.md`](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R4-R20): Updated to include explanations of the app's architecture, storage, module separation, domain layer, and testing strategies. Also included a list of suggested improvements for the app.


Diff:
diff --git a/MODULES.md b/MODULES.md
new file mode 100644
index 0000000..c778b59
--- /dev/null
+++ b/MODULES.md
@@ -0,0 +1,61 @@
+# Module separation
+Application logic separated into individual modules provides numerous benefits, such as clear separation of concern, built time improvements, clear dependency management and more.
+
+### Major benefits to module separation:
+
+##### :tada: Clear Separation of Concerns
+Separating related logic into specific modules prevents package, naming and location choices having to be made for each piece of logic that needs creating.
+
+##### :clipboard: Clear Understanding of Dependencies
+As modules only know of their own code, it will be necessary to explicitly state any dependencies, which in turn will show what logic is dependent on what other logic.
+
+##### :bulb: Small and Compact code
+Small pieces of logic, with clear dependencies, makes code readable and understandable, reducing complexity and allowing for better testing and development.
+
+##### :bell: Core Functionality + Features
+Modules allow core functionality, used in general scenarios, to be separate from specific features, used only occasionally and in specific scenarios.
+
+##### :rocket: Massively Improved Built Times
+Because each module is built separately and also re-built independently of other modules, only changed modules need to be re-compiled and re-built, allowing all unchanged modules to be reused.
+
+<hr />
+:warning: Note that the below image is a massive over-simplification of the complexities that go into a modular app, but it does demonstrate very well the intended idea behind modularisation.
+<img src="https://miro.medium.com/max/1400/1*Ujp5FfuGSqmrAMik0BzORA.png">
+
+<hr />
+
+### :warning: Modularisation - Concerns
+With every step forward in the sphere of software development, there are some trade-offs.
+
+###### Data Storage
+Because each module is separate, it is necessary to carefully consider the data storage needs of each module and the application as a whole. Any module specific data, which means data not needed by the rest of the app, must be stored in such a way that it does not break module separation, becoming unnecessarily exposed to the rest of the app.
+
+###### Transitive Dependencies
+Dependencies that are not direct, but come through another dependency are call Transitive Dependencies. It is important to keep this in mind when working with modules so that a modules dependencies are not forced onto other modules without an explicit need being present.
+
+###### Dependency Injection
+Using Dagger (Hilt) requires some setup to allow dependency inject to work correctly in a multi-module application. It is by no means impossible and already in use through the software development world. However, it does require a somewhat better understanding of dependency injection than in monolithic app development. Things such as Transitive Dependencies and any tool limitations must be kept in mind to not break the setup.
+
+###### External Dependencies
+Dependencies external to the app and its modules must be kept uniform, i.e. same version, to not create any unexpected behaviour. For example, the same exact version of RxJava must be used through all the application.
+
+###### Common Functionality
+Functionality that is shared by multiple modules, such as data classes, styling/theming and logging, must be separated out of each module and placed into their own module or a common module allowing for use by other modules. However, module specific functionality must be kept internal to each module. This assessment is not always easy to make and must be done carefully and considering the future needs of the app and other modules.
+
+###### Generated Code
+Code that is generated by a tool, such as Dagger or SafeArgs, might not always behave in the way one expects, so it very important to determine any logical or practical limitations of the code generating tool before using it in any of part of the code base.
+###### Merged Manifests
+Because each module will contain its own Manifest, which is merged into a final Manifest at build time, it is important to keep in mind issues that might arise from conflicting Manifest instruction.
+
+<hr />
+
+### :bomb: Modularisation - Existing Issues
+The following are existing issues with Modularisation with the current tools used in Android.
+
+###### :warning: Hilt & Transitive Dependencies
+Hilt/Dagger needs a specific flag enabled to allow the generated code access to any Transitive Dependencies, i.e. dependencies of dependencies. For example, if Module A depends only on Module B and Module B only depends on Module C, such that A ← B ← C, we need to enable the specific flag to allow Hilt/Dagger to be able to create the dependencies needed in B, namely C.<br>
+See [Suggestion needed for using Hilt in library modules](https://github.com/google/dagger/issues/1991)
+
+###### :warning: SafeArgs, Destinations and Modules
+The tools used to facilitate navigation (with data) between destinations in the app, Navigation Component and SafeArgs, are generating the necessary code in such a way that they need to know about specific destinations and their arguments. This means that if a Destination exists in Feature Module A, the app must know about (include as its dependency) Feature Module A. However, since we need to navigate away from the Destination that exists in Feature Module A to, say, a Destination in the Core, it follows that Feature Module A must know about (include as its dependency) the App Module. This cannot be as it massively breaks separation of concerns and the Feature modules will all end up depending on each other. [See detailed explanation](https://proandroiddev.com/androidx-navigation-building-on-the-wrong-abstraction-1d7c4a64318c).<br>
+This has been resolved by placing the Navigation Graph inside the a common Navigation module and using Fully Qualified names for the destinations and arguments. While this works and provides the desired output, it is nonetheless slightly brittle as Android Studio cannot keep track of names of files and belonging packages, so any changes in destinations and arguments might require manual updates in the Navigation Graph.
diff --git a/README.md b/README.md
index 31a4998..ef31a90 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,22 @@
 # game-deals-android-app
 A repository for an Android app showing game deals from CheapShark and GamerPower API
 
+#### App explanations
+- Architecture: MVVM
+- Storage: Room + SharedPreferences
+- Separation of code into logical modules (see [MODULES.md](MODULES.md))
+- Domain layer separation from API
+- Unit testing of standalone logic
+- Instrumentation testing of end-to-end journeys
+
+#### Usage
+- App can be used as a standalone app
+##### List of improvements
+- Instrumentation testing tooling should be improved to allow less boilerplate code and more generalisation and abstraction, allowing faster writing of tests.
+- App designs should be done by actual designer.
+- Themes and styles could be created for specific elements to allow faster and more uniform styling of the UI elements.
+- Pagination could be used for loading items from Room database.
+
 # External Tools
 ## Code Quality
 [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=Mithrandir21_game-deals-android-app)](https://sonarcloud.io/summary/new_code?id=Mithrandir21_game-deals-android-app)
diff --git a/feature/game/src/androidTest/java/pm/bam/gamedeals/feature/game/ui/GameScreenTest.kt b/feature/game/src/androidTest/java/pm/bam/gamedeals/feature/game/ui/GameScreenTest.kt
index 92fe188..04f7acc 100644
--- a/feature/game/src/androidTest/java/pm/bam/gamedeals/feature/game/ui/GameScreenTest.kt
+++ b/feature/game/src/androidTest/java/pm/bam/gamedeals/feature/game/ui/GameScreenTest.kt
@@ -194,9 +194,6 @@ class GameScreenTest {
             .assertIsDisplayed()
             .assertTextEquals(gameTitle)
 
-        composeTestRule.onNodeWithTag(GameDealItemTag)
-            .assertIsDisplayed()
-
         composeTestRule.onNodeWithTag(GameDealItemStoreTitleLabelTag, useUnmergedTree = true)
             .assertIsDisplayed()
             .assertTextEquals(mockStoreName)


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: 

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**feature/game/src/androidTest/java/pm/bam/gamedeals/feature/game/ui/GameScreenTest.kt:196**
* The removal of the assertion for 'GameDealItemTag' might reduce test coverage of the UI element. Please ensure that its absence does not leave a gap in verifying essential UI functionality.
```
composeTestRule.onNodeWithTag(GameDealItemTag)
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-06T12:47:30Z

Review comments:
diff_hunk: @@ -1,6 +1,23 @@
 # game-deals-android-app
 A repository for an Android app showing game deals from CheapShark and GamerPower API
 
+#### App explanations
+- Architecture: MVVM
+- Storage: Room + SharedPreferences
+- Separation of code into logical modules (see [MODULES.md](MODULES.md))
+- Domain layer separation from API
+- Unit testing of standalone logic
+- Instrumentation testing of end-to-end journeys
+
+#### Usage
+- App can used as standalone app
+
path: README.md
user: login: Copilot
body: There appears to be a grammatical error: 'App can used as standalone app' should be 'App can be used as a standalone app'.
```suggestion
- App can be used as a standalone app
```
created_at: 2025-04-06T12:47:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,62 @@
+# Module separation
+Application logic separated into individual modules provides numerous benefits, such as clear separation of concern, built time improvements, clear dependency management and more.
+
+### Major benefits to module separation:
+
+##### :tada: Clear Separation of Concerns
+Separating related logic into specific modules prevents package, naming and location choices having to be made for each piece of logic that needs creating.
+
+##### :clipboard: Clear Understanding of Dependencies
+As modules only know of their own code, it will be necessary to explicitly state any dependencies, which in turn will show what logic is dependent on what other logic.
+
+##### :bulb: Small and Compact code
+Small pieces of logic, with clear dependencies, makes code readable and understandable, reducing complexity and allowing for better testing and development.
+
+##### :bell: Core Functionality + Features
+Modules allow core functionality, used in general scenarios, to be separate from specific features, used only occasionally and in specific scenarios.
+
+##### :rocket: Massively Improved Built Times
+Because each module is built separately and also re-built independently of other modules, only changed modules need to be re-compiled and re-built, allowing all unchanged modules to be reused.
+
+<hr />
+:warning: Note that the below image is a massive over-simplification of the complexities that go into a modular app, but it does demonstrate very well the intended idea behind modularisation.
+<img src="https://miro.medium.com/max/1400/1*Ujp5FfuGSqmrAMik0BzORA.png">
+
+<hr />
+
+### :warning: Modularisation - Concerns
+With every step forward in the sphere of software development, there are some trade-offs.
+
+###### Data Storage
+Because each module is separate, it is necessary to carefully consider the data storage needs of each module and the application as a whole. Any module specific data, which means data not needed by the rest of the app, must be stored in such a way that it does not break module separation, becoming unnecessarily exposed to the rest of the app.
+
+###### Transitive Dependencies
+Dependencies that are not direct, but come through another dependency are call Transitive Dependencies. It is important to keep this in mind when working with modules so that a modules dependencies are not forced onto other modules without an explicit need being present.
+
+###### Dependency Injection
+Using Dagger (Hilt) requires some setup to allow dependency inject to work correctly in a multi-module application. It is by no means impossible and already in use through the software development world. However, it does require a somewhat better understanding of dependency injection than in monolithic app development. Things such as Transitive Dependencies and any tool limitations must be kept in mind to not break the setup.
+
+###### External Dependencies
+Dependencies external to the app and its modules must be kept uniform, i.e. same version, to not create any unexpected behaviour. For example, the same exact version of RxJava must be used through all the application.
+
+###### Common Functionality
+Functionality that is shared by multiple modules, such as data classes, styling/theming and logging, must be separated out of each module and placed into their own module or a common module allowing for use by other modules. However, module specific functionality must be kept internal to each module. This assessment is not always easy to make and must be done carefully and considering the future needs of the app and other modules.
+
+###### Generated Code
+Code that is generated by a tool, such a Dagger or SafeArgs, might not always behave in the way one expects, so it very important to determine any logical or practical limitations of the code generating tool before using it in any of part of the code base.
+
path: MODULES.md
user: login: Copilot
body: There's a likely typo: 'such a Dagger' should be 'such as Dagger'.
```suggestion
Code that is generated by a tool, such as Dagger or SafeArgs, might not always behave in the way one expects, so it very important to determine any logical or practical limitations of the code generating tool before using it in any of part of the code base.
```
created_at: 2025-04-06T12:47:30Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-04-06T12:54:46Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=Mithrandir21_game-deals-android-app&pullRequest=11) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=Mithrandir21_game-deals-android-app&pullRequest=11&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=Mithrandir21_game-deals-android-app&pullRequest=11&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=Mithrandir21_game-deals-android-app&pullRequest=11&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=Mithrandir21_game-deals-android-app&pullRequest=11&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=Mithrandir21_game-deals-android-app&pullRequest=11&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=Mithrandir21_game-deals-android-app&pullRequest=11)


author_association: NONE