diff --git a/.editorconfig b/.editorconfig
index 762d29c8..a1324524 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,7 +1,16 @@
-[*.{kt, kts, java, xml, gradle, md}]
+[*.{kt,kts,java,xml,gradle,md}]
+
+# General rules
disabled_rules = import-ordering, filename
wildcard_import_limit = 999
+
+# Kotlin rules
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
ij_java_class_count_to_use_import_on_demand = 999
-max_line_length = 120
+
+# Line rules
+max_line_length = 160
+end_of_line = lf
+insert_final_newline = true
+ij_any_method_annotation_wrap = split_into_lines
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..032e9a9c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# app/features/src/debug/**/*.png filter=lfs diff=lfs merge=lfs -text
+**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3a82c9ea..a78aeedf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,14 @@
.cxx
repo
/artifacts
-
+ci/.idea
+ci/env
+app/android/r8
+.kotlin/
+signing.properties
+erp-release-keystore-huawei.jks
+erp-release-keystore-play.jks
+requirements-report.html
Jenkinsfile
Nightly.Jenkinsfile
Archive.Jenkinsfile
@@ -21,14 +28,27 @@ DependencyReport.Jenkinsfile
EspressoTest.Jenkinsfile
Release.Jenkinsfile
Multibranch.Jenkinsfile
-ci
ci-overrides.properties
nexus-init.gradle.kts
-documentation-internal
-android/src/androidTest
technical_requirements_report.html
-keystore
CODEOWNERS
local.cliactions.yaml
+**/virtual_smartcards.json
+2021_s.csv
+2024_s.csv
+mapping.txt
+.aiexclude
+sonar-project.properties
+.snyk
+keystore
jenkinsfiles
+desktop
+smartcard-wrapper
+common/src/desktopMain
+app/test-actions
+documentation-internal
+app/android/src/androidTest
+ci
+requirements
+gutachter
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..ba4cd8b2
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,75 @@
+## Code of Conduct
+
+### Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+### Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Calls for violence, vilification and advertising
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+### Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+### Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+### Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at OSPO@gematik.de. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+### Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..a7060fa6
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,62 @@
+# Welcome to the gematik contributing guide
+
+Thank you for investing your time in contributing to our projects!
+
+Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
+
+In this guide you will get an overview how you can contribute to our projects by opening an issue, creating, reviewing and merging a pull request.
+
+Use the table of contents icon on the top left corner of this document to get to a specific section of this guide quickly.
+
+## Reporting a security vulnerability
+
+Please do not report vulnerabilities and security incidents as GitHub issues. Please contact us by sending an E-Mail to TODO or report them using the contact form at https://fachportal.gematik.de/kontaktformular.
+
+## New contributor guide
+
+To get an overview of the project, read the [README](./README.md).
+
+## Getting started
+
+### Issues
+
+#### Create a new issue
+
+If you spot a problem or have a feature request, search if an issue already exists.
+If a related issue doesn't exist, you can open a new issue.
+
+#### Solve an issue
+
+Scan through our existing issues to find one that interests you. If you find an issue to work on, you are welcome to open a PR with a fix.
+
+### Coding Style
+
+gematik projects follow the kotlin style guide conventions, see [kotlin style guide android](https://developer.android.com/kotlin/style-guide) or [kotlin lang style guide](https://kotlinlang.org/docs/coding-conventions.html). Please follow them when working on your contributions.
+
+### Code Coverage, Sonars, OWASP, Code format, etc.
+
+- CodeFormat & Style: Please check your code with Ktlint and Detekt. commands: "./gradlew ktlintformat" & "./gradlew detekt"
+- Code Coverage: If you add UseCases or ViewModels please add corresponding UnitTests as well.
+- Code Coverage: If you add or change UI make sure these changes are covered by screenshotstests "./gradlew verifyPaparazziDebug".
+
+
+### Commit your update
+
+Commit the changes once you are happy with them.
+
+### Pull Request Process
+
+- When you're finished with the changes, create a pull request, also known as a PR.
+- Fill the pull request template so that we can review your PR. This template helps reviewers to understand your changes as well as the purpose of your pull request.
+- Don't forget to [link the PR to the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
+- Once you submit your PR, a project team member will review your proposal. We may ask questions or request additional information.
+- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request)
+ or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
+- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
+- If your pull request is approved by our developers, we may merge it into the project.
+
+### Your PR is merged!
+
+Congratulations: The gematik team thanks you.
+
+Once your PR is merged, your contributions will be publicly visible on the [gematik github page](https://github.com/gematik/).
diff --git a/LICENSE.md b/LICENSE.md
index 9348db2a..bfac47dd 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,14 +1,14 @@
+# License
Copyright (c) 2024 gematik GmbH
-
Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
the European Commission - subsequent versions of the EUPL (the Licence);
You may not use this work except in compliance with the Licence.
You may obtain a copy of the Licence at:
- https://joinup.ec.europa.eu/software/page/eupl
+https://joinup.ec.europa.eu/software/page/eupl
Unless required by applicable law or agreed to in writing, software
distributed under the Licence is distributed on an "AS IS" basis,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the Licence for the specific language governing permissions and
-limitations under the Licence.
\ No newline at end of file
+limitations under the Licence.
diff --git a/README.md b/README.md
index 28c18ce5..6641e65c 100644
--- a/README.md
+++ b/README.md
@@ -1,60 +1,57 @@
-# E-Rezept App
-## Introduction
-
+
+
+# E-Rezept App
+
+## Table Of Contents
+
+- [About The Project](#about-the-project)
+ - [Release Notes](#release-notes)
+- [Getting Started](#getting-started)
+ - [Prerequisites](#prerequisites)
+ - [Structure](#structure)
+ - [Installation](#installation)
+- [Usage](#usage)
+- [Contributing](#contributing)
+- [Security And Privacy](#security-and-privacy)
+- [License](#license)
+- [Contact](#contact)
+- [Additional Links And Sourcecode](#additional-links-and-sourcecode)
+
+## About The Project
Prescriptions for medicines that are only available in pharmacies can be issued as electronic prescriptions (e-prescriptions resp. E-Rezepte) for people with public health insurance from 1 July 2021.
The official gematik E-Rezept App (electronic prescription app) is available to receive and redeem prescriptions digitally. Anyone can download the app for free:
[![Download E-Rezept on the App Store](https://user-images.githubusercontent.com/52454541/126137060-cb8c7ceb-6a72-423d-9079-f3e1a98b2638.png)](https://apps.apple.com/de/app/das-e-rezept/id1511792179)[![Download E-Rezept on the PlayStore](https://user-images.githubusercontent.com/52454541/126138350-a52e1d84-1588-4e8a-86df-189ee4df8bc8.png)](https://play.google.com/store/apps/details?id=de.gematik.ti.erp.app)[![Download E-Rezept on the App Gallery](https://user-images.githubusercontent.com/52454541/126158983-15d73f12-36c6-41ce-8de5-29d10baaed04.png)](https://appgallery.huawei.com/#/app/C104463531)
-and login with the health card of the public health insurance. In July 2021, the e-prescription started with a test phase, initially in the focus region Berlin-Brandenburg. The nationwide rollout started three month later in September 2022.
+or as an apk here in GitHub: [Releases](https://github.com/gematik/E-Rezept-App-Android/releases)
+
+Login is possible with the health card or the app of the users public health insurance company. In July 2021, the e-prescription started with a test phase, initially in the focus region Berlin-Brandenburg. The nationwide rollout started three month later in September 2022.
The e-prescriptions are stored in the telematics infrastructure, for which gematik is responsible.
Visit our [FAQ page](https://www.das-e-rezept-fuer-deutschland.de/faq) for more information about the e-prescription.
-### Support & Feedback
-
-For endusers and insurant:
-
-[![E-Rezept Webseite](https://img.shields.io/badge/web-E%20Rezept%20Webseite-green?logo=web.ru&style=flat-square&logoColor=white)](https://www.das-e-rezept-fuer-deutschland.de/)
-[![eMail E-Rezept](https://img.shields.io/badge/email-E%20Rezept%20team-green?logo=mail.ru&style=flat-square&logoColor=white)](mailto:app-feedback@gematik.de)
-[![E-Rezept Support Telephone](https://img.shields.io/badge/phone-E%20Rezept%20Service-green?logo=phone.ru&style=flat-square&logoColor=white)](tel:+498002773777)
-
-Members of the health-industry with functional questions
-
-[![eMail E-Rezept Team](https://img.shields.io/badge/web-E%20Rezept%20Industrie-green?logo=web.ru&style=flat-square&logoColor=white)](https://www.gematik.de/hilfe-kontakt/hersteller/)
-
-IT specialists
-
-[![eMail E-Rezept Fachportal](https://img.shields.io/badge/web-E%20Rezept%20Fachportal-green?logo=web.ru&style=flat-square&logoColor=white)](https://fachportal.gematik.de/anwendungen/elektronisches-rezept)
-[![eMail E-Rezept Team](https://img.shields.io/badge/email-E%20Rezept%20team-green?logo=mail.ru&style=flat-square&logoColor=white)](mailto:app-feedback@gematik.de)
-
-### Data Privacy
+### Release Notes
+See [ReleaseNotes.md](./ReleaseNotes.md) for all information regarding the (newest) releases.
-You can find the privacy policy for the app at: [https://www.das-e-rezept-fuer-deutschland.de/app/datenschutz](https://www.das-e-rezept-fuer-deutschland.de/app/datenschutz)
+## Getting Started
+This section provides instructions on how to get started with the project,
+including setting up the development environment and building the application.
-### Contributors
+### Prerequisites
+Before you can build and run the application, ensure you have the following prerequisites installed on your system:
-We plan to enable contribution to the E-Rezept App in the near future.
+- **Android Studio:** The official IDE for Android app development.
+- **Kotlin:** The primary programming language used in this project. Android Studio comes bundled with Kotlin support.
+- **Git:** A distributed version control system used to manage the project's source code.
-### Licensing
+**Getting the Project Code**
-The E-Rezept App is licensed under the European Union Public Licence (EUPL); every use of the E-Rezept App Sourcecode must be in compliance with the EUPL.
-
-You will find more details about the EUPL here: [https://joinup.ec.europa.eu/collection/eupl](https://joinup.ec.europa.eu/collection/eupl)
-
-Unless required by applicable law or agreed to in writing, software distributed under the EUPL is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the EUPL for the specific language governing permissions and limitations under the License.
-
-## Development
-
-### Getting started
-
-To get started, build one of the \*Pu\* variants. Currently, the Google and Huawei variants differ only in configuration. The code is identical. This is likely to change soon.
-
-This repository is an [Kotlin Multiplatform Project](https://kotlinlang.org/docs/multiplatform.html) unifying the upcoming E-Rezept App for desktop and the Android App.
+To begin, clone the project's repository from GitHub using the following command in your terminal:
+"git clone https://github.com/gematik/E-Rezept-App-Android.git" or by using the version control tool of Android Studio.
### Structure
-
+The following graphic provides an overview over the more important parts of the kotlin multiplatform project:
```text
|-- app
| `-- android
@@ -77,52 +74,61 @@ This repository is an [Kotlin Multiplatform Project](https://kotlinlang.org/docs
| |-- androidTest
| |-- main
| `-- test
-| `-- shared-test
+| `-- test-actions
| `-- src
| |-- main
|-- common
| `-- src
| |-- androidMain
-| |-- androidTest
| |-- commonMain
| |-- commonTest
-| |-- desktopMain
-| `-- desktopTest
-|-- desktop
-| `-- src
-| |-- jvmMain
-| `-- jvmTest
-`-- plugins
- `-- dependencies
+`-- ui-components
+ `-- src
```
-`plugins/dependencies` is a [composed build](https://docs.gradle.org/current/userguide/composite_builds.html) required by any of the other modules (android, common and desktop) managing the dependencies in one place.
+- **app/android/src/main:** includes build parameters for the android app.
+- **app/android-mock/src/main:** includes build parameters for the android app-mock (mostly used for testing).
+- **app/features/src/main:** includes the core logic of the android app. Including Screens, UseCases and Navigation.
+- **app/demo-mode/src/main:** includes the core logic of the demo-mode of the android app. Including all overwritten Datasources and UseCases
+- **common/src/commonMain:** includes the general logic of app. Most important the localDatasource and it's entities.
-The `gradle.properties` file contains all pre-defined properties required to communicate with the FD (**F**ach**D**ienst), IDP (**ID**entity **P**rovider) and the pharmacy lookup service.
-Unfortunately the actual values are not meant to be public.
+### Installation
+To create and install an unsigned debug.apk on your connected android device, run:
+- "./gradlew :app:android:assembleGoogleTuInternalDebug" in your terminal.
+ - This will create an apk in the following path "app/android/build/outputs/apk/googleTuInternal/debug", which you can then install on your device
+ - run "adb install app/android/build/outputs/apk/googleTuInternal/debug/android-googleTuInternal-debug.apk"
+- or click on the green "run"-Button in the top right of android studio.
-### Android
+## Usage
+The installed debug.apk can't communicate to connected servers. It's purpose is for local testing only. To show some data, you can enter the demo-mode via the settings.
+If you want or need an active app, please download a live version from the sources mentioned in the [About The Project](#about-the-project) section.
-To build the Android App choose one variant (e.g. `gradle :android:assembleGooglePuExternalDebug -Pbuildkonfig.flavor=googlePuExternal`):
+## Contributing
+See [Contributing.md](./CONTRIBUTING.md) for all information regarding the the contributing process in this project.
-```shell
-gradle :android:assemble(Google|Huawei)Pu(External|Internal)(Debug|Release) -Pbuildkonfig.flavor=(google|huawei)Pu(External|Internal)
-```
+## Security And Privacy
+See [Security.md](./SECURITY.md) for all information regarding the used security and privacy guidelines in this project.
-*Note: Currently the android build variant is derived from the `buildkonfig.flavor` property.*
+## License
+See [License.md](./LICENSE.md) for all information regarding the used license.
-#### APK
+## Contact
+For endusers and insurant:
-The resulting `.apk` can be found in e.g. `app/android/build/outputs/apk/googlePuExternal/debug/`.
+[![E-Rezept Webseite](https://img.shields.io/badge/web-E%20Rezept%20Webseite-green?logo=web.ru&style=flat-square&logoColor=white)](https://www.das-e-rezept-fuer-deutschland.de/)
+[![eMail E-Rezept](https://img.shields.io/badge/email-E%20Rezept%20team-green?logo=mail.ru&style=flat-square&logoColor=white)](mailto:app-feedback@gematik.de)
+[![E-Rezept Support Telephone](https://img.shields.io/badge/phone-E%20Rezept%20Service-green?logo=phone.ru&style=flat-square&logoColor=white)](tel:+498002773777)
-Additionally, you can find the latest apk [here](https://github.com/gematik/E-Rezept-App-Android/releases/latest)
+Members of the health-industry with functional questions
-#### Visualize Test Tags
+[![eMail E-Rezept Team](https://img.shields.io/badge/web-E%20Rezept%20Industrie-green?logo=web.ru&style=flat-square&logoColor=white)](https://www.gematik.de/hilfe-kontakt/hersteller/)
-See [Visualize Test Tags](documentation/test-tags.md)
+IT specialists
+[![eMail E-Rezept Fachportal](https://img.shields.io/badge/web-E%20Rezept%20Fachportal-green?logo=web.ru&style=flat-square&logoColor=white)](https://fachportal.gematik.de/anwendungen/elektronisches-rezept)
+[![eMail E-Rezept Team](https://img.shields.io/badge/email-E%20Rezept%20team-green?logo=mail.ru&style=flat-square&logoColor=white)](mailto:app-feedback@gematik.de)
-### Links Sourcecode
+### Additional Links And Sourcecode
- [E-Rezept iOS implementation](https://github.com/gematik/E-Rezept-App-iOS)
- Reference implementation of the [IDP (**ID**entity **P**rovider)](https://github.com/gematik/ref-idp-server)
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 1b2dd8a3..e1907111 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -1,7 +1,49 @@
+# Release 1.26.0
+- added: link to organ donation register in settings
+- added: in-app notification about the latest changes
+- added: option to have both appPassword and device credentials as login method
+- changed: accessibility overhaul on many screens
+- Bug fixes
+- infrastructure/ project improvements
+- UX improvements
+
+# Release 1.25.1
+- added: saving the credentials of the user when logging in with gid
+- added: no internet hint
+- reworked: app-login
+- Bug fixes
+- infrastructure/ project improvements
+- UX improvements
+
+# Release 1.24.0
+- Bug fixes
+- infrastructure/ project improvements
+- UX improvements
+
+# Release 1.23.0
+- added: help-section for GID usage
+- added: in-app language change for android 13 and higher, lower versions are getting redirected to android settings
+- added: profile picture enhancements: stickers, emojis, bitmojis
+- Bug fixes
+- infrastructure/ project improvements
+- UX improvements
+
+# Release 1.22.0
+- Saving credentials possible for all devices with hardware backed keystore
+- Redeem from detail view
+- Refactoring of pharmacy feature, redeem feature
+- Bug fixes
+- Url updates
+- UX improvements
+
+# Release 1.21.0
+- skipped
+
# Release 1.20.0
-- Added multi-language support for privacy policy
+- Refactor of egk card feature
+- Partial refactoring of pharmacy feature
+- Add multi language support for privacy policy
- Update health insurance contacts
-- Optimized performance
- Bug fixes
# Release 1.19.1
diff --git a/app/android-mock/build.gradle.kts b/app/android-mock/build.gradle.kts
index 6fa67b70..c7d408a1 100644
--- a/app/android-mock/build.gradle.kts
+++ b/app/android-mock/build.gradle.kts
@@ -1,74 +1,33 @@
-import de.gematik.ti.erp.Dependencies
-import de.gematik.ti.erp.inject
-import de.gematik.ti.erp.overriding
-import org.owasp.dependencycheck.reporting.ReportGenerator.Format
+@file:Suppress("VariableNaming", "PropertyName", "UnusedPrivateProperty")
-// TODO: Duplicate of android build.gradle, make this into one
-plugins {
- id("com.android.application")
- kotlin("android")
- id("org.jetbrains.compose")
- id("io.realm.kotlin")
- kotlin("plugin.serialization")
- id("org.owasp.dependencycheck")
- id("com.jaredsburrows.license")
- id("de.gematik.ti.erp.dependencies")
- id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
- id("de.gematik.ti.erp.technical-requirements")
-}
-
-val VERSION_CODE: String by overriding()
-val VERSION_NAME: String by overriding()
-val TEST_INSTRUMENTATION_ORCHESTRATOR: String? by project
+import de.gematik.ti.erp.app.plugins.dependencies.overrides
+import de.gematik.ti.erp.app.plugins.names.AppDependencyNamesPlugin
-afterEvaluate {
- val taskRegEx = """assemble(Google|Huawei)(PuExternalDebug|PuExternalRelease)""".toRegex()
- tasks.forEach { task ->
- taskRegEx.matchEntire(task.name)?.let {
- val (_, version, flavor) = it.groupValues
- task.dependsOn(tasks.getByName("license${version}${flavor}Report"))
- }
- }
+plugins {
+ id("base-android-application")
+ id("de.gematik.ti.erp.names")
+ id("de.gematik.ti.erp.dependency-overrides")
}
-licenseReport {
- generateCsvReport = false
- generateHtmlReport = false
- generateJsonReport = true
- copyJsonReportToAssets = true
-}
+val VERSION_CODE: String by overrides()
+val VERSION_NAME: String by overrides()
+val gematik = AppDependencyNamesPlugin()
android {
- namespace = "de.gematik.ti.erp.app.mock"
+ namespace = gematik.moduleName("mock")
defaultConfig {
- applicationId = "de.gematik.ti.erp.app.mock"
+ applicationId = gematik.idName("mock")
versionCode = VERSION_CODE.toInt()
versionName = VERSION_NAME
- testApplicationId = "de.gematik.ti.erp.app"
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ testApplicationId = gematik.moduleName("mock.test")
+ // Check if MAPS_API_KEY is defined, otherwise provide a default value
+ val mapsApiKey = project.findProperty("MAPS_API_KEY") ?: "DEFAULT_PLACEHOLDER_KEY"
+ manifestPlaceholders["MAPS_API_KEY"] = mapsApiKey
}
-
androidResources {
- noCompress("srt", "csv", "json")
+ generateLocaleConfig = true
}
- kotlinOptions {
- jvmTarget = Dependencies.Versions.JavaVersion.KOTLIN_OPTIONS_JVM_TARGET
- freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
- }
- dependencyCheck {
- analyzers.assemblyEnabled = false
- suppressionFile = "${project.rootDir}" + "/config/dependency-check/suppressions.xml"
- formats = listOf(Format.HTML, Format.XML)
- scanConfigurations = configurations.filter {
- it.name.startsWith("api") ||
- it.name.startsWith("implementation") ||
- it.name.startsWith("kapt")
- }.map {
- it.name
- }
- }
-
buildTypes {
val release by getting {
resValue("string", "app_label", "E-Rezept Mock")
@@ -78,135 +37,30 @@ android {
resValue("string", "app_label", "E-Rezept Mock")
versionNameSuffix = "-debug"
}
- create("minifiedDebug") {
+ create(gematik.minifiedDebug) {
initWith(debug)
}
}
-
- packagingOptions {
- resources {
- excludes += "META-INF/**"
- // for JNA and JNA-platform
- excludes += "META-INF/AL2.0"
- excludes += "META-INF/LGPL2.1"
- // for byte-buddy
- excludes += "META-INF/licenses/ASM"
- pickFirsts += "win32-x86-64/attach_hotspot_windows.dll"
- pickFirsts += "win32-x86/attach_hotspot_windows.dll"
- }
- }
}
dependencies {
- implementation(project(":app:features"))
- implementation(project(":app:demo-mode"))
- androidTestImplementation(project(":app:shared-test"))
- implementation(project(":common"))
- testImplementation(project(":common"))
- testImplementation(kotlin("test"))
- implementation("com.tom-roush:pdfbox-android:2.0.27.0") {
- exclude(group = "org.bouncycastle")
- implementation(kotlin("stdlib"))
- implementation(kotlin("reflect"))
- }
-
- inject {
- dateTime {
- implementation(datetime)
- testCompileOnly(datetime)
- }
- android {
- coreLibraryDesugaring(desugaring)
- debugImplementation(processPhoenix)
- }
- androidX {
- implementation(appcompat)
- implementation(composeNavigation)
- implementation(security)
- implementation(lifecycleViewmodel)
- implementation(lifecycleProcess)
- implementation(lifecycleComposeRuntime)
- }
- dependencyInjection {
- compileOnly(kodeinCompose)
- androidTestImplementation(kodeinCompose)
- }
- logging {
- implementation(napier)
- }
- tracking {
- implementation(contentSquare)
- }
- compose {
- implementation(runtime)
- implementation(foundation)
- implementation(uiTooling)
- implementation(preview)
- }
- crypto {
- testImplementation(jose4j)
- testImplementation(bouncycastleBcprov)
- testImplementation(bouncycastleBcpkix)
- }
- database {
- compileOnly(realm)
- testCompileOnly(realm)
- }
- network {
- implementation(retrofit)
- implementation(retrofit2KotlinXSerialization)
- implementation(okhttp3)
- implementation(okhttpLogging)
- // Work around vulnerable Okio version 3.1.0 (CVE-2023-3635).
- // Can be removed as soon as Retrofit releases a new version >2.9.0.
- implementation(okio)
-
- androidTestImplementation(okhttp3)
- }
- playServices {
- implementation(appUpdate)
- }
- serialization {
- implementation(kotlinXJson)
- }
- androidXTest {
- testImplementation(archCore)
- androidTestImplementation(core)
- androidTestImplementation(rules)
- androidTestImplementation(junitExt)
- androidTestImplementation(runner)
- androidTestUtil(orchestrator)
- androidTestUtil(services)
- // androidTestImplementation(navigation)
- androidTestImplementation(espresso)
- androidTestImplementation(espressoIntents)
- }
- tracing {
- debugImplementation(tracing)
- implementation(tracing)
- }
- coroutinesTest {
- testImplementation(coroutinesTest)
- }
- composeTest {
- androidTestImplementation(ui)
- debugImplementation(uiManifest)
- androidTestImplementation(junit4)
- }
- networkTest {
- testImplementation(mockWebServer)
- }
- test {
- testImplementation(junit4)
- testImplementation(snakeyaml)
- testImplementation(json)
- testImplementation(mockk)
- androidTestImplementation(mockkAndroid)
- }
- }
+ implementation(project(gematik.feature))
+ implementation(project(gematik.demoMode))
+ implementation(project(gematik.uiComponents))
+ implementation(project(gematik.multiplatform))
+ implementation(libs.tracing)
+ implementation(libs.bundles.crypto)
+ implementation(libs.bundles.accompanist)
+ implementation(libs.bundles.database)
+ testImplementation(project(gematik.multiplatform))
+ androidTestImplementation(project(gematik.testActions))
+ androidTestImplementation(project(gematik.testTags))
+ debugImplementation(libs.tracing)
}
-secrets {
- defaultPropertiesFileName = if (project.rootProject.file("ci-overrides.properties").exists()
- ) "ci-overrides.properties" else "gradle.properties"
+// todo: check if this affects the ui-tests
+configurations.all {
+ resolutionStrategy {
+ force("com.google.protobuf:protobuf-java:4.28.2")
+ }
}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/PharmacyUITest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/PharmacyUITest.kt
deleted file mode 100644
index 224a2801..00000000
--- a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/PharmacyUITest.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import de.gematik.ti.erp.app.sharedtest.testresources.actions.PharmacyScreenAction
-
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class PharmacyUITest {
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val actions = PharmacyScreenAction(composeRule)
-
- @Test
- fun pickupServiceSuccessTest() {
- actions.pickupServiceSuccessTest()
- }
-
- @Test
- fun courierDeliverySuccessTest() {
- actions.courierDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceMailDeliverySuccessTest() {
- actions.pickupServiceMailDeliverySuccessTest()
- }
-
- @Test
- fun mailDeliverySuccessTest() {
- actions.mailDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceCourierSuccessTest() {
- actions.pickupServiceCourierSuccessTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryCourierDeliverySuccessTest() {
- actions.pickupServiceMailDeliveryCourierDeliverySuccessTest()
- }
-
- @Test
- fun mailDeliveryCourierDeliverySuccessTest() {
- actions.mailDeliveryCourierDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceFailTest() {
- actions.pickupServiceFailTest()
- }
-
- @Test
- fun courierDeliveryFailTest() {
- actions.courierDeliveryFailTest()
- }
-
- @Test
- fun mailDeliveryFailTest() {
- actions.mailDeliveryFailTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryCourierDeliveryFailTest() {
- actions.pickupServiceMailDeliveryCourierDeliveryFailTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryFailTest() {
- actions.pickupServiceMailDeliveryFailTest()
- }
-
-}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/UiTest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/UiTest.kt
new file mode 100644
index 00000000..4ab0bc6b
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/UiTest.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app
+
+import android.content.Context
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Rule
+import org.junit.runner.RunWith
+
+@Suppress("UnnecessaryAbstractClass")
+@RunWith(AndroidJUnit4::class)
+abstract class UiTest {
+ private val application = ApplicationProvider.getApplicationContext() as MockErezeptApp
+
+ @get:Rule
+ val composeRule = createAndroidComposeRule()
+
+ val context: Context = application.applicationContext
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/components/InjectionConfig.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/components/InjectionConfig.kt
new file mode 100644
index 00000000..2373f4ba
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/components/InjectionConfig.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.components
+
+import android.content.Context
+import androidx.compose.ui.test.junit4.AndroidComposeTestRule
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import de.gematik.ti.erp.app.MockMainActivity
+import de.gematik.ti.erp.app.config.TestScenario
+import de.gematik.ti.erp.app.config.injectionConfig
+
+/**
+ * Every scenario is injected as an intent to start the mock app for that test
+ */
+
+fun AndroidComposeTestRule, MockMainActivity>.injectConfig(
+ applicationContext: Context,
+ config: TestScenario
+): ActivityScenario = activityRule.scenario.onActivity {
+ it.injectionConfig(applicationContext, config)
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/onboarding/OnboardingTests.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/onboarding/OnboardingTests.kt
new file mode 100644
index 00000000..8a808d5b
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/onboarding/OnboardingTests.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.onboarding
+
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.performTextInput
+import de.gematik.ti.erp.app.TestTag
+import de.gematik.ti.erp.app.UiTest
+import de.gematik.ti.erp.app.components.injectConfig
+import de.gematik.ti.erp.app.config.TestScenario
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+
+class OnboardingTests : UiTest() {
+
+ @Test
+ fun onboardingNotDoneTest() {
+ runTest {
+ composeRule.injectConfig(
+ applicationContext = context,
+ config = TestScenario(isOnboardingDone = false)
+ )
+ composeRule.apply {
+ onNodeWithTag(TestTag.Onboarding.WelcomeScreen)
+ .assertIsDisplayed()
+ }
+ }
+ }
+
+ @Test
+ fun onboardingDoneTest() {
+ runTest {
+ composeRule.injectConfig(
+ applicationContext = context,
+ config = TestScenario(isOnboardingDone = true)
+ )
+ composeRule.apply {
+ onNodeWithTag("password_prompt_password_field")
+ .assertIsDisplayed()
+ .performTextInput("password")
+ onNodeWithTag("password_prompt")
+ .assertIsDisplayed()
+ .performClick()
+ }
+ }
+ }
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/pharmacy/PharmacyForUserNotLoggedInTest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/pharmacy/PharmacyForUserNotLoggedInTest.kt
new file mode 100644
index 00000000..88609841
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/pharmacy/PharmacyForUserNotLoggedInTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.pharmacy
+
+import de.gematik.ti.erp.app.UiTest
+import de.gematik.ti.erp.app.testactions.actions.pharmacy.PharmacyScreenAction
+import org.junit.Test
+
+class PharmacyForUserNotLoggedInTest : UiTest() {
+
+ private val actions = PharmacyScreenAction(composeRule)
+
+ @Test
+ fun pickupServiceSuccessTest() {
+ actions.pickupServiceSuccessTest()
+ }
+
+ @Test
+ fun courierDeliverySuccessTest() {
+ actions.courierDeliverySuccessTest()
+ }
+
+ @Test
+ fun pickupServiceMailDeliverySuccessTest() {
+ actions.pickupServiceMailDeliverySuccessTest()
+ }
+
+ @Test
+ fun mailDeliverySuccessTest() {
+ actions.mailDeliverySuccessTest()
+ }
+
+ @Test
+ fun pickupServiceCourierSuccessTest() {
+ actions.pickupServiceCourierSuccessTest()
+ }
+
+ @Test
+ fun pickupServiceMailDeliveryCourierDeliverySuccessTest() {
+ actions.pickupServiceMailDeliveryCourierDeliverySuccessTest()
+ }
+
+ @Test
+ fun mailDeliveryCourierDeliverySuccessTest() {
+ actions.mailDeliveryCourierDeliverySuccessTest()
+ }
+
+ @Test
+ fun pickupServiceFailTest() {
+ actions.pickupServiceFailTest()
+ }
+
+ @Test
+ fun courierDeliveryFailTest() {
+ actions.courierDeliveryFailTest()
+ }
+
+ @Test
+ fun mailDeliveryFailTest() {
+ actions.mailDeliveryFailTest()
+ }
+
+ @Test
+ fun pickupServiceMailDeliveryCourierDeliveryFailTest() {
+ actions.pickupServiceMailDeliveryCourierDeliveryFailTest()
+ }
+
+ @Test
+ fun pickupServiceMailDeliveryFailTest() {
+ actions.pickupServiceMailDeliveryFailTest()
+ }
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/prescription/SubstitutionMedicationTest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/prescription/SubstitutionMedicationTest.kt
new file mode 100644
index 00000000..f99addf1
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/prescription/SubstitutionMedicationTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.prescription
+
+import de.gematik.ti.erp.app.UiTest
+import de.gematik.ti.erp.app.testactions.actions.prescription.PrescriptionScreenAction
+import org.junit.Before
+import org.junit.Test
+
+class SubstitutionMedicationTest : UiTest() {
+
+ private val actions = PrescriptionScreenAction(composeRule)
+
+ @Before
+ fun setup() {
+ actions.skipOnboarding()
+ }
+
+ /**
+ * When substitution medication available
+ * */
+ @Test
+ fun substituteMedicationSuccessTest() {
+ actions.substituteMedicationSuccessTest()
+ }
+
+ /**
+ * When substitution medication unavailable
+ * */
+ @Test
+ fun substituteMedicationFailTest() {
+ actions.substituteMedicationFailTest()
+ }
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/profile/ProfileEditTest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/profile/ProfileEditTest.kt
new file mode 100644
index 00000000..8eb40a18
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/profile/ProfileEditTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.profile
+
+import de.gematik.ti.erp.app.UiTest
+import de.gematik.ti.erp.app.testactions.actions.profile.ProfileMainScreenAction
+import org.junit.Before
+import org.junit.Test
+
+class ProfileEditTest : UiTest() {
+
+ private val actions = ProfileMainScreenAction(composeRule)
+
+ @Before
+ fun setup() {
+ actions.skipOnboarding()
+ }
+
+ /**
+ * change profile image as Symbols
+ * */
+ @Test
+ fun symbolsAsProfileImage() {
+ actions.symbolsAsProfileImage()
+ }
+
+ /**
+ * change profile image
+ * */
+ @Test
+ fun changeProfileImageTest() {
+ actions.changeProfileImageTest()
+ }
+
+ /**
+ * check avatar images
+ * */
+ @Test
+ fun checkAvatarImageTest() {
+ actions.checkAvatarImageTest()
+ }
+
+ /**
+ * Delete profile picture
+ * */
+ @Test
+ fun deleteAvatarTest() {
+ actions.deleteAvatarTest()
+ }
+
+ /**
+ * profile dialog text check
+ * */
+ @Test
+ fun profileDialogTextTest() {
+ actions.profileDialogTextTest()
+ }
+}
diff --git a/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/settings/ChangeAppLanguageTest.kt b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/settings/ChangeAppLanguageTest.kt
new file mode 100644
index 00000000..e6d3c4b5
--- /dev/null
+++ b/app/android-mock/src/androidTest/kotlin/de/gematik/ti/erp/app/settings/ChangeAppLanguageTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.settings
+
+import de.gematik.ti.erp.app.UiTest
+import de.gematik.ti.erp.app.testactions.actions.settings.SettingsScreenAction
+import org.junit.Before
+import org.junit.Test
+
+class ChangeAppLanguageTest : UiTest() {
+
+ private val actions = SettingsScreenAction(composeRule)
+
+ @Before
+ fun setup() {
+ actions.skipOnboarding()
+ }
+
+ /**
+ * check app languages exist test
+ * */
+ @Test
+ fun checkAllLanguageExistTest() {
+ actions.checkAllLanguageExistTest()
+ }
+
+ /**
+ * change app language test
+ * */
+ @Test
+ fun changeLanguageTest() {
+ actions.changeLanguageTest()
+ }
+}
diff --git a/app/android-mock/src/main/AndroidManifest.xml b/app/android-mock/src/main/AndroidManifest.xml
index 075a4453..ba795d06 100644
--- a/app/android-mock/src/main/AndroidManifest.xml
+++ b/app/android-mock/src/main/AndroidManifest.xml
@@ -17,7 +17,7 @@
android:required="false" />
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/DefaultErezeptMockApp.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/DefaultErezeptMockApp.kt
deleted file mode 100644
index c28ca8ec..00000000
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/DefaultErezeptMockApp.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * "${GEMATIK_COPYRIGHT_STATEMENT}"
- */
-
-package de.gematik.ti.erp.app
-
-import androidx.lifecycle.ProcessLifecycleOwner
-import com.contentsquare.android.Contentsquare
-import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
-import de.gematik.ti.erp.app.di.appModules
-import de.gematik.ti.erp.app.di.mockFeatureModule
-import de.gematik.ti.erp.app.userauthentication.observer.InactivityTimeoutObserver
-import de.gematik.ti.erp.app.userauthentication.observer.ProcessLifecycleObserver
-import io.github.aakira.napier.DebugAntilog
-import io.github.aakira.napier.Napier
-import org.kodein.di.DI
-import org.kodein.di.DIAware
-import org.kodein.di.android.x.androidXModule
-import org.kodein.di.bindSingleton
-import org.kodein.di.instance
-
-class DefaultErezeptMockApp : ErezeptApp(), DIAware {
-
- override val di by DI.lazy {
- import(androidXModule(this@DefaultErezeptMockApp))
- importAll(appModules)
- importAll(mockFeatureModule, allowOverride = true)
- bindSingleton { InactivityTimeoutObserver(instance(), instance()) }
- bindSingleton { ProcessLifecycleObserver(ProcessLifecycleOwner, instance()) }
- bindSingleton { VisibleDebugTree() }
- }
-
- private val processLifecycleObserver: ProcessLifecycleObserver by instance()
-
- private val visibleDebugTree: VisibleDebugTree by instance()
-
- override fun onCreate() {
- super.onCreate()
- Napier.base(DebugAntilog())
- Napier.base(visibleDebugTree)
-
- processLifecycleObserver.observeForInactivity()
-
- PDFBoxResourceLoader.init(this)
-
- Contentsquare.start(this)
- }
-}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockErezeptApp.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockErezeptApp.kt
new file mode 100644
index 00000000..ccb6fb8a
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockErezeptApp.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+/*
+ * "${GEMATIK_COPYRIGHT_STATEMENT}"
+ */
+
+package de.gematik.ti.erp.app
+
+import androidx.lifecycle.ProcessLifecycleOwner
+import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
+import de.gematik.ti.erp.app.di.appModules
+import de.gematik.ti.erp.app.di.mockFeatureModule
+import de.gematik.ti.erp.app.usecase.CreateProfileWhenMissingUseCase
+import de.gematik.ti.erp.app.userauthentication.observer.InactivityTimeoutObserver
+import de.gematik.ti.erp.app.userauthentication.observer.ProcessLifecycleObserver
+import io.github.aakira.napier.DebugAntilog
+import io.github.aakira.napier.Napier
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import org.kodein.di.DI
+import org.kodein.di.DIAware
+import org.kodein.di.android.x.androidXModule
+import org.kodein.di.bindProvider
+import org.kodein.di.bindSingleton
+import org.kodein.di.instance
+
+class MockErezeptApp : ErezeptApp(), DIAware {
+
+ override var di = DI.lazy {
+ import(androidXModule(this@MockErezeptApp), allowOverride = true)
+ importAll(appModules, allowOverride = true)
+ importAll(mockFeatureModule, allowOverride = true)
+ bindProvider { CreateProfileWhenMissingUseCase(instance(), instance()) }
+ bindSingleton { InactivityTimeoutObserver(instance(), instance()) }
+ bindSingleton { ProcessLifecycleObserver(ProcessLifecycleOwner, instance()) }
+ bindSingleton { VisibleDebugTree() }
+ }
+
+ private val processLifecycleObserver: ProcessLifecycleObserver by instance()
+
+ private val visibleDebugTree: VisibleDebugTree by instance()
+
+ // only for mock
+ private val createProfile: CreateProfileWhenMissingUseCase by instance()
+
+ @OptIn(DelicateCoroutinesApi::class)
+ override fun onCreate() {
+ super.onCreate()
+ Napier.base(DebugAntilog())
+ Napier.base(visibleDebugTree)
+ processLifecycleObserver.observeForInactivity()
+
+ PDFBoxResourceLoader.init(this)
+ GlobalScope.launch { createProfile.invoke() }
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockMainActivity.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockMainActivity.kt
new file mode 100644
index 00000000..b40c6fd8
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/MockMainActivity.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app
+
+import android.content.Intent
+import android.os.Build
+import de.gematik.ti.erp.app.appupdate.usecase.CheckVersionUseCase
+import de.gematik.ti.erp.app.config.TestConfigKey
+import de.gematik.ti.erp.app.config.TestScenario
+import de.gematik.ti.erp.app.config.UiTestsIntent
+import de.gematik.ti.erp.app.demomode.di.demoModeModule
+import de.gematik.ti.erp.app.demomode.di.demoModeOverrides
+import de.gematik.ti.erp.app.di.overrides.testScenarioOverrides
+import de.gematik.ti.erp.app.features.BuildConfig
+import de.gematik.ti.erp.app.mocks.settings.OnboardingDoneMockSettingsDataSource
+import org.kodein.di.Copy
+import org.kodein.di.DI
+import org.kodein.di.android.closestDI
+import org.kodein.di.android.retainedSubDI
+import org.kodein.di.bindProvider
+import org.kodein.di.instance
+
+class MockMainActivity : MainActivity() {
+
+ private var diBuilder: DI.MainBuilder? = null
+
+ override val di by retainedSubDI(closestDI(), copy = Copy.All) {
+
+ fullDescriptionOnError = true
+ fullContainerTreeOnError = true
+ diBuilder = this
+
+ // add testScenarioOverrides to the DI
+ intent?.scenarios(diBuilder)
+
+ import(demoModeModule)
+ if (isDemoMode()) demoModeOverrides()
+ if (BuildConfig.DEBUG && BuildKonfig.INTERNAL) debugOverrides()
+ bindProvider { CheckVersionUseCase(instance()) }
+
+ // domain verification is only available on SDK 31 and above
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ bindProvider { Sdk31DomainVerifier(instance()) }
+ } else {
+ bindProvider { OlderSdkDomainVerifier() }
+ }
+ }
+}
+
+private fun Intent.scenarios(diMainBuilder: DI.MainBuilder?) {
+ when (this.action.equals(UiTestsIntent)) {
+ // can be changed when minSDK = 33
+ true -> this.getParcelableExtra(TestConfigKey)?.let { testScenario ->
+ diMainBuilder?.testScenarioOverrides(testScenario)
+ }
+
+ else -> OnboardingDoneMockSettingsDataSource()
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/ConfigNames.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/ConfigNames.kt
new file mode 100644
index 00000000..0ea54a4c
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/ConfigNames.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.config
+
+internal const val TestConfigKey = "TestConfig"
+internal const val UiTestsIntent = "ui-tests"
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/InjectExtensions.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/InjectExtensions.kt
new file mode 100644
index 00000000..2952b1bd
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/InjectExtensions.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.config
+
+import android.content.Context
+import android.content.Intent
+import de.gematik.ti.erp.app.MockMainActivity
+
+fun MockMainActivity.injectionConfig(
+ applicationContext: Context,
+ config: TestScenario
+) {
+ startActivity(
+ Intent(applicationContext, MockMainActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ putExtra(TestConfigKey, config)
+ action = UiTestsIntent
+ }
+ )
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/TestScenario.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/TestScenario.kt
new file mode 100644
index 00000000..d2aa982d
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/config/TestScenario.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.config
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+/**
+ * This data class is a config file which decides what mocks we need to inject based on the test case
+ */
+@Parcelize
+data class TestScenario(
+ val isOnboardingDone: Boolean = false
+) : Parcelable
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/MockDataSource.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/MockDataSource.kt
new file mode 100644
index 00000000..096478e0
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/MockDataSource.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.datasource
+
+import de.gematik.ti.erp.app.datasource.data.MockPrescriptionInfo
+import de.gematik.ti.erp.app.datasource.data.MockProfileInfo.mockProfile01
+import de.gematik.ti.erp.app.model.MockProfileLinkedCommunication
+import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import kotlinx.coroutines.flow.MutableStateFlow
+
+const val INDEX_OUT_OF_BOUNDS = -1
+
+class MockDataSource {
+// todo: include pharmacies data source here in future!
+
+ val profiles: MutableStateFlow> =
+ MutableStateFlow(mutableListOf(mockProfile01))
+
+ val syncedTasks: MutableStateFlow> =
+ MutableStateFlow(
+ mutableListOf(
+ MockPrescriptionInfo.MockSyncedPrescription.syncedTask(
+ mockProfile01.id,
+ status = SyncedTaskData.TaskStatus.Ready,
+ index = 0
+ ),
+ MockPrescriptionInfo.MockSyncedPrescription.syncedTask(
+ mockProfile01.id,
+ status = SyncedTaskData.TaskStatus.InProgress,
+ index = 1
+ )
+ )
+ )
+
+ val scannedTasks: MutableStateFlow> =
+ MutableStateFlow(
+ mutableListOf(
+ MockPrescriptionInfo.MockScannedPrescription.mockScannedTask01,
+ MockPrescriptionInfo.MockScannedPrescription.mockScannedTask02
+ )
+ )
+
+ val communications: MutableStateFlow> =
+ MutableStateFlow(mutableListOf())
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockConstants.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockConstants.kt
new file mode 100644
index 00000000..36a7aba8
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockConstants.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.datasource.data
+
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+import kotlin.time.Duration.Companion.days
+
+object MockConstants {
+ internal val fixedTime = Instant.parse("2021-11-25T15:20:00Z")
+ internal val longerRandomTimeToday = Instant.parse("2021-11-25T15:20:00Z")
+ internal const val SYNCED_TASK_PRESET = "110.000.002.345.863"
+ internal val NOW = Clock.System.now()
+ internal val EXPIRY_DATE = Clock.System.now().plus(200.days)
+ internal val SHORT_EXPIRY_DATE = Clock.System.now().plus(20.days)
+ internal const val MOCK_COMMUNICATION_ID_01 = "CID-123-001"
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockPrescriptionInfo.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockPrescriptionInfo.kt
new file mode 100644
index 00000000..8ba63628
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockPrescriptionInfo.kt
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.datasource.data
+
+import de.gematik.ti.erp.app.datasource.data.MockConstants.EXPIRY_DATE
+import de.gematik.ti.erp.app.datasource.data.MockConstants.NOW
+import de.gematik.ti.erp.app.datasource.data.MockConstants.SHORT_EXPIRY_DATE
+import de.gematik.ti.erp.app.datasource.data.MockConstants.SYNCED_TASK_PRESET
+import de.gematik.ti.erp.app.datasource.data.MockConstants.fixedTime
+import de.gematik.ti.erp.app.datasource.data.MockConstants.longerRandomTimeToday
+import de.gematik.ti.erp.app.datasource.data.MockProfileInfo.mockProfile01
+import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationDispense
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationPZN
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationRequest
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Organization
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Patient
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Practitioner
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Quantity
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Ratio
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import de.gematik.ti.erp.app.utils.FhirTemporal
+import java.util.UUID
+
+object MockPrescriptionInfo {
+
+ private val BOOLEAN = listOf(true, false)
+
+ private const val SYNCED_MEDICATION_NAMES =
+ "Ibuprofen 600"
+
+ private const val SCANNED_MEDICINE_NAMES = "Lopressor"
+
+ private const val DOSAGE = "1-0-1-1"
+
+ private const val STREET_NAMES = "Marktplatz"
+
+ private const val POSTAL_CODES = "10115"
+
+ private const val CITY_NAMES = "Berlin"
+
+ private const val FLOORS = "1. Stock"
+
+ private const val PHONE_NUMBERS = "+49 123 4567890"
+
+ private const val FIRST_NAMES = "Hans"
+
+ private const val NAMES = "Hans Müller"
+
+ private const val MEDICATION_SPECIALITIES = "Fachärztin für Innere Medizin"
+
+ private val MEDICAL_PRACTICES = "Praxis Erika Mustermann" to "erika@mustermann.de"
+
+ private const val DOCTORS_NOTES = "Patient hat grippeähnliche Symptome und sollte sich ausruhen."
+
+ private const val normSizeMappings = "KA"
+
+ private const val codeToFormMapping = "AEO"
+
+ private const val PERFORMERS = "Apotheker"
+
+ internal const val MOCK_IDENTIFIER = "1234567890"
+
+ internal val PRACTITIONER = Practitioner(
+ name = NAMES,
+ qualification = MEDICATION_SPECIALITIES,
+ practitionerIdentifier = MOCK_IDENTIFIER
+ )
+
+ private val ADDRESS = SyncedTaskData.Address(
+ line1 = STREET_NAMES,
+ line2 = FLOORS,
+ postalCode = POSTAL_CODES,
+ city = CITY_NAMES
+ )
+
+ private fun organization(): Organization {
+ val item = MEDICAL_PRACTICES
+ return Organization(
+ name = item.first,
+ address = ADDRESS,
+ uniqueIdentifier = MOCK_IDENTIFIER,
+ phone = PHONE_NUMBERS,
+ mail = item.second
+ )
+ }
+
+ internal val ORGANIZATION = organization()
+
+ internal val PATIENT = Patient(
+ name = "$FIRST_NAMES Mustermann",
+ address = ADDRESS,
+ birthdate = null,
+ insuranceIdentifier = MOCK_IDENTIFIER
+ )
+
+ private val RATIO = Ratio(
+ numerator = Quantity(
+ value = "1",
+ unit = "oz"
+ ),
+ denominator = null
+ )
+
+ private val MEDICATION = MedicationPZN(
+ category = SyncedTaskData.MedicationCategory.entries[0],
+ vaccine = true,
+ text = SYNCED_MEDICATION_NAMES,
+ form = codeToFormMapping,
+ lotNumber = MOCK_IDENTIFIER,
+ expirationDate = FhirTemporal.Instant(EXPIRY_DATE),
+ uniqueIdentifier = MOCK_IDENTIFIER,
+ normSizeCode = normSizeMappings,
+ amount = RATIO
+ )
+
+ internal val MEDICATION_DISPENSE = MedicationDispense(
+ dispenseId = UUID.randomUUID().toString(),
+ patientIdentifier = PATIENT.insuranceIdentifier ?: "",
+ medication = MEDICATION,
+ wasSubstituted = true,
+ dosageInstruction = DOSAGE,
+ performer = PERFORMERS,
+ whenHandedOver = null
+ )
+
+ internal var MEDICATION_REQUEST = MedicationRequest(
+ medication = MEDICATION,
+ dateOfAccident = null,
+ location = CITY_NAMES,
+ emergencyFee = true,
+ dosageInstruction = DOSAGE,
+ multiplePrescriptionInfo = SyncedTaskData.MultiplePrescriptionInfo(),
+ note = DOCTORS_NOTES,
+ substitutionAllowed = true
+ )
+
+ internal object MockScannedPrescription {
+ internal val mockScannedTask01 = ScannedTaskData.ScannedTask(
+ profileId = mockProfile01.id,
+ taskId = "160.000.006.394.157.15",
+ index = 0,
+ name = SCANNED_MEDICINE_NAMES,
+ accessCode = "8cc887c16681517e2db71078f367d4446c156bde743e15c2440722ec0835f406",
+ scannedOn = fixedTime,
+ redeemedOn = null,
+ communications = emptyList()
+ )
+ internal val mockScannedTask02 = ScannedTaskData.ScannedTask(
+ profileId = mockProfile01.id,
+ taskId = "160.000.006.386.866.63",
+ index = 1,
+ name = SCANNED_MEDICINE_NAMES,
+ accessCode = "c0967e56ccbcb55ef0851ac9ad3a03dcfbb5ba1934d8d1338290167e348c876f",
+ scannedOn = fixedTime,
+ redeemedOn = null,
+ communications = emptyList()
+ )
+ }
+
+ internal object MockSyncedPrescription {
+ internal fun syncedTask(
+ profileIdentifier: ProfileIdentifier,
+ status: SyncedTaskData.TaskStatus = SyncedTaskData.TaskStatus.Ready,
+ index: Int
+ ) = SyncedTaskData.SyncedTask(
+ profileId = profileIdentifier,
+ taskId = "$SYNCED_TASK_PRESET.$index",
+ isIncomplete = false,
+ pvsIdentifier = MOCK_IDENTIFIER,
+ accessCode = MOCK_IDENTIFIER,
+ lastModified = longerRandomTimeToday,
+ organization = ORGANIZATION,
+ practitioner = PRACTITIONER,
+ patient = PATIENT,
+ insuranceInformation = SyncedTaskData.InsuranceInformation(
+ name = null,
+ status = null,
+ coverageType = SyncedTaskData.CoverageType.GKV
+ ),
+ expiresOn = EXPIRY_DATE,
+ acceptUntil = SHORT_EXPIRY_DATE,
+ authoredOn = NOW,
+ status = status,
+ medicationRequest = MEDICATION_REQUEST.copy(
+ substitutionAllowed = BOOLEAN[index]
+ ), // Making sure the substitutionAllowed is different for each task
+ medicationDispenses = listOf(MEDICATION_DISPENSE),
+ communications = emptyList(),
+ failureToReport = ""
+ )
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockProfileInfo.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockProfileInfo.kt
new file mode 100644
index 00000000..d1dec16a
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/datasource/data/MockProfileInfo.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+@file:Suppress("MagicNumber")
+
+package de.gematik.ti.erp.app.datasource.data
+
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import kotlinx.datetime.Instant
+
+object MockProfileInfo {
+ private const val HEALTH_INSURANCE_COMPANIES = "GesundheitsVersichert AG"
+
+ private const val INSURANCE_NUMBER = "10000000"
+
+ internal val mockProfile01 = profile(
+ profileName = "Erika Mustermann",
+ isActive = true,
+ color = ProfilesData.ProfileColorNames.SUN_DEW,
+ insuranceType = ProfilesData.InsuranceType.PKV, // Note: Private insurance account
+ avatar = ProfilesData.Avatar.FemaleDoctor,
+ lastAuthenticated = null
+ )
+
+ private fun profile(
+ profileName: String,
+ isActive: Boolean = true,
+ color: ProfilesData.ProfileColorNames = ProfilesData.ProfileColorNames.SUN_DEW,
+ avatar: ProfilesData.Avatar = ProfilesData.Avatar.FemaleDoctor,
+ insuranceType: ProfilesData.InsuranceType = ProfilesData.InsuranceType.GKV,
+ lastAuthenticated: Instant? = null
+ ): ProfilesData.Profile {
+ return ProfilesData.Profile(
+ id = "1",
+ name = profileName,
+ color = color,
+ avatar = avatar,
+ insuranceIdentifier = INSURANCE_NUMBER,
+ insuranceType = insuranceType,
+ insurantName = profileName,
+ insuranceName = HEALTH_INSURANCE_COMPANIES,
+ singleSignOnTokenScope = null,
+ active = isActive,
+ isConsentDrawerShown = false,
+ lastAuthenticated = lastAuthenticated
+ )
+ }
+
+ internal fun String.create() = profile(profileName = this)
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/AppModules.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/AppModules.kt
index 24cd9303..e0e98e0b 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/AppModules.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/AppModules.kt
@@ -1,24 +1,27 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.di
import android.content.Context
+import android.content.res.AssetManager
+import android.content.res.Resources
+import android.os.Looper
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import de.gematik.ti.erp.app.DispatchProvider
@@ -26,6 +29,7 @@ import de.gematik.ti.erp.app.featuretoggle.FeatureToggleManager
import de.gematik.ti.erp.app.info.mockBuildConfigurationModule
import de.gematik.ti.erp.app.pkv.mockFileProviderAuthorityModule
import org.kodein.di.DI
+import org.kodein.di.bindProvider
import org.kodein.di.bindSingleton
import org.kodein.di.instance
@@ -38,8 +42,20 @@ const val ApplicationPreferencesTag = "ApplicationPreferences"
const val NetworkPreferencesTag = "NetworkPreferences"
const val NetworkSecurePreferencesTag = "NetworkSecurePreferences"
-val appModules = DI.Module("appModules") {
+val appModules = DI.Module("appModules", allowSilentOverride = true) {
bindSingleton { object : DispatchProvider {} }
+ bindProvider {
+ val context = instance()
+ context.resources
+ }
+ bindProvider {
+ val context = instance()
+ context.assets
+ }
+ bindProvider {
+ val context = instance()
+ context.mainLooper
+ }
bindSingleton(ApplicationPreferencesTag) {
val context = instance()
context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE)
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/MockFeatureModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/MockFeatureModule.kt
index 78a1ab3e..7153ccd9 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/MockFeatureModule.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/MockFeatureModule.kt
@@ -1,43 +1,51 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.di
import de.gematik.ti.erp.app.analytics.di.analyticsModule
import de.gematik.ti.erp.app.appsecurity.appSecurityModule
+import de.gematik.ti.erp.app.appupdate.di.appUpdateModule
import de.gematik.ti.erp.app.authentication.di.authenticationModule
import de.gematik.ti.erp.app.cardunlock.di.cardUnlockModule
import de.gematik.ti.erp.app.cardwall.cardWallModule
+import de.gematik.ti.erp.app.debugsettings.di.debugSettingsModule
+import de.gematik.ti.erp.app.di.datasource.mockDataSourceModule
+import de.gematik.ti.erp.app.di.pharmacy.mockPharmacyRepositoryModule
+import de.gematik.ti.erp.app.di.prescription.mockPrescriptionRepositoryModule
+import de.gematik.ti.erp.app.di.prescription.mockTaskRepositoryModule
+import de.gematik.ti.erp.app.di.profile.mockProfileRepositoryModule
+import de.gematik.ti.erp.app.di.settings.mockSettingsRepositoryModule
+import de.gematik.ti.erp.app.featuretoggle.di.newFeaturesSharedPrefsModule
import de.gematik.ti.erp.app.idp.idpModule
import de.gematik.ti.erp.app.idp.idpUseCaseModule
+import de.gematik.ti.erp.app.logger.di.loggerModule
+import de.gematik.ti.erp.app.messages.di.messageRepositoryModule
+import de.gematik.ti.erp.app.messages.di.messagesModule
import de.gematik.ti.erp.app.mlkit.mlKitModule
-import de.gematik.ti.erp.app.orderhealthcard.orderHealthCardModule
-import de.gematik.ti.erp.app.orders.messageRepositoryModule
-import de.gematik.ti.erp.app.orders.messagesModule
-import de.gematik.ti.erp.app.pharmacy.di.pharmacyRepositoryModule
-import de.gematik.ti.erp.app.pharmacy.pharmacyMockModule
+import de.gematik.ti.erp.app.onboarding.di.onboardingModule
+import de.gematik.ti.erp.app.orderhealthcard.di.orderHealthCardModule
+import de.gematik.ti.erp.app.pharmacy.di.pharmacyModule
import de.gematik.ti.erp.app.pkv.consentRepositoryModule
import de.gematik.ti.erp.app.pkv.pkvModule
import de.gematik.ti.erp.app.prescription.prescriptionModule
import de.gematik.ti.erp.app.prescription.prescriptionRepositoryModule
import de.gematik.ti.erp.app.prescription.taskModule
-import de.gematik.ti.erp.app.prescription.taskRepositoryModule
-import de.gematik.ti.erp.app.profiles.profileRepositoryModule
import de.gematik.ti.erp.app.profiles.profilesModule
import de.gematik.ti.erp.app.protocol.protocolModule
import de.gematik.ti.erp.app.protocol.protocolRepositoryModule
@@ -49,16 +57,20 @@ import org.kodein.di.DI
val mockFeatureModule = DI.Module("featureModule", allowSilentOverride = true) {
importAll(
+ applicationControllerModule,
+ onboardingModule,
+ dispatchersModule,
cardWallModule,
appSecurityModule,
networkModule,
+ loggerModule,
realmModule,
idpModule,
idpUseCaseModule,
messagesModule,
orderHealthCardModule,
+ pharmacyModule,
redeemModule,
- prescriptionModule,
profilesModule,
protocolModule,
taskModule,
@@ -67,18 +79,27 @@ val mockFeatureModule = DI.Module("featureModule", allowSilentOverride = true) {
cardUnlockModule,
pkvModule,
authenticationModule,
- profileRepositoryModule,
+ // shared-prefs modules
+ timeoutsSharedPrefsModule,
+ newFeaturesSharedPrefsModule,
+ // other modules
+ analyticsModule,
+ debugSettingsModule,
+ mlKitModule,
+ appUpdateModule,
+ prescriptionModule,
+ // repositories
prescriptionRepositoryModule,
consentRepositoryModule,
protocolRepositoryModule,
- pharmacyRepositoryModule,
messageRepositoryModule,
- taskRepositoryModule,
- timeoutsSharedPrefsModule,
- analyticsModule,
- mlKitModule,
// mocked modules
- pharmacyMockModule,
+ mockPharmacyRepositoryModule,
+ mockTaskRepositoryModule,
+ mockProfileRepositoryModule,
+ mockDataSourceModule,
+ mockPrescriptionRepositoryModule,
+ mockSettingsRepositoryModule,
allowOverride = true
)
}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/datasource/MockDataSourceModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/datasource/MockDataSourceModule.kt
new file mode 100644
index 00000000..cf096319
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/datasource/MockDataSourceModule.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.datasource
+
+import de.gematik.ti.erp.app.datasource.MockDataSource
+import org.kodein.di.DI
+import org.kodein.di.bindSingleton
+
+val mockDataSourceModule = DI.Module("mockDataSourceModule") {
+ bindSingleton { MockDataSource() }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/overrides/TestConfigOverrides.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/overrides/TestConfigOverrides.kt
new file mode 100644
index 00000000..b4aa6a03
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/overrides/TestConfigOverrides.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.overrides
+
+import de.gematik.ti.erp.app.config.TestScenario
+import de.gematik.ti.erp.app.mocks.settings.OnboardingDoneMockSettingsDataSource
+import de.gematik.ti.erp.app.mocks.settings.OnboardingNotDoneMockSettingsDataSource
+import de.gematik.ti.erp.app.settings.datasource.SettingsDataSource
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+
+/**
+ * Overrides designed specifically for different test scenarios
+ */
+fun DI.MainBuilder.testScenarioOverrides(scenario: TestScenario) {
+ when (scenario.isOnboardingDone) {
+ true -> bindProvider(overrides = true) { OnboardingDoneMockSettingsDataSource() }
+ false -> bindProvider(overrides = true) { OnboardingNotDoneMockSettingsDataSource() }
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/pharmacy/MockPharmacyModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/pharmacy/MockPharmacyModule.kt
new file mode 100644
index 00000000..3f13ec45
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/pharmacy/MockPharmacyModule.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.pharmacy
+
+import de.gematik.ti.erp.app.pharmacy.repository.PharmacyRepository
+import de.gematik.ti.erp.app.pharmacy.repository.PreviewMapCoordinatesRepository
+import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.DefaultFavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.DefaultOftenUsePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.FavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.OftenUsedPharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.PharmacyRemoteDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.PreviewMapCoordinatesDataSource
+import de.gematik.ti.erp.app.redeem.repository.datasource.DefaultRedeemLocalDataSource
+import de.gematik.ti.erp.app.redeem.repository.datasource.RedeemLocalDataSource
+import de.gematik.ti.erp.app.repository.MockShippingContactRepository
+import de.gematik.ti.erp.app.repository.pharmacy.MockPharmacyRepository
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+import org.kodein.di.bindSingleton
+import org.kodein.di.instance
+
+val mockPharmacyRepositoryModule = DI.Module("mockPharmacyModule") {
+ bindProvider { PharmacyRemoteDataSource(instance(), instance()) }
+ bindProvider { DefaultRedeemLocalDataSource(instance()) }
+ bindProvider { DefaultOftenUsePharmacyLocalDataSource(instance()) }
+ bindProvider { DefaultFavouritePharmacyLocalDataSource(instance()) }
+ bindSingleton { PreviewMapCoordinatesDataSource() }
+ bindProvider { PreviewMapCoordinatesRepository(instance()) }
+ bindProvider { MockPharmacyRepository(instance(), instance(), instance()) }
+ bindProvider { MockShippingContactRepository() }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockPrescriptionModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockPrescriptionModule.kt
new file mode 100644
index 00000000..6aa7910d
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockPrescriptionModule.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.prescription
+
+import de.gematik.ti.erp.app.prescription.repository.PrescriptionRepository
+import de.gematik.ti.erp.app.repository.prescription.MockPrescriptionsRepository
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+import org.kodein.di.instance
+
+val mockPrescriptionRepositoryModule = DI.Module("mockPrescriptionRepositoryModule", allowSilentOverride = true) {
+ bindProvider { MockPrescriptionsRepository(instance()) }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockTaskModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockTaskModule.kt
new file mode 100644
index 00000000..cfa3ba70
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/prescription/MockTaskModule.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.prescription
+
+import de.gematik.ti.erp.app.prescription.repository.TaskRepository
+import de.gematik.ti.erp.app.repository.prescription.MockTaskRepository
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+import org.kodein.di.instance
+
+val mockTaskRepositoryModule = DI.Module("mockTaskRepositoryModule", allowSilentOverride = true) {
+ bindProvider { MockTaskRepository(instance()) }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/profile/MockProfileModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/profile/MockProfileModule.kt
new file mode 100644
index 00000000..0b7a1ce5
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/profile/MockProfileModule.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.profile
+
+import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
+import de.gematik.ti.erp.app.repository.profiles.MockProfilesRepository
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+import org.kodein.di.instance
+
+val mockProfileRepositoryModule = DI.Module("mockProfileRepositoryModule", allowSilentOverride = true) {
+ bindProvider {
+ MockProfilesRepository(instance())
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/settings/SettingsMockModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/settings/SettingsMockModule.kt
new file mode 100644
index 00000000..1aa2cf09
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/di/settings/SettingsMockModule.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.di.settings
+
+import de.gematik.ti.erp.app.mocks.settings.OnboardingDoneMockSettingsDataSource
+import de.gematik.ti.erp.app.repository.MockSettingsRepository
+import de.gematik.ti.erp.app.settings.ApplicationPreferencesTag
+import de.gematik.ti.erp.app.settings.datasource.SettingsDataSource
+import de.gematik.ti.erp.app.settings.repository.CardWallRepository
+import de.gematik.ti.erp.app.settings.repository.SettingsRepository
+import org.kodein.di.DI
+import org.kodein.di.bindProvider
+import org.kodein.di.bindSingleton
+import org.kodein.di.instance
+
+val mockSettingsRepositoryModule = DI.Module("mockSettingsModule", allowSilentOverride = true) {
+ bindProvider { CardWallRepository(prefs = instance(ApplicationPreferencesTag)) }
+ bindProvider { MockSettingsRepository(instance(), instance(), instance()) }
+ bindSingleton { OnboardingDoneMockSettingsDataSource() }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigInformation.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigInformation.kt
index 0cdbffb5..0b902271 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigInformation.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigInformation.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.info
@@ -39,4 +39,5 @@ class MockBuildConfigInformation : BuildConfigInformation {
@Composable
override fun inDarkTheme(): String = if (isSystemInDarkTheme()) DARK_THEME_ON else DARK_THEME_OFF
override fun nfcInformation(context: Context): String = "nicht vorhanden"
+ override fun isMockedApp(): Boolean = true
}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigurationModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigurationModule.kt
index 5eeee5bc..2db2837d 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigurationModule.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/info/MockBuildConfigurationModule.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.info
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/profile/ProfileDataSource.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/profile/ProfileDataSource.kt
new file mode 100644
index 00000000..6ca2e95b
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/profile/ProfileDataSource.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.mocks.profile
+
+import de.gematik.ti.erp.app.BuildKonfig
+import de.gematik.ti.erp.app.idp.model.IdpData
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.datetime.Clock
+import org.bouncycastle.cert.X509CertificateHolder
+import org.bouncycastle.util.encoders.Base64
+import java.util.UUID
+import kotlin.time.Duration.Companion.days
+
+class ProfileDataSource {
+
+ private val can = "123123"
+ private val byteArray = Base64.decode(BuildKonfig.DEFAULT_VIRTUAL_HEALTH_CARD_CERTIFICATE)
+ private val healthCertificate = X509CertificateHolder(byteArray)
+ private val singleSignOnToken = IdpData.SingleSignOnToken(
+ token = UUID.randomUUID().toString(),
+ expiresOn = Clock.System.now().plus(200.days),
+ validOn = Clock.System.now().plus(20.days)
+ )
+
+ private val firstProfile = ProfilesData.Profile(
+ id = "1",
+ name = "Max Mustermann",
+ color = ProfilesData.ProfileColorNames.BLUE_MOON,
+ lastAuthenticated = Clock.System.now(),
+ avatar = ProfilesData.Avatar.ManWithPhone,
+ insuranceName = "AOK",
+ insuranceType = ProfilesData.InsuranceType.GKV,
+ isConsentDrawerShown = true,
+ active = true,
+ singleSignOnTokenScope = IdpData.DefaultToken(
+ token = singleSignOnToken,
+ cardAccessNumber = can,
+ healthCardCertificate = healthCertificate
+ )
+ )
+
+ val profiles = MutableStateFlow(mutableListOf(firstProfile))
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingDoneMockSettingsDataSource.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingDoneMockSettingsDataSource.kt
new file mode 100644
index 00000000..08ec6cc5
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingDoneMockSettingsDataSource.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.mocks.settings
+
+import de.gematik.ti.erp.app.settings.datasource.SettingsDataSource
+import de.gematik.ti.erp.app.settings.model.SettingsData
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class OnboardingDoneMockSettingsDataSource : SettingsDataSource {
+ override val appVersion = SETTINGS_APP_VERSION_DATA
+
+ override val authentication: MutableStateFlow =
+ MutableStateFlow(SETTINGS_PASSWORD)
+
+ override val pharmacySearch: MutableStateFlow =
+ MutableStateFlow(SETTINGS_PHARMACY_SEARCH_RESULT_DATA)
+
+ override val generalData: MutableStateFlow =
+ MutableStateFlow(
+ SETTINGS_GENERAL_DATA.copy(onboardingShownIn = appVersion)
+ )
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingNotDoneMockSettingsDataSource.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingNotDoneMockSettingsDataSource.kt
new file mode 100644
index 00000000..1213b3d8
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/OnboardingNotDoneMockSettingsDataSource.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.mocks.settings
+
+import de.gematik.ti.erp.app.settings.datasource.SettingsDataSource
+import de.gematik.ti.erp.app.settings.model.SettingsData
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class OnboardingNotDoneMockSettingsDataSource : SettingsDataSource {
+ override val appVersion = SETTINGS_APP_VERSION_DATA
+
+ override val authentication: MutableStateFlow =
+ MutableStateFlow(SETTINGS_UNSPECIFIED)
+
+ override val pharmacySearch: MutableStateFlow =
+ MutableStateFlow(SETTINGS_PHARMACY_SEARCH_RESULT_DATA)
+
+ override val generalData: MutableStateFlow =
+ MutableStateFlow(SETTINGS_GENERAL_DATA)
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/SettingsMocks.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/SettingsMocks.kt
new file mode 100644
index 00000000..e9094cc8
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/mocks/settings/SettingsMocks.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.mocks.settings
+
+import de.gematik.ti.erp.app.settings.model.SettingsData
+
+internal val SETTINGS_APP_VERSION_DATA = SettingsData.AppVersion(
+ code = 1,
+ name = "1.0.0"
+)
+
+internal val SETTINGS_PHARMACY_SEARCH_RESULT_DATA = SettingsData.PharmacySearch(
+ name = "TEST-ONLY",
+ locationEnabled = true,
+ deliveryService = false,
+ onlineService = false,
+ openNow = false
+)
+
+internal val SETTINGS_GENERAL_DATA = SettingsData.General(
+ latestAppVersion = SETTINGS_APP_VERSION_DATA,
+ onboardingShownIn = null, // app will show onboarding if this is null
+ welcomeDrawerShown = true,
+ zoomEnabled = false,
+ userHasAcceptedInsecureDevice = true,
+ mainScreenTooltipsShown = true,
+ mlKitAccepted = false,
+ screenShotsAllowed = true,
+ trackingAllowed = false,
+ userHasAcceptedIntegrityNotOk = true
+)
+
+internal val SETTINGS_PASSWORD = SettingsData.Authentication(
+ password = SettingsData.Authentication.Password(password = "password"),
+ deviceSecurity = false,
+ failedAuthenticationAttempts = 0
+)
+
+internal val SETTINGS_UNSPECIFIED = SettingsData.Authentication(
+ password = null,
+ deviceSecurity = false,
+ failedAuthenticationAttempts = 0
+)
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockProfileLinkedCommunication.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockProfileLinkedCommunication.kt
new file mode 100644
index 00000000..28eac055
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockProfileLinkedCommunication.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.model
+
+import de.gematik.ti.erp.app.datasource.data.MockConstants.MOCK_COMMUNICATION_ID_01
+import de.gematik.ti.erp.app.prescription.model.Communication
+import de.gematik.ti.erp.app.prescription.model.CommunicationProfile
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+
+/**
+ * This is created to link the communication with a particular profile
+ */
+data class MockProfileLinkedCommunication(
+ val profileId: String,
+ val taskId: String,
+ val communicationId: String,
+ val orderId: String,
+ val profile: CommunicationProfile,
+ val sentOn: Instant,
+ val sender: String,
+ val recipient: String,
+ val payload: String?,
+ val consumed: Boolean
+)
+
+fun MockProfileLinkedCommunication.toSyncedTaskDataCommunication() =
+ Communication(
+ taskId = taskId,
+ communicationId = communicationId,
+ orderId = orderId,
+ profile = profile,
+ sentOn = sentOn,
+ sender = sender,
+ recipient = recipient,
+ payload = payload,
+ consumed = consumed
+ )
+
+internal fun MockSentCommunicationJson.toMockProfileLinkedCommunication(
+ profileId: ProfileIdentifier
+) =
+ MockProfileLinkedCommunication(
+ profileId = profileId,
+ communicationId = MOCK_COMMUNICATION_ID_01,
+ taskId = basedOn.firstNotNullOfOrNull { it.taskId } ?: "",
+ orderId = identifier.firstNotNullOfOrNull { it.value } ?: "",
+ profile = when (meta.isRequest) {
+ true -> CommunicationProfile.ErxCommunicationDispReq
+ false -> CommunicationProfile.ErxCommunicationReply
+ },
+ sentOn = Clock.System.now(),
+ sender = payload.firstNotNullOfOrNull { it.name } ?: "",
+ recipient = recipient.firstNotNullOfOrNull { it.identifier.value } ?: "",
+ payload = payload.firstNotNullOfOrNull { it.contentString },
+ consumed = false
+ )
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockSentCommunicationJson.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockSentCommunicationJson.kt
new file mode 100644
index 00000000..a9c4510c
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/model/MockSentCommunicationJson.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.model
+
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import kotlinx.serialization.Serializable
+import org.json.JSONObject
+
+@Serializable
+data class MockSentCommunicationJson(
+ val resourceType: String,
+ val meta: MockSentCommunicationMeta,
+ val identifier: List,
+ val status: String,
+ val basedOn: List,
+ val recipient: List,
+ val payload: List
+)
+
+@Serializable
+data class MockSentCommunicationMeta(
+ val profile: List
+) {
+ val isRequest = profile.any { it.contains("GEM_ERP_PR_Communication_DispReq") }
+}
+
+@Serializable
+data class MockCommunicationOrderIdIdentifier(
+ val system: String,
+ // order-id
+ val value: String
+)
+
+@Serializable
+data class MockCommunicationTaskIdIdentifierReference(
+ val reference: String
+) {
+ val taskId = reference.split('/').getOrNull(1) // task-id
+}
+
+@Serializable
+data class MockCommunicationRecipient(
+ val identifier: MockCommunicationRecipientBundle
+)
+
+@Serializable
+data class MockCommunicationRecipientBundle(
+ val system: String,
+ val value: String // telematik.id
+)
+
+@Serializable
+data class MockCommunicationPayloadContent(
+ val contentString: String
+) {
+ private fun jsonObject() = JSONObject(contentString)
+ val name: String
+ get() = jsonObject().getString("name")
+
+ val supplyOptionType: String
+ get() = jsonObject().getString("supplyOptionsType")
+
+ val address: SyncedTaskData.Address
+ get() {
+ val item = jsonObject().getString("address").split(',')
+ return SyncedTaskData.Address(
+ line1 = item[0],
+ line2 = item[1],
+ postalCode = item[2],
+ city = item[3]
+ )
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pharmacy/PharmacyMockModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/pharmacy/PharmacyMockModule.kt
deleted file mode 100644
index b6024e1a..00000000
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pharmacy/PharmacyMockModule.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.pharmacy
-
-import de.gematik.ti.erp.app.pharmacy.repository.PharmacyRemoteDataSource
-import de.gematik.ti.erp.app.pharmacy.repository.PharmacyRepository
-import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
-import de.gematik.ti.erp.app.pharmacy.usecase.GetOrderStateUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.GetOverviewPharmaciesUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacyDirectRedeemUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacyMapsUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacyOverviewUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacySearchUseCase
-import de.gematik.ti.erp.app.repository.PharmacyMockRepository
-import org.kodein.di.DI
-import org.kodein.di.bindProvider
-import org.kodein.di.instance
-
-val pharmacyMockModule = DI.Module("pharmacyMockModule") {
- bindProvider { PharmacyRemoteDataSource(instance(), instance()) }
- bindProvider { PharmacyMockRepository() }
- bindProvider { ShippingContactRepository(instance(), instance()) }
- bindProvider { PharmacyDirectRedeemUseCase(instance()) }
- bindProvider { PharmacyMapsUseCase(instance(), instance(), instance()) }
- bindProvider { PharmacySearchUseCase(instance(), instance(), instance(), instance(), instance()) }
- bindProvider { PharmacyOverviewUseCase(instance(), instance()) }
- bindProvider { GetOrderStateUseCase(instance(), instance(), instance()) }
- bindProvider { GetOverviewPharmaciesUseCase(instance()) }
-}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthority.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthority.kt
index 0707084a..12cc48e8 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthority.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthority.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.pkv
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthorityModule.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthorityModule.kt
index fbf165f1..0bbe5c71 100644
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthorityModule.kt
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/pkv/MockFileProviderAuthorityModule.kt
@@ -1,20 +1,21 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
+
package de.gematik.ti.erp.app.pkv
import org.kodein.di.DI
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockSettingsRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockSettingsRepository.kt
new file mode 100644
index 00000000..bfccc322
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockSettingsRepository.kt
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.repository
+
+import de.gematik.ti.erp.app.db.entities.v1.ProfileEntityV1
+import de.gematik.ti.erp.app.db.entities.v1.SettingsEntityV1
+import de.gematik.ti.erp.app.db.writeToRealm
+import de.gematik.ti.erp.app.settings.datasource.SettingsDataSource
+import de.gematik.ti.erp.app.settings.model.SettingsData
+import de.gematik.ti.erp.app.settings.repository.SettingsRepository
+import io.realm.kotlin.Realm
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Instant
+
+class MockSettingsRepository(
+ private val settingsDataSource: SettingsDataSource,
+ // keep realm till the profile mock is implemented
+ private val realm: Realm,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : SettingsRepository(
+ dispatchers = dispatcher,
+ realm = realm
+) {
+ override val general: Flow
+ get() = settingsDataSource.generalData
+
+ override suspend fun acceptUpdatedDataTerms(now: Instant) {
+ // no-op
+ }
+
+ override suspend fun saveOnboardingData(
+ authentication: SettingsData.Authentication,
+ profileName: String,
+ now: Instant
+ ) {
+ withContext(dispatcher) {
+ if (authentication.methodIsPassword) {
+ settingsDataSource.authentication.value = authentication
+ }
+ }
+ withContext(dispatcher) {
+ realm.writeToRealm { profile ->
+ copyToRealm(
+ ProfileEntityV1().apply {
+ this.name = profileName
+ this.active = true
+ }
+ )
+ }
+ }
+ }
+
+ override suspend fun enableDeviceSecurity() {
+ // no-op since we only support password authentication for mock
+ }
+
+ override suspend fun disableDeviceSecurity() {
+ // no-op since we only support password authentication for mock
+ }
+
+ override suspend fun setPassword(password: SettingsData.Authentication.Password) {
+ settingsDataSource.authentication.value = SettingsData.Authentication(
+ password = password,
+ deviceSecurity = false,
+ failedAuthenticationAttempts = 0
+ )
+ }
+
+ override suspend fun resetPassword() {
+ // no-op since we only support password authentication for mock
+ }
+
+ override val authentication: Flow
+ get() = settingsDataSource.authentication
+
+ override suspend fun saveZoomPreference(enabled: Boolean) {
+ settingsDataSource.generalData.update {
+ it.copy(
+ zoomEnabled = enabled
+ )
+ }
+ }
+
+ override suspend fun acceptInsecureDevice() {
+ settingsDataSource.generalData.update {
+ it.copy(
+ userHasAcceptedInsecureDevice = true
+ )
+ }
+ }
+
+ override suspend fun incrementNumberOfAuthenticationFailures() {
+ settingsDataSource.authentication.update {
+ it.copy(
+ failedAuthenticationAttempts = it.failedAuthenticationAttempts + 1
+ )
+ }
+ }
+
+ override suspend fun resetNumberOfAuthenticationFailures() {
+ settingsDataSource.authentication.update {
+ it.copy(
+ failedAuthenticationAttempts = 0
+ )
+ }
+ }
+
+ override suspend fun saveWelcomeDrawerShown() {
+ settingsDataSource.generalData.update {
+ it.copy(
+ welcomeDrawerShown = true
+ )
+ }
+ }
+
+ override suspend fun saveMainScreenTooltipShown() {
+ settingsDataSource.generalData.update {
+ it.copy(
+ mainScreenTooltipsShown = true
+ )
+ }
+ }
+
+ override suspend fun acceptMlKit() {
+ settingsDataSource.generalData.update {
+ it.copy(
+ mlKitAccepted = true
+ )
+ }
+ }
+
+ override suspend fun saveAllowScreenshots(allow: Boolean) {
+ settingsDataSource.generalData.update {
+ it.copy(
+ screenShotsAllowed = allow
+ )
+ }
+ }
+
+ override suspend fun saveAllowTracking(allow: Boolean) {
+ settingsDataSource.generalData.update {
+ it.copy(
+ trackingAllowed = allow
+ )
+ }
+ }
+
+ override suspend fun acceptIntegrityNotOk() {
+ settingsDataSource.generalData.update {
+ it.copy(
+ userHasAcceptedIntegrityNotOk = true
+ )
+ }
+ }
+
+ override suspend fun savePharmacySearch(search: SettingsData.PharmacySearch) {
+ settingsDataSource.pharmacySearch.update {
+ it.copy(
+ name = search.name,
+ locationEnabled = search.locationEnabled,
+ deliveryService = search.deliveryService,
+ onlineService = search.onlineService,
+ openNow = search.openNow
+ )
+ }
+ }
+
+ override val pharmacySearch: Flow
+ get() = settingsDataSource.pharmacySearch
+
+ override fun isAnalyticsAllowed(): Flow {
+ return settingsDataSource.generalData.map { it.trackingAllowed }
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockShippingContactRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockShippingContactRepository.kt
new file mode 100644
index 00000000..bdaa3a83
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/MockShippingContactRepository.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.repository
+
+import de.gematik.ti.erp.app.pharmacy.model.PharmacyData
+import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+class MockShippingContactRepository : ShippingContactRepository {
+ override fun shippingContact(): Flow {
+ return flowOf(
+ PharmacyData.ShippingContact(
+ name = "Helga Schmetterling",
+ line1 = "Schmetterlingweg 1",
+ line2 = "2 Stockwerk rechts",
+ postalCode = "12345",
+ city = "Berlin",
+ telephoneNumber = "123456789",
+ mail = "schmetterling@butterfly.com",
+ deliveryInformation = "Bitte klingeln"
+ )
+ )
+ }
+
+ override suspend fun saveShippingContact(contact: PharmacyData.ShippingContact) {
+ // Add implementation
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/PharmacyMockRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/PharmacyMockRepository.kt
deleted file mode 100644
index 0788e7b0..00000000
--- a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/PharmacyMockRepository.kt
+++ /dev/null
@@ -1,1993 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.repository
-
-import de.gematik.ti.erp.app.fhir.model.PharmacyServices
-import de.gematik.ti.erp.app.fhir.model.extractPharmacyServices
-import de.gematik.ti.erp.app.fhir.model.json
-import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
-import de.gematik.ti.erp.app.pharmacy.repository.PharmacyRepository
-import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
-import io.github.aakira.napier.Napier
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOf
-
-@Suppress("LargeClass")
-class PharmacyMockRepository : PharmacyRepository {
-
- override suspend fun searchPharmacies(names: List, filter: Map): Result {
- return Result.success(extractedPharmacies)
- }
-
- override suspend fun searchPharmaciesByBundle(bundleId: String, offset: Int, count: Int): Result {
- return Result.success(extractedPharmacies)
- }
-
- override suspend fun searchBinaryCerts(locationId: String): Result> {
- return Result.success(emptyList())
- }
-
- override suspend fun redeemPrescriptionDirectly(
- url: String,
- message: ByteArray,
- pharmacyTelematikId: String,
- transactionId: String
- ): Result {
- return Result.success(Unit)
- }
-
- override fun loadOftenUsedPharmacies(): Flow> {
- return flowOf(emptyList())
- }
-
- override fun loadFavoritePharmacies(): Flow> {
- return flowOf(emptyList())
- }
-
- @Suppress("EmptyFunctionBlock")
- override suspend fun saveOrUpdateOftenUsedPharmacy(pharmacy: PharmacyUseCaseData.Pharmacy) {
- }
-
- @Suppress("EmptyFunctionBlock")
- override suspend fun deleteOverviewPharmacy(overviewPharmacy: OverviewPharmacyData.OverviewPharmacy) {
- }
-
- @Suppress("EmptyFunctionBlock")
- override suspend fun saveOrUpdateFavoritePharmacy(pharmacy: PharmacyUseCaseData.Pharmacy) {
- }
-
- @Suppress("EmptyFunctionBlock")
- override suspend fun deleteFavoritePharmacy(favoritePharmacy: PharmacyUseCaseData.Pharmacy) {
- }
-
- override suspend fun searchPharmacyByTelematikId(telematikId: String): Result {
- return Result.success(extractedPharmacies)
- }
-
- override fun isPharmacyInFavorites(pharmacy: PharmacyUseCaseData.Pharmacy): Flow {
- return flowOf(true)
- }
-
- @Suppress("EmptyFunctionBlock")
- override suspend fun markAsRedeemed(taskId: String) {
- }
-
- private val jsonStringMocked = """{
- "id": "49b6b9fd-eec7-41f3-b624-cc99d46fb828",
- "meta": {
- "lastUpdated": "2023-08-31T12:18:10.94674676+02:00"
- },
- "resourceType": "Bundle",
- "type": "searchset",
- "total": 20,
- "link": [
- {
- "relation": "self",
- "url": "Bundle49b6b9fd-eec7-41f3-b624-cc99d46fb828"
- }
- ],
- "entry": [
- {
- "resource": {
- "id": "6bb01538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 01"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.201"
- }
- ],
- "name": "ZoTI_01_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb02538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 02"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.202"
- }
- ],
- "name": "ZoTI_02_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb03538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 03"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.203"
- }
- ],
- "name": "ZoTI_03_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb04538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 04"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.204"
- }
- ],
- "name": "ZoTI_04_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 300
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb05538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 05"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.205"
- }
- ],
- "name": "ZoTI_05_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb06538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "2d1f1f35-d03d-4932-a78a-67715cbb7963",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb06538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 06"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.206"
- }
- ],
- "name": "ZoTI_06_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb07538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 07"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.207"
- }
- ],
- "name": "ZoTI_07_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb08538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 08"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.208"
- }
- ],
- "name": "ZoTI_08_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb09538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 09"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.209"
- }
- ],
- "name": "ZoTI_09_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb10538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "fe9a01e8-d702-4b9d-a997-096eca057b74",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb10538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 10"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.210"
- }
- ],
- "name": "ZoTI_10_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb11538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "0991992b-b3fd-4f3e-a331-d4f0e2856185",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb11538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 11"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.211"
- }
- ],
- "name": "ZoTI_11_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb12538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "ae48f60e-9c17-4610-a0c4-d1f7ac6abb5b",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb12538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 12"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.212"
- }
- ],
- "name": "ZoTI_12_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb13538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "e63f85da-3c1a-4f16-8059-45321bec107f",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb13538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 13"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.213"
- }
- ],
- "name": "ZoTI_13_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb14538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "bb022669-f8fc-424a-8bfa-e9b5e8102333",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb14538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 14"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.214"
- }
- ],
- "name": "ZoTI_14_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb15538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 15"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.215"
- }
- ],
- "name": "ZoTI_15_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb16538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 16"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.216"
- }
- ],
- "name": "ZoTI_16_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb17538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "0f4ae22e-f717-47b1-893e-1d41684c8579",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb17538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 17"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.217"
- }
- ],
- "name": "ZoTI_17_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb18538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 18"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.218"
- }
- ],
- "name": "ZoTI_18_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
- "use": "mobile",
- "rank": 100
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb19538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "2"
- },
- "resourceType": "Location",
- "contained": [
- {
- "id": "72ab1d02-d3e2-4af1-891f-a476c23eaf44",
- "resourceType": "HealthcareService",
- "active": true,
- "coverageArea": [
- {
- "extension": [
- {
- "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
- "valueQuantity": {
- "value": 10000,
- "unit": "m"
- }
- }
- ]
- }
- ],
- "location": [
- {
- "reference": "/Location/6bb1 2023-08-31 12:18:11.626 28938-31101 OkHttp de.gematik.ti.erp.app.test D 9538-5924-4be3-98ff-7475d27aee4f"
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "498",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- }
- ],
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 19"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.219"
- }
- ],
- "name": "ZoTI_19_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "telecom": [
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
- "use": "mobile",
- "rank": 300
- },
- {
- "system": "other",
- "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
- "use": "mobile",
- "rank": 200
- }
- ],
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "PHARM",
- "display": "pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- },
- {
- "resource": {
- "id": "6bb20538-5924-4be3-98ff-7475d27aee4f",
- "meta": {
- "lastUpdated": "2023-08-07T10:48:51.845+02:00",
- "versionId": "3"
- },
- "resourceType": "Location",
- "address": {
- "type": "physical",
- "line": [
- "ZoTIstr. 20"
- ],
- "postalCode": "10117",
- "city": "ZoTI-Town",
- "country": "D"
- },
- "hoursOfOperation": [
- {
- "daysOfWeek": [
- "mon",
- "tue",
- "wed",
- "thu",
- "fri"
- ],
- "openingTime": "08:00:00",
- "closingTime": "18:00:00"
- }
- ],
- "identifier": [
- {
- "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
- "value": "3-01.2.2023001.16.220"
- }
- ],
- "name": "ZoTI_20_TEST-ONLY",
- "position": {
- "latitude": 13.387627883956709,
- "longitude": 52.5226398750957
- },
- "status": "active",
- "type": [
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/service-type",
- "code": "DELEGATOR",
- "display": "eRX Token Receiver"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "OUTPHARM",
- "display": "outpatient pharmacy"
- }
- ]
- },
- {
- "coding": [
- {
- "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
- "code": "MOBL",
- "display": "Mobile Services"
- }
- ]
- }
- ]
- },
- "search": {
- "mode": "match"
- }
- }
- ]
-}"""
- private val jsonMockedData = json.parseToJsonElement(jsonStringMocked)
- private val extractedPharmacies =
- extractPharmacyServices(
- bundle = jsonMockedData,
- onError = { jsonElement, cause ->
- Napier.e(cause) {
- jsonElement.toString()
- }
- }
- )
-}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/pharmacy/MockPharmacyRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/pharmacy/MockPharmacyRepository.kt
new file mode 100644
index 00000000..214eeb02
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/pharmacy/MockPharmacyRepository.kt
@@ -0,0 +1,1988 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.repository.pharmacy
+
+import de.gematik.ti.erp.app.fhir.model.PharmacyServices
+import de.gematik.ti.erp.app.fhir.model.extractPharmacyServices
+import de.gematik.ti.erp.app.fhir.model.json
+import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
+import de.gematik.ti.erp.app.pharmacy.repository.PharmacyRepository
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.FavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.OftenUsedPharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
+import de.gematik.ti.erp.app.redeem.repository.datasource.RedeemLocalDataSource
+import io.github.aakira.napier.Napier
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+@Suppress("LargeClass")
+class MockPharmacyRepository(
+ private val favouriteLocalDataSource: FavouritePharmacyLocalDataSource,
+ private val oftenUsedLocalDataSource: OftenUsedPharmacyLocalDataSource,
+ private val redeemLocalDataSource: RedeemLocalDataSource
+) : PharmacyRepository {
+
+ override suspend fun searchPharmacies(names: List, filter: Map): Result {
+ return Result.success(extractedPharmacies)
+ }
+
+ override suspend fun searchPharmaciesByBundle(bundleId: String, offset: Int, count: Int): Result {
+ return Result.success(extractedPharmacies)
+ }
+
+ override suspend fun searchBinaryCerts(locationId: String): Result> {
+ return Result.success(emptyList())
+ }
+
+ override suspend fun redeemPrescriptionDirectly(
+ url: String,
+ message: ByteArray,
+ pharmacyTelematikId: String,
+ transactionId: String
+ ): Result {
+ return Result.success(Unit)
+ }
+
+ override fun loadOftenUsedPharmacies(): Flow> = oftenUsedLocalDataSource.loadOftenUsedPharmacies()
+
+ override fun loadFavoritePharmacies(): Flow> = favouriteLocalDataSource.loadFavoritePharmacies()
+
+ override suspend fun markPharmacyAsOftenUsed(pharmacy: PharmacyUseCaseData.Pharmacy) = oftenUsedLocalDataSource.markPharmacyAsOftenUsed(pharmacy)
+
+ override suspend fun deleteOverviewPharmacy(overviewPharmacy: OverviewPharmacyData.OverviewPharmacy) =
+ oftenUsedLocalDataSource.deleteOverviewPharmacy(overviewPharmacy)
+
+ override suspend fun markPharmacyAsFavourite(pharmacy: PharmacyUseCaseData.Pharmacy) = favouriteLocalDataSource.markPharmacyAsFavourite(pharmacy)
+
+ override suspend fun deleteFavoritePharmacy(favoritePharmacy: PharmacyUseCaseData.Pharmacy) =
+ favouriteLocalDataSource.deleteFavoritePharmacy(favoritePharmacy)
+
+ override suspend fun searchPharmacyByTelematikId(telematikId: String): Result {
+ return Result.success(extractedPharmacies)
+ }
+
+ override fun isPharmacyInFavorites(pharmacy: PharmacyUseCaseData.Pharmacy): Flow {
+ return flowOf(true)
+ }
+
+ override suspend fun markAsRedeemed(taskId: String) = redeemLocalDataSource.markAsRedeemed(taskId)
+
+ private val jsonStringMocked = """{
+ "id": "49b6b9fd-eec7-41f3-b624-cc99d46fb828",
+ "meta": {
+ "lastUpdated": "2023-08-31T12:18:10.94674676+02:00"
+ },
+ "resourceType": "Bundle",
+ "type": "searchset",
+ "total": 20,
+ "link": [
+ {
+ "relation": "self",
+ "url": "Bundle49b6b9fd-eec7-41f3-b624-cc99d46fb828"
+ }
+ ],
+ "entry": [
+ {
+ "resource": {
+ "id": "6bb01538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 01"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.201"
+ }
+ ],
+ "name": "ZoTI_01_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb02538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 02"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.202"
+ }
+ ],
+ "name": "ZoTI_02_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb03538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 03"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.203"
+ }
+ ],
+ "name": "ZoTI_03_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb04538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 04"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.204"
+ }
+ ],
+ "name": "ZoTI_04_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 300
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb05538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 05"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.205"
+ }
+ ],
+ "name": "ZoTI_05_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb06538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "2d1f1f35-d03d-4932-a78a-67715cbb7963",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb06538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 06"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.206"
+ }
+ ],
+ "name": "ZoTI_06_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb07538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 07"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.207"
+ }
+ ],
+ "name": "ZoTI_07_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb08538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 08"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.208"
+ }
+ ],
+ "name": "ZoTI_08_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb09538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 09"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.209"
+ }
+ ],
+ "name": "ZoTI_09_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb10538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "fe9a01e8-d702-4b9d-a997-096eca057b74",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb10538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 10"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.210"
+ }
+ ],
+ "name": "ZoTI_10_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb11538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "0991992b-b3fd-4f3e-a331-d4f0e2856185",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb11538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 11"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.211"
+ }
+ ],
+ "name": "ZoTI_11_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb12538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "ae48f60e-9c17-4610-a0c4-d1f7ac6abb5b",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb12538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 12"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.212"
+ }
+ ],
+ "name": "ZoTI_12_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb13538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "e63f85da-3c1a-4f16-8059-45321bec107f",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb13538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 13"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.213"
+ }
+ ],
+ "name": "ZoTI_13_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb14538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "bb022669-f8fc-424a-8bfa-e9b5e8102333",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb14538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 14"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.214"
+ }
+ ],
+ "name": "ZoTI_14_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb15538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 15"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.215"
+ }
+ ],
+ "name": "ZoTI_15_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb16538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 16"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.216"
+ }
+ ],
+ "name": "ZoTI_16_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb17538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "0f4ae22e-f717-47b1-893e-1d41684c8579",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb17538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 17"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.217"
+ }
+ ],
+ "name": "ZoTI_17_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb18538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 18"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.218"
+ }
+ ],
+ "name": "ZoTI_18_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/pick_up/",
+ "use": "mobile",
+ "rank": 100
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb19538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "2"
+ },
+ "resourceType": "Location",
+ "contained": [
+ {
+ "id": "72ab1d02-d3e2-4af1-891f-a476c23eaf44",
+ "resourceType": "HealthcareService",
+ "active": true,
+ "coverageArea": [
+ {
+ "extension": [
+ {
+ "url": "https://ngda.de/fhir/extensions/ServiceCoverageRange",
+ "valueQuantity": {
+ "value": 10000,
+ "unit": "m"
+ }
+ }
+ ]
+ }
+ ],
+ "location": [
+ {
+ "reference": "/Location/6bb1 2023-08-31 12:18:11.626 28938-31101 OkHttp de.gematik.ti.erp.app.test D 9538-5924-4be3-98ff-7475d27aee4f"
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "498",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 19"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.219"
+ }
+ ],
+ "name": "ZoTI_19_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "telecom": [
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/delivery_only",
+ "use": "mobile",
+ "rank": 300
+ },
+ {
+ "system": "other",
+ "value": "https://erp-pharmacy-serviceprovider.dev.gematik.solutions/local_delivery/?req=",
+ "use": "mobile",
+ "rank": 200
+ }
+ ],
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "PHARM",
+ "display": "pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ },
+ {
+ "resource": {
+ "id": "6bb20538-5924-4be3-98ff-7475d27aee4f",
+ "meta": {
+ "lastUpdated": "2023-08-07T10:48:51.845+02:00",
+ "versionId": "3"
+ },
+ "resourceType": "Location",
+ "address": {
+ "type": "physical",
+ "line": [
+ "ZoTIstr. 20"
+ ],
+ "postalCode": "10117",
+ "city": "ZoTI-Town",
+ "country": "D"
+ },
+ "hoursOfOperation": [
+ {
+ "daysOfWeek": [
+ "mon",
+ "tue",
+ "wed",
+ "thu",
+ "fri"
+ ],
+ "openingTime": "08:00:00",
+ "closingTime": "18:00:00"
+ }
+ ],
+ "identifier": [
+ {
+ "system": "https://gematik.de/fhir/NamingSystem/TelematikID",
+ "value": "3-01.2.2023001.16.220"
+ }
+ ],
+ "name": "ZoTI_20_TEST-ONLY",
+ "position": {
+ "latitude": 13.387627883956709,
+ "longitude": 52.5226398750957
+ },
+ "status": "active",
+ "type": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/service-type",
+ "code": "DELEGATOR",
+ "display": "eRX Token Receiver"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "OUTPHARM",
+ "display": "outpatient pharmacy"
+ }
+ ]
+ },
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
+ "code": "MOBL",
+ "display": "Mobile Services"
+ }
+ ]
+ }
+ ]
+ },
+ "search": {
+ "mode": "match"
+ }
+ }
+ ]
+}"""
+ private val jsonMockedData = json.parseToJsonElement(jsonStringMocked)
+ private val extractedPharmacies =
+ extractPharmacyServices(
+ bundle = jsonMockedData,
+ onError = { jsonElement, cause ->
+ Napier.e(cause) {
+ jsonElement.toString()
+ }
+ }
+ )
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockPrescriptionsRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockPrescriptionsRepository.kt
new file mode 100644
index 00000000..45188f87
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockPrescriptionsRepository.kt
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.repository.prescription
+
+import de.gematik.ti.erp.app.datasource.INDEX_OUT_OF_BOUNDS
+import de.gematik.ti.erp.app.datasource.MockDataSource
+import de.gematik.ti.erp.app.model.MockSentCommunicationJson
+import de.gematik.ti.erp.app.model.toMockProfileLinkedCommunication
+import de.gematik.ti.erp.app.prescription.model.ScannedTaskData.ScannedTask
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.SyncedTask
+import de.gematik.ti.erp.app.prescription.repository.PrescriptionRepository
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Instant
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.JsonPrimitive
+import kotlinx.serialization.json.decodeFromJsonElement
+
+class MockPrescriptionsRepository(
+ private val dataSource: MockDataSource,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : PrescriptionRepository {
+ override suspend fun saveScannedTasks(
+ profileId: ProfileIdentifier,
+ tasks: List,
+ medicationString: String
+ ) {
+ withContext(dispatcher) {
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
+ val scannedList = it.toMutableList()
+ scannedList.addAll(tasks)
+ scannedList
+ }
+ }
+ }
+
+ override fun scannedTasks(profileId: ProfileIdentifier): Flow> = dataSource.scannedTasks
+ .map { list -> list.filter { it.profileId == profileId } }
+
+ override fun syncedTasks(profileId: ProfileIdentifier): Flow> =
+ dataSource.syncedTasks.mapNotNull { taskList ->
+ taskList.filter { it.profileId == profileId }.sortedBy { it.lastModified }
+ }.flowOn(dispatcher)
+
+ override suspend fun redeemPrescription(
+ profileId: ProfileIdentifier,
+ communication: JsonElement,
+ accessCode: String
+ ): Result =
+ withContext(dispatcher) {
+ val decodedCommunication = Json
+ .decodeFromJsonElement(communication)
+ .toMockProfileLinkedCommunication(profileId)
+ dataSource.communications.value = dataSource.communications.updateAndGet { communications ->
+ communications.add(decodedCommunication)
+ communications
+ }
+ Result.success(JsonPrimitive("success"))
+ }
+
+ override suspend fun deleteRemoteTaskById(
+ profileId: ProfileIdentifier,
+ taskId: String
+ ): Result =
+ withContext(dispatcher) {
+ dataSource.syncedTasks.value = dataSource.syncedTasks.updateAndGet { syncedList ->
+ syncedList.removeIf { it.taskId == taskId && it.profileId == profileId }
+ syncedList
+ }
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
+ val scannedList = it.toMutableList()
+ scannedList
+ .removeIf { scannedItem -> scannedItem.taskId == taskId && scannedItem.profileId == profileId }
+ scannedList
+ }
+ Result.success(null)
+ }
+
+ // used only for scanned
+ override suspend fun updateRedeemedOn(taskId: String, timestamp: Instant?) {
+ withContext(dispatcher) {
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
+ val scannedList = it.toMutableList()
+ val index = scannedList.indexOfFirst { item -> item.taskId == taskId }
+ if (index != INDEX_OUT_OF_BOUNDS) {
+ scannedList[index] = scannedList[index].copy(redeemedOn = timestamp)
+ }
+ scannedList
+ }
+ }
+ }
+
+ override suspend fun updateScannedTaskName(taskId: String, name: String) {
+ withContext(dispatcher) {
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
+ val scannedList = it.toMutableList()
+ val index = scannedList.indexOfFirst { item -> item.taskId == taskId }
+ if (index != INDEX_OUT_OF_BOUNDS) {
+ scannedList[index] = scannedList[index].copy(name = name)
+ }
+ scannedList
+ }
+ }
+ }
+
+ override fun loadSyncedTaskByTaskId(taskId: String) =
+ dataSource.syncedTasks.mapNotNull { list ->
+ list.find { it.taskId == taskId }
+ }.flowOn(dispatcher)
+
+ override fun loadScannedTaskByTaskId(taskId: String) =
+ dataSource.scannedTasks.mapNotNull { list ->
+ list.find { it.taskId == taskId }
+ }.flowOn(dispatcher)
+
+ override fun loadTaskIds() =
+ combine(
+ dataSource.scannedTasks,
+ dataSource.syncedTasks
+ ) { scannedTasks, syncedTasks ->
+ scannedTasks.map { it.taskId }.plus(
+ syncedTasks.map { it.taskId }
+ )
+ }.flowOn(dispatcher)
+
+ override suspend fun deleteLocalTaskById(taskId: String) {
+ // do nothing
+ }
+
+ override suspend fun wasProfileEverAuthenticated(profileId: ProfileIdentifier): Boolean {
+ return true
+ }
+
+ override suspend fun redeemScannedTasks(taskIds: List) {
+ // do nothing
+ }
+
+ override fun loadAllTaskIds(profileId: ProfileIdentifier): Flow> {
+ return flowOf(emptyList())
+ }
+
+ override suspend fun deleteLocalInvoicesById(taskId: String) {
+ // do nothing
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockTaskRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockTaskRepository.kt
new file mode 100644
index 00000000..c2c78cea
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/prescription/MockTaskRepository.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+@file:Suppress("MagicNumber")
+
+package de.gematik.ti.erp.app.repository.prescription
+
+import de.gematik.ti.erp.app.api.ResourcePaging
+import de.gematik.ti.erp.app.prescription.repository.TaskRepository
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Instant
+
+class MockTaskRepository(
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : TaskRepository {
+ override suspend fun downloadTasks(profileId: ProfileIdentifier): Result =
+ withContext(dispatcher) {
+ Result.success(0)
+ }
+
+ override suspend fun downloadResource(
+ profileId: ProfileIdentifier,
+ timestamp: String?,
+ count: Int?
+ ): Result> = Result.success(ResourcePaging.ResourceResult(0, 0))
+
+ override suspend fun syncedUpTo(profileId: ProfileIdentifier): Instant? = null
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/profiles/MockProfilesRepository.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/profiles/MockProfilesRepository.kt
new file mode 100644
index 00000000..c60248a7
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/repository/profiles/MockProfilesRepository.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.repository.profiles
+
+import de.gematik.ti.erp.app.datasource.INDEX_OUT_OF_BOUNDS
+import de.gematik.ti.erp.app.datasource.MockDataSource
+import de.gematik.ti.erp.app.datasource.data.MockProfileInfo.create
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
+import de.gematik.ti.erp.app.repository.profiles.MockProfilesRepository.ImageActions.Add
+import de.gematik.ti.erp.app.repository.profiles.MockProfilesRepository.ImageActions.NoAction
+import de.gematik.ti.erp.app.repository.profiles.MockProfilesRepository.ImageActions.Remove
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Instant
+
+class MockProfilesRepository(
+ private val dataSource: MockDataSource,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : ProfileRepository {
+
+ private fun mockProfiles(): MutableStateFlow> = dataSource.profiles
+ override fun profiles(): Flow> = mockProfiles()
+
+ override fun activeProfile() = mockProfiles().mapNotNull {
+ it.find { profile -> profile.active }
+ }
+
+ override suspend fun saveProfile(profileName: String, activate: Boolean) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profileList ->
+ val profiles = profileList.deactivateAllProfiles()
+ profiles.add(profileName.create())
+ profiles
+ }
+ }
+ }
+
+ override suspend fun createNewProfile(profileName: String) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profileList ->
+ val profiles = profileList.deactivateAllProfiles()
+ profiles.add(profileName.create())
+ profiles
+ }
+ }
+ }
+
+ override suspend fun activateProfile(profileId: ProfileIdentifier) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profileList ->
+ val profiles = profileList.deactivateAllProfiles()
+ val updatedProfiles = profiles.replace(profileId = profileId, activate = true)
+ updatedProfiles
+ }
+ }
+ }
+
+ override suspend fun removeProfile(profileId: ProfileIdentifier) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profiles ->
+ profiles.removeIf { profile -> profile.id == profileId }
+ profiles
+ }
+ }
+ }
+
+ override suspend fun saveInsuranceInformation(
+ profileId: ProfileIdentifier,
+ insurantName: String,
+ insuranceIdentifier: String,
+ insuranceName: String
+ ) {
+ // Not implemented
+ }
+
+ override suspend fun updateProfileName(profileId: ProfileIdentifier, profileName: String) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet {
+ it.replace(profileId = profileId, name = profileName)
+ }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun updateProfileColor(profileId: ProfileIdentifier, color: ProfilesData.ProfileColorNames) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profileList ->
+ val updatedList = profileList.replace(profileId = profileId, color = color)
+ updatedList
+ }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun updateLastAuthenticated(profileId: ProfileIdentifier, lastAuthenticated: Instant) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { it.replace(profileId = profileId, lastAuthenticated = lastAuthenticated) }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun saveAvatarFigure(profileId: ProfileIdentifier, avatar: ProfilesData.Avatar) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { it.replace(profileId = profileId, avatar = avatar) }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun savePersonalizedProfileImage(profileId: ProfileIdentifier, profileImage: ByteArray) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { it.replace(profileId = profileId, profileImage = profileImage, imageAction = Add) }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun clearPersonalizedProfileImage(profileId: ProfileIdentifier) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { it.replace(profileId = profileId, profileImage = null, imageAction = Remove) }
+ .updateUUIDForChangeVisibility()
+ }
+ }
+
+ override suspend fun switchProfileToPKV(profileId: ProfileIdentifier): Boolean {
+ // Not implemented for mocks
+ return false
+ }
+
+ override suspend fun switchProfileToGKV(profileId: ProfileIdentifier): Boolean {
+ return true
+ }
+
+ override suspend fun checkIsProfilePKV(profileId: ProfileIdentifier): Boolean = false
+
+ override fun getProfileById(profileId: ProfileIdentifier): Flow = mockProfiles()
+ .mapNotNull {
+ it.find { profile -> profile.id == profileId }
+ }
+
+ override suspend fun isSsoTokenValid(profileId: ProfileIdentifier): Flow {
+ return flowOf(true)
+ }
+
+ private fun MutableList.index(profileId: ProfileIdentifier) =
+ indexOfFirst { profile -> profile.id == profileId }
+ .takeIf { it != INDEX_OUT_OF_BOUNDS }
+
+ private fun MutableList.replace(
+ profileId: ProfileIdentifier,
+ activate: Boolean? = null,
+ name: String? = null,
+ color: ProfilesData.ProfileColorNames? = null,
+ lastAuthenticated: Instant? = null,
+ avatar: ProfilesData.Avatar? = null,
+ profileImage: ByteArray? = null,
+ imageAction: ImageActions = NoAction
+ ): MutableList =
+ index(profileId)?.let { index ->
+ val existingProfile = this[index]
+ this[index] = this[index].copy(
+ active = activate ?: existingProfile.active,
+ name = name ?: existingProfile.name,
+ color = color ?: existingProfile.color,
+ lastAuthenticated = lastAuthenticated,
+ avatar = avatar ?: existingProfile.avatar,
+ image = when (imageAction) {
+ Add -> profileImage
+ Remove -> null
+ NoAction -> existingProfile.image
+ }
+ )
+ this
+ } ?: this
+
+ private fun List.deactivateAllProfiles() =
+ mapNotNull {
+ it.copy(active = false)
+ }.toMutableList()
+
+ private fun MutableList.updateUUIDForChangeVisibility() =
+ map { it.copy() }.toMutableList()
+
+ enum class ImageActions {
+ Add, Remove, NoAction
+ }
+}
diff --git a/app/android-mock/src/main/java/de/gematik/ti/erp/app/usecase/CreateProfileWhenMissingUseCase.kt b/app/android-mock/src/main/java/de/gematik/ti/erp/app/usecase/CreateProfileWhenMissingUseCase.kt
new file mode 100644
index 00000000..a884ce3e
--- /dev/null
+++ b/app/android-mock/src/main/java/de/gematik/ti/erp/app/usecase/CreateProfileWhenMissingUseCase.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.usecase
+
+import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
+import de.gematik.ti.erp.app.settings.model.SettingsData
+import de.gematik.ti.erp.app.settings.repository.SettingsRepository
+import kotlinx.coroutines.flow.first
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toInstant
+
+class CreateProfileWhenMissingUseCase(
+ private val profileRepository: ProfileRepository,
+ private val settingsRepository: SettingsRepository
+) {
+ suspend operator fun invoke() {
+ if (profileRepository.profiles().first().isEmpty()) {
+ settingsRepository.saveOnboardingData(
+ authentication = SettingsData.Authentication(
+ deviceSecurity = false,
+ password = SettingsData.Authentication.Password("password"),
+ failedAuthenticationAttempts = 0
+ ),
+ profileName = "Test",
+ now = fixedInstant()
+ )
+ }
+ }
+
+ @Suppress("MagicNumber")
+ private fun fixedInstant(): Instant {
+ // Define the date and time, October 03, 2023, 00:00:00
+ val year = 2023
+ val month = 10
+ val day = 3
+ val hour = 0 // Midnight
+ val minute = 0
+ val second = 0
+
+ // Create a LocalDateTime
+ val localDateTime = LocalDateTime(year, month, day, hour, minute, second)
+
+ // Convert LocalDateTime to Instant assuming UTC timezone
+ return localDateTime.toInstant(TimeZone.UTC)
+ }
+}
diff --git a/app/android-mock/src/main/res/resources.properties b/app/android-mock/src/main/res/resources.properties
new file mode 100644
index 00000000..fccdea81
--- /dev/null
+++ b/app/android-mock/src/main/res/resources.properties
@@ -0,0 +1 @@
+unqualifiedResLocale=de
\ No newline at end of file
diff --git a/app/android-mock/src/test/java/de/gematik/ti/erp/app/ExampleUnitTest.kt b/app/android-mock/src/test/java/de/gematik/ti/erp/app/ExampleUnitTest.kt
index 4fe4c56e..a1f1d304 100644
--- a/app/android-mock/src/test/java/de/gematik/ti/erp/app/ExampleUnitTest.kt
+++ b/app/android-mock/src/test/java/de/gematik/ti/erp/app/ExampleUnitTest.kt
@@ -1,9 +1,26 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
package de.gematik.ti.erp.app
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Example local unit test, which will execute on the development machine (host).
*
@@ -14,4 +31,4 @@ class ExampleUnitTest {
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
-}
\ No newline at end of file
+}
diff --git a/app/android/build.gradle.kts b/app/android/build.gradle.kts
index 226c0ca1..347ad37a 100644
--- a/app/android/build.gradle.kts
+++ b/app/android/build.gradle.kts
@@ -1,75 +1,35 @@
+@file:Suppress("VariableNaming", "PropertyName", "UnusedPrivateProperty")
-import de.gematik.ti.erp.AppDependenciesPlugin
-import de.gematik.ti.erp.Dependencies
-import de.gematik.ti.erp.inject
-import de.gematik.ti.erp.overriding
-import org.owasp.dependencycheck.reporting.ReportGenerator.Format
+import de.gematik.ti.erp.app.plugins.dependencies.overrides
+import de.gematik.ti.erp.app.plugins.names.AppDependencyNamesPlugin
import java.util.Properties
plugins {
- id("com.android.application")
- kotlin("android")
- id("org.jetbrains.compose")
- id("io.realm.kotlin")
- kotlin("plugin.serialization")
- id("org.owasp.dependencycheck")
- id("com.jaredsburrows.license")
- id("de.gematik.ti.erp.dependencies")
- id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
- id("de.gematik.ti.erp.technical-requirements")
+ id("base-android-application")
+ id("de.gematik.ti.erp.dependency-overrides")
+ id("de.gematik.ti.erp.names")
// Release app into play-store
id("com.github.triplet.play") version "3.8.6" apply true
}
-val VERSION_CODE: String by overriding()
-val VERSION_NAME: String by overriding()
-val TEST_INSTRUMENTATION_ORCHESTRATOR: String? by project
-
-afterEvaluate {
- val taskRegEx = """assemble(Google|Huawei)(PuExternalDebug|PuExternalRelease)""".toRegex()
- tasks.forEach { task ->
- taskRegEx.matchEntire(task.name)?.let {
- val (_, version, flavor) = it.groupValues
- task.dependsOn(tasks.getByName("license${version}${flavor}Report"))
- }
- }
-}
-
-licenseReport {
- generateCsvReport = false
- generateHtmlReport = false
- generateJsonReport = true
- copyJsonReportToAssets = true
-}
+// these two need to be in uppercase since it is declared that way in gradle.properties
+val VERSION_CODE: String by overrides()
+val VERSION_NAME: String by overrides()
+val gematik = AppDependencyNamesPlugin()
android {
- namespace = AppDependenciesPlugin.APP_NAME_SPACE
+ namespace = gematik.appNameSpace
defaultConfig {
- applicationId = AppDependenciesPlugin.APP_ID
+ applicationId = gematik.appId
versionCode = VERSION_CODE.toInt()
versionName = VERSION_NAME
- testApplicationId = "de.gematik.ti.erp.app.test.test"
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- }
- kotlinOptions {
- jvmTarget = Dependencies.Versions.JavaVersion.KOTLIN_OPTIONS_JVM_TARGET
- freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
- }
- dependencyCheck {
- analyzers.assemblyEnabled = false
- suppressionFile = "${project.rootDir}" + "/config/dependency-check/suppressions.xml"
- formats = listOf(Format.HTML, Format.XML)
- scanConfigurations = configurations.filter {
- it.name.startsWith("api") ||
- it.name.startsWith("implementation") ||
- it.name.startsWith("kapt")
- }.map {
- it.name
- }
- }
- androidResources {
- generateLocaleConfig = true
+ testApplicationId = gematik.moduleName("test.test")
+ testInstrumentationRunnerArguments["clearPackageData"] = "true"
+ testOptions.execution = "ANDROID_TEST_ORCHESTRATOR"
+ // Check if MAPS_API_KEY is defined, otherwise provide a default value
+ val mapsApiKey = project.findProperty("MAPS_API_KEY") ?: "DEFAULT_PLACEHOLDER_KEY"
+ manifestPlaceholders["MAPS_API_KEY"] = mapsApiKey
}
val rootPath = project.rootProject
val signingPropsFile = rootPath.file("signing.properties")
@@ -78,18 +38,20 @@ android {
val signingProps = Properties()
signingProps.load(signingPropsFile.inputStream())
signingConfigs {
- fun creatingRelease() = creating {
- val target = this.name // property name; e.g. googleRelease
- println("Create signing config for: $target")
- storeFile = signingProps["$target.storePath"]?.let {
- rootPath.file("erp-app-android/$it")
+ fun creatingRelease() =
+ creating {
+ val target = this.name // property name; e.g. googleRelease
+ println("Create signing config for: $target")
+ storeFile =
+ signingProps["$target.storePath"]?.let {
+ rootPath.file("erp-app-android/$it")
+ }
+ println("\tstore: ${signingProps["$target.storePath"]}")
+ keyAlias = signingProps["$target.keyAlias"] as? String
+ println("\tkeyAlias: ${signingProps["$target.keyAlias"]}")
+ storePassword = signingProps["$target.storePassword"] as? String
+ keyPassword = signingProps["$target.keyPassword"] as? String
}
- println("\tstore: ${signingProps["$target.storePath"]}")
- keyAlias = signingProps["$target.keyAlias"] as? String
- println("\tkeyAlias: ${signingProps["$target.keyAlias"]}")
- storePassword = signingProps["$target.storePassword"] as? String
- keyPassword = signingProps["$target.keyPassword"] as? String
- }
if (signingProps["googleRelease.storePath"] != null) {
val googleRelease by creatingRelease()
}
@@ -100,14 +62,13 @@ android {
} else {
println("No signing properties found!")
}
-
buildTypes {
val release by getting {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
+ "proguard-rules.pro",
)
if (signingPropsFile.canRead()) {
signingConfig = signingConfigs.getByName("googleRelease")
@@ -116,27 +77,32 @@ android {
}
val debug by getting {
applicationIdSuffix = ".test"
- resValue("string", "app_label", "E-Rezept Debug")
versionNameSuffix = "-debug"
- signingConfigs {
- getByName("debug") {
- storeFile = rootPath.file("keystore/debug.keystore")
- keyAlias = "androiddebugkey"
- storePassword = "android"
- keyPassword = "android"
+ resValue("string", "app_label", "E-Rezept Debug")
+ if(rootPath.file("keystore/debug.keystore").exists()) { // needed tp be able to build on github
+ signingConfigs {
+ getByName("debug") {
+ storeFile = rootPath.file("keystore/debug.keystore")
+ keyAlias = "androiddebugkey"
+ storePassword = "android"
+ keyPassword = "android"
+ }
}
}
}
- create("minifiedDebug") {
- initWith(debug)
+ create(gematik.minifiedDebug) {
applicationIdSuffix = ".minirelease"
+ isDebuggable = true
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
+ "proguard-rules.pro",
)
- resValue("string", "app_label", "E-Rezept MiniRelease")
+ if (signingPropsFile.canRead()) {
+ signingConfig = signingConfigs.getByName("googleRelease")
+ }
+ resValue("string", "app_label", "E-Rezept Mini")
}
}
flavorDimensions += listOf("version")
@@ -162,6 +128,7 @@ android {
applicationIdSuffix = ".konnektathon.ru"
versionNameSuffix = "-konnektathon-RU"
signingConfig = signingConfigs.findByName("googleRelease")
+ resValue("string", "app_label", "E-Rezept Konny")
}
}
if (flavor?.startsWith("konnektathonDevru") == true) {
@@ -170,137 +137,38 @@ android {
applicationIdSuffix = ".konnektathon.rudev"
versionNameSuffix = "-konnektathon-RUDEV"
signingConfig = signingConfigs.findByName("googleRelease")
+ resValue("string", "app_label", "E-Rezept Konny Dev")
}
}
}
- packagingOptions {
- resources {
- excludes += "META-INF/**"
- // for JNA and JNA-platform
- excludes += "META-INF/AL2.0"
- excludes += "META-INF/LGPL2.1"
- // for byte-buddy
- excludes += "META-INF/licenses/ASM"
- pickFirsts += "win32-x86-64/attach_hotspot_windows.dll"
- pickFirsts += "win32-x86/attach_hotspot_windows.dll"
- }
+ testOptions {
+ animationsDisabled = true
}
}
dependencies {
- implementation(project(":app:features"))
- implementation(project(":app:demo-mode"))
- androidTestImplementation(project(":app:shared-test"))
- implementation(project(":common"))
- testImplementation(project(":common"))
- testImplementation(kotlin("test"))
- implementation("com.tom-roush:pdfbox-android:2.0.27.0") {
- exclude(group = "org.bouncycastle")
- implementation(kotlin("stdlib"))
- implementation(kotlin("reflect"))
- }
+ implementation(project(gematik.feature))
+ implementation(project(gematik.demoMode))
+ implementation(project(gematik.uiComponents))
+ androidTestImplementation(project(gematik.testActions))
+ androidTestImplementation(project(gematik.testTags))
+ implementation(project(gematik.multiplatform))
+ testImplementation(project(gematik.multiplatform))
+ implementation(libs.play.app.update)
+ implementation(libs.tracing)
+ debugImplementation(libs.tracing)
- inject {
- dateTime {
- implementation(datetime)
- testCompileOnly(datetime)
- }
- android {
- coreLibraryDesugaring(desugaring)
- debugImplementation(processPhoenix)
- }
- androidX {
- implementation(appcompat)
- implementation(composeNavigation)
- implementation(security)
- implementation(lifecycleViewmodel)
- implementation(lifecycleProcess)
- implementation(lifecycleComposeRuntime)
- }
- dependencyInjection {
- compileOnly(kodeinCompose)
- androidTestImplementation(kodeinCompose)
- }
- logging {
- implementation(napier)
- }
- tracking {
- implementation(contentSquare)
- }
- compose {
- implementation(runtime)
- implementation(foundation)
- implementation(uiTooling)
- implementation(preview)
- }
- crypto {
- testImplementation(jose4j)
- testImplementation(bouncycastleBcprov)
- testImplementation(bouncycastleBcpkix)
- }
- database {
- testCompileOnly(realm)
- }
- network {
- implementation(retrofit)
- implementation(retrofit2KotlinXSerialization)
- implementation(okhttp3)
- implementation(okhttpLogging)
- // Work around vulnerable Okio version 3.1.0 (CVE-2023-3635).
- // Can be removed as soon as Retrofit releases a new version >2.9.0.
- implementation(okio)
+ androidTestImplementation(libs.kodeon.core)
+ androidTestImplementation(libs.kodeon.android)
+ androidTestImplementation(libs.primsys.client)
+}
- androidTestImplementation(okhttp3)
- }
- database {
- compileOnly(realm)
- testCompileOnly(realm)
- }
- playServices {
- implementation(appUpdate)
- }
- serialization {
- implementation(kotlinXJson)
- }
- androidXTest {
- testImplementation(archCore)
- androidTestImplementation(core)
- androidTestImplementation(rules)
- androidTestImplementation(junitExt)
- androidTestImplementation(runner)
- androidTestUtil(orchestrator)
- androidTestUtil(services)
- // androidTestImplementation(navigation)
- androidTestImplementation(espresso)
- androidTestImplementation(espressoIntents)
- }
- tracing {
- debugImplementation(tracing)
- implementation(tracing)
- }
- coroutinesTest {
- testImplementation(coroutinesTest)
- }
- composeTest {
- androidTestImplementation(ui)
- debugImplementation(uiManifest)
- androidTestImplementation(junit4)
- }
- networkTest {
- testImplementation(mockWebServer)
- }
- test {
- testImplementation(junit4)
- testImplementation(snakeyaml)
- testImplementation(json)
- testImplementation(mockkOld)
- androidTestImplementation(mockkAndroid)
- }
+// keep this here since it cannot be changed for mock app
+configurations.all {
+ resolutionStrategy {
+ force("io.netty:netty-codec-http2:4.1.100.Final")
+ force("com.google.protobuf:protobuf-java:4.28.2")
}
}
-secrets {
- defaultPropertiesFileName = if (project.rootProject.file("ci-overrides.properties").exists()
- ) "ci-overrides.properties" else "gradle.properties"
-}
diff --git a/app/android/proguard-rules.pro b/app/android/proguard-rules.pro
index d159bfe9..4680d16a 100644
--- a/app/android/proguard-rules.pro
+++ b/app/android/proguard-rules.pro
@@ -128,6 +128,9 @@
-keep,allowobfuscation,allowshrinking class okhttp3.RequestBody
-keep,allowobfuscation,allowshrinking class okhttp3.ResponseBody
+# app classes
+-keep class de.gematik.ti.erp.app.debugsettings.** { *; }
+
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
@@ -139,5 +142,9 @@
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
+# Keep all classes, methods, and fields in the com.appmattus.certificatetransparency package
+-keep class com.appmattus.certificatetransparency.** { *; }
+-keep class com.appmattus.certificatetransparency.**$* { *; }
+
-printconfiguration "~/tmp/full-r8-config.txt"
diff --git a/app/android/src/androidTest/AndroidManifest.xml b/app/android/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 4e10e648..00000000
--- a/app/android/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/TestConfig.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/TestConfig.kt
deleted file mode 100644
index 9b40c15b..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/TestConfig.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-@file:Suppress("ktlint:max-line-length")
-
-package de.gematik.ti.erp.app.test.test
-
-object TestConfig {
- const val WeakPassword = "TrustNo1"
- const val StrongPassword = "Jaja Ding Dong!"
- const val DefaultProfileName = "Rainer Reizdarm"
- const val DefaultEGKCAN = "123123"
- const val DefaultEGKPassword = "123456"
- const val WaitTimeout1Sec = 1_000L
- const val ScreenChangeTimeout = 3_000L
- const val LoadPrescriptionsTimeout = 20_000L
-
- const val AppDefaultVirtualEgkKvnr = "X764228532"
- const val PharmacyName = "Apotheke am Flughafen - E2E-Test"
- const val PharmacyTelematikId = "3-SMC-B-Testkarte-883110000116873"
-
- const val PharmacyZoti01 = "ZoTI_01_TEST-ONLY"
- const val PharmacyZoti02 = "ZoTI_02_TEST-ONLY"
- const val PharmacyZoti03 = "ZoTI_03_TEST-ONLY"
- const val PharmacyZoti04 = "ZoTI_04_TEST-ONLY"
- const val PharmacyZoti05 = "ZoTI_05_TEST-ONLY"
- const val PharmacyZoti06 = "ZoTI_06_TEST-ONLY"
- const val PharmacyZoti07 = "ZoTI_07_TEST-ONLY"
- const val PharmacyZoti08 = "ZoTI_08_TEST-ONLY"
- const val PharmacyZoti09 = "ZoTI_09_TEST-ONLY"
- const val PharmacyZoti10 = "ZoTI_10_TEST-ONLY"
- const val PharmacyZoti11 = "ZoTI_11_TEST-ONLY"
- const val PharmacyZoti12 = "ZoTI_12_TEST-ONLY"
- const val PharmacyZoti13 = "ZoTI_13_TEST-ONLY"
- const val PharmacyZoti14 = "ZoTI_14_TEST-ONLY"
- const val PharmacyZoti15 = "ZoTI_15_TEST-ONLY"
- const val PharmacyZoti16 = "ZoTI_16_TEST-ONLY"
- const val PharmacyZoti17 = "ZoTI_17_TEST-ONLY"
- const val PharmacyZoti18 = "ZoTI_18_TEST-ONLY"
- const val PharmacyZoti19 = "ZoTI_19_TEST-ONLY"
- const val PharmacyZoti20 = "ZoTI_20_TEST-ONLY"
-
- object FD {
- const val DefaultServer = "https://erpps-test.dev.gematik.solutions"
- const val DefaultDoctor = "9a15b6f9f4b8f2e9df1db745a4091bbd"
- const val DefaultPharmacy = "886c6eda7dd5a1c6b1d112907f544d3"
- }
-}
-
-interface VirtualEgk {
- val certificate: String
- val privateKey: String
- val kvnr: String
- val name: String
-}
-
-object VirtualEgk1 : VirtualEgk {
- @Suppress("MaxLineLength")
- override val certificate =
- "MIIDXTCCAwSgAwIBAgIHAs9vZEwB8jAKBggqhkjOPQQDAjCBljELMAkGA1UEBhMCREUxHzAdBgNVBAoMFmdlbWF0aWsgR21iSCBOT1QtVkFMSUQxRTBDBgNVBAsMPEVsZWt0cm9uaXNjaGUgR2VzdW5kaGVpdHNrYXJ0ZS1DQSBkZXIgVGVsZW1hdGlraW5mcmFzdHJ1a3R1cjEfMB0GA1UEAwwWR0VNLkVHSy1DQTEwIFRFU1QtT05MWTAeFw0yMjAxMjQwMDAwMDBaFw0yNzAxMjMyMzU5NTlaMIHgMQswCQYDVQQGEwJERTEpMCcGA1UECgwgZ2VtYXRpayBNdXN0ZXJrYXNzZTFHS1ZOT1QtVkFMSUQxEjAQBgNVBAsMCTk5OTU2Nzg5MDETMBEGA1UECwwKWDExMDU5Mjk3MTEUMBIGA1UEBAwLVsOzcm13aW5rZWwxHDAaBgNVBCoME1hlbmlhIFZlcmEgQWRlbGhlaWQxEjAQBgNVBAwMCVByb2YuIERyLjE1MDMGA1UEAwwsUHJvZi4gRHIuIFhlbmlhIFZlcmEgQS4gVsOzcm13aW5rZWxURVNULU9OTFkwWjAUBgcqhkjOPQIBBgkrJAMDAggBAQcDQgAEczsMfajcnKpGYyNeXUhODjyrX4z4j9Qzio/Ulq5COPVySk0CxYBDj+1VEd5FalhEJXC9HjVRCflQx+RkEQFbvqOB7zCB7DAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFESxTAFYVB7c2Te+5LI/Km6kXIkdMCAGA1UdIAQZMBcwCgYIKoIUAEwEgSMwCQYHKoIUAEwERjAwBgUrJAgDAwQnMCUwIzAhMB8wHTAQDA5WZXJzaWNoZXJ0ZS8tcjAJBgcqghQATAQxMB0GA1UdDgQWBBTCDfBZ8X30CZnFk7E2x8+lMM5uODA4BggrBgEFBQcBAQQsMCowKAYIKwYBBQUHMAGGHGh0dHA6Ly9laGNhLmdlbWF0aWsuZGUvb2NzcC8wDgYDVR0PAQH/BAQDAgeAMAoGCCqGSM49BAMCA0cAMEQCIDDAXcyOKDYOZpoH0iYijr1yisyxHeT3ch6XZlFNXPrKAiAHepW4TOQAoqyoGG9Pgly0TO2tTB7WLKEc7B3F6lNhpA=="
- override val privateKey = "AJzshqeIuhwReqZpWbqY0PnRjTdTRzk4Zj9GpSxcUukA"
- override val kvnr = "X110592971"
- override val name = "Vórmwinkel Xenia Vera Adelheid"
-}
-
-object VirtualEgkWithPrescription : VirtualEgk {
- @Suppress("MaxLineLength")
- override val certificate =
- "MIIDLTCCAtSgAwIBAgIHAZ/zfVKUfTAKBggqhkjOPQQDAjCBljELMAkGA1UEBhMCREUxHzAdBgNVBAoMFmdlbWF0aWsgR21iSCBOT1QtVkFMSUQxRTBDBgNVBAsMPEVsZWt0cm9uaXNjaGUgR2VzdW5kaGVpdHNrYXJ0ZS1DQSBkZXIgVGVsZW1hdGlraW5mcmFzdHJ1a3R1cjEfMB0GA1UEAwwWR0VNLkVHSy1DQTEwIFRFU1QtT05MWTAeFw0yMjAyMDQwMDAwMDBaFw0yNzAyMDMyMzU5NTlaMIGwMQswCQYDVQQGEwJERTEpMCcGA1UECgwgZ2VtYXRpayBNdXN0ZXJrYXNzZTFHS1ZOT1QtVkFMSUQxEjAQBgNVBAsMCTk5OTU2Nzg5MDETMBEGA1UECwwKWDExMDUzNTU0MTEOMAwGA1UEBAwFS2zDtm4xDTALBgNVBCoMBEx1Y2ExDDAKBgNVBAwMA0RyLjEgMB4GA1UEAwwXRHIuIEx1Y2EgS2zDtm5URVNULU9OTFkwWjAUBgcqhkjOPQIBBgkrJAMDAggBAQcDQgAETn/MKYxsnBH9khicaXG3mFc5v4RoL0ILuJ3TreTsiFsv91OA6Yj/O4EAxm6dCpPtGgWRyVUYbOgDkaDurSUPpqOB7zCB7DAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFESxTAFYVB7c2Te+5LI/Km6kXIkdMCAGA1UdIAQZMBcwCgYIKoIUAEwEgSMwCQYHKoIUAEwERjAwBgUrJAgDAwQnMCUwIzAhMB8wHTAQDA5WZXJzaWNoZXJ0ZS8tcjAJBgcqghQATAQxMB0GA1UdDgQWBBRhIkfxtBhE+Z3fcu+OWu/3gnnYqjA4BggrBgEFBQcBAQQsMCowKAYIKwYBBQUHMAGGHGh0dHA6Ly9laGNhLmdlbWF0aWsuZGUvb2NzcC8wDgYDVR0PAQH/BAQDAgeAMAoGCCqGSM49BAMCA0cAMEQCIGHDnSVg2A9NmFPhtzo4dL3CVbN94k3NrYhXLOZoCUFXAiBlE6TfW6uL91jhv8JuupHhr7X6B9YcbVizWoMxo1grFA=="
- override val privateKey = "cv2z1KGMJi+M5foz3GCz0bi5pSdBIjVTqw2cUuIsJcY="
- override val kvnr = "X110535541"
- override val name = "Klön Luca"
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/WithFontScale.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/WithFontScale.kt
deleted file mode 100644
index 2f5e22d9..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/WithFontScale.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test
-
-import de.gematik.ti.erp.app.test.test.core.execShellCmd
-import org.junit.After
-import org.junit.AfterClass
-import org.junit.Before
-import org.junit.BeforeClass
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-open class WithFontScale(protected val fontScale: String) {
- companion object {
- @JvmStatic
- @Parameterized.Parameters(name = "{index}: fontScale={0}")
- fun data(): Collection> {
- return listOf(
- arrayOf("1.0"),
- arrayOf("1.3")
- )
- }
-
- @JvmStatic
- @BeforeClass
- fun disableGestureNavbar() {
- execShellCmd("cmd overlay disable com.android.internal.systemui.navbar.gestural")
- }
-
- @JvmStatic
- @AfterClass
- fun enableGestureNavbar() {
- execShellCmd("cmd overlay enable com.android.internal.systemui.navbar.gestural")
- }
- }
-
- @Before
- fun changeScales() {
- execShellCmd("settings put system font_scale $fontScale")
- }
-
- @After
- fun resetScales() {
- execShellCmd("settings put system font_scale 1.0")
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/compose/EditableTextFieldTest.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/compose/EditableTextFieldTest.kt
deleted file mode 100644
index 1e1520a9..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/compose/EditableTextFieldTest.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.compose
-
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onNodeWithText
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextClearance
-import androidx.compose.ui.test.performTextReplacement
-import de.gematik.ti.erp.app.theme.AppTheme
-import de.gematik.ti.erp.app.utils.compose.EditableTextField
-import de.gematik.ti.erp.app.utils.compose.ErrorTextTag
-import io.github.aakira.napier.Napier
-import org.junit.Rule
-import org.junit.Test
-
-class EditableTextFieldTest {
-
- @get:Rule
- val composeTestRule = createComposeRule()
-
- @Test
- fun testEditableTextField() {
- val text = "some random text"
- val newText = "some new text"
-
- composeTestRule.setContent {
- AppTheme {
- EditableTextField(
- text = text,
- textMinLength = 20,
- onDoneClicked = {
- Napier.d { "text is $it" }
- }
- )
- }
- }
-
- // test existing text
- composeTestRule.onNodeWithText(text).assertIsDisplayed()
- composeTestRule.onNodeWithText(text).performClick()
- composeTestRule.onNodeWithText(text).assertHasClickAction()
-
- // test text change
- composeTestRule.onNodeWithText(text).performTextReplacement(newText)
- composeTestRule.onNodeWithText(newText).assertIsDisplayed()
-
- // test showing error text
- composeTestRule.onNodeWithText(newText).performTextClearance()
- composeTestRule.onNodeWithTag(ErrorTextTag).assertIsDisplayed()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/TaskCollection.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/TaskCollection.kt
deleted file mode 100644
index 1c9aca52..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/TaskCollection.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core
-
-import android.util.Log
-import de.gematik.ti.erp.app.TestWrapper
-import de.gematik.ti.erp.app.test.test.core.prescription.CommunicationPayloadInbox
-import de.gematik.ti.erp.app.test.test.core.prescription.Prescription
-import de.gematik.ti.erp.app.test.test.core.prescription.PrescriptionDoctorUseCase
-import de.gematik.ti.erp.app.test.test.core.prescription.PrescriptionPharmacyUseCase
-import de.gematik.ti.erp.app.test.test.core.prescription.Task
-import de.gematik.ti.erp.app.test.test.core.prescription.retry
-import org.junit.Assume
-import org.junit.AssumptionViolatedException
-
-private val doctorUseCase by lazy { PrescriptionDoctorUseCase() }
-private val pharmacyUseCase by lazy { PrescriptionPharmacyUseCase() }
-
-class TaskCollection(
- data: List,
- private val testWrapper: TestWrapper
-) {
- data class TaskAndPrescription(
- val task: Task,
- val prescription: Prescription,
- val isDispensed: Boolean = false
- )
-
- private val _taskData = mutableListOf()
- .apply {
- addAll(data)
- }
-
- val taskData: List
- get() = _taskData
-
- fun deleteAll() {
- // clean up - allowed to throw, so test won't fail
- taskData.forEach { (task, _, isDispensed) ->
- if (task.secret == null || isDispensed) {
- testWrapper.deleteTask(task.taskId)
- } else {
- runCatching {
- pharmacyUseCase
- .abortTask(taskId = task.taskId, accessCode = task.accessCode, secret = task.secret)
- }
- }
- .onFailure { Log.e("deleteTask", "Deleting task with id `${task.taskId}` failed", it) }
- .onSuccess { Log.d("deleteTask", "Task with id `${task.taskId}` deleted") }
- }
- }
-
- fun accept(data: TaskAndPrescription): Task {
- val taskWithSecret = pharmacyUseCase.acceptTask(taskId = data.task.taskId, accessCode = data.task.accessCode)
- requireNotNull(taskWithSecret.secret) { "Accepting a task must return secret!" }
-
- _taskData.replaceWith(data.copy(task = taskWithSecret))
-
- return taskWithSecret
- }
-
- fun reply(data: TaskAndPrescription, message: CommunicationPayloadInbox) {
- pharmacyUseCase.replyWithCommunication(
- taskId = data.task.taskId,
- kvNr = data.prescription.patient!!.kvnr!!,
- message = message
- )
- }
-
- fun dispense(data: TaskAndPrescription) {
- requireNotNull(data.task.secret) { "Task can be only dispensed with the `secret`" }
- pharmacyUseCase.dispenseMedication(
- taskId = data.task.taskId,
- accessCode = data.task.accessCode,
- secret = data.task.secret
- )
- _taskData.replaceWith(data.copy(isDispensed = true))
- }
-
- companion object {
- fun generate(count: Int, kvnr: String, testWrapper: TestWrapper): TaskCollection {
- require(count >= 1)
-
- val taskData = (1..count).mapNotNull {
- retry(3) { doctorUseCase.prescribeToPatient(kvnr) }
- }
- val prescriptions = taskData.mapNotNull { data ->
- retry(3) { doctorUseCase.prescriptionDetails(data.taskId) }
- }
-
- try {
- Assume.assumeTrue(
- "Prescription server couldn't create all tasks",
- taskData.size == prescriptions.size && taskData.size == count
- )
- } catch (e: AssumptionViolatedException) {
- taskData.forEach { data ->
- val taskId = data.taskId
- testWrapper.deleteTask(taskId)
- .onFailure { Log.e("deleteTask", "Deleting task with id `$taskId` failed", it) }
- .onSuccess { Log.d("deleteTask", "Task with id `$taskId` deleted") }
- }
- throw e
- }
-
- val data = taskData.zip(prescriptions) { tD: Task, p: Prescription ->
- TaskAndPrescription(
- task = tD,
- prescription = p
- )
- }
-
- Log.d("generate", "Prescriptions:\n${prescriptions.joinToString("\n\n") { it.toString() }}")
-
- return TaskCollection(
- data,
- testWrapper
- )
- }
- }
-}
-
-private fun MutableList.replaceWith(data: TaskCollection.TaskAndPrescription) {
- val ix = indexOfFirst { it.task.taskId == data.task.taskId }
- require(ix != -1)
- this[ix] = data
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/Util.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/Util.kt
deleted file mode 100644
index 630f2f6e..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/Util.kt
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core
-
-import androidx.compose.ui.semantics.SemanticsProperties
-import androidx.compose.ui.semantics.getOrNull
-import androidx.compose.ui.test.SemanticsMatcher
-import androidx.compose.ui.test.SemanticsNodeInteraction
-import androidx.compose.ui.test.SemanticsNodeInteractionCollection
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.filter
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onRoot
-import androidx.compose.ui.test.printToString
-import androidx.test.platform.app.InstrumentationRegistry
-import de.gematik.ti.erp.app.InsuranceState
-import de.gematik.ti.erp.app.MedicationCategory
-import de.gematik.ti.erp.app.PharmacyId
-import de.gematik.ti.erp.app.PrescriptionId
-import de.gematik.ti.erp.app.SubstitutionAllowed
-import de.gematik.ti.erp.app.SupplyForm
-
-fun ComposeTestRule.awaitDisplay(timeout: Long, vararg tags: String): String {
- val t0 = System.currentTimeMillis()
- do {
- tags.forEach { tag ->
- try {
- onNodeWithTag(tag).assertIsDisplayed()
- return tag
- } catch (_: AssertionError) {
- }
- }
- mainClock.advanceTimeBy(100)
- Thread.sleep(100)
- } while (System.currentTimeMillis() - t0 < timeout)
- throw AssertionError(
- "Node was not displayed after $timeout milliseconds. Root node was:\n${
- onRoot().printToString(Int.MAX_VALUE)
- }"
- )
-}
-
-fun ComposeTestRule.awaitDisplay(timeout: Long, node: () -> SemanticsNodeInteraction) {
- val t0 = System.currentTimeMillis()
- do {
- try {
- node().assertIsDisplayed()
- return
- } catch (_: AssertionError) {
- }
- mainClock.advanceTimeBy(100)
- Thread.sleep(100)
- } while (System.currentTimeMillis() - t0 < timeout)
- throw AssertionError(
- "Node was not displayed after $timeout milliseconds. Root node was:\n${
- onRoot().printToString(Int.MAX_VALUE)
- }"
- )
-}
-
-fun ComposeTestRule.await(timeout: Long, node: () -> Unit) {
- val t0 = System.currentTimeMillis()
- do {
- try {
- node()
- return
- } catch (_: AssertionError) {
- }
- mainClock.advanceTimeBy(100)
- Thread.sleep(100)
- } while (System.currentTimeMillis() - t0 < timeout)
- throw AssertionError(
- "Node was not displayed after $timeout milliseconds. Root node was:\n${
- onRoot().printToString(Int.MAX_VALUE)
- }"
- )
-}
-
-fun ComposeTestRule.sleep(timeout: Long) {
- val t0 = System.currentTimeMillis()
- do {
- mainClock.advanceTimeBy(100)
- Thread.sleep(100)
- } while (System.currentTimeMillis() - t0 < timeout)
-}
-
-fun SemanticsNodeInteraction.assertHasText(includeEditableText: Boolean = true) =
- assert(hasText(includeEditableText))
-
-fun hasText(
- includeEditableText: Boolean = true
-): SemanticsMatcher {
- val propertyName = if (includeEditableText) {
- "${SemanticsProperties.Text.name} + ${SemanticsProperties.EditableText.name}"
- } else {
- SemanticsProperties.Text.name
- }
- return SemanticsMatcher(
- propertyName
- ) { node ->
- val actual = mutableListOf()
- if (includeEditableText) {
- node.config.getOrNull(SemanticsProperties.EditableText)
- ?.let { actual.add(it.text) }
- }
- node.config.getOrNull(SemanticsProperties.Text)
- ?.let { actual.addAll(it.map { anStr -> anStr.text }) }
- actual.all { it.isNotBlank() }
- }
-}
-
-fun SemanticsNodeInteractionCollection.assertNone(
- matcher: SemanticsMatcher
-): SemanticsNodeInteractionCollection =
- filter(matcher)
- .assertCountEquals(0)
-
-fun hasPrescriptionId(id: String): SemanticsMatcher =
- SemanticsMatcher.expectValue(PrescriptionId, id)
-
-fun hasPharmacyId(id: String): SemanticsMatcher =
- SemanticsMatcher.expectValue(PharmacyId, id)
-
-fun hasInsuranceState(state: String?): SemanticsMatcher =
- SemanticsMatcher.expectValue(InsuranceState, state)
-
-fun hasSubstitutionAllowed(allowed: Boolean): SemanticsMatcher =
- SemanticsMatcher.expectValue(SubstitutionAllowed, allowed)
-
-fun hasSupplyForm(form: String): SemanticsMatcher =
- SemanticsMatcher.expectValue(SupplyForm, form)
-
-fun hasMedicationCategory(form: String): SemanticsMatcher =
- SemanticsMatcher.expectValue(MedicationCategory, form)
-
-fun execShellCmd(cmd: String) {
- InstrumentationRegistry.getInstrumentation().uiAutomation
- .executeShellCommand(cmd)
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/CommunicationPayload.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/CommunicationPayload.kt
deleted file mode 100644
index 5dacac56..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/CommunicationPayload.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-enum class SupplyOptionsType {
- @SerialName("shipment")
- Shipment,
-
- @SerialName("onPremise")
- OnPremise,
-
- @SerialName("delivery")
- Delivery
-}
-
-@Serializable
-data class CommunicationPayloadInbox(
- val version: String = "1",
- val supplyOptionsType: SupplyOptionsType,
- @SerialName("info_text") val infoText: String? = null,
- val url: String? = null,
- val pickUpCodeHR: String? = null,
- val pickUpCodeDMC: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Coverage.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Coverage.kt
deleted file mode 100644
index 4bbf6ac2..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Coverage.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Coverage(
- @SerialName("iknr")
- val iknr: String? = null,
- @SerialName("insuranceKind")
- val insuranceKind: String? = null,
- @SerialName("insuranceName")
- val insuranceName: String? = null,
- @SerialName("insuranceState")
- val insuranceState: String? = null,
- @SerialName("payorType")
- val payorType: String? = null,
- @SerialName("personGroup")
- val personGroup: String? = null,
- @SerialName("wop")
- val wop: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Medication.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Medication.kt
deleted file mode 100644
index 66090324..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Medication.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Medication(
- @SerialName("amount")
- val amount: Int? = null,
- @SerialName("category")
- val category: String? = null,
- @SerialName("dosage")
- val dosage: String? = null,
- @SerialName("freeText")
- val freeText: String? = null,
- @SerialName("ingredient")
- val ingredient: String? = null,
- @SerialName("ingredientStrength")
- val ingredientStrength: String? = null,
- @SerialName("name")
- val name: String? = null,
- @SerialName("packageQuantity")
- val packageQuantity: Int? = null,
- @SerialName("pzn")
- val pzn: String? = null,
- @SerialName("standardSize")
- val standardSize: String? = null,
- @SerialName("substitutionAllowed")
- val substitutionAllowed: Boolean? = null,
- @SerialName("supplyForm")
- val supplyForm: String? = null,
- @SerialName("type")
- val type: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Patient.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Patient.kt
deleted file mode 100644
index 554cd04f..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Patient.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Patient(
- @SerialName("birthDate")
- val birthDate: String? = null,
- @SerialName("city")
- val city: String? = null,
- @SerialName("firstName")
- val firstName: String? = null,
- @SerialName("kvnr")
- val kvnr: String? = null,
- @SerialName("lastName")
- val lastName: String? = null,
- @SerialName("postal")
- val postal: String? = null,
- @SerialName("street")
- val street: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Practitioner.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Practitioner.kt
deleted file mode 100644
index 37fdd884..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Practitioner.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Practitioner(
- @SerialName("bsnr")
- val bsnr: String? = null,
- @SerialName("city")
- val city: String? = null,
- @SerialName("email")
- val email: String? = null,
- @SerialName("hba")
- val hba: String? = null,
- @SerialName("id")
- val id: String? = null,
- @SerialName("lanr")
- val lanr: String? = null,
- @SerialName("name")
- val name: String? = null,
- @SerialName("officeName")
- val officeName: String? = null,
- @SerialName("phone")
- val phone: String? = null,
- @SerialName("postal")
- val postal: String? = null,
- @SerialName("smcb")
- val smcb: String? = null,
- @SerialName("street")
- val street: String? = null,
- @SerialName("ti")
- val telematik: Telematik? = null,
- @SerialName("type")
- val type: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Prescription.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Prescription.kt
deleted file mode 100644
index 3235cbaf..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Prescription.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Prescription(
- @SerialName("accessCode")
- val accessCode: String? = null,
- @SerialName("authoredOn")
- val authoredOn: Long? = null,
- @SerialName("authoredOnFormatted")
- val authoredOnFormatted: String? = null,
- @SerialName("coverage")
- val coverage: Coverage? = null,
- @SerialName("medication")
- val medication: Medication? = null,
- @SerialName("patient")
- val patient: Patient? = null,
- @SerialName("practitioner")
- val practitioner: Practitioner? = null,
- @SerialName("prescriptionId")
- val prescriptionId: String? = null,
- @SerialName("taskId")
- val taskId: String = ""
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionDoctorUseCase.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionDoctorUseCase.kt
deleted file mode 100644
index 96f81d6a..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionDoctorUseCase.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import android.util.Log
-import de.gematik.ti.erp.app.test.test.TestConfig
-import kotlinx.serialization.json.Json
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-
-private fun defaultPayload(kvnr: String) = """
-{
- "patient": {
- "kvnr": "$kvnr"
- },
- "medication": {
- "category": "00"
- }
-}
-"""
-
-class PrescriptionDoctorUseCase {
- private val okHttp by lazy { OkHttpClient.Builder().build() }
-
- private val json = Json {
- encodeDefaults = false
- ignoreUnknownKeys = true
- }
-
- fun prescribeToPatient(kvNr: String): Task {
- val payload = defaultPayload(kvNr)
-
- val response = okHttp.newCall(
- Request.Builder()
- .url("${TestConfig.FD.DefaultServer}/doc/${TestConfig.FD.DefaultDoctor}/prescribe")
- .post(payload.toRequestBody("application/json".toMediaType()))
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
-
- val body = requireNotNull(response.body).string()
- Log.d("prescribeToPatient", body)
-
- return json.decodeFromString(body)
- }
-
- fun prescriptionDetails(taskId: String): Prescription {
- val response = okHttp.newCall(
- Request.Builder()
- .url("${TestConfig.FD.DefaultServer}/prescription/$taskId")
- .get()
- .build()
- ).execute()
-
- require(response.isSuccessful)
-
- val body = requireNotNull(response.body).string()
- Log.d("prescriptionDetails", body)
-
- return json.decodeFromString(body)
- }
-}
-
-fun retry(n: Int, block: () -> T): T? {
- var retriesLeft = n
- while (retriesLeft > 0) {
- try {
- return block()
- } catch (e: Exception) {
- Log.e("retry", "Reason: ", e)
- retriesLeft--
- }
- }
- return null
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionPharmacyUseCase.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionPharmacyUseCase.kt
deleted file mode 100644
index 5a4ef7c5..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionPharmacyUseCase.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import android.util.Log
-import de.gematik.ti.erp.app.test.test.TestConfig
-import kotlinx.serialization.decodeFromString
-import kotlinx.serialization.encodeToString
-import kotlinx.serialization.json.Json
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-
-class PrescriptionPharmacyUseCase {
- private val okHttp by lazy { OkHttpClient.Builder().build() }
-
- private val json = Json {
- encodeDefaults = false
- ignoreUnknownKeys = true
- }
- fun rejectTask(taskId: String, accessCode: String, secret: String) {
- val response = okHttp.newCall(
- @Suppress("ktlint:max-line-length", "MaxLineLength")
- Request.Builder()
- .url(
- "${TestConfig.FD.DefaultServer}/pharm/${TestConfig.FD.DefaultPharmacy}/reject/?taskId=$taskId&ac=$accessCode&secret=$secret"
- )
- .post("".toRequestBody())
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
- }
-
- fun acceptTask(taskId: String, accessCode: String): Task {
- val response = okHttp.newCall(
- @Suppress("ktlint:max-line-length", "MaxLineLength")
- Request.Builder()
- .url(
- "${TestConfig.FD.DefaultServer}/pharm/${TestConfig.FD.DefaultPharmacy}/accept/?taskId=$taskId&ac=$accessCode"
- )
- .post("".toRequestBody())
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
-
- val body = requireNotNull(response.body).string()
- Log.d("acceptTask", body)
-
- return json.decodeFromString(body)
- }
-
- fun abortTask(taskId: String, accessCode: String, secret: String) {
- val response = okHttp.newCall(
- @Suppress("ktlint:max-line-length", "MaxLineLength")
- Request.Builder()
- .url(
- "${TestConfig.FD.DefaultServer}/pharm/${TestConfig.FD.DefaultPharmacy}/abort/?taskId=$taskId&ac=$accessCode&secret=$secret"
- )
- .delete()
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
- }
-
- fun replyWithCommunication(taskId: String, kvNr: String, message: CommunicationPayloadInbox) {
- val supplyOption = when (message.supplyOptionsType) {
- SupplyOptionsType.Shipment -> "shipment"
- SupplyOptionsType.OnPremise -> "onPremise"
- SupplyOptionsType.Delivery -> "delivery"
- }
-
- val response = okHttp.newCall(
- @Suppress("ktlint:max-line-length", "MaxLineLength")
- Request.Builder()
- .url(
- "${TestConfig.FD.DefaultServer}/pharm/${TestConfig.FD.DefaultPharmacy}/reply/?taskId=$taskId&kvnr=$kvNr&supplyOption=$supplyOption"
- )
- .post(json.encodeToString(message).toRequestBody())
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
- }
-
- fun dispenseMedication(taskId: String, accessCode: String, secret: String) {
- val response = okHttp.newCall(
- @Suppress("ktlint:max-line-length", "MaxLineLength")
- Request.Builder()
- .url(
- "${TestConfig.FD.DefaultServer}/pharm/${TestConfig.FD.DefaultPharmacy}/close/?taskId=$taskId&ac=$accessCode&secret=$secret"
- )
- .delete()
- .build()
- ).execute()
-
- require(response.isSuccessful) { "Response was: $response" }
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionUtils.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionUtils.kt
deleted file mode 100644
index ecea4731..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/PrescriptionUtils.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import androidx.test.ext.junit.rules.ActivityScenarioRule
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.core.sleep
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.PrescriptionsScreen
-
-class PrescriptionUtils(
- private val composeRule: AndroidComposeTestRule, MainActivity>,
- private val mainScreen: MainScreen,
- private val prescriptionsScreen: PrescriptionsScreen
-) {
- fun loginWithVirtualHealthCardFromMainScreen() {
- mainScreen.userSeesMainScreen()
- composeRule.activity.testWrapper.loginWithVirtualHealthCard()
- composeRule.sleep(1_000L)
- prescriptionsScreen.refreshPrescriptions()
- }
-
- fun deleteAllPrescriptions() {
- composeRule.activity.testWrapper.deleteAllTasksSafe()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Task.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Task.kt
deleted file mode 100644
index 64155211..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Task.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.ExperimentalSerializationApi
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.JsonNames
-
-@Serializable
-data class Task
-@OptIn(ExperimentalSerializationApi::class)
-constructor(
- @SerialName("task-id")
- val taskId: String,
- @JsonNames("access-code", "accessCode")
- val accessCode: String,
- @SerialName("secret")
- val secret: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Telematik.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Telematik.kt
deleted file mode 100644
index 49bbaabb..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/core/prescription/Telematik.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.core.prescription
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Telematik(
- @SerialName("discoveryDocument")
- val discoveryDocument: String? = null,
- @SerialName("fachdienst")
- val fachdienst: String? = null,
- @SerialName("tsl")
- val tsl: String? = null
-)
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/functions/ReadyPrescriptionStateInfoTest.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/functions/ReadyPrescriptionStateInfoTest.kt
deleted file mode 100644
index 9d29e0af..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/functions/ReadyPrescriptionStateInfoTest.kt
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.functions
-
-import androidx.compose.ui.test.hasText
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.test.platform.app.InstrumentationRegistry
-import de.gematik.ti.erp.app.features.R
-import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
-import de.gematik.ti.erp.app.prescription.ui.PrescriptionStateInfo
-import de.gematik.ti.erp.app.theme.AppTheme
-import de.gematik.ti.erp.app.utils.toStartOfDayInUTC
-import kotlinx.datetime.Clock
-import org.junit.Rule
-import org.junit.Test
-import kotlin.time.Duration.Companion.days
-
-class ReadyPrescriptionStateInfoTest {
- @get:Rule
- val composeTestRule = createComposeRule()
-
- private val context = InstrumentationRegistry.getInstrumentation().targetContext
- private val now = Clock.System.now()
-
- @Test
- fun syncedTaskReadyState_27AcceptDaysLeftTest() {
- val acceptUntil = now.plus(27.days).toStartOfDayInUTC()
- val expiresOn = now.plus(90.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = String.format(context.resources.getString(R.string.prescription_item_accept_days_left), "27")
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_2AcceptDaysLeftTest() {
- val acceptUntil = now.plus(2.days).toStartOfDayInUTC()
- val expiresOn = now.plus(65.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = context.resources.getString(R.string.prescription_item_warning_amber) +
- String.format(context.resources.getString(R.string.prescription_item_two_accept_days_left), "2")
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_1AcceptDaysLeftTest() {
- val acceptUntil = now.plus(1.days).toStartOfDayInUTC()
- val expiresOn = now.plus(64.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = context.resources.getString(R.string.prescription_item_warning_amber) +
- context.resources.getString(R.string.prescription_item_accept_only_tomorrow)
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_0AcceptDaysLeftTest() {
- val acceptUntil = now.toStartOfDayInUTC()
- val expiresOn = now.plus(63.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = String.format(context.resources.getString(R.string.prescription_item_warning_amber)) +
- context.resources.getString(R.string.prescription_item_accept_only_today)
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
-
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_62ExpiryDaysLeftTest() {
- val acceptUntil = now.minus(1.days).toStartOfDayInUTC()
- val expiresOn = now.plus(62.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText =
- String.format(context.resources.getString(R.string.prescription_item_expiration_days_left), "62")
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_2ExpiryDaysLeftTest() {
- val acceptUntil = now.minus(61.days).toStartOfDayInUTC()
- val expiresOn = now.plus(2.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = context.resources.getString(R.string.prescription_item_warning_amber) +
- String.format(context.resources.getString(R.string.prescription_item_two_expiration_days_left), "2")
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_1ExpiryDaysLeftTest() {
- val acceptUntil = now.minus(62.days).toStartOfDayInUTC()
- val expiresOn = now.plus(1.days).toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = context.resources.getString(R.string.prescription_item_warning_amber) +
- context.resources.getString(R.string.prescription_item_expiration_only_tomorrow)
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-
- @Test
- fun syncedTaskReadyState_0ExpiryDaysLeftTest() {
- val acceptUntil = now.minus(63.days).toStartOfDayInUTC()
- val expiresOn = now.toStartOfDayInUTC()
- val readyState = SyncedTaskData.SyncedTask.Ready(acceptUntil = acceptUntil, expiresOn = expiresOn)
- val expectedText = context.resources.getString(R.string.prescription_item_warning_amber) +
- context.resources.getString(R.string.prescription_item_expiration_only_today)
- composeTestRule.setContent {
- AppTheme {
- PrescriptionStateInfo(state = readyState)
- }
- }
- composeTestRule.onNode(hasText(expectedText)).assertExists()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Cleanup.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Cleanup.kt
deleted file mode 100644
index 2da55556..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Cleanup.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.core.prescription.PrescriptionUtils
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.OnboardingScreen
-import de.gematik.ti.erp.app.test.test.screens.PrescriptionsScreen
-import org.junit.Assume
-import org.junit.Rule
-import org.junit.Test
-
-class Cleanup {
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingScreen by lazy { OnboardingScreen(composeRule) }
- private val mainScreen by lazy { MainScreen(composeRule) }
- private val prescriptionsScreen by lazy { PrescriptionsScreen(composeRule) }
- private val prescriptionUtils by lazy { PrescriptionUtils(composeRule, mainScreen, prescriptionsScreen) }
-
- @Test
- fun not_a_test_cleanup() {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
- prescriptionsScreen.awaitPrescriptions()
- prescriptionUtils.deleteAllPrescriptions()
- Assume.assumeTrue(false)
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/HealthCardOrder.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/HealthCardOrder.kt
deleted file mode 100644
index 7ece16ee..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/HealthCardOrder.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.LargeTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.steps.CardWallScreenSteps
-import de.gematik.ti.erp.app.test.test.steps.MainScreenSteps
-import de.gematik.ti.erp.app.test.test.steps.OnboardingSteps
-import de.gematik.ti.erp.app.test.test.steps.SettingScreenSteps
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-@LargeTest
-class HealthCardOrder(fontScale: String) : WithFontScale(fontScale) {
-
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingSteps by lazy { OnboardingSteps(composeRule) }
- private val mainScreenSteps by lazy { MainScreenSteps(composeRule) }
- private val cardWallScreenSteps by lazy { CardWallScreenSteps(composeRule) }
-
- private val settingScreenSteps by lazy { SettingScreenSteps(composeRule) }
-
- @Before
- fun skipsOnboarding() {
- onboardingSteps.userSkipsOnboarding()
- }
-
- @After
- fun destroyActivity() {
- composeRule.activity.finish()
- }
-
- @Test
- fun list_health_insurance_company() {
- mainScreenSteps.userTapsSettingsMenuButton()
- settingScreenSteps.userWantsToOrderNewCard()
- settingScreenSteps.userSeesAListOfInsurances()
- }
-
- @Test
- fun ordering_new_EGKFromSettings() {
- mainScreenSteps.userTapsSettingsMenuButton()
- settingScreenSteps.userWantsToOrderNewCard()
- settingScreenSteps.userSeesAListOfInsurances()
- settingScreenSteps.userChoosesInsurance("AOK - Die Gesundheitskasse Hessen")
- settingScreenSteps.userSeesOrderOptionScreen()
- settingScreenSteps.userSeesPossibilitiesWhatCanBeOrdered("Karten & PIN, Nur PIN")
- settingScreenSteps.userSeesHealthCardOrderContactScreen()
- settingScreenSteps.userSeesPossibilitiesHowCanBeOrdered("Webseite")
- }
-
- @Test
- fun ordering_new_EGKFromIntroScreen() {
- cardWallScreenSteps.fakeNFCCapabilities()
- mainScreenSteps.userTapsConnect()
- cardWallScreenSteps.userClicksOrderHealthCardFromCardWallIntroScreen()
- settingScreenSteps.userSeesAListOfInsurances()
- settingScreenSteps.userChoosesInsurance("AOK - Die Gesundheitskasse Hessen")
- settingScreenSteps.userSeesOrderOptionScreen()
- settingScreenSteps.userSeesPossibilitiesWhatCanBeOrdered("Karten & PIN, Nur PIN")
- settingScreenSteps.userSeesHealthCardOrderContactScreen()
- settingScreenSteps.userSeesPossibilitiesHowCanBeOrdered("Webseite")
- }
-
- @Test
- fun ordering_new_EGKFromCANScreen() {
- cardWallScreenSteps.fakeNFCCapabilities()
- mainScreenSteps.userTapsConnect()
- cardWallScreenSteps.userClicksOrderHealthCardFromCardWallCANScreen()
- settingScreenSteps.userSeesAListOfInsurances()
- settingScreenSteps.userChoosesInsurance("AOK - Die Gesundheitskasse Hessen")
- settingScreenSteps.userSeesOrderOptionScreen()
- settingScreenSteps.userSeesPossibilitiesWhatCanBeOrdered("Karten & PIN, Nur PIN")
- settingScreenSteps.userSeesHealthCardOrderContactScreen()
- settingScreenSteps.userSeesPossibilitiesHowCanBeOrdered("Webseite")
- }
-
- @Test
- fun ordering_new_EGKFromPINScreen() {
- cardWallScreenSteps.fakeNFCCapabilities()
- mainScreenSteps.userTapsConnect()
- cardWallScreenSteps.userClicksOrderHealthCardFromCardWallPinScreen()
- settingScreenSteps.userSeesAListOfInsurances()
- settingScreenSteps.userChoosesInsurance("AOK - Die Gesundheitskasse Hessen")
- settingScreenSteps.userSeesOrderOptionScreen()
- settingScreenSteps.userSeesPossibilitiesWhatCanBeOrdered("Karten & PIN, Nur PIN")
- settingScreenSteps.userSeesHealthCardOrderContactScreen()
- settingScreenSteps.userSeesPossibilitiesHowCanBeOrdered("Webseite")
- }
-
- @Test
- fun cancel_ordering_new_EGK() {
- mainScreenSteps.userTapsSettingsMenuButton()
- settingScreenSteps.userWantsToOrderNewCard()
- settingScreenSteps.userSeesAListOfInsurances()
- settingScreenSteps.userAbortsOrderingOfNewCard()
- settingScreenSteps.userSeesSettingsScreen()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/MultiProfileScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/MultiProfileScreen.kt
deleted file mode 100644
index f69be2e3..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/MultiProfileScreen.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.MediumTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.steps.MainScreenSteps
-import de.gematik.ti.erp.app.test.test.steps.OnboardingSteps
-import de.gematik.ti.erp.app.test.test.steps.ProfileSettingsSteps
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-@MediumTest
-class MultiProfileScreen(fontScale: String) : WithFontScale(fontScale) {
-
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingSteps by lazy { OnboardingSteps(composeRule) }
- private val mainScreenSteps by lazy { MainScreenSteps(composeRule) }
-
- private val profileSettingSteps by lazy { ProfileSettingsSteps(composeRule) }
-
- @Before
- fun skipsOnboarding() {
- onboardingSteps.userSkipsOnboarding()
- }
-
- @Test
- fun create_second_profile_and_delete_first_one() {
- mainScreenSteps.createNewProfile("Herbert Hepatitis B")
- profileSettingSteps.userHasNumberOfProfiles(2)
- profileSettingSteps.userDeletesProfile("Profil 1")
- profileSettingSteps.userHasProfilesWithName(1, "Herbert Hepatitis B")
- }
-
- @Test
- fun delete_last_profile() {
- mainScreenSteps.userTapsSettingsMenuButton()
- profileSettingSteps.userDeletesProfile("Profil 1")
- profileSettingSteps.createProfileAfterLastOneWasDeleted()
- profileSettingSteps.userHasProfilesWithName(1, "Profil 1")
- }
-
- @Test
- fun abort_delete_last_profile() {
- profileSettingSteps.userInterruptsDeletingProfile("Profil 1")
- profileSettingSteps.userHasProfilesWithName(1, "Profil 1")
- }
-
- @Test
- fun abort_create_new_profile() {
- mainScreenSteps.userTapsAddProfileButton()
- mainScreenSteps.userCantConfirmCreation()
- mainScreenSteps.userTapsAbort()
- }
-
- @Test
- fun create_profile_without_name() {
- mainScreenSteps.userTapsAddProfileButton()
- mainScreenSteps.userCantConfirmCreation()
- mainScreenSteps.userTapsAbort()
- profileSettingSteps.userHasNumberOfProfiles(1)
- }
-
- @Test
- fun delete_name_of_a_profile() {
- profileSettingSteps.editProfileName("Profil 1", "")
- profileSettingSteps.assertErrorMessageEmptyProfileName("Das Namensfeld darf nicht leer sein.")
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV1.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV1.kt
deleted file mode 100644
index e8177cce..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV1.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.SmallTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.steps.OnboardingSteps
-import org.junit.Rule
-import org.junit.Test
-
-@SmallTest
-class OnboardingV1(fontScale: String) : WithFontScale(fontScale) {
-
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingSteps by lazy { OnboardingSteps(composeRule) }
- private fun restartApp() {
- composeRule.activityRule.scenario.recreate()
- }
-
- @Test
- fun first_time() {
- // Onboarding wird beim 1. App-Start angezeigt
- onboardingSteps.userSeesWelcomeScreen()
- }
-
- @Test
- fun shown_again_if_not_finished() {
- // Onboarding wird nach App-Neustart weiterhin angezeigt, solange es noch nicht beendet wurde
-
- onboardingSteps.userSeesWelcomeScreen()
- restartApp()
- onboardingSteps.userSeesWelcomeScreen()
- }
-
- @Test
- fun navigate_through_onboarding_without_analytics() {
- // welcome screen
- onboardingSteps.userSeesWelcomeScreen()
- onboardingSteps.userIsFinishingTheOnboardingWithoutAnalytics()
- }
-
- @Test
- fun navigate_through_analytics_optional() {
- // welcome screen
- onboardingSteps.userSeesWelcomeScreen()
- onboardingSteps.userIsFinishingTheOnboardingWithAnalytics()
- }
-
- @Test
- fun navigate_through_and_restart_app() {
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.MainScreen)
-
- restartApp()
-
- onboardingSteps.userIsNotSeeingTheOnboarding()
- onboardingSteps.userSeesMainScreen()
- }
-
- @Test
- fun weak_password_blocks_next() {
- // Onboarding Screen 3 >>> Zu schwaches Passwort = Weiter-Button inaktiv + Fehlermeldung
-
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.Credentials)
- // credentials screen
- onboardingSteps.userSeesCredentialScreen()
-
- onboardingSteps.userEntersAWeakPasswordTwice()
-
- onboardingSteps.userDoesNotSeeContinueButton()
- onboardingSteps.userSeesErrorMessageForPasswordStrength()
- }
-
- @Test
- fun no_password_blocks_next() {
- // Onboarding Screen 3 >>> kein Passwort = Weiter-Button inaktiv + Fehlermeldung
-
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.Credentials)
- // credentials screen
- onboardingSteps.userSeesCredentialScreen()
-
- onboardingSteps.userSwitchesToPasswordMode()
-
- onboardingSteps.userDoesNotSeeContinueButton()
- onboardingSteps.userSeesErrorMessageForPasswordStrength()
- }
-
- @Test
- fun not_confirming_data_protection_blocks_next() {
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.DataTerms)
- onboardingSteps.dataTermsSwitchDeactivated()
- onboardingSteps.confirmContinueButtonIsDeactivated()
- onboardingSteps.toggleDataTermsSwitch()
- onboardingSteps.userSeesActivatedContinueButton()
- onboardingSteps.toggleDataTermsSwitch()
- onboardingSteps.confirmContinueButtonIsDeactivated()
- }
-
- @Test
- fun data_protection_can_be_read() {
- // Datenschutzbestimmungen werden angezeigt und können geschlossen werden
-
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.DataTerms)
-
- onboardingSteps.userDoesntSeeDataProtection()
- onboardingSteps.userOpensDataProtection()
- onboardingSteps.userSeesDataProtection()
- onboardingSteps.userClosesDataProtection()
- onboardingSteps.userDoesntSeeDataProtection()
- }
-
- @Test
- fun terms_of_use_can_be_read() {
- // Nutzungsbedingungen werden angezeigt und können geschlossen werden
-
- onboardingSteps.userNavigatesToOnboardingScreenName(OnboardingSteps.Page.DataTerms)
-
- onboardingSteps.userSeesNoTermsOfUse()
- onboardingSteps.userOpensTermsOfUse()
- onboardingSteps.userSeesTermsOfUse()
- onboardingSteps.userClosesTermsOfUse()
- onboardingSteps.userSeesNoTermsOfUse()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV2.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV2.kt
deleted file mode 100644
index 414e6440..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/OnboardingV2.kt
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.SmallTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.OnboardingScreen
-import org.junit.Rule
-import org.junit.Test
-
-@SmallTest
-class OnboardingV2(fontScale: String) : WithFontScale(fontScale) {
-
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingScreen by lazy { OnboardingScreen(composeRule) }
- private val mainScreen by lazy { MainScreen(composeRule) }
-
- private fun restartApp() {
- composeRule.activityRule.scenario.recreate()
- }
-
- @Test
- fun first_time() {
- // Onboarding wird beim 1. App-Start angezeigt
-
- onboardingScreen.checkWelcomePageIsPresent()
- }
-
- @Test
- fun shown_again_if_not_finished() {
- // Onboarding wird nach App-Neustart weiterhin angezeigt, solange es noch nicht beendet wurde
-
- onboardingScreen.checkWelcomePageIsPresent()
- restartApp()
- onboardingScreen.checkWelcomePageIsPresent()
- }
-
- @Test
- fun navigate_through() {
- // welcome screen
- onboardingScreen.checkWelcomePageIsPresent()
- onboardingScreen.waitForSecondOnboardingPage()
-
- // data terms screen
- onboardingScreen.checkDataTermsPageIsPresent()
-
- onboardingScreen.checkDataTermsSwitchDeactivated()
- onboardingScreen.checkContinueTutorialButtonIsDeactivated()
-
- onboardingScreen.tapDataTermsSwitch()
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.tapContinueButton()
-
- // credentials screen
- onboardingScreen.checkCredentialsPageIsPresent()
-
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.StrongPassword)
- onboardingScreen.enterPasswordB(TestConfig.StrongPassword)
- onboardingScreen.tapContinueButton()
-
- // analytics screen
- onboardingScreen.checkAnalyticsPageIsPresent()
-
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.checkAnalyticsSwitchIsDeactivated()
-
- onboardingScreen.toggleAnalyticsSwitch()
- onboardingScreen.waitForAnalyticsPage()
- onboardingScreen.tapAcceptAnalyticsButton()
-
- onboardingScreen.checkAnalyticsSwitchIsActivated()
-
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.tapContinueButton()
-
- // main screen
- mainScreen.userSeesMainScreen()
- }
-
- @Test
- fun navigate_through_analytics_optional() {
- // welcome screen
- onboardingScreen.checkWelcomePageIsPresent()
- onboardingScreen.waitForSecondOnboardingPage()
-
- // data terms screen
- onboardingScreen.checkDataTermsPageIsPresent()
-
- onboardingScreen.checkDataTermsSwitchDeactivated()
- onboardingScreen.checkContinueTutorialButtonIsDeactivated()
-
- onboardingScreen.tapDataTermsSwitch()
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.tapContinueButton()
-
- // credentials screen
- onboardingScreen.checkCredentialsPageIsPresent()
-
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.StrongPassword)
- onboardingScreen.enterPasswordB(TestConfig.StrongPassword)
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.tapContinueButton()
-
- // analytics screen
- onboardingScreen.checkAnalyticsPageIsPresent()
-
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
- onboardingScreen.checkAnalyticsSwitchIsDeactivated()
-
- onboardingScreen.tapContinueButton()
-
- // main screen
- mainScreen.userSeesMainScreen()
- }
-
- private enum class Page {
- DataTerms, Credentials, Analytics, MainScreen
- }
-
- @Suppress("ReturnCount")
- private fun walkThroughOnboardingWithoutChecks(until: Page? = null) {
- // welcome screen
- onboardingScreen.checkWelcomePageIsPresent()
- onboardingScreen.waitForSecondOnboardingPage()
-
- if (until == Page.DataTerms) return
-
- // data terms screen
- onboardingScreen.checkDataTermsPageIsPresent()
-
- onboardingScreen.tapDataTermsSwitch()
-
- onboardingScreen.tapContinueButton()
-
- if (until == Page.Credentials) return
-
- // credentials screen
- onboardingScreen.checkCredentialsPageIsPresent()
-
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.StrongPassword)
- onboardingScreen.enterPasswordB(TestConfig.StrongPassword)
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
-
- onboardingScreen.tapContinueButton()
-
- if (until == Page.Analytics) return
-
- // analytics screen
- onboardingScreen.checkAnalyticsPageIsPresent()
-
- onboardingScreen.tapContinueButton()
-
- if (until == Page.MainScreen) return
-
- // main screen
- mainScreen.userSeesMainScreen()
- }
-
- @Test
- fun navigate_through_and_restart_app() {
- walkThroughOnboardingWithoutChecks()
-
- restartApp()
-
- mainScreen.userSeesMainScreen()
- }
-
- @Test
- fun weak_password_blocks_next() {
- // Onboarding Screen 3 >>> Zu schwaches Passwort = Weiter-Button inaktiv + Fehlermeldung
-
- walkThroughOnboardingWithoutChecks(until = Page.Credentials)
-
- // credentials screen
- onboardingScreen.checkCredentialsPageIsPresent()
-
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.WeakPassword)
- onboardingScreen.enterPasswordB(TestConfig.WeakPassword)
-
- onboardingScreen.checkContinueTutorialButtonIsDisabled()
- onboardingScreen.checkPasswordErrorMessagePresent()
- }
-
- @Test
- fun data_protection_can_be_read() {
- // Datenschutzbestimmungen werden angezeigt und können geschlossen werden
-
- walkThroughOnboardingWithoutChecks(until = Page.DataTerms)
-
- onboardingScreen.checkDataTermsPageIsPresent()
- onboardingScreen.checkDataProtectionAreNotDisplayed()
- onboardingScreen.openDataProtection()
- onboardingScreen.checkDataProtectionIsDisplayed()
- onboardingScreen.closeDataProtection()
- onboardingScreen.checkDataProtectionAreNotDisplayed()
- }
-
- @Test
- fun terms_of_use_can_be_read() {
- // Nutzungsbedingungen werden angezeigt und können geschlossen werden
-
- walkThroughOnboardingWithoutChecks(until = Page.DataTerms)
-
- onboardingScreen.checkDataTermsPageIsPresent()
- onboardingScreen.checkTermsOfUseAreNotDisplayed()
- onboardingScreen.openTermsOfUse()
- onboardingScreen.checkTermsOfUseAreDisplayed()
- onboardingScreen.closeTermsOfUse()
- onboardingScreen.checkTermsOfUseAreNotDisplayed()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Orders.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Orders.kt
deleted file mode 100644
index f96e2fc1..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/Orders.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.espresso.intent.rule.IntentsRule
-import androidx.test.filters.LargeTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.core.TaskCollection
-import de.gematik.ti.erp.app.test.test.core.prescription.CommunicationPayloadInbox
-import de.gematik.ti.erp.app.test.test.core.prescription.PrescriptionUtils
-import de.gematik.ti.erp.app.test.test.core.prescription.SupplyOptionsType
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.OnboardingScreen
-import de.gematik.ti.erp.app.test.test.screens.PharmacySearchScreen
-import de.gematik.ti.erp.app.test.test.screens.PrescriptionOrderScreen
-import de.gematik.ti.erp.app.test.test.screens.PrescriptionsScreen
-import org.junit.Rule
-import org.junit.Test
-
-@LargeTest
-class Orders(fontScale: String) : WithFontScale(fontScale) {
- @get:Rule(order = 1)
- val composeRule = createAndroidComposeRule()
-
- @get:Rule(order = 0)
- val intentsRule = IntentsRule()
-
- private val onboardingScreen by lazy { OnboardingScreen(composeRule) }
- private val mainScreen by lazy { MainScreen(composeRule) }
- private val prescriptionsScreen by lazy { PrescriptionsScreen(composeRule) }
- private val pharmacySearchScreen by lazy { PharmacySearchScreen(composeRule) }
- private val prescriptionOrderScreen by lazy { PrescriptionOrderScreen(composeRule) }
- private val prescriptionUtils by lazy { PrescriptionUtils(composeRule, mainScreen, prescriptionsScreen) }
-
- @Test
- fun order_prescription() {
- val tasks = TaskCollection.generate(
- 1,
- TestConfig.AppDefaultVirtualEgkKvnr,
- composeRule.activity.testWrapper
- )
-
- fun firstTask() = tasks.taskData.first()
-
- try {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
- prescriptionsScreen.awaitPrescriptions()
-
- prescriptionsScreen.userSeesPZNPrescription(
- data = firstTask().prescription,
- inState = PrescriptionsScreen.PrescriptionState.Redeemable
- )
-
- mainScreen.userClicksBottomBarPharmacy()
-
- pharmacySearchScreen.userSeesPharmacyOverviewScreen()
-
- pharmacySearchScreen.userClicksSearchButton()
- pharmacySearchScreen.userSeesPharmacySearchResultScreen()
- pharmacySearchScreen.userSearchesForTestPharmacy()
- pharmacySearchScreen.awaitSearchResults()
- pharmacySearchScreen.userClicksOnTestPharmacy()
-
- pharmacySearchScreen.userSeesPharmacyOrderOptions()
- pharmacySearchScreen.awaitOrderOptionsEnabled()
- pharmacySearchScreen.userClicksOnOrderByPickUp()
-
- pharmacySearchScreen.userSeesPharmacyOrderSummaryScreen()
-
- // all contact information should be available; therefore the order button is enabled
- pharmacySearchScreen.userSeesSendOrderButtonEnabled()
-
- pharmacySearchScreen.userClicksPrescriptionSelection()
- pharmacySearchScreen.userSeesPrescriptionSelectionScreen()
- pharmacySearchScreen.userDeselectsAllPrescriptions()
- pharmacySearchScreen.userSelectsPrescription(firstTask().prescription)
- pharmacySearchScreen.userClicksBack()
- pharmacySearchScreen.userSeesPharmacyOrderSummaryScreen()
-
- pharmacySearchScreen.userSeesSendOrderButtonEnabled()
- pharmacySearchScreen.userClicksSendOrderButton()
-
- mainScreen.userSeesMainScreen(10_000L)
- prescriptionsScreen.refreshPrescriptions()
-
- prescriptionsScreen.userSeesPZNPrescription(
- data = firstTask().prescription,
- inState = PrescriptionsScreen.PrescriptionState.WaitForResponse
- )
-
- // pharmacy accepts task
- tasks.accept(firstTask())
- val message = CommunicationPayloadInbox(
- supplyOptionsType = SupplyOptionsType.Delivery,
- url = "https://www.whatever.de/blablub",
- infoText = "Hey u!",
- pickUpCodeHR = "a1234567890",
- pickUpCodeDMC = "b1234567890"
- )
- tasks.reply(firstTask(), message)
-
- prescriptionsScreen.refreshPrescriptions()
-
- prescriptionsScreen.userSeesPZNPrescription(
- data = firstTask().prescription,
- inState = PrescriptionsScreen.PrescriptionState.InProgress
- )
-
- mainScreen.userClicksBottomBarOrders()
-
- prescriptionOrderScreen.userSeesOrderScreen()
- prescriptionOrderScreen.awaitOrders()
-
- prescriptionOrderScreen.userClicksNewestOrder()
- prescriptionOrderScreen.userSeesOrderDetailsScreen()
- prescriptionOrderScreen.userSeesOnePrescription(firstTask().prescription)
- prescriptionOrderScreen.userSeesAndClicksMessage()
- prescriptionOrderScreen.userExpectsMessageContent(message)
- prescriptionOrderScreen.userClicksMessageLink(message)
-
- prescriptionOrderScreen.userClosesMessageSheetBySwipe()
-
- prescriptionOrderScreen.userClicksPrescription(firstTask().prescription)
- prescriptionsScreen.userSeesPrescriptionDetails()
- prescriptionsScreen.userClicksClose()
- prescriptionOrderScreen.userClicksBack()
-
- // dispense medication
- tasks.dispense(firstTask())
-
- mainScreen.userClicksBottomBarPrescriptions()
-
- prescriptionsScreen.awaitPrescriptionScreen()
- prescriptionsScreen.refreshPrescriptions()
-
- prescriptionsScreen.userMissesPrescription(firstTask().prescription)
- prescriptionsScreen.userClicksArchiveButton()
- prescriptionsScreen.awaitArchivedPrescriptions()
- prescriptionsScreen.userSeesPrescriptionInArchive(
- data = firstTask().prescription,
- inState = PrescriptionsScreen.PrescriptionState.Redeemed
- )
- } finally {
- tasks.deleteAll()
- }
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PharmacyUITest.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PharmacyUITest.kt
deleted file mode 100644
index d4d51f79..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PharmacyUITest.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.sharedtest.testresources.actions.PharmacyScreenAction
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class PharmacyUITest {
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val actions = PharmacyScreenAction(composeRule)
-
- @Test
- fun pickupServiceSuccessTest() {
- actions.pickupServiceSuccessTest()
- }
-
- @Test
- fun courierDeliverySuccessTest() {
- actions.courierDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceMailDeliverySuccessTest() {
- actions.pickupServiceMailDeliverySuccessTest()
- }
-
- @Test
- fun mailDeliverySuccessTest() {
- actions.mailDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceCourierSuccessTest() {
- actions.pickupServiceCourierSuccessTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryCourierDeliverySuccessTest() {
- actions.pickupServiceMailDeliveryCourierDeliverySuccessTest()
- }
-
- @Test
- fun mailDeliveryCourierDeliverySuccessTest() {
- actions.mailDeliveryCourierDeliverySuccessTest()
- }
-
- @Test
- fun pickupServiceFailTest() {
- actions.pickupServiceFailTest()
- }
-
- @Test
- fun courierDeliveryFailTest() {
- actions.courierDeliveryFailTest()
- }
-
- @Test
- fun mailDeliveryFailTest() {
- actions.mailDeliveryFailTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryCourierDeliveryFailTest() {
- actions.pickupServiceMailDeliveryCourierDeliveryFailTest()
- }
-
- @Test
- fun pickupServiceMailDeliveryFailTest() {
- actions.pickupServiceMailDeliveryFailTest()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PrescriptionDetailsScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PrescriptionDetailsScreen.kt
deleted file mode 100644
index 3612b9b5..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/PrescriptionDetailsScreen.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.LargeTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.core.TaskCollection
-import de.gematik.ti.erp.app.test.test.core.prescription.PrescriptionUtils
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.OnboardingScreen
-import de.gematik.ti.erp.app.test.test.screens.PrescriptionsScreen
-import org.junit.Rule
-import org.junit.Test
-
-@LargeTest
-class PrescriptionDetailsScreen(fontScale: String) : WithFontScale(fontScale) {
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingScreen by lazy { OnboardingScreen(composeRule) }
- private val mainScreen by lazy { MainScreen(composeRule) }
- private val prescriptionsScreen by lazy { PrescriptionsScreen(composeRule) }
- private val prescriptionUtils by lazy { PrescriptionUtils(composeRule, mainScreen, prescriptionsScreen) }
-
- @Test
- fun pzn_medication_details() {
- val tasks = TaskCollection.generate(1, TestConfig.AppDefaultVirtualEgkKvnr, composeRule.activity.testWrapper)
- val prescriptionData = tasks.taskData.first().prescription
-
- try {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
- prescriptionsScreen.awaitPrescriptions()
-
- // details main page
- prescriptionsScreen.clickOnPrescription(prescriptionData)
- prescriptionsScreen.userSeesPrescriptionDetails()
- prescriptionsScreen.userExpectsPrescriptionData(prescriptionData)
-
- // technical details
- prescriptionsScreen.userClicksOnTechnicalDetails()
- prescriptionsScreen.userSeesTechnicalDetailsScreen()
- prescriptionsScreen.userExpectsTechnicalInformationData(prescriptionData)
-
- prescriptionsScreen.userClicksBack()
- prescriptionsScreen.userSeesPrescriptionDetails()
-
- // patient page
- prescriptionsScreen.userClicksOnPatientDetails()
- prescriptionsScreen.userSeesPatientDetailsScreen()
- prescriptionsScreen.userExpectsPatientDetailsData(prescriptionData)
-
- prescriptionsScreen.userClicksBack()
- prescriptionsScreen.userSeesPrescriptionDetails()
-
- // organization page
- prescriptionsScreen.userClicksOnOrganizationDetails()
- prescriptionsScreen.userSeesOrganizationDetailsScreen()
- prescriptionsScreen.userExpectsOrganizationDetailsData(prescriptionData)
-
- prescriptionsScreen.userClicksBack()
- prescriptionsScreen.userSeesPrescriptionDetails()
-
- // medication page
- prescriptionsScreen.userClicksOnMedicationDetails()
- prescriptionsScreen.userSeesMedicationDetailsScreen()
- prescriptionsScreen.userExpectsMedicationDetailsData(prescriptionData)
-
- prescriptionsScreen.userClicksBack()
- prescriptionsScreen.userSeesPrescriptionDetails()
- } finally {
- tasks.deleteAll()
- }
- }
-
- @Test
- fun delete_task() {
- val tasks = TaskCollection.generate(1, TestConfig.AppDefaultVirtualEgkKvnr, composeRule.activity.testWrapper)
- val prescriptionData = tasks.taskData.first().prescription
-
- try {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
- prescriptionsScreen.awaitPrescriptions()
-
- // details main page
- prescriptionsScreen.clickOnPrescription(prescriptionData)
- prescriptionsScreen.userSeesPrescriptionDetails()
-
- prescriptionsScreen.userClicksMoreButton()
- prescriptionsScreen.userClicksDeleteButton()
- prescriptionsScreen.userSeesConfirmDeleteDialog()
- prescriptionsScreen.userConfirmsDeletion()
-
- mainScreen.userSeesMainScreen()
- prescriptionsScreen.awaitPrescriptions()
-
- prescriptionsScreen.userMissesPrescription(prescriptionData)
- } finally {
- tasks.deleteAll()
- }
- }
-
- @Test
- fun main_screen_with_many_prescriptions() {
- val tasks = TaskCollection.generate(6, TestConfig.AppDefaultVirtualEgkKvnr, composeRule.activity.testWrapper)
-
- try {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
-
- tasks.taskData.forEach { data ->
- prescriptionsScreen.awaitPrescriptions()
- prescriptionsScreen.clickOnPrescription(data.prescription)
- prescriptionsScreen.userSeesPrescriptionDetails()
-
- // technical details
- prescriptionsScreen.userClicksOnTechnicalDetails()
- prescriptionsScreen.userSeesTechnicalDetailsScreen()
- prescriptionsScreen.userExpectsTechnicalInformationData(data.prescription)
-
- prescriptionsScreen.userClicksBack()
- prescriptionsScreen.userSeesPrescriptionDetails()
- prescriptionsScreen.userClicksClose()
- mainScreen.userSeesMainScreen()
- }
-
- // TODO use expiresOn and TODO sorting is unstable (uses expiresOn with day accuracy) in app
- // val fromOldToNew = tasks.prescriptions.sortedBy { it.authoredOn }
- // prescriptionsScreen.userSeesPrescriptionSortedBy(fromOldToNew)
- } finally {
- tasks.deleteAll()
- }
- }
-
- @Test
- fun main_screen_check_if_prescriptions_exist() {
- val tasks = TaskCollection.generate(6, TestConfig.AppDefaultVirtualEgkKvnr, composeRule.activity.testWrapper)
-
- try {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.tapTooltips()
- prescriptionUtils.loginWithVirtualHealthCardFromMainScreen()
- prescriptionsScreen.awaitPrescriptions()
-
- tasks.taskData.forEach { data ->
- prescriptionsScreen.userSeesPZNPrescription(data.prescription)
- }
- } finally {
- tasks.deleteAll()
- }
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/ProfileScreenSettings.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/ProfileScreenSettings.kt
deleted file mode 100644
index 4f00f7ad..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/scenarios/ProfileScreenSettings.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.scenarios
-
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.test.filters.MediumTest
-import de.gematik.ti.erp.app.MainActivity
-import de.gematik.ti.erp.app.test.test.WithFontScale
-import de.gematik.ti.erp.app.test.test.core.sleep
-import de.gematik.ti.erp.app.test.test.steps.CardWallScreenSteps
-import de.gematik.ti.erp.app.test.test.steps.MainScreenSteps
-import de.gematik.ti.erp.app.test.test.steps.OnboardingSteps
-import de.gematik.ti.erp.app.test.test.steps.ProfileSettingsSteps
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-@MediumTest
-class ProfileScreenSettings(fontScale: String) : WithFontScale(fontScale) {
-
- @get:Rule
- val composeRule = createAndroidComposeRule()
-
- private val onboardingSteps by lazy { OnboardingSteps(composeRule) }
- private val mainScreenSteps by lazy { MainScreenSteps(composeRule) }
- private val profileSettingsSteps by lazy { ProfileSettingsSteps(composeRule) }
- private val cardWallScreenSteps by lazy { CardWallScreenSteps(composeRule) }
-
- @Before
- fun skipOnboarding() {
- onboardingSteps.userSkipsOnboarding()
- }
-
- @Test
- fun no_token_in_profile_if_not_logged_in() {
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.checkNoTokenPresent()
- profileSettingsSteps.checkTokenHintPresent()
- }
-
- @Test
- fun token_in_profile_if_logged_in() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.checkTokenPresent()
- profileSettingsSteps.hintTextNotPresent()
- }
-
- @Test
- fun no_token_in_profile_after_logged_out() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- profileSettingsSteps.logoutViaProfileSettings()
- profileSettingsSteps.noTokenPresentInProfileSettings()
- profileSettingsSteps.checkTokenHintPresent(
- "Sie erhalten einen Token, wenn Sie am Rezeptdienst angemeldet sind."
- )
- }
-
- @Test
- fun login_in_profile_settings_opens_cardwall() {
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.tapLoginButton()
- profileSettingsSteps.userSeesCardwallWelcomeScreen()
- }
-
- @Test
- fun no_kvnr_in_profile_settings_if_never_logged_in() {
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.checkNoKVNRIsVisible()
- }
-
- @Test
- fun kvnr_in_profile_settings_is_visible_if_logged_in() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.checkKVNRIsVisible()
- }
-
- @Test
- fun kvnr_in_profile_settings_is_visible_if_logged_out() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- profileSettingsSteps.logoutViaProfileSettings()
- profileSettingsSteps.openProfileSettings()
- profileSettingsSteps.checkKVNRIsVisible()
- }
-
- @Test
- fun if_profile_changed_show_no_kvnr() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- mainScreenSteps.createNewProfile("Karoline Karies")
- profileSettingsSteps.openProfileSettingsForCertainProfile(2)
- profileSettingsSteps.checkNoKVNRIsVisible()
- }
-
- @Test
- fun show_no_access_protocol_screen() {
- profileSettingsSteps.userSeesAuditEventsScreen(1)
- profileSettingsSteps.userSeesEmptyStateForCertainProfile()
- }
-
- @Test
- fun show_no_access_protocol_screen_when_switching_to_logged_out_profile() {
- cardWallScreenSteps.userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully()
- mainScreenSteps.createNewProfile("Karoline Karies")
- profileSettingsSteps.userSeesAuditEventsScreen(2)
- profileSettingsSteps.userSeesEmptyStateForCertainProfile()
- }
-
- @Test
- fun show_protocol_after_logout() {
- cardWallScreenSteps.setVirtualEGKWithPrescriptions()
- composeRule.sleep(5_000L) // await audit events
- profileSettingsSteps.userLogsOutOffProfile(1)
- profileSettingsSteps.userSeesAuditEventsScreen(1)
- profileSettingsSteps.userDoesNotSeesEmptyStateForCertainProfile()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/AuditEventsScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/AuditEventsScreen.kt
deleted file mode 100644
index 931d8605..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/AuditEventsScreen.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onAllNodesWithTag
-import androidx.compose.ui.test.onNodeWithTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class AuditEventsScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesAuditEventsScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Profile.AuditEvents.AuditEventsScreen)
- }
-
- fun checkAuditEventsDoNotExist() {
- onNodeWithTag(TestTag.Profile.AuditEvents.NoAuditEventHeader)
- .assertIsDisplayed()
- onNodeWithTag(TestTag.Profile.AuditEvents.NoAuditEventInfo)
- .assertIsDisplayed()
- }
-
- fun checkAuditEventsExist() {
- onAllNodesWithTag(TestTag.Profile.AuditEvents.AuditEvent)[0]
- .assertIsDisplayed()
- }
-
- fun checkNoAuditEventsHeaderAndInfoDoesNotExist() {
- onNodeWithTag(TestTag.Profile.AuditEvents.NoAuditEventHeader)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Profile.AuditEvents.NoAuditEventInfo)
- .assertDoesNotExist()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/CardWallScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/CardWallScreen.kt
deleted file mode 100644
index a65906b8..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/CardWallScreen.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextInput
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class CardWallScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesIntroScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.CardWall.Intro.IntroScreen)
- }
- fun userSeesPinScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.CardWall.PIN.PinScreen)
- }
- fun userSeesCANScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.CardWall.CAN.CANScreen)
- }
-
- // ****** LoginScreen ******
- fun continueWithEGK() {
- onNodeWithTag(TestTag.CardWall.ContinueButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- // ****** CAN and PIN Screen ******
- fun enterCAN() {
- // CAN
- onNodeWithTag(TestTag.CardWall.CAN.CANField)
- .assertIsDisplayed()
- .performTextInput(TestConfig.DefaultEGKCAN)
- onNodeWithTag(TestTag.CardWall.ContinueButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun enterPin() {
- // PIN
- onNodeWithTag(TestTag.CardWall.PIN.PINField)
- .assertIsDisplayed()
- .performTextInput(TestConfig.DefaultEGKPassword)
- onNodeWithTag(TestTag.CardWall.ContinueButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun saveCredentials() {
- onNodeWithTag(TestTag.CardWall.StoreCredentials.Save)
- .assertIsDisplayed()
- .performClick()
- onNodeWithTag(TestTag.CardWall.SecurityAcceptance.AcceptButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun dontSaveCredentials() {
- onNodeWithTag(TestTag.CardWall.StoreCredentials.DontSave)
- .assertIsDisplayed()
- .performClick()
- onNodeWithTag(TestTag.CardWall.ContinueButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userSeesNfcScreen() {
- onNodeWithTag(TestTag.CardWall.Nfc.NfcScreen)
- .assertIsDisplayed()
- }
-
- fun tapOrderEgkFromIntroScreen() {
- onNodeWithTag(TestTag.CardWall.Intro.OrderEgkButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun tapOrderEgkFromCANScreen() {
- onNodeWithTag(TestTag.CardWall.CAN.OrderEgkButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun tapOrderEgkFromPinScreen() {
- onNodeWithTag(TestTag.CardWall.PIN.OrderEgkButton)
- .assertIsDisplayed()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/DebugMenuScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/DebugMenuScreen.kt
deleted file mode 100644
index 5f16b191..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/DebugMenuScreen.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsNotEnabled
-import androidx.compose.ui.test.assertIsToggleable
-import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollToNode
-import androidx.compose.ui.test.performTextReplacement
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.VirtualEgk
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class DebugMenuScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesDebugMenuScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.DebugMenu.DebugMenuScreen)
- }
-
- fun waitTillVirtualHealthCardIsSet() {
- composeRule.awaitDisplay(10000) {
- onNodeWithTag(TestTag.DebugMenu.SetVirtualHealthCardButton)
- .assertIsNotEnabled()
- }
- composeRule.awaitDisplay(10000) {
- onNodeWithTag(TestTag.DebugMenu.SetVirtualHealthCardButton)
- .assertIsEnabled()
- }
- }
-
- fun tapSetVirtualCard() {
- onNodeWithTag(TestTag.DebugMenu.DebugMenuContent)
- .performScrollToNode(hasTestTag(TestTag.DebugMenu.SetVirtualHealthCardButton))
- onNodeWithTag(TestTag.DebugMenu.SetVirtualHealthCardButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- waitTillVirtualHealthCardIsSet()
- }
-
- fun closeDebugMenu() {
- onNodeWithTag(TestTag.TopNavigation.CloseButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun fillCustomCertificateAndPrivateKey(virtualEgk: VirtualEgk) {
- fillCertificateFieldWith(virtualEgk.certificate)
- fillPrivateKeyFieldWith(virtualEgk.privateKey)
- }
-
- fun fillCertificateFieldWith(certificateString: String) {
- onNodeWithTag(TestTag.DebugMenu.DebugMenuContent)
- .performScrollToNode(hasTestTag(TestTag.DebugMenu.CertificateField))
- onNodeWithTag(TestTag.DebugMenu.CertificateField)
- .assertIsDisplayed()
- .performTextReplacement(certificateString)
- }
-
- fun fillPrivateKeyFieldWith(privateKeyString: String) {
- onNodeWithTag(TestTag.DebugMenu.DebugMenuContent)
- .performScrollToNode(hasTestTag(TestTag.DebugMenu.PrivateKeyField))
- onNodeWithTag(TestTag.DebugMenu.PrivateKeyField)
- .assertIsDisplayed()
- .performTextReplacement(privateKeyString)
- }
-
- fun tapFakeNFCCapabilitiesSwitch() {
- onNodeWithTag(TestTag.DebugMenu.DebugMenuContent)
- .performScrollToNode(hasTestTag(TestTag.DebugMenu.FakeNFCCapabilities))
-
- onNodeWithTag(TestTag.DebugMenu.FakeNFCCapabilities)
- .assertIsDisplayed()
- .assertIsToggleable()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/MainScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/MainScreen.kt
deleted file mode 100644
index 84fb7a80..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/MainScreen.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsNotEnabled
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onNodeWithText
-import androidx.compose.ui.test.onRoot
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextInput
-import androidx.compose.ui.test.performTouchInput
-import androidx.compose.ui.test.swipeDown
-import androidx.compose.ui.test.swipeUp
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class MainScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesMainScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Main.MainScreen)
- }
-
- fun userSeesBottomSheet(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Main.MainScreenBottomSheet.Modal)
- onNodeWithTag(TestTag.Main.MainScreenBottomSheet.Modal).performTouchInput { swipeUp() }
- }
-
- fun checkProfileHasState(profileName: String, profileState: String) {
- onNodeWithText(profileName, substring = true)
- .assertIsDisplayed()
- onNodeWithText(profileState, substring = true)
- .assertIsDisplayed()
- }
-
- fun refreshMainScreenBySwipe() {
- onNodeWithTag(TestTag.Main.MainScreen)
- .assertIsDisplayed()
- .performTouchInput { swipeDown() }
- }
-
- fun tapLoginButton() {
- onNodeWithTag(TestTag.Main.LoginButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun tapConnectLater() {
- userSeesBottomSheet(5000)
- onNodeWithTag(TestTag.Main.MainScreenBottomSheet.ConnectLaterButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapTooltips() {
- onRoot().performClick()
- onRoot().performClick()
- onRoot().performClick()
- onRoot().performClick()
- onRoot().performClick()
- onRoot().performClick()
- onRoot().performClick()
- }
-
- fun tapSettingsButton() {
- onNodeWithTag(TestTag.BottomNavigation.SettingsButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userClicksBottomBarPrescriptions() {
- onNodeWithTag(TestTag.BottomNavigation.PrescriptionButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userClicksBottomBarPharmacy() {
- onNodeWithTag(TestTag.BottomNavigation.PharmaciesButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userClicksPharmacySearchBar() {
- onNodeWithTag(TestTag.PharmacySearch.TextSearchButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- TestConfig.ScreenChangeTimeout
- }
-
- fun userClicksBottomBarOrders() {
- onNodeWithTag(TestTag.BottomNavigation.OrdersButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapAddProfileButton() {
- onNodeWithTag(TestTag.Main.AddProfileButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun enterProfileName(name: String) {
- onNodeWithTag(TestTag.Main.MainScreenBottomSheet.ProfileNameField)
- .assertIsDisplayed()
- .performClick()
- .performTextInput(name)
- }
-
- fun tapNewProfileConfirmButton() {
- userSeesBottomSheet(5000L)
- onNodeWithTag(TestTag.Main.MainScreenBottomSheet.SaveProfileNameButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapCancelAddProfileButton() {
- userSeesBottomSheet()
- onNodeWithTag(TestTag.Main.LoginButton) // BottomSheet has no CancelButton
- .performClick()
- }
-
- fun assertConfirmationCanNotBeClicked() {
- onNodeWithTag(TestTag.Main.MainScreenBottomSheet.SaveProfileNameButton)
- .assertIsNotEnabled()
- }
-
- /**
- * cancel user login
- * click-though all tool-tips
- * click on pharmacies bottom button
- */
- fun openPharmaciesFromBottomBarFromStart() {
- tapConnectLater()
- tapTooltips()
- userClicksBottomBarPharmacy()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OnboardingScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OnboardingScreen.kt
deleted file mode 100644
index f9136dfb..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OnboardingScreen.kt
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.semantics.SemanticsProperties
-import androidx.compose.ui.test.SemanticsMatcher
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsFocused
-import androidx.compose.ui.test.assertIsNotEnabled
-import androidx.compose.ui.test.assertIsOff
-import androidx.compose.ui.test.assertIsOn
-import androidx.compose.ui.test.assertIsToggleable
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollTo
-import androidx.compose.ui.test.performTextInput
-import androidx.compose.ui.test.performTouchInput
-import androidx.compose.ui.test.swipeLeft
-import androidx.compose.ui.test.swipeRight
-import androidx.compose.ui.test.swipeUp
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class OnboardingScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun checkTutorialIsNotPresent() {
- onNodeWithTag(TestTag.Onboarding.Pager)
- .assertDoesNotExist()
- }
-
- fun waitForSecondOnboardingPage() {
- composeRule.awaitDisplay(5000L, TestTag.Onboarding.DataTermsScreen)
- }
-
- fun waitForAnalyticsPage() {
- composeRule.awaitDisplay(5000L, TestTag.Onboarding.Analytics.ScreenContent)
- }
-
- fun tapContinueButton() {
- onNodeWithTag(TestTag.Onboarding.NextButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun switchToPasswordMode() {
- onNodeWithTag(TestTag.Onboarding.Credentials.PasswordTab)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun enterPasswordA(password: String) {
- onNodeWithTag(TestTag.Onboarding.Credentials.PasswordFieldA)
- .assertIsDisplayed()
- .performClick()
- .assertIsFocused()
- .performTextInput(password)
- }
-
- fun enterPasswordB(password: String) {
- onNodeWithTag(TestTag.Onboarding.ScreenContent)
- .performTouchInput {
- swipeUp()
- }
-
- onNodeWithTag(TestTag.Onboarding.Credentials.PasswordFieldB)
- .assertIsDisplayed()
- .performClick()
- .assertIsFocused()
- .performTextInput(password)
- }
-
- fun tapDataTermsSwitch() {
- onNodeWithTag(TestTag.Onboarding.ScreenContent)
- .performTouchInput {
- swipeUp()
- }
-
- onNodeWithTag(TestTag.Onboarding.DataTerms.AcceptDataTermsSwitch)
- .assertIsDisplayed()
- .assertIsToggleable()
- .performClick()
- }
-
- fun closeDataProtection() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun checkDataProtectionIsDisplayed() {
- onNodeWithTag(TestTag.Onboarding.DataProtectionScreen)
- .assertIsDisplayed()
- }
-
- fun openDataProtection() {
- onNodeWithTag(TestTag.Onboarding.DataTerms.OpenDataProtectionButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun checkDataProtectionAreNotDisplayed() {
- onNodeWithTag(TestTag.Onboarding.DataProtectionScreen)
- .assertDoesNotExist()
- }
-
- fun closeTermsOfUse() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun openTermsOfUse() {
- onNodeWithTag(TestTag.Onboarding.DataTerms.OpenTermsOfUseButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun checkTermsOfUseAreDisplayed() {
- onNodeWithTag(TestTag.Onboarding.TermsOfUseScreen)
- .assertIsDisplayed()
- }
-
- fun checkTermsOfUseAreNotDisplayed() {
- onNodeWithTag(TestTag.Onboarding.TermsOfUseScreen)
- .assertDoesNotExist()
- }
-
- fun checkNoPasswordErrorMessagePresent() {
- onNodeWithTag(TestTag.Onboarding.Credentials.PasswordStrengthCheck)
- .assertIsDisplayed()
- .assert(SemanticsMatcher.expectValue(SemanticsProperties.StateDescription, "sufficient"))
- }
-
- fun checkPasswordErrorMessagePresent() {
- onNodeWithTag(TestTag.Onboarding.Credentials.PasswordStrengthCheck)
- .assertIsDisplayed()
- .assert(SemanticsMatcher.expectValue(SemanticsProperties.StateDescription, "insufficient"))
- }
-
- fun checkContinueTutorialButtonIsEnabled() {
- onNodeWithTag(TestTag.Onboarding.NextButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- }
-
- fun checkContinueTutorialButtonIsDeactivated() {
- onNodeWithTag(TestTag.Onboarding.NextButton)
- .assertIsDisplayed()
- .assertIsNotEnabled()
- }
-
- fun checkDataTermsSwitchDeactivated() {
- onNodeWithTag(TestTag.Onboarding.DataTerms.AcceptDataTermsSwitch)
- .assertIsDisplayed()
- .assertIsToggleable()
- .assertIsOff()
- }
-
- fun checkWelcomePageIsPresent() {
- onNodeWithTag(TestTag.Onboarding.WelcomeScreen)
- .assertExists()
- }
-
- fun checkCredentialsPageIsPresent() {
- onNodeWithTag(TestTag.Onboarding.CredentialsScreen)
- .assertExists()
- }
-
- fun checkAnalyticsPageIsPresent() {
- onNodeWithTag(TestTag.Onboarding.AnalyticsScreen)
- .assertExists()
- }
-
- fun checkDataTermsPageIsPresent() {
- onNodeWithTag(TestTag.Onboarding.DataTermsScreen)
- .assertExists()
- }
-
- fun swipeToNextTutorialStep() {
- onNodeWithTag(TestTag.Onboarding.Pager)
- .assertIsDisplayed()
- .performTouchInput { swipeLeft() }
- }
-
- fun swipeToPreviousTutorialStep() {
- onNodeWithTag(TestTag.Onboarding.Pager)
- .assertIsDisplayed()
- .performTouchInput { swipeRight() }
- }
-
- fun checkContinueTutorialButtonIsDisabled() {
- onNodeWithTag(TestTag.Onboarding.NextButton)
- .assertIsDisplayed()
- .assertIsNotEnabled()
- }
-
- fun tapSkipOnboardingButton() {
- onNodeWithTag(TestTag.Onboarding.SkipOnboardingButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun checkAnalyticsSwitchIsDeactivated() {
- onNodeWithTag(TestTag.Onboarding.AnalyticsSwitch)
- .performScrollTo()
- .assertIsDisplayed()
- .assertIsToggleable()
- .assertIsOff()
- }
-
- fun checkAnalyticsSwitchIsActivated() {
- onNodeWithTag(TestTag.Onboarding.AnalyticsSwitch)
- .performScrollTo()
- .assertIsDisplayed()
- .assertIsToggleable()
- .assertIsOn()
- }
-
- fun toggleAnalyticsSwitch() {
- onNodeWithTag(TestTag.Onboarding.ScreenContent)
- .performTouchInput {
- swipeUp()
- }
-
- onNodeWithTag(TestTag.Onboarding.AnalyticsSwitch)
- .assertIsDisplayed()
- .assertIsToggleable()
- .performClick()
- }
-
- fun tapAcceptAnalyticsButton() {
- onNodeWithTag(TestTag.Onboarding.Analytics.AcceptAnalyticsButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OrderEgkScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OrderEgkScreen.kt
deleted file mode 100644
index 93d2429c..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/OrderEgkScreen.kt
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onAllNodesWithTag
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onNodeWithText
-import androidx.compose.ui.test.performClick
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class OrderEgkScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesOrderEgkScreenScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Settings.OrderEgk.OrderEgkScreen)
- }
-
- fun tapNFCExplanationPageLink() {
- onNodeWithTag(TestTag.Settings.OrderEgk.NFCExplanationPageLink)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun checkIfAtLeastFourInsurerIsVisible() {
- for (i in 0..3) {
- onAllNodesWithTag(TestTag.Settings.InsuranceCompanyList.ListOfInsuranceButtons)[i]
- .assertIsDisplayed()
- .assertHasClickAction()
- }
- }
-
- fun chooseInsurance(insurance: String) {
- onNodeWithText(insurance, substring = true)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun checkOrderPossibilities(orderPossibility: String) {
- when (orderPossibility) {
- "Keine Bestellmöglichkeit" -> {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.OrderEgkAndPinButton)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.OrderPinButton)
- .assertDoesNotExist()
- }
- "Karten & PIN, Nur PIN" -> {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.OrderPinButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.OrderEgkAndPinButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
- }
- }
-
- fun checkContactPossibilities(contactPossibility: String) {
- if (contactPossibility.contains("Telefon")) {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.TelephoneButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- }
- if (contactPossibility.contains("Webseite")) {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.WebsiteButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- }
- if (contactPossibility.contains("Mail")) {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.MailToButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- }
- if (contactPossibility.contains("Keine Kontaktmöglichkeit")) {
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.TelephoneButton)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.WebsiteButton)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.MailToButton)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Settings.ContactInsuranceCompany.NoContactInfoTextBox)
- .assertIsDisplayed()
- }
- }
-
- fun tapOrderCardAbort() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PharmacySearchScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PharmacySearchScreen.kt
deleted file mode 100644
index eeb4c67c..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PharmacySearchScreen.kt
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsFocused
-import androidx.compose.ui.test.assertIsNotSelected
-import androidx.compose.ui.test.assertIsSelected
-import androidx.compose.ui.test.filterToOne
-import androidx.compose.ui.test.hasAnyChild
-import androidx.compose.ui.test.hasAnyDescendant
-import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.hasText
-import androidx.compose.ui.test.isSelected
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onChildren
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performImeAction
-import androidx.compose.ui.test.performScrollToKey
-import androidx.compose.ui.test.performScrollToNode
-import androidx.compose.ui.test.performTextInput
-import de.gematik.ti.erp.app.PrescriptionIds
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.TestConfig.WaitTimeout1Sec
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-import de.gematik.ti.erp.app.test.test.core.hasPharmacyId
-import de.gematik.ti.erp.app.test.test.core.hasPrescriptionId
-import de.gematik.ti.erp.app.test.test.core.prescription.Prescription
-import de.gematik.ti.erp.app.test.test.core.sleep
-
-class PharmacySearchScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesPharmacyOverviewScreen() {
- onNodeWithTag(TestTag.PharmacySearch.OverviewScreen, useUnmergedTree = true)
- .assertIsDisplayed()
- }
-
- fun userClicksSearchButton() {
- onNodeWithTag(TestTag.PharmacySearch.TextSearchButton)
- .performClick()
- }
-
- fun userSeesPharmacySearchResultScreen() {
- onNodeWithTag(TestTag.PharmacySearch.ResultScreen)
- .assertIsDisplayed()
- }
-
- fun userSearchesForTestPharmacy() {
- onNodeWithTag(TestTag.PharmacySearch.TextSearchField)
- .performClick()
- .assertIsFocused()
- .performTextInput(TestConfig.PharmacyName)
-
- onNodeWithTag(TestTag.PharmacySearch.TextSearchField)
- .performImeAction()
- }
-
- fun awaitSearchResults() {
- composeRule.awaitDisplay(20_000L) {
- onNodeWithTag(TestTag.PharmacySearch.ResultContent)
- .assertIsDisplayed()
- .assert(hasAnyChild(hasTestTag(TestTag.PharmacySearch.PharmacyListEntry)))
- }
- composeRule.sleep(1_000L)
- }
-
- fun userClicksOnTestPharmacy() {
- onNodeWithTag(TestTag.PharmacySearch.ResultContent, useUnmergedTree = true)
- .assertIsDisplayed()
- .performScrollToNode(hasPharmacyId(TestConfig.PharmacyTelematikId))
- .onChildren()
- .filterToOne(hasPharmacyId(TestConfig.PharmacyTelematikId))
- .performClick()
- }
-
- fun userClicksOnPharmacyFromListByName(name: String) {
- composeRule.sleep(WaitTimeout1Sec)
- onNodeWithTag(TestTag.PharmacySearch.ResultContent, useUnmergedTree = true)
- .performScrollToNode(hasAnyDescendant(hasText(name)))
- .onChildren()
- .filterToOne(hasAnyDescendant(hasText(name)))
- .performClick()
- }
-
- fun userSeesPharmacyOrderOptions() {
- composeRule.sleep(WaitTimeout1Sec)
- onNodeWithTag(TestTag.PharmacySearch.OrderOptions.Content, useUnmergedTree = true)
- .assertExists()
- }
-
- fun awaitOrderOptionsEnabled() {
- composeRule.sleep(1_000L)
- }
-
- fun dismissOrderOptionsBottomSheet() {
- onNodeWithTag(TestTag.PharmacySearch.TextSearchField)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userClicksOnOrderByCourierDelivery() {
- onNodeWithTag(TestTag.PharmacySearch.OrderOptions.CourierDeliveryOptionButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .performClick()
- }
-
- fun userClicksOnOrderByPickUp() {
- onNodeWithTag(TestTag.PharmacySearch.OrderOptions.PickUpOptionButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .performClick()
- }
-
- fun checkToastMessageWhenOrderOptionClicked() {
- onNodeWithTag(TestTag.PharmacySearch.OrderOptions.ComposeToast, useUnmergedTree = true)
- .assertExists()
- }
-
- fun checkAndClickNoPrescriptionDialog() {
- onNodeWithTag(TestTag.AlertDialog.ConfirmButton).assertIsDisplayed().performClick()
- }
-
- fun userClicksOnOrderByMailDelivery() {
- onNodeWithTag(TestTag.PharmacySearch.OrderOptions.MailDeliveryOptionButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .performClick()
- }
-
- fun userSeesPharmacyOrderSummaryScreen() {
- onNodeWithTag(TestTag.PharmacySearch.OrderSummary.Screen)
- .assertIsDisplayed()
- }
-
- fun userSeesSendOrderButtonEnabled() {
- // asynchronous process enabling the button
- composeRule.awaitDisplay(1_000L) {
- onNodeWithTag(TestTag.PharmacySearch.OrderSummary.SendOrderButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- }
- }
-
- fun userClicksPrescriptionSelection() {
- onNodeWithTag(TestTag.PharmacySearch.OrderSummary.PrescriptionSelectionButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userSeesPrescriptionSelectionScreen() {
- onNodeWithTag(TestTag.PharmacySearch.OrderPrescriptionSelection.Screen)
- .assertIsDisplayed()
- }
-
- fun userDeselectsAllPrescriptions() {
- val prescriptionIds = onNodeWithTag(TestTag.PharmacySearch.OrderPrescriptionSelection.Content)
- .fetchSemanticsNode()
- .config[PrescriptionIds]!!
-
- prescriptionIds.forEach {
- onNodeWithTag(TestTag.PharmacySearch.OrderPrescriptionSelection.Content)
- .performScrollToKey("prescription-$it")
- .onChildren()
- .filterToOne(hasPrescriptionId(it).and(isSelected()))
- .performClick()
- }
- }
-
- fun userSelectsPrescription(prescription: Prescription) {
- onNodeWithTag(TestTag.PharmacySearch.OrderPrescriptionSelection.Content)
- .assertIsDisplayed()
- .performScrollToKey("prescription-${prescription.taskId}")
- .onChildren()
- .filterToOne(hasPrescriptionId(prescription.taskId))
- .assertIsNotSelected()
- .assertIsDisplayed()
- .performClick()
- .assertIsSelected()
- }
-
- fun userClicksBack() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userClicksSendOrderButton() {
- onNodeWithTag(TestTag.PharmacySearch.OrderSummary.SendOrderButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .performClick()
- }
-
- fun openOrderOptionsByPharmacyName(name: String) {
- userSeesPharmacyOverviewScreen()
- userClicksSearchButton()
- awaitSearchResults()
- userClicksOnPharmacyFromListByName(name)
- userSeesPharmacyOrderOptions()
- awaitOrderOptionsEnabled()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionOrderScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionOrderScreen.kt
deleted file mode 100644
index 808f016b..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionOrderScreen.kt
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import android.app.Activity
-import android.app.Instrumentation
-import android.content.Intent
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertTextContains
-import androidx.compose.ui.test.filter
-import androidx.compose.ui.test.filterToOne
-import androidx.compose.ui.test.hasAnyChild
-import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onChildren
-import androidx.compose.ui.test.onFirst
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollToKey
-import androidx.compose.ui.test.performTouchInput
-import androidx.compose.ui.test.swipeDown
-import androidx.test.espresso.intent.Intents
-import androidx.test.espresso.intent.matcher.IntentMatchers
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.core.await
-import de.gematik.ti.erp.app.test.test.core.hasPrescriptionId
-import de.gematik.ti.erp.app.test.test.core.prescription.CommunicationPayloadInbox
-import de.gematik.ti.erp.app.test.test.core.prescription.Prescription
-import de.gematik.ti.erp.app.test.test.core.sleep
-
-class PrescriptionOrderScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesOrderScreen() {
- onNodeWithTag(TestTag.Orders.Content)
- .assertIsDisplayed()
- }
-
- fun awaitOrders() {
- composeRule.await(20_000L) {
- onNodeWithTag(TestTag.Orders.Content)
- .assertIsDisplayed()
- .assert(hasAnyChild(hasTestTag(TestTag.Orders.OrderListItem)))
- }
- composeRule.sleep(2500L)
- }
-
- fun userClicksNewestOrder() {
- onNodeWithTag(TestTag.Orders.Content)
- .assertIsDisplayed()
- .onChildren()
- .filter(hasTestTag(TestTag.Orders.OrderListItem))
- .onFirst()
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userSeesOrderDetailsScreen() {
- onNodeWithTag(TestTag.Orders.Details.Screen)
- .assertIsDisplayed()
- }
-
- fun userSeesOnePrescription(prescription: Prescription) {
- onNodeWithTag(TestTag.Orders.Details.Content)
- .assertIsDisplayed()
- .performScrollToKey("prescriptions")
- .onChildren()
- .filterToOne(hasPrescriptionId(prescription.taskId))
- .assertIsDisplayed()
- }
-
- fun userSeesAndClicksMessage() {
- onNodeWithTag(TestTag.Orders.Details.Content)
- .assertIsDisplayed()
- .performScrollToKey("prescriptions")
- .onChildren()
- .filterToOne(hasTestTag(TestTag.Orders.Details.MessageListItem))
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userExpectsMessageContent(message: CommunicationPayloadInbox) {
- onNodeWithTag(TestTag.Orders.Messages.Content)
- .assertIsDisplayed()
-
- message.infoText?.let {
- onNodeWithTag(TestTag.Orders.Messages.Text)
- .assertIsDisplayed()
- .assertTextContains(message.infoText)
- }
- ?: onNodeWithTag(TestTag.Orders.Messages.Text).assertDoesNotExist()
-
- message.url?.let {
- onNodeWithTag(TestTag.Orders.Messages.Link)
- .assertIsDisplayed()
-
- onNodeWithTag(TestTag.Orders.Messages.LinkButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .assertHasClickAction()
- }
- ?: onNodeWithTag(TestTag.Orders.Messages.Link).assertDoesNotExist()
-
- if (message.pickUpCodeHR != null || message.pickUpCodeDMC != null) {
- onNodeWithTag(TestTag.Orders.Messages.Code)
- .assertIsDisplayed()
-
- if (message.pickUpCodeDMC != null) {
- onNodeWithTag(TestTag.Orders.Messages.CodeLabelContent)
- .assertTextContains(message.pickUpCodeDMC, substring = true)
- } else if (message.pickUpCodeHR != null) {
- onNodeWithTag(TestTag.Orders.Messages.CodeLabelContent)
- .assertTextContains(message.pickUpCodeHR, substring = true)
- }
- } else {
- onNodeWithTag(TestTag.Orders.Messages.Code).assertDoesNotExist()
- }
- }
-
- fun userClicksMessageLink(message: CommunicationPayloadInbox) {
- Intents.intending(IntentMatchers.hasData(message.url))
- .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, Intent()))
-
- onNodeWithTag(TestTag.Orders.Messages.LinkButton)
- .assertIsDisplayed()
- .assertIsEnabled()
- .assertHasClickAction()
- .performClick()
-
- Intents.intended(IntentMatchers.hasData(message.url))
- }
-
- fun userClosesMessageSheetBySwipe() {
- onNodeWithTag(TestTag.Orders.Details.Content)
- .performTouchInput {
- swipeDown()
- }
- }
-
- fun userClicksPrescription(prescription: Prescription) {
- onNodeWithTag(TestTag.Orders.Details.Content)
- .assertIsDisplayed()
- .performScrollToKey("prescriptions")
- .onChildren()
- .filterToOne(hasPrescriptionId(prescription.taskId))
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userClicksBack() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionsScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionsScreen.kt
deleted file mode 100644
index a45304bf..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/PrescriptionsScreen.kt
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import android.util.Log
-import androidx.compose.ui.semantics.SemanticsProperties
-import androidx.compose.ui.test.SemanticsNodeInteraction
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertTextContains
-import androidx.compose.ui.test.filter
-import androidx.compose.ui.test.filterToOne
-import androidx.compose.ui.test.hasAnyChild
-import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onChildren
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollToIndex
-import androidx.compose.ui.test.performScrollToKey
-import androidx.compose.ui.test.performScrollToNode
-import androidx.compose.ui.test.performTouchInput
-import androidx.compose.ui.test.swipeDown
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.assertHasText
-import de.gematik.ti.erp.app.test.test.core.await
-import de.gematik.ti.erp.app.test.test.core.hasInsuranceState
-import de.gematik.ti.erp.app.test.test.core.hasMedicationCategory
-import de.gematik.ti.erp.app.test.test.core.hasPrescriptionId
-import de.gematik.ti.erp.app.test.test.core.hasSubstitutionAllowed
-import de.gematik.ti.erp.app.test.test.core.hasSupplyForm
-import de.gematik.ti.erp.app.test.test.core.prescription.Prescription
-import de.gematik.ti.erp.app.test.test.core.sleep
-import org.junit.Assert.assertTrue
-
-@Suppress("UnusedPrivateMember")
-class PrescriptionsScreen(private val composeRule: ComposeTestRule) : SemanticsNodeInteractionsProvider by composeRule {
- enum class PrescriptionState {
- Redeemable, // ready
- WaitForResponse, // artificial state
- InProgress, // inProgress
- Redeemed
- }
-
- fun userClicksBack() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userClicksClose() {
- onNodeWithTag(TestTag.TopNavigation.CloseButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun awaitPrescriptions() {
- composeRule.await(TestConfig.LoadPrescriptionsTimeout) {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .assertIsDisplayed()
- .assert(hasAnyChild(hasTestTag(TestTag.Prescriptions.FullDetailPrescription)))
- }
- composeRule.sleep(2500L)
- }
-
- fun awaitArchivedPrescriptions() {
- composeRule.await(TestConfig.LoadPrescriptionsTimeout) {
- onNodeWithTag(TestTag.Prescriptions.Archive.Content)
- .assertIsDisplayed()
- .assert(hasAnyChild(hasTestTag(TestTag.Prescriptions.FullDetailPrescription)))
- }
- composeRule.sleep(2500L)
- }
-
- fun awaitPrescriptionScreen() {
- composeRule.await(TestConfig.ScreenChangeTimeout) {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .assertIsDisplayed()
- }
- }
-
- fun refreshPrescriptions() {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .performScrollToIndex(0)
- .performTouchInput {
- swipeDown()
- }
- composeRule.sleep(2500L)
- }
-
- fun userSeesPZNPrescription(
- data: Prescription,
- inState: PrescriptionState = PrescriptionState.Redeemable
- ) {
- val prescriptionNode = onNodeWithTag(TestTag.Prescriptions.Content, useUnmergedTree = true)
- .assertIsDisplayed()
- .performScrollToKey("prescription-${data.taskId}")
- .onChildren()
- .filterToOne(hasPrescriptionId(data.taskId))
- .onChildren()
-
- prescriptionNode
- .filterToOne(hasTestTag(TestTag.Prescriptions.FullDetailPrescriptionName))
- .assertTextContains(data.medication?.name ?: "")
-
- val expectedTestTag = when (inState) {
- PrescriptionState.Redeemable -> TestTag.Prescriptions.PrescriptionRedeemable
- PrescriptionState.WaitForResponse -> TestTag.Prescriptions.PrescriptionWaitForResponse
- PrescriptionState.InProgress -> TestTag.Prescriptions.PrescriptionInProgress
- PrescriptionState.Redeemed -> TestTag.Prescriptions.PrescriptionRedeemed
- }
- prescriptionNode
- .filterToOne(hasTestTag(expectedTestTag))
- .assertIsDisplayed()
- }
-
- fun userSeesPrescriptionInArchive(
- data: Prescription,
- inState: PrescriptionState = PrescriptionState.Redeemable
- ) {
- val prescriptionNode = onNodeWithTag(TestTag.Prescriptions.Archive.Content, useUnmergedTree = true)
- .assertIsDisplayed()
- .performScrollToKey("prescription-${data.taskId}")
- .onChildren()
- .filterToOne(hasPrescriptionId(data.taskId))
- .onChildren()
-
- prescriptionNode
- .filterToOne(hasTestTag(TestTag.Prescriptions.FullDetailPrescriptionName))
- .assertTextContains(data.medication?.name ?: "")
-
- val expectedTestTag = when (inState) {
- PrescriptionState.Redeemable -> TestTag.Prescriptions.PrescriptionRedeemable
- PrescriptionState.WaitForResponse -> TestTag.Prescriptions.PrescriptionWaitForResponse
- PrescriptionState.InProgress -> TestTag.Prescriptions.PrescriptionInProgress
- PrescriptionState.Redeemed -> TestTag.Prescriptions.PrescriptionRedeemed
- }
- prescriptionNode
- .filterToOne(hasTestTag(expectedTestTag))
- .assertIsDisplayed()
- }
-
- fun clickOnPrescription(data: Prescription) {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .assertIsDisplayed()
- .performScrollToKey("prescription-${data.taskId}")
- .onChildren()
- .filterToOne(hasPrescriptionId(data.taskId))
- .performClick()
- }
-
- fun userSeesPrescriptionDetails() {
- composeRule.await(TestConfig.ScreenChangeTimeout) {
- onNodeWithTag(TestTag.Prescriptions.Details.Screen)
- .assertIsDisplayed()
- }
- }
-
- fun userClicksMoreButton() {
- onNodeWithTag(TestTag.Prescriptions.Details.MoreButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userClicksDeleteButton() {
- onNodeWithTag(TestTag.Prescriptions.Details.DeleteButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userSeesConfirmDeleteDialog() {
- onNodeWithTag(TestTag.AlertDialog.Modal, useUnmergedTree = true)
- .assertIsDisplayed()
- }
-
- fun userConfirmsDeletion() {
- onNodeWithTag(TestTag.AlertDialog.ConfirmButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun userMissesPrescription(data: Prescription) {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .assertIsDisplayed()
- .onChildren()
- .filter(hasPrescriptionId(data.taskId))
- .assertCountEquals(0)
- }
-
- fun userClicksArchiveButton() {
- onNodeWithTag(TestTag.Prescriptions.Content)
- .performScrollToNode(hasTestTag(TestTag.Prescriptions.ArchiveButton))
-
- onNodeWithTag(TestTag.Prescriptions.ArchiveButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun userSeesPrescriptionSortedBy(prescriptions: List) {
- val node = onNodeWithTag(TestTag.Prescriptions.Content)
- .fetchSemanticsNode()
- val config = node.config[SemanticsProperties.IndexForKey]
-
- val all = prescriptions.map { prescription ->
- val index = config.invoke("prescription-${prescription.taskId}")
- "$index - ${prescription.taskId} - ${prescription.authoredOn}"
- }.joinToString("\n")
-
- prescriptions.fold(-1) { previousIndex, prescription ->
- val index = config.invoke("prescription-${prescription.taskId}")
- val msg = "Index should match: $index > $previousIndex for ${prescription.taskId}\n$all"
- assertTrue(msg, index > previousIndex)
- index
- }
- }
-
- //
-
- private fun onDetailsNode(testTag: String, contentTestTag: String) =
- onNodeWithTag(contentTestTag)
- .assertIsDisplayed()
- .performScrollToNode(hasTestTag(testTag))
- .onChildren()
- .filterToOne(hasTestTag(testTag))
-
- private fun assertWith(
- testTag: String,
- contentTestTag: String,
- with: SemanticsNodeInteraction.() -> Unit
- ) {
- onDetailsNode(testTag, contentTestTag).with()
- }
-
- private fun assertText(testTag: String, contentTestTag: String, vararg data: String?) {
- val node = onDetailsNode(testTag, contentTestTag).assertHasText(includeEditableText = false)
- val dataFiltered = data.filterNotNull()
- Log.d("assertText", "Assert hasText: ${dataFiltered.joinToString(" and ") { "[$it]" }} on $testTag")
-
- dataFiltered.forEach {
- node
- .assertTextContains(it, substring = true, ignoreCase = true)
- }
- }
-
- private fun assertDetailsText(testTag: String, vararg data: String?) =
- assertText(testTag = testTag, contentTestTag = TestTag.Prescriptions.Details.Content, *data)
-
- fun userExpectsPrescriptionData(data: Prescription) {
- assertDetailsText(TestTag.Prescriptions.Details.MedicationButton, data.medication?.name)
- assertDetailsText(TestTag.Prescriptions.Details.PatientButton, data.patient?.firstName, data.patient?.lastName)
- assertDetailsText(TestTag.Prescriptions.Details.PrescriberButton, data.practitioner?.name)
- }
-
- // technical details
-
- fun userClicksOnTechnicalDetails() {
- onDetailsNode(TestTag.Prescriptions.Details.TechnicalInformationButton, TestTag.Prescriptions.Details.Content)
- .assertHasClickAction()
- .performClick()
- }
-
- fun userSeesTechnicalDetailsScreen() {
- onNodeWithTag(TestTag.Prescriptions.Details.TechnicalInformation.Screen)
- .assertIsDisplayed()
- }
-
- private fun assertTechnicalText(testTag: String, vararg data: String?) =
- assertText(
- testTag = testTag,
- contentTestTag = TestTag.Prescriptions.Details.TechnicalInformation.Content,
- *data
- )
-
- fun userExpectsTechnicalInformationData(data: Prescription) {
- assertTechnicalText(TestTag.Prescriptions.Details.TechnicalInformation.TaskId, data.taskId)
- assertTechnicalText(TestTag.Prescriptions.Details.TechnicalInformation.AccessCode, data.accessCode)
- }
-
- // patient
-
- fun userClicksOnPatientDetails() {
- onDetailsNode(TestTag.Prescriptions.Details.PatientButton, TestTag.Prescriptions.Details.Content)
- .assertHasClickAction()
- .performClick()
- }
-
- fun userSeesPatientDetailsScreen() {
- onNodeWithTag(TestTag.Prescriptions.Details.Patient.Screen)
- .assertIsDisplayed()
- }
-
- private fun assertPatientText(testTag: String, vararg data: String?) =
- assertText(
- testTag = testTag,
- contentTestTag = TestTag.Prescriptions.Details.Patient.Content,
- *data
- )
-
- fun userExpectsPatientDetailsData(data: Prescription) {
- assertPatientText(TestTag.Prescriptions.Details.Patient.KVNR, data.patient?.kvnr)
- assertPatientText(TestTag.Prescriptions.Details.Patient.BirthDate, data.patient?.birthDate)
- assertPatientText(TestTag.Prescriptions.Details.Patient.Name, data.patient?.firstName, data.patient?.lastName)
- assertPatientText(TestTag.Prescriptions.Details.Patient.InsuranceName, data.coverage?.insuranceName)
- assertPatientText(
- TestTag.Prescriptions.Details.Patient.Address,
- data.patient?.city,
- data.patient?.postal,
- data.patient?.street
- )
- assertWith(
- testTag = TestTag.Prescriptions.Details.Patient.InsuranceState,
- contentTestTag = TestTag.Prescriptions.Details.Patient.Content,
- with = {
- data.coverage?.insuranceState?.let {
- assert(hasInsuranceState(it))
- }
- }
- )
- }
-
- // organization
-
- fun userClicksOnOrganizationDetails() {
- onDetailsNode(TestTag.Prescriptions.Details.OrganizationButton, TestTag.Prescriptions.Details.Content)
- .assertHasClickAction()
- .performClick()
- }
-
- fun userSeesOrganizationDetailsScreen() {
- onNodeWithTag(TestTag.Prescriptions.Details.Organization.Screen)
- .assertIsDisplayed()
- }
-
- private fun assertOrganizationText(testTag: String, vararg data: String?) =
- assertText(
- testTag = testTag,
- contentTestTag = TestTag.Prescriptions.Details.Organization.Content,
- *data
- )
-
- fun userExpectsOrganizationDetailsData(data: Prescription) {
- assertOrganizationText(TestTag.Prescriptions.Details.Organization.Name, data.practitioner?.officeName)
- assertOrganizationText(
- TestTag.Prescriptions.Details.Organization.Address,
- data.practitioner?.city,
- data.practitioner?.postal,
- data.practitioner?.street
- )
- assertOrganizationText(TestTag.Prescriptions.Details.Organization.BSNR, data.practitioner?.bsnr)
- assertOrganizationText(TestTag.Prescriptions.Details.Organization.Phone, data.practitioner?.phone)
- assertOrganizationText(TestTag.Prescriptions.Details.Organization.EMail, data.practitioner?.email)
- }
-
- // medication
-
- fun userClicksOnMedicationDetails() {
- onDetailsNode(TestTag.Prescriptions.Details.MedicationButton, TestTag.Prescriptions.Details.Content)
- .assertHasClickAction()
- .performClick()
- }
-
- fun userSeesMedicationDetailsScreen() {
- onNodeWithTag(TestTag.Prescriptions.Details.Medication.Screen)
- .assertIsDisplayed()
- }
-
- private fun assertMedicationText(testTag: String, vararg data: String?) =
- assertText(
- testTag = testTag,
- contentTestTag = TestTag.Prescriptions.Details.Medication.Content,
- *data
- )
-
- fun userExpectsMedicationDetailsData(data: Prescription) {
- assertMedicationText(TestTag.Prescriptions.Details.Medication.Name, data.medication?.name)
- assertMedicationText(TestTag.Prescriptions.Details.Medication.Amount, data.medication?.amount.toString())
- assertMedicationText(TestTag.Prescriptions.Details.Medication.PZN, data.medication?.pzn.toString())
- assertMedicationText(TestTag.Prescriptions.Details.Medication.DosageInstruction, data.medication?.dosage)
- assertWith(
- testTag = TestTag.Prescriptions.Details.Medication.SubstitutionAllowed,
- contentTestTag = TestTag.Prescriptions.Details.Medication.Content,
- with = {
- data.medication?.substitutionAllowed?.let {
- assert(hasSubstitutionAllowed(it))
- }
- }
- )
- assertWith(
- testTag = TestTag.Prescriptions.Details.Medication.SupplyForm,
- contentTestTag = TestTag.Prescriptions.Details.Medication.Content,
- with = {
- data.medication?.supplyForm?.let {
- assert(hasSupplyForm(it))
- }
- }
- )
- assertWith(
- testTag = TestTag.Prescriptions.Details.Medication.Category,
- contentTestTag = TestTag.Prescriptions.Details.Medication.Content,
- with = {
- data.medication?.category?.let {
- assert(hasMedicationCategory(it))
- }
- }
- )
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileSettingsScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileSettingsScreen.kt
deleted file mode 100644
index 84eea35d..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileSettingsScreen.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.hasText
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onNodeWithText
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollToNode
-import androidx.compose.ui.test.performTextReplacement
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class ProfileSettingsScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesProfileSettingsScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Profile.ProfileScreen)
- }
- fun userSeesDeleteProfileAlert(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.AlertDialog.Modal)
- }
-
- fun tapDisplayTokensButton() {
- onNodeWithTag(TestTag.Profile.ProfileScreenContent)
- .performScrollToNode(hasTestTag(TestTag.Profile.OpenTokensScreenButton))
- onNodeWithTag(TestTag.Profile.OpenTokensScreenButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun checkKVNRNotVisible() {
- onNodeWithTag(TestTag.Profile.InsuranceId)
- .assertDoesNotExist()
- }
-
- fun checkKVNRIsVisible() {
- onNodeWithTag(TestTag.Profile.InsuranceId)
- .assertIsDisplayed()
- .assert(!hasText(""))
- }
-
- fun tapLoginButton() {
- onNodeWithTag(TestTag.Profile.LoginButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun assertHintTextNotPresent() {
- onNodeWithTag(TestTag.Profile.TokenList.NoTokenInfo)
- .assertDoesNotExist()
- }
-
- fun tapThreeDotsMenuButton() {
- onNodeWithTag(TestTag.Profile.ThreeDotMenuButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapAuditEventsButton() {
- onNodeWithTag(TestTag.Profile.ProfileScreenContent)
- .performScrollToNode(hasTestTag(TestTag.Profile.OpenAuditEventsScreenButton))
- onNodeWithTag(TestTag.Profile.OpenAuditEventsScreenButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapLogoutButton() {
- onNodeWithTag(TestTag.Profile.LogoutButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun closeProfileSettings() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .performClick()
- }
-
- fun tapDeleteProfile() {
- onNodeWithTag(TestTag.Profile.DeleteProfileButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapConfirmDeleteProfile() {
- onNodeWithTag(TestTag.AlertDialog.ConfirmButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapAbortDeleteButton() {
- onNodeWithTag(TestTag.AlertDialog.CancelButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapEditProfileNameButton() {
- onNodeWithTag(TestTag.Profile.EditProfileNameButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun enterNewProfileName(newProfileName: String) {
- onNodeWithTag(TestTag.Profile.NewProfileNameField)
- .assertIsDisplayed()
- .performClick()
- .performTextReplacement(newProfileName)
- }
-
- fun assertErrorMessageEmptyProfileName(errorMessage: String) {
- onNodeWithText(errorMessage)
- .assertIsDisplayed()
- }
-
- fun tapEditProfileIconButton() {
- onNodeWithTag(TestTag.Profile.EditProfileImageButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun changeProfilePictureColor(color: String) {
- val colorToTestTag = mapOf(
- "grau" to TestTag.Profile.EditProfileIcon.ColorSelectorSpringGrayButton,
- "gelb" to TestTag.Profile.EditProfileIcon.ColorSelectorSunDewButton,
- "rosa" to TestTag.Profile.EditProfileIcon.ColorSelectorPinkButton,
- "grün" to TestTag.Profile.EditProfileIcon.ColorSelectorTreeButton,
- "blau" to TestTag.Profile.EditProfileIcon.ColorSelectorBlueMoonButton
- )
-
- val testTag = colorToTestTag[color.lowercase()]
-
- testTag?.let {
- onNodeWithTag(testTag)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
- }
-
- fun tapBackToSettingsButton() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileTokenListScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileTokenListScreen.kt
deleted file mode 100644
index 29303154..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/ProfileTokenListScreen.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertTextContains
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performClick
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.assertHasText
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-
-class ProfileTokenListScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesProfileTokenListScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Profile.TokenList.TokenScreen)
- }
-
- fun checkTokensDoNotExist() {
- onNodeWithTag(TestTag.Profile.TokenList.AccessToken)
- .assertDoesNotExist()
- onNodeWithTag(TestTag.Profile.TokenList.SSOToken)
- .assertDoesNotExist()
- }
-
- fun checkAccessTokenPresent() {
- onNodeWithTag(TestTag.Profile.TokenList.AccessToken)
- .assertIsDisplayed()
- .assertHasText()
- }
-
- fun checkSSOTokenPresent() {
- onNodeWithTag(TestTag.Profile.TokenList.SSOToken)
- .assertIsDisplayed()
- .assertHasText()
- }
-
- fun assertHeaderTextNotEmpty() {
- onNodeWithTag(TestTag.Profile.TokenList.NoTokenHeader)
- .assertIsDisplayed()
- .assertHasText()
- }
-
- fun assertInfoTextNotEmpty() {
- onNodeWithTag(TestTag.Profile.TokenList.NoTokenInfo)
- .assertIsDisplayed()
- .assertHasText()
- }
-
- fun assertInfoTextPresent(text: String) {
- onNodeWithTag(TestTag.Profile.TokenList.NoTokenInfo)
- .assertIsDisplayed()
- .assertTextContains(text, substring = true)
- }
-
- fun closeTokenList() {
- onNodeWithTag(TestTag.TopNavigation.BackButton)
- .assertIsDisplayed()
- .performClick()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/SettingsScreen.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/SettingsScreen.kt
deleted file mode 100644
index 5dce5557..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/screens/SettingsScreen.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.screens
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.compose.ui.test.onAllNodesWithTag
-import androidx.compose.ui.test.onAllNodesWithText
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onNodeWithText
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextInput
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-import junit.framework.TestCase.assertTrue
-
-class SettingsScreen(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- fun userSeesSettingsScreen(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Settings.SettingsScreen)
- }
- fun userSeesCreateNewProfileAlert(timeoutMillis: Long = TestConfig.ScreenChangeTimeout) {
- composeRule.awaitDisplay(timeoutMillis, TestTag.Settings.AddProfileDialog.Modal)
- }
-
- private val profileSettingsScreen by lazy { ProfileSettingsScreen(composeRule) }
-
- fun goToFirstProfileDetails() {
- goToProfileDetails(0)
- }
-
- fun goToProfileDetails(index: Int) {
- tapProfileDetailsButton(index)
- profileSettingsScreen.userSeesProfileSettingsScreen()
- }
-
- fun assertAmountOfProfiles(numberOfProfiles: Int) {
- assertTrue(
- onAllNodesWithTag(TestTag.Settings.ProfileButton)
- .fetchSemanticsNodes().size == numberOfProfiles
- )
- }
-
- fun tapDebugMenuButton() {
- onNodeWithTag(TestTag.Settings.DebugMenuButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun enterProfileName(name: String) {
- onNodeWithTag(TestTag.Settings.AddProfileDialog.ProfileNameTextField)
- .assertIsDisplayed()
- .performClick()
- .performTextInput(name)
- }
-
- fun tapNewProfileConfirmButton() {
- onNodeWithTag(TestTag.Settings.AddProfileDialog.ConfirmButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapReturnToPrescriptionScreen() {
- onNodeWithTag(TestTag.BottomNavigation.PrescriptionButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapOrderEgk() {
- onNodeWithTag(TestTag.Settings.OrderNewCardButton)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapProfileWithName(profileName: String) {
- onNodeWithText(profileName)
- .assertIsDisplayed()
- .assertHasClickAction()
- .performClick()
- }
-
- fun tapProfileDetailsButton(profileNumber: Int) {
- onAllNodesWithTag(TestTag.Settings.ProfileButton)[profileNumber]
- .assertIsDisplayed()
- .performClick()
- }
-
- fun checkAmountOfProfilesWithNames(numberOfProfiles: Int, profileNames: String) {
- assert(onAllNodesWithText(profileNames).fetchSemanticsNodes().size == numberOfProfiles)
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/CardWallScreenSteps.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/CardWallScreenSteps.kt
deleted file mode 100644
index 0c910023..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/CardWallScreenSteps.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.steps
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import androidx.test.platform.app.InstrumentationRegistry
-import de.gematik.ti.erp.app.test.test.VirtualEgk1
-import de.gematik.ti.erp.app.test.test.VirtualEgkWithPrescription
-import de.gematik.ti.erp.app.test.test.screens.CardWallScreen
-import de.gematik.ti.erp.app.test.test.screens.DebugMenuScreen
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.SettingsScreen
-
-class CardWallScreenSteps(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- private val mainScreen by lazy { MainScreen(composeRule) }
- private val cardWallScreen by lazy { CardWallScreen(composeRule) }
- private val settingsScreen by lazy { SettingsScreen(composeRule) }
- private val debugMenuScreen by lazy { DebugMenuScreen(composeRule) }
-
- fun userStartsAndFinishsTheCardwallSuccessfully() {
- InstrumentationRegistry.getInstrumentation().uiAutomation.executeShellCommand("svc nfc enable")
-
- mainScreen.userSeesMainScreen()
- mainScreen.refreshMainScreenBySwipe()
- mainScreen.tapLoginButton()
-
- cardWallScreen.continueWithEGK()
- cardWallScreen.enterCAN()
- cardWallScreen.enterPin()
- cardWallScreen.dontSaveCredentials()
- cardWallScreen.userSeesNfcScreen()
-
- InstrumentationRegistry.getInstrumentation().uiAutomation.executeShellCommand("svc nfc disable")
- Thread.sleep(2000)
- InstrumentationRegistry.getInstrumentation().uiAutomation.executeShellCommand("svc nfc enable")
-
- mainScreen.userSeesMainScreen(15000)
- }
-
- fun userStartsAndFinishsTheCardwallWithVirtualCardSuccessfully() {
- mainScreen.userSeesMainScreen()
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapDebugMenuButton()
- debugMenuScreen.userSeesDebugMenuScreen()
- debugMenuScreen.tapSetVirtualCard()
- debugMenuScreen.closeDebugMenu()
- settingsScreen.tapReturnToPrescriptionScreen()
- mainScreen.userSeesMainScreen()
- }
-
- fun fakeNFCCapabilities() {
- mainScreen.userSeesMainScreen()
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapDebugMenuButton()
- debugMenuScreen.userSeesDebugMenuScreen()
- debugMenuScreen.tapFakeNFCCapabilitiesSwitch()
- debugMenuScreen.closeDebugMenu()
- settingsScreen.tapReturnToPrescriptionScreen()
- mainScreen.userSeesMainScreen()
- }
-
- fun setCustomEgk() {
- // only for demonstration purposes
- mainScreen.userSeesMainScreen()
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapDebugMenuButton()
- debugMenuScreen.userSeesDebugMenuScreen()
- debugMenuScreen.fillCustomCertificateAndPrivateKey(VirtualEgk1)
- debugMenuScreen.tapSetVirtualCard()
- debugMenuScreen.closeDebugMenu()
- settingsScreen.tapReturnToPrescriptionScreen()
- mainScreen.userSeesMainScreen()
- }
-
- fun setVirtualEGKWithPrescriptions() {
- // only for demonstration purposes
- mainScreen.userSeesMainScreen()
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapDebugMenuButton()
- debugMenuScreen.userSeesDebugMenuScreen()
- debugMenuScreen.fillCustomCertificateAndPrivateKey(VirtualEgkWithPrescription)
- debugMenuScreen.tapSetVirtualCard()
- debugMenuScreen.closeDebugMenu()
- settingsScreen.tapReturnToPrescriptionScreen()
- mainScreen.userSeesMainScreen()
- }
-
- fun userClicksOrderHealthCardFromCardWallIntroScreen() {
- cardWallScreen.userSeesIntroScreen()
- cardWallScreen.tapOrderEgkFromIntroScreen()
- }
-
- fun userClicksOrderHealthCardFromCardWallCANScreen() {
- cardWallScreen.userSeesIntroScreen()
- cardWallScreen.continueWithEGK()
- cardWallScreen.userSeesCANScreen()
- cardWallScreen.tapOrderEgkFromCANScreen()
- }
-
- fun userClicksOrderHealthCardFromCardWallPinScreen() {
- cardWallScreen.userSeesIntroScreen()
- cardWallScreen.continueWithEGK()
- cardWallScreen.userSeesCANScreen()
- cardWallScreen.enterCAN()
- cardWallScreen.userSeesPinScreen()
- cardWallScreen.tapOrderEgkFromPinScreen()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/MainScreenSteps.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/MainScreenSteps.kt
deleted file mode 100644
index cad1658c..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/MainScreenSteps.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.steps
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-
-class MainScreenSteps(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- private val mainScreen by lazy { MainScreen(composeRule) }
-
- fun userTapsSettingsMenuButton() {
- mainScreen.tapSettingsButton()
- }
-
- fun createNewProfile(profileName: String) {
- userTapsAddProfileButton()
- mainScreen.enterProfileName(profileName)
- if ("" != profileName) {
- mainScreen.tapNewProfileConfirmButton()
- mainScreen.userSeesMainScreen()
- }
- }
-
- fun userTapsAddProfileButton() {
- mainScreen.tapAddProfileButton()
- mainScreen.userSeesBottomSheet()
- }
-
- fun userTapsAbort() {
- mainScreen.userSeesBottomSheet()
- mainScreen.tapCancelAddProfileButton()
- mainScreen.userClicksBottomBarPrescriptions()
- }
-
- fun userCantConfirmCreation() {
- mainScreen.userSeesBottomSheet()
- mainScreen.assertConfirmationCanNotBeClicked()
- }
-
- fun userTapsConnect() {
- mainScreen.tapLoginButton()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/OnboardingSteps.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/OnboardingSteps.kt
deleted file mode 100644
index fabb05a8..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/OnboardingSteps.kt
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.steps
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.sleep
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.OnboardingScreen
-
-class OnboardingSteps(
- private val composeRule: ComposeTestRule
-) : SemanticsNodeInteractionsProvider by composeRule {
-
- private val onboardingScreen by lazy { OnboardingScreen(composeRule) }
- private val mainScreen by lazy { MainScreen(composeRule) }
-
- enum class Page {
- DataTerms, Credentials, Analytics, MainScreen
- }
-
- fun userSeesMainScreen() {
- mainScreen.userSeesMainScreen()
- }
-
- fun userIsNotSeeingTheOnboarding() {
- onboardingScreen.checkTutorialIsNotPresent()
- }
-
- fun userIsFinishingTheOnboardingWithoutAnalytics() {
- userNavigatesToOnboardingScreenName(Page.MainScreen)
- }
-
- fun userIsFinishingTheOnboardingWithAnalytics() {
- userNavigatesToOnboardingScreenName(Page.Analytics)
- onboardingScreen.toggleAnalyticsSwitch()
- onboardingScreen.waitForAnalyticsPage()
- onboardingScreen.tapAcceptAnalyticsButton()
- onboardingScreen.checkAnalyticsSwitchIsActivated()
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
- onboardingScreen.tapContinueButton()
- mainScreen.userSeesMainScreen()
- }
-
- fun userSkipsOnboarding() {
- onboardingScreen.tapSkipOnboardingButton()
- mainScreen.tapConnectLater()
- mainScreen.userSeesMainScreen()
- tapToGetRidOfTour()
- }
-
- fun tapToGetRidOfTour() {
- mainScreen.userClicksBottomBarPrescriptions()
- mainScreen.userClicksBottomBarPrescriptions()
- mainScreen.userClicksBottomBarPrescriptions()
- mainScreen.userClicksBottomBarPrescriptions()
- mainScreen.userClicksBottomBarPrescriptions()
- composeRule.sleep(2000L)
- }
-
- fun userSeesWelcomeScreen() {
- onboardingScreen.checkWelcomePageIsPresent()
- }
-
- fun userNavigatesToOnboardingScreenName(page: Page) {
- when (page) {
- // go to Data Terms Screen
- Page.DataTerms -> {
- onboardingScreen.waitForSecondOnboardingPage()
- onboardingScreen.checkDataTermsPageIsPresent()
- }
- Page.Credentials -> { // go to Password Screen
- onboardingScreen.waitForSecondOnboardingPage()
- onboardingScreen.tapDataTermsSwitch()
- onboardingScreen.tapContinueButton()
- onboardingScreen.checkCredentialsPageIsPresent()
- }
- Page.Analytics -> { // go to Analytics Screen
- userNavigatesToOnboardingScreenName(Page.Credentials)
- onboardingScreen.switchToPasswordMode()
- userEntersStrongEnoughPasswordTwice()
- onboardingScreen.tapContinueButton()
- userSeesAnalyticsScreen()
- }
- Page.MainScreen -> {
- userNavigatesToOnboardingScreenName(Page.Analytics)
- onboardingScreen.tapContinueButton()
- mainScreen.userSeesMainScreen()
- }
- }
- }
-
- private fun userSeesAnalyticsScreen() {
- onboardingScreen.checkAnalyticsPageIsPresent()
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
- onboardingScreen.checkAnalyticsSwitchIsDeactivated()
- }
-
- fun userSeesCredentialScreen() {
- onboardingScreen.checkCredentialsPageIsPresent()
- }
-
- fun dataTermsSwitchDeactivated() {
- onboardingScreen.checkDataTermsSwitchDeactivated()
- }
-
- fun confirmContinueButtonIsDeactivated() {
- onboardingScreen.checkContinueTutorialButtonIsDeactivated()
- }
-
- fun toggleDataTermsSwitch() {
- onboardingScreen.tapDataTermsSwitch()
- }
-
- fun userEntersAWeakPasswordTwice() {
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.WeakPassword)
- onboardingScreen.enterPasswordB(TestConfig.WeakPassword)
- }
-
- fun userEntersStrongEnoughPasswordTwice() {
- onboardingScreen.switchToPasswordMode()
- onboardingScreen.enterPasswordA(TestConfig.StrongPassword)
- onboardingScreen.enterPasswordB(TestConfig.StrongPassword)
- onboardingScreen.checkNoPasswordErrorMessagePresent()
- }
-
- fun userSwitchesToPasswordMode() {
- onboardingScreen.switchToPasswordMode()
- }
-
- fun userDoesNotSeeContinueButton() {
- onboardingScreen.checkContinueTutorialButtonIsDisabled()
- }
-
- fun userSeesActivatedContinueButton() {
- onboardingScreen.checkContinueTutorialButtonIsEnabled()
- }
-
- fun userSeesTermsOfUse() {
- onboardingScreen.checkTermsOfUseAreDisplayed()
- }
-
- fun userSeesNoTermsOfUse() {
- onboardingScreen.checkTermsOfUseAreNotDisplayed()
- }
-
- fun userOpensTermsOfUse() {
- onboardingScreen.openTermsOfUse()
- }
-
- fun userClosesTermsOfUse() {
- onboardingScreen.closeTermsOfUse()
- }
-
- fun userDoesntSeeDataProtection() {
- onboardingScreen.checkDataProtectionAreNotDisplayed()
- }
-
- fun userOpensDataProtection() {
- onboardingScreen.openDataProtection()
- }
-
- fun userSeesDataProtection() {
- onboardingScreen.checkDataProtectionIsDisplayed()
- }
-
- fun userClosesDataProtection() {
- onboardingScreen.closeDataProtection()
- }
-
- fun userSeesErrorMessageForPasswordStrength() {
- onboardingScreen.checkPasswordErrorMessagePresent()
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/ProfileSettingsSteps.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/ProfileSettingsSteps.kt
deleted file mode 100644
index da59de5f..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/ProfileSettingsSteps.kt
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.steps
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import de.gematik.ti.erp.app.test.test.screens.AuditEventsScreen
-import de.gematik.ti.erp.app.test.test.screens.CardWallScreen
-import de.gematik.ti.erp.app.test.test.screens.MainScreen
-import de.gematik.ti.erp.app.test.test.screens.ProfileSettingsScreen
-import de.gematik.ti.erp.app.test.test.screens.ProfileTokenListScreen
-import de.gematik.ti.erp.app.test.test.screens.SettingsScreen
-
-class ProfileSettingsSteps(
- private val composeRule: ComposeTestRule
-) : SemanticsNodeInteractionsProvider by composeRule {
-
- private val mainScreen by lazy { MainScreen(composeRule) }
- private val profileSettingsScreen by lazy { ProfileSettingsScreen(composeRule) }
- private val profileTokenListScreen by lazy { ProfileTokenListScreen(composeRule) }
- private val cardWallScreen by lazy { CardWallScreen(composeRule) }
- private val settingsScreen by lazy { SettingsScreen(composeRule) }
- private val auditEventsScreen by lazy { AuditEventsScreen(composeRule) }
-
- fun openProfileSettings() {
- mainScreen.tapSettingsButton()
- settingsScreen.goToFirstProfileDetails()
- profileSettingsScreen.userSeesProfileSettingsScreen()
- }
-
- fun openProfileSettingsForCertainProfile(profileIndex: Int) {
- mainScreen.userSeesMainScreen()
- // to keep scenarios human-readable, we'll hide the fact, that the index actually starts at zero ¯\_(ツ)_/¯
- mainScreen.tapSettingsButton()
- settingsScreen.goToProfileDetails(profileIndex - 1)
- }
-
- fun checkNoTokenPresent() {
- profileSettingsScreen.tapDisplayTokensButton()
- profileTokenListScreen.userSeesProfileTokenListScreen()
- profileTokenListScreen.checkTokensDoNotExist()
- }
-
- fun checkTokenHintPresent() {
- profileTokenListScreen.assertHeaderTextNotEmpty()
- profileTokenListScreen.assertInfoTextNotEmpty()
- }
-
- fun checkTokenHintPresent(text: String) {
- profileSettingsScreen.tapDisplayTokensButton()
- profileTokenListScreen.assertInfoTextPresent(text)
- }
-
- fun checkNoKVNRIsVisible() {
- profileSettingsScreen.checkKVNRNotVisible()
- }
-
- fun checkKVNRIsVisible() {
- profileSettingsScreen.checkKVNRIsVisible()
- }
-
- fun tapLoginButton() {
- profileSettingsScreen.tapThreeDotsMenuButton()
- profileSettingsScreen.tapLoginButton()
- }
-
- fun userSeesCardwallWelcomeScreen() {
- cardWallScreen.userSeesIntroScreen()
- }
-
- fun checkTokenPresent() {
- profileSettingsScreen.tapDisplayTokensButton()
- profileTokenListScreen.userSeesProfileTokenListScreen()
- profileTokenListScreen.checkAccessTokenPresent()
- profileTokenListScreen.checkSSOTokenPresent()
- profileTokenListScreen.closeTokenList()
- }
-
- fun hintTextNotPresent() {
- profileSettingsScreen.tapDisplayTokensButton()
- profileSettingsScreen.assertHintTextNotPresent()
- }
-
- fun logoutViaProfileSettings() {
- mainScreen.tapSettingsButton()
- settingsScreen.goToFirstProfileDetails()
- profileSettingsScreen.tapThreeDotsMenuButton()
- profileSettingsScreen.tapLogoutButton()
- profileSettingsScreen.closeProfileSettings()
- }
-
- fun noTokenPresentInProfileSettings() {
- mainScreen.tapSettingsButton()
- settingsScreen.goToFirstProfileDetails()
- profileSettingsScreen.tapDisplayTokensButton()
- profileTokenListScreen.checkTokensDoNotExist()
- profileTokenListScreen.closeTokenList()
- }
-
- fun userSeesAuditEventsScreen(profileIndex: Int) {
- mainScreen.userSeesMainScreen()
- mainScreen.tapSettingsButton()
- // -1 durch Differenzen zum normalen Sprachgebrauch
- settingsScreen.goToProfileDetails(profileIndex - 1)
- profileSettingsScreen.tapAuditEventsButton()
- auditEventsScreen.userSeesAuditEventsScreen()
- }
-
- fun userSeesEmptyStateForCertainProfile() {
- auditEventsScreen.userSeesAuditEventsScreen()
- auditEventsScreen.checkAuditEventsDoNotExist()
- }
-
- fun userLogsOutOffProfile(index: Int) {
- mainScreen.tapSettingsButton()
- settingsScreen.goToProfileDetails(index - 1)
- profileSettingsScreen.tapThreeDotsMenuButton()
- profileSettingsScreen.tapLogoutButton()
- profileSettingsScreen.closeProfileSettings()
- mainScreen.userSeesMainScreen()
- }
-
- fun userDoesNotSeesEmptyStateForCertainProfile() {
- auditEventsScreen.userSeesAuditEventsScreen()
- auditEventsScreen.checkNoAuditEventsHeaderAndInfoDoesNotExist()
- }
-
- fun userHasNumberOfProfiles(numberOfProfiles: Int) {
- mainScreen.tapSettingsButton()
- settingsScreen.assertAmountOfProfiles(numberOfProfiles)
- mainScreen.userClicksBottomBarPrescriptions()
- mainScreen.userSeesMainScreen()
- }
-
- fun userDeletesProfile(profileName: String) {
- mainScreen.tapSettingsButton()
- settingsScreen.tapProfileWithName(profileName)
- profileSettingsScreen.userSeesProfileSettingsScreen()
- profileSettingsScreen.tapThreeDotsMenuButton()
- profileSettingsScreen.tapDeleteProfile()
- profileSettingsScreen.tapConfirmDeleteProfile()
- }
-
- fun userHasProfilesWithName(numberOfProfiles: Int, profileNames: String) {
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.checkAmountOfProfilesWithNames(numberOfProfiles, profileNames)
- }
-
- fun createProfileAfterLastOneWasDeleted() {
- settingsScreen.userSeesCreateNewProfileAlert()
- settingsScreen.enterProfileName("Profil 1")
- settingsScreen.tapNewProfileConfirmButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapReturnToPrescriptionScreen()
- mainScreen.userSeesMainScreen()
- }
-
- fun userInterruptsDeletingProfile(profileName: String) {
- navigateToProfileWithName(profileName)
- profileSettingsScreen.userSeesProfileSettingsScreen()
- profileSettingsScreen.tapThreeDotsMenuButton()
- profileSettingsScreen.tapDeleteProfile()
- profileSettingsScreen.tapAbortDeleteButton()
- profileSettingsScreen.tapBackToSettingsButton()
- }
-
- fun editProfileName(profileName: String, newProfileName: String) {
- navigateToProfileWithName(profileName)
- profileSettingsScreen.tapEditProfileNameButton()
- profileSettingsScreen.enterNewProfileName(newProfileName)
- }
-
- fun assertErrorMessageEmptyProfileName(errorMessage: String) {
- profileSettingsScreen.assertErrorMessageEmptyProfileName(errorMessage)
- }
-
- fun userChangesProfilePictureOfProfileFromColorTo(profileName: String, color: String) {
- navigateToProfileWithName(profileName)
- profileSettingsScreen.tapEditProfileIconButton()
- profileSettingsScreen.changeProfilePictureColor(color)
- profileSettingsScreen.tapBackToSettingsButton()
- }
-
- private fun navigateToProfileWithName(profileName: String) {
- mainScreen.tapSettingsButton()
- settingsScreen.userSeesSettingsScreen()
- settingsScreen.tapProfileWithName(profileName)
- }
-}
diff --git a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/SettingScreenSteps.kt b/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/SettingScreenSteps.kt
deleted file mode 100644
index a9c05ed4..00000000
--- a/app/android/src/androidTest/java/de/gematik/ti/erp/app/test/test/steps/SettingScreenSteps.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.test.test.steps
-
-import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
-import androidx.compose.ui.test.junit4.ComposeTestRule
-import de.gematik.ti.erp.app.TestTag
-import de.gematik.ti.erp.app.test.test.TestConfig
-import de.gematik.ti.erp.app.test.test.core.awaitDisplay
-import de.gematik.ti.erp.app.test.test.screens.OrderEgkScreen
-import de.gematik.ti.erp.app.test.test.screens.SettingsScreen
-
-class SettingScreenSteps(private val composeRule: ComposeTestRule) :
- SemanticsNodeInteractionsProvider by composeRule {
-
- private val settingsScreen by lazy { SettingsScreen(composeRule) }
- private val orderEgkScreen by lazy { OrderEgkScreen(composeRule) }
-
- fun userWantsToOrderNewCard() {
- settingsScreen.tapOrderEgk()
- orderEgkScreen.userSeesOrderEgkScreenScreen()
- }
-
- fun userUsesLinkAboutNFC() {
- orderEgkScreen.tapNFCExplanationPageLink()
- }
-
- fun userIsNotInERezeptAppAnymore() {
- // TODO Wir sind im browser und wollen den URL prüfen. URL = "das-e-rezept-fuer-deutschland.de"
- }
-
- fun userSeesAListOfInsurances() {
- orderEgkScreen.userSeesOrderEgkScreenScreen()
- orderEgkScreen.checkIfAtLeastFourInsurerIsVisible()
- }
-
- fun userChoosesInsurance(insurance: String) {
- orderEgkScreen.chooseInsurance(insurance)
- }
-
- fun userSeesOrderOptionScreen() {
- composeRule.awaitDisplay(TestConfig.ScreenChangeTimeout, TestTag.Settings.OrderEgk.SelectOrderOptionScreen)
- }
-
- fun userSeesHealthCardOrderContactScreen() {
- composeRule.awaitDisplay(TestConfig.ScreenChangeTimeout, TestTag.Settings.OrderEgk.HealthCardOrderContactScreen)
- }
-
- fun userSeesPossibilitiesWhatCanBeOrdered(orderPossibility: String) {
- orderEgkScreen.checkOrderPossibilities(orderPossibility)
- }
-
- fun userSeesPossibilitiesHowCanBeOrdered(contactPossibility: String) {
- orderEgkScreen.checkContactPossibilities(contactPossibility)
- }
-
- fun userAbortsOrderingOfNewCard() {
- orderEgkScreen.tapOrderCardAbort()
- }
-
- fun userSeesSettingsScreen() {
- settingsScreen.userSeesSettingsScreen()
- }
-}
diff --git a/app/android/src/main/AndroidManifest.xml b/app/android/src/main/AndroidManifest.xml
index e7d7cf8e..8280b0a1 100644
--- a/app/android/src/main/AndroidManifest.xml
+++ b/app/android/src/main/AndroidManifest.xml
@@ -28,9 +28,14 @@
android:name="android.hardware.camera"
android:required="false" />
+
+
{ object : DispatchProvider {} }
+ bindProvider {
+ val context = instance()
+ context.resources
+ }
+ bindProvider {
+ val context = instance()
+ context.assets
+ }
+ bindProvider {
+ val context = instance()
+ context.mainLooper
+ }
bindSingleton(ApplicationPreferencesTag) {
val context = instance()
context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE)
@@ -57,6 +68,13 @@ val appModules = DI.Module("appModules") {
bindSingleton(NetworkSecurePreferencesTag) {
val context = instance()
+ @Requirement(
+ "O.Arch_2#1",
+ "O.Data_2#4",
+ "O.Data_3#4",
+ sourceSpecification = "BSI-eRp-ePA",
+ rationale = "Data storage using EncryptedSharedPreferences."
+ )
EncryptedSharedPreferences.create(
context,
NETWORK_SECURE_PREFS_FILE_NAME,
diff --git a/app/android/src/main/java/de/gematik/ti/erp/app/di/ModuleNames.kt b/app/android/src/main/java/de/gematik/ti/erp/app/di/ModuleNames.kt
index 9f25f6ee..1cbaf52c 100644
--- a/app/android/src/main/java/de/gematik/ti/erp/app/di/ModuleNames.kt
+++ b/app/android/src/main/java/de/gematik/ti/erp/app/di/ModuleNames.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.di
diff --git a/app/android/src/main/java/de/gematik/ti/erp/app/info/DefaultBuildConfigInformation.kt b/app/android/src/main/java/de/gematik/ti/erp/app/info/DefaultBuildConfigInformation.kt
index d90324aa..097968c2 100644
--- a/app/android/src/main/java/de/gematik/ti/erp/app/info/DefaultBuildConfigInformation.kt
+++ b/app/android/src/main/java/de/gematik/ti/erp/app/info/DefaultBuildConfigInformation.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.info
@@ -40,6 +40,8 @@ class DefaultBuildConfigInformation : BuildConfigInformation {
defaultValue = NFC_NOT_AVAILABLE
) ?: NFC_NOT_AVAILABLE
+ override fun isMockedApp(): Boolean = false
+
companion object {
private const val DARK_THEME_ON = "an"
private const val DARK_THEME_OFF = "aus"
diff --git a/app/android/src/main/java/de/gematik/ti/erp/app/info/di/BuildConfigInformationModule.kt b/app/android/src/main/java/de/gematik/ti/erp/app/info/di/BuildConfigInformationModule.kt
index 016c42b0..8374daa2 100644
--- a/app/android/src/main/java/de/gematik/ti/erp/app/info/di/BuildConfigInformationModule.kt
+++ b/app/android/src/main/java/de/gematik/ti/erp/app/info/di/BuildConfigInformationModule.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.info.di
diff --git a/app/android/src/main/java/de/gematik/ti/erp/app/pkv/DefaultFileProviderAuthority.kt b/app/android/src/main/java/de/gematik/ti/erp/app/pkv/DefaultFileProviderAuthority.kt
index ae1739d9..6ac3ccdf 100644
--- a/app/android/src/main/java/de/gematik/ti/erp/app/pkv/DefaultFileProviderAuthority.kt
+++ b/app/android/src/main/java/de/gematik/ti/erp/app/pkv/DefaultFileProviderAuthority.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.pkv
diff --git a/app/android/src/main/java/de/gematik/ti/erp/app/pkv/FileProviderAuthorityModule.kt b/app/android/src/main/java/de/gematik/ti/erp/app/pkv/FileProviderAuthorityModule.kt
index 3977bc00..75d04e93 100644
--- a/app/android/src/main/java/de/gematik/ti/erp/app/pkv/FileProviderAuthorityModule.kt
+++ b/app/android/src/main/java/de/gematik/ti/erp/app/pkv/FileProviderAuthorityModule.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.pkv
diff --git a/app/android/src/main/res/xml/data_extraction_rules.xml b/app/android/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..78a61775
--- /dev/null
+++ b/app/android/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/android/src/main/res/xml/network_security_config.xml b/app/android/src/main/res/xml/network_security_config.xml
index 4517087e..b8f65835 100644
--- a/app/android/src/main/res/xml/network_security_config.xml
+++ b/app/android/src/main/res/xml/network_security_config.xml
@@ -1,67 +1,11 @@
-
- erp-ref.app.ti-dienste.de
-
- RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
- e0IRz5Tio3GA1Xs4fUVWmH1xHDiH2dMbVtCBSkOIdqM=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
-
-
-
-
- erp-test.app.ti-dienste.de
-
- RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
- e0IRz5Tio3GA1Xs4fUVWmH1xHDiH2dMbVtCBSkOIdqM=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
-
-
-
-
- erp.app.ti-dienste.de
-
- RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
- e0IRz5Tio3GA1Xs4fUVWmH1xHDiH2dMbVtCBSkOIdqM=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
-
-
-
-
-
- idp-ref.app.ti-dienste.de
-
- 86fLIetopQLDNxFZ0uMI66Xpl1pFgLlHHn9v6kT0i4I=
- OD/WDbD3VsfMwwNzzy9MWd9JXppKB77Vb3ST2wn9meg=
-
-
-
-
- idp-test.app.ti-dienste.de
-
- 86fLIetopQLDNxFZ0uMI66Xpl1pFgLlHHn9v6kT0i4I=
- OD/WDbD3VsfMwwNzzy9MWd9JXppKB77Vb3ST2wn9meg=
-
-
-
-
- idp.app.ti-dienste.de
-
- 86fLIetopQLDNxFZ0uMI66Xpl1pFgLlHHn9v6kT0i4I=
- OD/WDbD3VsfMwwNzzy9MWd9JXppKB77Vb3ST2wn9meg=
-
-
-
-
- apovzd.app.ti-dienste.de
-
- e0IRz5Tio3GA1Xs4fUVWmH1xHDiH2dMbVtCBSkOIdqM=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
- qBRjZmOmkSNJL0p70zek7odSIzqs/muR4Jk9xYyCP+E=
-
-
-
+
+
+
+
diff --git a/app/android/src/test/java/android/util/Base64.kt b/app/android/src/test/java/android/util/Base64.kt
deleted file mode 100644
index 79f2d834..00000000
--- a/app/android/src/test/java/android/util/Base64.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-@file:JvmName("Base64")
-
-package android.util
-
-fun decode(input: ByteArray, flag: Int): ByteArray {
- return java.util.Base64.getDecoder().decode(input)
-}
-
-fun decode(input: String, flag: Int): ByteArray {
- return when (flag) {
- 0 -> java.util.Base64.getDecoder().decode(input)
- 8 -> java.util.Base64.getUrlDecoder().decode(input)
- else -> java.util.Base64.getUrlDecoder().decode(input)
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/CoroutineTestRule.kt b/app/android/src/test/java/de/gematik/ti/erp/app/CoroutineTestRule.kt
index aab2eae0..fe01f78e 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/CoroutineTestRule.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/CoroutineTestRule.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/idp/JWTExtensionsTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/idp/JWTExtensionsTest.kt
index d934d68d..e9e0ba9d 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/idp/JWTExtensionsTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/idp/JWTExtensionsTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.idp
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/InvoiceUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/InvoiceUseCaseTest.kt
deleted file mode 100644
index 3d1c5c35..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/InvoiceUseCaseTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-@file:Suppress("ktlint:max-line-length", "ktlint:argument-list-wrapping")
-
-package de.gematik.ti.erp.app.invoice.usecase
-
-import de.gematik.ti.erp.app.CoroutineTestRule
-import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
-import io.mockk.MockKAnnotations
-import io.mockk.every
-import io.mockk.impl.annotations.MockK
-import io.mockk.spyk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.runTest
-import kotlinx.datetime.TimeZone
-import kotlinx.datetime.toLocalDateTime
-import org.junit.Rule
-import kotlin.test.Test
-import kotlin.test.BeforeTest
-
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class InvoiceUseCaseTest {
-
- @get:Rule
- val coroutineRule = CoroutineTestRule()
-
- @MockK
- lateinit var useCase: InvoiceUseCase
-
- @MockK
- lateinit var repositpry: InvoiceRepository
-
- @BeforeTest
- fun setup() {
- MockKAnnotations.init(this)
- useCase = spyk(
- InvoiceUseCase(repositpry, coroutineRule.dispatchers)
- )
- }
-
- @Test
- fun `invoices - should return invoices sorted by timestamp and grouped by year`() =
-
- runTest {
- every { useCase.invoicesFlow("1234") } returns flowOf(listOf(pkvInvoice, pkvInvoice2))
-
- val invoices = useCase.invoices("1234").first()
-
- println("size : " + invoices.size)
- assertEquals(
- mapOf(
- Pair(
- first = later.toLocalDateTime(TimeZone.currentSystemDefault()).year,
- second = listOf(pkvInvoice2)
- ),
- Pair(
- first = now.toLocalDateTime(TimeZone.currentSystemDefault()).year,
- second = listOf(pkvInvoice)
- )
- ),
- invoices
- )
- }
-
- @Test
- fun `invoice create dmc payload`() =
- assertEquals("{\"urls\":[\"ChargeItem/01234?ac=98765\"]}", pkvInvoice.dmcPayload)
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/TestInvoices.kt b/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/TestInvoices.kt
index 9e50f8c3..31c8f1e3 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/TestInvoices.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/invoice/usecase/TestInvoices.kt
@@ -1,26 +1,26 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.invoice.usecase
-import de.gematik.ti.erp.app.utils.asFhirTemporal
import de.gematik.ti.erp.app.invoice.model.InvoiceData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.utils.asFhirTemporal
import kotlinx.datetime.Clock
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.plus
@@ -28,7 +28,7 @@ import kotlinx.datetime.plus
val now = Clock.System.now()
val later = now.plus(8760, DateTimeUnit.HOUR)
-val pkvInvoice = InvoiceData.PKVInvoice(
+val pkvInvoiceRecord = InvoiceData.PKVInvoiceRecord(
profileId = "1234",
taskId = "01234",
accessCode = "98765",
@@ -66,11 +66,12 @@ val pkvInvoice = InvoiceData.PKVInvoice(
null, null, false, null,
SyncedTaskData.MultiplePrescriptionInfo(false), 1, null, null, SyncedTaskData.AdditionalFee.None
),
- whenHandedOver = now.asFhirTemporal()
+ whenHandedOver = now.asFhirTemporal(),
+ consumed = false
)
-val pkvInvoice2 = InvoiceData.PKVInvoice(
+val pkvInvoiceRecord2 = InvoiceData.PKVInvoiceRecord(
profileId = "23456",
taskId = "65432",
accessCode = "98765",
@@ -108,6 +109,7 @@ val pkvInvoice2 = InvoiceData.PKVInvoice(
null, null, false, null,
SyncedTaskData.MultiplePrescriptionInfo(false), 1, null, null, SyncedTaskData.AdditionalFee.None
),
- whenHandedOver = later.asFhirTemporal()
+ whenHandedOver = later.asFhirTemporal(),
+ consumed = false
)
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/mocks/MessageMocks.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/mocks/MessageMocks.kt
new file mode 100644
index 00000000..c9b88244
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/mocks/MessageMocks.kt
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.mocks
+
+import de.gematik.ti.erp.app.invoice.model.InvoiceData
+import de.gematik.ti.erp.app.messages.repository.CachedPharmacy
+import de.gematik.ti.erp.app.messages.domain.model.OrderUseCaseData
+import de.gematik.ti.erp.app.prescription.model.Communication
+import de.gematik.ti.erp.app.prescription.model.CommunicationProfile
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.prescription.usecase.model.Prescription
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import kotlinx.datetime.Instant
+
+object MessageMocks {
+
+ internal const val MOCK_ORDER_ID = "testOrderId"
+
+ internal const val MOCK_TASK_ID_01 = "123-001"
+
+ internal const val MOCK_TASK_ID_02 = "456-002"
+
+ private const val MOCK_COMMUNICATION_ID_01 = "CID-123-001"
+
+ private const val MOCK_COMMUNICATION_ID_02 = "CID-456-002"
+
+ internal const val MOCK_TRANSACTION_ID = "transactionMockId"
+
+ internal val MOCK_PHARMACY_O1 = CachedPharmacy(name = "Pharmacy1", telematikId = "123")
+
+ internal val MOCK_PHARMACY_O2 = CachedPharmacy(name = "Pharmacy2", telematikId = "456")
+
+ private const val MOCK_PRACTITIONER_NAME = "Dr. John Doe"
+
+ internal const val MOCK_PROFILE_IDENTIFIER = "testProfileIdentifier"
+
+ private val MOCK_PAYLOAD = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "info_text":"mock message." ,
+ "pickUpCodeHR":"T01__R01" ,
+ "pickUpCodeDMC":"Test_01___Rezept_01___abcdefg12345" ,
+ "url":"https://www.tree.fm/forest/33"
+ }
+ """.trimIndent()
+
+ private val MOCK_PAYLOAD_02 = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "info_text":"mock message_02." ,
+ "pickUpCodeHR":"T01__R02" ,
+ "pickUpCodeDMC":"Test_01___Rezept_02___abcdefg12345" ,
+ "url":"https://www.tree.fm/forest/35"
+ }
+ """.trimIndent()
+
+ private val MOCK_PRACTITIONER = SyncedTaskData.Practitioner(
+ name = MOCK_PRACTITIONER_NAME,
+ qualification = "",
+ practitionerIdentifier = " "
+ )
+
+ private val MOCK_CHIP_INFO = Prescription.PrescriptionChipInformation(
+ isPartOfMultiplePrescription = false,
+ numerator = null,
+ denominator = null,
+ start = null
+ )
+
+ private val MOCK_PRESCRIPTION_01 = Prescription.SyncedPrescription(
+ taskId = MOCK_TASK_ID_01,
+ name = null,
+ redeemedOn = null,
+ expiresOn = Instant.fromEpochSeconds(123456),
+ state = SyncedTaskData.SyncedTask.Expired(
+ expiredOn = Instant.fromEpochSeconds(123456)
+ ),
+ isIncomplete = false,
+ organization = MOCK_PRACTITIONER_NAME,
+ authoredOn = Instant.fromEpochSeconds(123456),
+ acceptUntil = Instant.fromEpochSeconds(123456),
+ isDirectAssignment = false,
+ prescriptionChipInformation = MOCK_CHIP_INFO
+ )
+
+ private val MOCK_PRESCRIPTION_02 = Prescription.SyncedPrescription(
+ taskId = MOCK_TASK_ID_02,
+ name = null,
+ redeemedOn = null,
+ expiresOn = Instant.fromEpochSeconds(123456),
+ state = SyncedTaskData.SyncedTask.Expired(
+ expiredOn = Instant.fromEpochSeconds(123456)
+ ),
+ isIncomplete = false,
+ organization = MOCK_PRACTITIONER_NAME,
+ authoredOn = Instant.fromEpochSeconds(123456),
+ acceptUntil = Instant.fromEpochSeconds(123456),
+ isDirectAssignment = false,
+ prescriptionChipInformation = MOCK_CHIP_INFO
+ )
+
+ private val MOCK_TASK_DETAIL_BUNDLE_01 = OrderUseCaseData.TaskDetailedBundle(
+ prescription = MOCK_PRESCRIPTION_01,
+ invoiceInfo = OrderUseCaseData.InvoiceInfo(
+ hasInvoice = true,
+ invoiceSentOn = Instant.fromEpochSeconds(123456)
+ )
+ )
+
+ private val MOCK_TASK_DETAIL_BUNDLE_02 = OrderUseCaseData.TaskDetailedBundle(
+ prescription = MOCK_PRESCRIPTION_02,
+ invoiceInfo = OrderUseCaseData.InvoiceInfo(
+ hasInvoice = true,
+ invoiceSentOn = Instant.fromEpochSeconds(123456)
+ )
+ )
+
+ internal val MOCK_ORDER_DETAIL = OrderUseCaseData.OrderDetail(
+ orderId = MOCK_ORDER_ID,
+ taskDetailedBundles = listOf(
+ MOCK_TASK_DETAIL_BUNDLE_01,
+ MOCK_TASK_DETAIL_BUNDLE_02
+ ),
+ sentOn = Instant.fromEpochSeconds(123456),
+ pharmacy = OrderUseCaseData.Pharmacy(MOCK_PHARMACY_O1.name, ""),
+ hasUnreadMessages = false
+ )
+
+ internal val MOCK_ORDER_01 = OrderUseCaseData.Order(
+ orderId = MOCK_ORDER_ID,
+ prescriptions = listOf(null),
+ sentOn = Instant.fromEpochSeconds(123456),
+ pharmacy = OrderUseCaseData.Pharmacy(MOCK_PHARMACY_O1.name, ""),
+ hasUnreadMessages = true,
+ latestCommunicationMessage = null
+ )
+
+ internal val MOCK_DISP_REQ_COMMUNICATION_01 = Communication(
+ taskId = MOCK_TASK_ID_01,
+ communicationId = MOCK_COMMUNICATION_ID_01,
+ orderId = MOCK_ORDER_ID,
+ profile = CommunicationProfile.ErxCommunicationDispReq,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "sender1",
+ recipient = MOCK_PHARMACY_O1.name,
+ payload = "payload1",
+ consumed = true
+ )
+ internal val MOCK_DISP_REPLY_COMMUNICATION_01 = MOCK_DISP_REQ_COMMUNICATION_01.copy(
+ profile = CommunicationProfile.ErxCommunicationReply,
+ consumed = false,
+ payload = MOCK_PAYLOAD
+ )
+ internal val MOCK_DISP_REQ_COMMUNICATION_02 = Communication(
+ taskId = MOCK_TASK_ID_02,
+ communicationId = MOCK_COMMUNICATION_ID_02,
+ orderId = MOCK_ORDER_ID,
+ profile = CommunicationProfile.ErxCommunicationDispReq,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "sender2",
+ recipient = MOCK_PHARMACY_O2.name,
+ payload = "payload2",
+ consumed = true
+ )
+ internal val MOCK_DISP_REPLY_COMMUNICATION_02 = MOCK_DISP_REQ_COMMUNICATION_02.copy(
+ profile = CommunicationProfile.ErxCommunicationReply,
+ consumed = false,
+ payload = MOCK_PAYLOAD_02
+ )
+
+ private val MOCK_ORGANIZATION = SyncedTaskData.Organization(
+ name = "TestOrganization",
+ address = SyncedTaskData.Address(
+ line1 = "123 Main Street",
+ line2 = "Apt 4",
+ postalCode = "12345",
+ city = "City"
+ ),
+ uniqueIdentifier = "org123",
+ phone = "123-456-7890",
+ mail = "info@testorg.com"
+ )
+
+ private val MOCK_PATIENT = SyncedTaskData.Patient(
+ name = "Jane",
+ address = SyncedTaskData.Address(
+ line1 = "",
+ line2 = "",
+ postalCode = "",
+ city = ""
+ ),
+ birthdate = null,
+ insuranceIdentifier = "ins123"
+ )
+
+ private val MOCK_MEDICATION_REQ = SyncedTaskData.MedicationRequest(
+ null, null, null, SyncedTaskData.AccidentType.None,
+ null, null, false, null,
+ SyncedTaskData.MultiplePrescriptionInfo(false), 1, null, null, SyncedTaskData.AdditionalFee.None
+ )
+
+ private fun mockChargeItem(
+ itemDescription: String,
+ itemFactor: Double,
+ itemPrice: Double
+ ): InvoiceData.ChargeableItem {
+ return InvoiceData.ChargeableItem(
+ description = InvoiceData.ChargeableItem.Description.PZN("PZN123"),
+ text = itemDescription,
+ factor = itemFactor,
+ price = InvoiceData.PriceComponent(value = itemPrice, tax = 0.0)
+ )
+ }
+
+ private val MOCK_INVOICE = InvoiceData.Invoice(
+ totalAdditionalFee = 10.0,
+ totalBruttoAmount = 120.0,
+ currency = "EUR",
+ chargeableItems = listOf(
+ mockChargeItem("Description1", 2.0, 30.0),
+ mockChargeItem("Description2", 1.5, 50.0)
+ ),
+ additionalDispenseItems = emptyList(),
+ additionalInformation = listOf("AdditionalInfo1", "AdditionalInfo2")
+ )
+
+ internal val MOCK_INVOICE_01 = InvoiceData.PKVInvoiceRecord(
+ profileId = "testProfileId",
+ taskId = MOCK_TASK_ID_01,
+ accessCode = "testAccessCode",
+ timestamp = Instant.fromEpochSeconds(123456),
+ pharmacyOrganization = MOCK_ORGANIZATION,
+ practitionerOrganization = MOCK_ORGANIZATION,
+ practitioner = MOCK_PRACTITIONER,
+ patient = MOCK_PATIENT,
+ medicationRequest = MOCK_MEDICATION_REQ,
+ whenHandedOver = null,
+ invoice = MOCK_INVOICE,
+ dmcPayload = "testDmcPayload",
+ consumed = false
+ )
+
+ internal val MOCK_INVOICE_02 = InvoiceData.PKVInvoiceRecord(
+ profileId = "testProfileId",
+ taskId = MOCK_TASK_ID_02,
+ accessCode = "testAccessCode",
+ timestamp = Instant.fromEpochSeconds(123456),
+ pharmacyOrganization = MOCK_ORGANIZATION,
+ practitionerOrganization = MOCK_ORGANIZATION,
+ practitioner = MOCK_PRACTITIONER,
+ patient = MOCK_PATIENT,
+ medicationRequest = MOCK_MEDICATION_REQ,
+ whenHandedOver = null,
+ invoice = MOCK_INVOICE,
+ dmcPayload = "testDmcPayload",
+ consumed = false
+ )
+
+ internal val MOCK_SYNCED_TASK_DATA_01 = SyncedTaskData.SyncedTask(
+ profileId = "testProfileId",
+ taskId = MOCK_TASK_ID_01,
+ accessCode = "testAccessCode",
+ lastModified = Instant.fromEpochSeconds(123456),
+ organization = MOCK_ORGANIZATION,
+ practitioner = MOCK_PRACTITIONER,
+ patient = MOCK_PATIENT,
+ insuranceInformation = SyncedTaskData.InsuranceInformation(
+ name = "TestInsurance",
+ status = "Active",
+ coverageType = SyncedTaskData.CoverageType.GKV
+ ),
+ expiresOn = Instant.fromEpochSeconds(123456),
+ acceptUntil = Instant.fromEpochSeconds(123456),
+ authoredOn = Instant.fromEpochSeconds(123456),
+ status = SyncedTaskData.TaskStatus.Ready,
+ isIncomplete = false,
+ pvsIdentifier = "testPvsIdentifier",
+ failureToReport = "testFailureToReport",
+ medicationRequest = MOCK_MEDICATION_REQ,
+ lastMedicationDispense = null,
+ medicationDispenses = emptyList(),
+ communications = emptyList()
+ )
+
+ internal val MOCK_SYNCED_TASK_DATA_02 = SyncedTaskData.SyncedTask(
+ profileId = "testProfileId",
+ taskId = MOCK_TASK_ID_02,
+ accessCode = "testAccessCode",
+ lastModified = Instant.fromEpochSeconds(123456),
+ organization = MOCK_ORGANIZATION,
+ practitioner = MOCK_PRACTITIONER,
+ patient = MOCK_PATIENT,
+ insuranceInformation = SyncedTaskData.InsuranceInformation(
+ name = "TestInsurance",
+ status = "Active",
+ coverageType = SyncedTaskData.CoverageType.GKV
+ ),
+ expiresOn = Instant.fromEpochSeconds(123456),
+ acceptUntil = Instant.fromEpochSeconds(123456),
+ authoredOn = Instant.fromEpochSeconds(123456),
+ status = SyncedTaskData.TaskStatus.Ready,
+ isIncomplete = false,
+ pvsIdentifier = "testPvsIdentifier",
+ failureToReport = "testFailureToReport",
+ medicationRequest = MOCK_MEDICATION_REQ,
+ lastMedicationDispense = null,
+ medicationDispenses = emptyList(),
+ communications = emptyList()
+ )
+
+ internal val MOCK_MESSAGE_01 = OrderUseCaseData.Message(
+ communicationId = MOCK_COMMUNICATION_ID_01,
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = "mock message.",
+ pickUpCodeDMC = "Test_01___Rezept_01___abcdefg12345",
+ pickUpCodeHR = "T01__R01",
+ link = "https://www.tree.fm/forest/33",
+ consumed = false
+ )
+
+ internal val MOCK_MESSAGE_02 = OrderUseCaseData.Message(
+ communicationId = MOCK_COMMUNICATION_ID_02,
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = "mock message_02.",
+ pickUpCodeDMC = "Test_01___Rezept_02___abcdefg12345",
+ pickUpCodeHR = "T01__R02",
+ link = "https://www.tree.fm/forest/35",
+ consumed = false
+ )
+
+ internal val MOCK_PROFILE = ProfilesData.Profile(
+ id = "1",
+ name = "Mustermann",
+ color = ProfilesData.ProfileColorNames.PINK,
+ avatar = ProfilesData.Avatar.FemaleDoctor,
+ insuranceIdentifier = "12345567890",
+ insuranceType = ProfilesData.InsuranceType.GKV,
+ insurantName = "Mustermann",
+ insuranceName = "GesundheitsVersichert AG",
+ singleSignOnTokenScope = null,
+ active = false,
+ isConsentDrawerShown = false,
+ lastAuthenticated = null
+ )
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessageUsingOrderIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessageUsingOrderIdUseCaseTest.kt
new file mode 100644
index 00000000..cbde887f
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessageUsingOrderIdUseCaseTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
+import de.gematik.ti.erp.app.messages.domain.usecase.GetMessageUsingOrderIdUseCase
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_DISP_REQ_COMMUNICATION_02
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_INVOICE_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_INVOICE_02
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_ORDER_DETAIL
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_ORDER_ID
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_PHARMACY_O1
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_PHARMACY_O2
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_02
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_02
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertEquals
+
+@ExperimentalCoroutinesApi
+class GetMessageUsingOrderIdUseCaseTest {
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+ private val invoiceRepository: InvoiceRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: GetMessageUsingOrderIdUseCase
+
+ @Before
+ fun setup() {
+ coEvery {
+ communicationRepository.loadDispReqCommunications(any())
+ } returns flowOf(listOf(MOCK_DISP_REQ_COMMUNICATION_01, MOCK_DISP_REQ_COMMUNICATION_02))
+ coEvery { communicationRepository.loadPharmacies() } returns flowOf(listOf(MOCK_PHARMACY_O1, MOCK_PHARMACY_O2))
+ coEvery { communicationRepository.taskIdsByOrder(any()) } returns flowOf(listOf(MOCK_TASK_ID_01, MOCK_TASK_ID_02))
+ coEvery { communicationRepository.hasUnreadDispenseMessage(any(), any()) } returns flowOf(false)
+ coEvery { communicationRepository.hasUnreadRepliedMessages(any(), any()) } returns flowOf(false)
+ coEvery { communicationRepository.loadSyncedByTaskId(MOCK_TASK_ID_01) } returns flowOf(MOCK_SYNCED_TASK_DATA_01)
+ coEvery { communicationRepository.loadSyncedByTaskId(MOCK_TASK_ID_02) } returns flowOf(MOCK_SYNCED_TASK_DATA_02)
+ coEvery { communicationRepository.downloadMissingPharmacy(any()) } returns Result.success(null)
+ coEvery { invoiceRepository.invoiceByTaskId(MOCK_TASK_ID_01) } returns flowOf(MOCK_INVOICE_01)
+ coEvery { invoiceRepository.invoiceByTaskId(MOCK_TASK_ID_02) } returns flowOf(MOCK_INVOICE_02)
+
+ useCase = GetMessageUsingOrderIdUseCase(
+ communicationRepository = communicationRepository,
+ invoiceRepository = invoiceRepository,
+ dispatcher = dispatcher
+ )
+ }
+
+ @Test
+ fun `invoke should return order detail`() = runTest(dispatcher) {
+ val expectedOrderDetail = MOCK_ORDER_DETAIL
+
+ val resultOrderDetail = useCase(MOCK_ORDER_ID).first()
+
+ assertEquals(expectedOrderDetail, resultOrderDetail)
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessagesUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessagesUseCaseTest.kt
new file mode 100644
index 00000000..90e8e197
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetMessagesUseCaseTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_ORDER_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_PHARMACY_O1
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_PROFILE
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_01
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import de.gematik.ti.erp.app.messages.domain.model.OrderUseCaseData
+import de.gematik.ti.erp.app.messages.domain.usecase.GetMessagesUseCase
+import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertEquals
+
+@ExperimentalCoroutinesApi
+class GetMessagesUseCaseTest {
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+
+ private val profileRepository: ProfileRepository = mockk()
+
+ private val invoiceRepository: InvoiceRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: GetMessagesUseCase
+
+ @Before
+ fun setup() {
+ coEvery { profileRepository.profiles() } returns flowOf(listOf(MOCK_PROFILE))
+
+ coEvery {
+ communicationRepository.loadFirstDispReqCommunications(any())
+ } returns flowOf(listOf(MOCK_DISP_REQ_COMMUNICATION_01))
+
+ coEvery {
+ communicationRepository.loadPharmacies()
+ } returns flowOf(listOf(MOCK_PHARMACY_O1))
+
+ coEvery {
+ communicationRepository.taskIdsByOrder(any())
+ } returns flowOf(listOf(MOCK_TASK_ID_01))
+
+ coEvery {
+ communicationRepository.hasUnreadDispenseMessage(any(), any())
+ } returns flowOf(true)
+
+ coEvery {
+ communicationRepository.hasUnreadRepliedMessages(any(), any())
+ } returns flowOf(true)
+
+ coEvery {
+ communicationRepository.downloadMissingPharmacy(any())
+ } returns Result.success(null)
+
+ coEvery {
+ communicationRepository.loadSyncedByTaskId(any())
+ } returns flowOf(null)
+
+ coEvery {
+ communicationRepository.loadScannedByTaskId(any())
+ } returns flowOf(null)
+
+ coEvery {
+ communicationRepository.loadRepliedCommunications(any(), any())
+ } returns flowOf(emptyList())
+ coEvery {
+ communicationRepository.loadDispReqCommunications(any())
+ } returns flowOf(emptyList())
+
+ coEvery {
+ invoiceRepository.getInvoiceTaskIdAndConsumedStatus(any())
+ } returns flowOf(emptyList())
+
+ coEvery { invoiceRepository.hasUnreadInvoiceMessages(any()) } returns flowOf(false)
+
+ useCase = GetMessagesUseCase(
+ communicationRepository = communicationRepository,
+ profileRepository = profileRepository,
+ invoiceRepository = invoiceRepository,
+ dispatcher = dispatcher
+ )
+ }
+
+ @Test
+ fun `invoke should return list of orders`() = runTest(dispatcher) {
+ val expectedOrders = listOf(MOCK_ORDER_01)
+
+ val resultOrders: List = useCase()
+
+ assertEquals(expectedOrders, resultOrders)
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetRepliedMessagesUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetRepliedMessagesUseCaseTest.kt
new file mode 100644
index 00000000..ffcdbf01
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetRepliedMessagesUseCaseTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_DISP_REPLY_COMMUNICATION_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_DISP_REPLY_COMMUNICATION_02
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_MESSAGE_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_MESSAGE_02
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_ORDER_ID
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_02
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import de.gematik.ti.erp.app.messages.domain.model.OrderUseCaseData
+import de.gematik.ti.erp.app.messages.domain.usecase.GetRepliedMessagesUseCase
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertEquals
+
+@ExperimentalCoroutinesApi
+class GetRepliedMessagesUseCaseTest {
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: GetRepliedMessagesUseCase
+
+ @Before
+ fun setup() {
+ coEvery {
+ communicationRepository.taskIdsByOrder(any())
+ } returns flowOf(listOf(MOCK_TASK_ID_01, MOCK_TASK_ID_02))
+
+ coEvery {
+ communicationRepository.loadRepliedCommunications(any(), any())
+ } returns flowOf(listOf(MOCK_DISP_REPLY_COMMUNICATION_01, MOCK_DISP_REPLY_COMMUNICATION_02))
+
+ useCase = GetRepliedMessagesUseCase(
+ communicationRepository = communicationRepository,
+ dispatcher = dispatcher
+ )
+ }
+
+ @Test
+ fun `invoke should return list of replied messages`() = runTest(dispatcher) {
+ val expectedRepliedMessages = listOf(MOCK_MESSAGE_01, MOCK_MESSAGE_02)
+
+ val resultRepliedMessages: Flow> =
+ useCase(MOCK_ORDER_ID, "")
+
+ assertEquals(expectedRepliedMessages, resultRepliedMessages.first())
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetUnreadMessagesCountUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetUnreadMessagesCountUseCaseTest.kt
new file mode 100644
index 00000000..e527c9b4
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/GetUnreadMessagesCountUseCaseTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.CoroutineTestRule
+import de.gematik.ti.erp.app.changelogs.InAppMessageRepository
+import de.gematik.ti.erp.app.invoice.model.InvoiceData
+import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
+import de.gematik.ti.erp.app.messages.domain.usecase.GetUnreadMessagesCountUseCase
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.single
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import kotlin.test.assertEquals
+
+@ExperimentalCoroutinesApi
+class GetUnreadMessagesCountUseCaseTest {
+ @get:Rule
+ val coroutineRule = CoroutineTestRule()
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+ private val inAppMessageRepository: InAppMessageRepository = mockk()
+ private val invoiceRepository: InvoiceRepository = mockk()
+
+ private val profileId: ProfileIdentifier = "testProfileId"
+
+ @InjectMockKs
+ private lateinit var useCase: GetUnreadMessagesCountUseCase
+
+ @Before
+ fun setup() {
+ coEvery { communicationRepository.unreadMessagesCount(any()) } returns flowOf(15L)
+ coEvery {
+ invoiceRepository.getInvoiceTaskIdAndConsumedStatus(any())
+ } returns flowOf(listOf(InvoiceData.InvoiceStatus(taskId = "taskId1", consumed = false)))
+ coEvery { communicationRepository.loadFirstDispReqCommunications(any()) } returns flowOf(emptyList())
+ coEvery { communicationRepository.loadRepliedCommunications(any(), any()) } returns flowOf(emptyList())
+ coEvery { inAppMessageRepository.counter } returns flowOf(0L)
+ useCase = GetUnreadMessagesCountUseCase(communicationRepository, inAppMessageRepository, invoiceRepository, dispatcher)
+ }
+
+ @Test
+ fun `invoke should return flow of unread orders`() = runTest(dispatcher) {
+ val expectedUnreadCount = 15L
+
+ val resultOrders = useCase(profileId).single()
+
+ assertEquals(expectedUnreadCount, resultOrders)
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/MessageUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/MessageUseCaseTest.kt
new file mode 100644
index 00000000..bc4017cc
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/MessageUseCaseTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.CoroutineTestRule
+import de.gematik.ti.erp.app.messages.mappers.toMessage
+import de.gematik.ti.erp.app.messages.domain.model.OrderUseCaseData
+import de.gematik.ti.erp.app.prescription.model.Communication
+import de.gematik.ti.erp.app.prescription.model.CommunicationProfile
+import kotlinx.datetime.Instant
+import org.junit.Rule
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class MessageUseCaseTest {
+ @get:Rule
+ val coroutineRule = CoroutineTestRule()
+
+ @Test
+ fun `communication to message - normal`() {
+ val communication = Communication(
+ taskId = "",
+ orderId = "",
+ communicationId = "CID123456",
+ profile = CommunicationProfile.ErxCommunicationReply,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "ABC123456",
+ recipient = "ABC654321",
+ payload = """
+ {
+ "version": 1,
+ "info_text": "Hi!",
+ "supplyOptionsType": "shipment",
+ "url": "https://example.org"
+ }
+ """.trimIndent(),
+ consumed = false
+ )
+ val expected = OrderUseCaseData.Message(
+ communicationId = "CID123456",
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = "Hi!",
+ pickUpCodeDMC = null,
+ pickUpCodeHR = null,
+ link = "https://example.org",
+ consumed = false
+ )
+ assertEquals(expected, communication.toMessage())
+ }
+
+ @Test
+ fun `communication to message - payload partially empty`() {
+ val communication = Communication(
+ taskId = "",
+ orderId = "",
+ communicationId = "CID123456",
+ profile = CommunicationProfile.ErxCommunicationReply,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "ABC123456",
+ recipient = "ABC654321",
+ payload = """{ "version": 1, "supplyOptionsType": "shipment", "url": " ", "pickUpCodeHR": "" }""",
+ consumed = false
+ )
+ val expected = OrderUseCaseData.Message(
+ communicationId = "CID123456",
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = null,
+ pickUpCodeDMC = null,
+ pickUpCodeHR = null,
+ link = null,
+ consumed = false
+ )
+ assertEquals(expected, communication.toMessage())
+ }
+
+ @Test
+ fun `communication to message - payload broken`() {
+ val communication = Communication(
+ taskId = "",
+ orderId = "",
+ communicationId = "CID123456",
+ profile = CommunicationProfile.ErxCommunicationReply,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "ABC123456",
+ recipient = "ABC654321",
+ payload = """{ - """,
+ consumed = false
+ )
+ val expected = OrderUseCaseData.Message(
+ communicationId = "CID123456",
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = null,
+ pickUpCodeDMC = null,
+ pickUpCodeHR = null,
+ link = null,
+ consumed = false
+ )
+ assertEquals(expected, communication.toMessage())
+ }
+
+ @Test
+ fun `communication to message - invalid url`() {
+ val communication = Communication(
+ taskId = "",
+ orderId = "",
+ communicationId = "CID123456",
+ profile = CommunicationProfile.ErxCommunicationReply,
+ sentOn = Instant.fromEpochSeconds(123456),
+ sender = "ABC123456",
+ recipient = "ABC654321",
+ payload = """{ "version": 1, "supplyOptionsType": "shipment", "url": "ftp://example.org" }""",
+ consumed = false
+ )
+ val expected = OrderUseCaseData.Message(
+ communicationId = "CID123456",
+ sentOn = Instant.fromEpochSeconds(123456),
+ message = null,
+ pickUpCodeDMC = null,
+ pickUpCodeHR = null,
+ link = null,
+ consumed = false
+ )
+ assertEquals(expected, communication.toMessage())
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/SaveLocalCommunicationUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/SaveLocalCommunicationUseCaseTest.kt
new file mode 100644
index 00000000..601747d3
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/SaveLocalCommunicationUseCaseTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.CoroutineTestRule
+import de.gematik.ti.erp.app.messages.domain.usecase.SaveLocalCommunicationUseCase
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_PHARMACY_O1
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TASK_ID_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_TRANSACTION_ID
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import io.mockk.coEvery
+import io.mockk.coVerify
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@ExperimentalCoroutinesApi
+class SaveLocalCommunicationUseCaseTest {
+
+ @get:Rule
+ val coroutineRule = CoroutineTestRule()
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: SaveLocalCommunicationUseCase
+
+ @Before
+ fun setup() {
+ coEvery {
+ communicationRepository.saveLocalCommunication(
+ MOCK_TASK_ID_01,
+ MOCK_PHARMACY_O1.telematikId,
+ MOCK_TRANSACTION_ID
+ )
+ } returns Unit
+
+ useCase = SaveLocalCommunicationUseCase(
+ repository = communicationRepository,
+ dispatcher = dispatcher
+ )
+ }
+
+ @Test
+ fun `invoke should save local communication`() = runTest(dispatcher) {
+ val mockTaskId = MOCK_TASK_ID_01
+ val mockPharmacyId = MOCK_PHARMACY_O1.telematikId
+
+ useCase.invoke(mockTaskId, mockPharmacyId, MOCK_TRANSACTION_ID)
+
+ coVerify(exactly = 1) {
+ communicationRepository.saveLocalCommunication(mockTaskId, mockPharmacyId, MOCK_TRANSACTION_ID)
+ }
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt
new file mode 100644
index 00000000..5b020ced
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.messages.domain.usecase.UpdateCommunicationByCommunicationIdUseCase
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import io.mockk.coEvery
+import io.mockk.coVerify
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+
+@ExperimentalCoroutinesApi
+class UpdateCommunicationByCommunicationIdUseCaseTest {
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val communicationRepository: CommunicationRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: UpdateCommunicationByCommunicationIdUseCase
+
+ @Before
+ fun setup() {
+ useCase = UpdateCommunicationByCommunicationIdUseCase(
+ repository = communicationRepository,
+ dispatcher = dispatcher
+ )
+ }
+
+ @Test
+ fun `invoke should update communication status`() = runTest(dispatcher) {
+ val communicationId = MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01.communicationId
+ coEvery {
+ communicationRepository.setCommunicationStatus(communicationId, true)
+ } returns Unit
+
+ useCase(communicationId)
+
+ coVerify(exactly = 1) {
+ communicationRepository.setCommunicationStatus(communicationId, true)
+ }
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt
new file mode 100644
index 00000000..fb1ca1e3
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/messages/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.messages.usecase
+
+import de.gematik.ti.erp.app.messages.domain.usecase.UpdateCommunicationByOrderIdAndCommunicationIdUseCase
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertEquals
+
+@ExperimentalCoroutinesApi
+class UpdateCommunicationByOrderIdUseCaseTest {
+
+ private val dispatcher = StandardTestDispatcher()
+
+ private val repository: CommunicationRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: UpdateCommunicationByOrderIdAndCommunicationIdUseCase
+
+ @Before
+ fun setup() {
+ coEvery {
+ repository.loadDispReqCommunications(any())
+ } returns flowOf(
+ listOf(
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01,
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_02
+ )
+ )
+
+ coEvery {
+ repository.setCommunicationStatus(any(), any())
+ } returns Unit
+
+ useCase = UpdateCommunicationByOrderIdAndCommunicationIdUseCase(repository, dispatcher)
+ }
+
+ @Test
+ fun `invoke should update communication status`() = runTest(dispatcher) {
+ val communicationIdsCaptured = mutableListOf()
+
+ coEvery {
+ repository.loadDispReqCommunications(any())
+ } returns flowOf(
+ listOf(
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01,
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_02
+ )
+ )
+
+ coEvery {
+ repository.setCommunicationStatus(capture(communicationIdsCaptured), true)
+ } returns Unit
+
+ useCase(MessageMocks.MOCK_ORDER_ID)
+
+ assertEquals(
+ communicationIdsCaptured,
+ listOf(
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_01.communicationId,
+ MessageMocks.MOCK_DISP_REQ_COMMUNICATION_02.communicationId
+ )
+ )
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/HealthCardOrderUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/HealthCardOrderUseCaseTest.kt
deleted file mode 100644
index 154e2ecc..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/HealthCardOrderUseCaseTest.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orderhealthcard.usecase
-
-import org.junit.Test
-import kotlin.test.assertEquals
-
-private val contacts = """
- [
- {
- "name":"Kasse 1",
- "healthCardAndPinPhone":"+123123",
- "healthCardAndPinMail":"TestMail@test.de",
- "healthCardAndPinUrl":"https://www.TestURL.de/",
- "pinUrl":"https://www.TestPinURL.de/",
- "subjectCardAndPinMail":"testHeader",
- "bodyCardAndPinMail":"testBody",
- "subjectPinMail":"testHeader",
- "bodyPinMail":"testBody"
- },
- {
- "name":"Kasse 2",
- "healthCardAndPinPhone":null,
- "healthCardAndPinMail":null,
- "healthCardAndPinUrl":null,
- "pinUrl":null,
- "subjectCardAndPinMail":null,
- "bodyCardAndPinMail":null,
- "subjectPinMail":null,
- "bodyPinMail":null
- }
- ]
-""".trimIndent()
-
-class HealthCardOrderUseCaseTest {
-
- @Test
- fun `test loadHealthInsuranceContactsFromCSV() with expected data`() {
- loadHealthInsuranceContactsFromJSON(contacts.byteInputStream()).let {
- assertEquals("Kasse 1", it[0].name)
- assertEquals("TestMail@test.de", it[0].healthCardAndPinMail)
- assertEquals("+123123", it[0].healthCardAndPinPhone)
- assertEquals("https://www.TestURL.de/", it[0].healthCardAndPinUrl)
- assertEquals("https://www.TestPinURL.de/", it[0].pinUrl)
- assertEquals("testHeader", it[0].subjectCardAndPinMail)
- assertEquals("testBody", it[0].bodyCardAndPinMail)
- assertEquals("testHeader", it[0].subjectPinMail)
- assertEquals("testBody", it[0].bodyPinMail)
-
- assertEquals("Kasse 2", it[1].name)
- assertEquals(null, it[1].healthCardAndPinMail)
- assertEquals(null, it[1].healthCardAndPinPhone)
- assertEquals(null, it[1].healthCardAndPinUrl)
- assertEquals(null, it[1].pinUrl)
- assertEquals(null, it[1].subjectCardAndPinMail)
- assertEquals(null, it[1].bodyCardAndPinMail)
- assertEquals(null, it[1].subjectPinMail)
- assertEquals(null, it[1].bodyPinMail)
- }
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/LoadHealthInsuranceListUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/LoadHealthInsuranceListUseCaseTest.kt
new file mode 100644
index 00000000..d14f3e35
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/orderhealthcard/usecase/LoadHealthInsuranceListUseCaseTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.orderhealthcard.usecase
+
+import org.junit.Test
+import kotlin.test.assertEquals
+
+private val contacts = """
+ [
+ {
+ "name":"Kasse 1",
+ "healthCardAndPinPhone":"+123123",
+ "healthCardAndPinMail":"TestMail@test.de",
+ "healthCardAndPinUrl":"https://www.TestURL.de/",
+ "pinUrl":"https://www.TestPinURL.de/",
+ "subjectCardAndPinMail":"testHeader",
+ "bodyCardAndPinMail":"testBody",
+ "subjectPinMail":"testHeader",
+ "bodyPinMail":"testBody"
+ },
+ {
+ "name":"Kasse 2",
+ "healthCardAndPinPhone":null,
+ "healthCardAndPinMail":null,
+ "healthCardAndPinUrl":null,
+ "pinUrl":null,
+ "subjectCardAndPinMail":null,
+ "bodyCardAndPinMail":null,
+ "subjectPinMail":null,
+ "bodyPinMail":null
+ }
+ ]
+""".trimIndent()
+
+class LoadHealthInsuranceListUseCaseTest {
+
+ @Test
+ fun `test loadHealthInsuranceContactsFromCSV() with expected data`() {
+ loadHealthInsuranceContactsFromJSON(contacts.byteInputStream()).let {
+ assertEquals("Kasse 1", it[0].name)
+ assertEquals("TestMail@test.de", it[0].healthCardAndPinMail)
+ assertEquals("+123123", it[0].healthCardAndPinPhone)
+ assertEquals("https://www.TestURL.de/", it[0].healthCardAndPinUrl)
+ assertEquals("https://www.TestPinURL.de/", it[0].pinUrl)
+ assertEquals("testHeader", it[0].subjectCardAndPinMail)
+ assertEquals("testBody", it[0].bodyCardAndPinMail)
+ assertEquals("testHeader", it[0].subjectPinMail)
+ assertEquals("testBody", it[0].bodyPinMail)
+
+ assertEquals("Kasse 2", it[1].name)
+ assertEquals(null, it[1].healthCardAndPinMail)
+ assertEquals(null, it[1].healthCardAndPinPhone)
+ assertEquals(null, it[1].healthCardAndPinUrl)
+ assertEquals(null, it[1].pinUrl)
+ assertEquals(null, it[1].subjectCardAndPinMail)
+ assertEquals(null, it[1].bodyCardAndPinMail)
+ assertEquals(null, it[1].subjectPinMail)
+ assertEquals(null, it[1].bodyPinMail)
+ }
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/mocks/OrderMocks.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/mocks/OrderMocks.kt
deleted file mode 100644
index 43a7717b..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/mocks/OrderMocks.kt
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.mocks
-
-import de.gematik.ti.erp.app.invoice.model.InvoiceData
-import de.gematik.ti.erp.app.orders.repository.CachedPharmacy
-import de.gematik.ti.erp.app.orders.usecase.model.OrderUseCaseData
-import de.gematik.ti.erp.app.prescription.model.Communication
-import de.gematik.ti.erp.app.prescription.model.CommunicationProfile
-import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
-import de.gematik.ti.erp.app.prescription.usecase.model.Prescription
-import kotlinx.datetime.Instant
-
-object OrderMocks {
-
- internal const val MOCK_ORDER_ID = "testOrderId"
-
- internal const val MOCK_TASK_ID_01 = "123-001"
-
- internal const val MOCK_TASK_ID_02 = "456-002"
-
- private const val MOCK_COMMUNICATION_ID_01 = "CID-123-001"
-
- private const val MOCK_COMMUNICATION_ID_02 = "CID-456-002"
-
- internal const val MOCK_TRANSACTION_ID = "transactionMockId"
-
- internal val MOCK_PHARMACY_O1 = CachedPharmacy(name = "Pharmacy1", telematikId = "123")
-
- internal val MOCK_PHARMACY_O2 = CachedPharmacy(name = "Pharmacy2", telematikId = "456")
-
- private const val MOCK_PRACTITIONER_NAME = "Dr. John Doe"
-
- internal const val MOCK_PROFILE_IDENTIFIER = "testProfileIdentifier"
-
- private val MOCK_PAYLOAD = """
- {
- "version":1 ,
- "supplyOptionsType":"onPremise" ,
- "info_text":"mock message." ,
- "pickUpCodeHR":"T01__R01" ,
- "pickUpCodeDMC":"Test_01___Rezept_01___abcdefg12345" ,
- "url":"https://www.tree.fm/forest/33"
- }
- """.trimIndent()
-
- private val MOCK_PAYLOAD_02 = """
- {
- "version":1 ,
- "supplyOptionsType":"onPremise" ,
- "info_text":"mock message_02." ,
- "pickUpCodeHR":"T01__R02" ,
- "pickUpCodeDMC":"Test_01___Rezept_02___abcdefg12345" ,
- "url":"https://www.tree.fm/forest/35"
- }
- """.trimIndent()
-
- private val MOCK_PRACTITIONER = SyncedTaskData.Practitioner(
- name = MOCK_PRACTITIONER_NAME,
- qualification = "",
- practitionerIdentifier = " "
- )
-
- private val MOCK_CHIP_INFO = Prescription.PrescriptionChipInformation(
- isPartOfMultiplePrescription = false,
- numerator = null,
- denominator = null,
- start = null
- )
-
- private val MOCK_PRESCRIPTION_01 = Prescription.SyncedPrescription(
- taskId = MOCK_TASK_ID_01,
- name = null,
- redeemedOn = null,
- expiresOn = Instant.fromEpochSeconds(123456),
- state = SyncedTaskData.SyncedTask.Expired(
- expiredOn = Instant.fromEpochSeconds(123456)
- ),
- isIncomplete = false,
- organization = MOCK_PRACTITIONER_NAME,
- authoredOn = Instant.fromEpochSeconds(123456),
- acceptUntil = Instant.fromEpochSeconds(123456),
- isDirectAssignment = false,
- prescriptionChipInformation = MOCK_CHIP_INFO
- )
-
- private val MOCK_PRESCRIPTION_02 = Prescription.SyncedPrescription(
- taskId = MOCK_TASK_ID_02,
- name = null,
- redeemedOn = null,
- expiresOn = Instant.fromEpochSeconds(123456),
- state = SyncedTaskData.SyncedTask.Expired(
- expiredOn = Instant.fromEpochSeconds(123456)
- ),
- isIncomplete = false,
- organization = MOCK_PRACTITIONER_NAME,
- authoredOn = Instant.fromEpochSeconds(123456),
- acceptUntil = Instant.fromEpochSeconds(123456),
- isDirectAssignment = false,
- prescriptionChipInformation = MOCK_CHIP_INFO
- )
-
- private val MOCK_TASK_DETAIL_BUNDLE_01 = OrderUseCaseData.TaskDetailedBundle(
- taskId = MOCK_TASK_ID_01,
- prescription = MOCK_PRESCRIPTION_01,
- hasInvoice = true
- )
-
- private val MOCK_TASK_DETAIL_BUNDLE_02 = OrderUseCaseData.TaskDetailedBundle(
- taskId = MOCK_TASK_ID_02,
- prescription = MOCK_PRESCRIPTION_02,
- hasInvoice = true
- )
-
- internal val MOCK_ORDER_DETAIL = OrderUseCaseData.OrderDetail(
- orderId = MOCK_ORDER_ID,
- taskDetailedBundles = listOf(
- MOCK_TASK_DETAIL_BUNDLE_01,
- MOCK_TASK_DETAIL_BUNDLE_02
- ),
- sentOn = Instant.fromEpochSeconds(123456),
- pharmacy = OrderUseCaseData.Pharmacy(MOCK_PHARMACY_O1.name, ""),
- hasUnreadMessages = true
- )
-
- internal val MOCK_ORDER_01 = OrderUseCaseData.Order(
- orderId = MOCK_ORDER_ID,
- taskIds = listOf(MOCK_TASK_ID_01),
- prescriptions = emptyList(),
- sentOn = Instant.fromEpochSeconds(123456),
- pharmacy = OrderUseCaseData.Pharmacy(MOCK_PHARMACY_O1.name, ""),
- hasUnreadMessages = true
- )
-
- internal val MOCK_DISP_REQ_COMMUNICATION_01 = Communication(
- taskId = MOCK_TASK_ID_01,
- communicationId = MOCK_COMMUNICATION_ID_01,
- orderId = MOCK_ORDER_ID,
- profile = CommunicationProfile.ErxCommunicationDispReq,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "sender1",
- recipient = MOCK_PHARMACY_O1.name,
- payload = "payload1",
- consumed = true
- )
- internal val MOCK_DISP_REPLY_COMMUNICATION_01 = MOCK_DISP_REQ_COMMUNICATION_01.copy(
- profile = CommunicationProfile.ErxCommunicationReply,
- consumed = false,
- payload = MOCK_PAYLOAD
- )
- internal val MOCK_DISP_REQ_COMMUNICATION_02 = Communication(
- taskId = MOCK_TASK_ID_02,
- communicationId = MOCK_COMMUNICATION_ID_02,
- orderId = MOCK_ORDER_ID,
- profile = CommunicationProfile.ErxCommunicationDispReq,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "sender2",
- recipient = MOCK_PHARMACY_O2.name,
- payload = "payload2",
- consumed = true
- )
- internal val MOCK_DISP_REPLY_COMMUNICATION_02 = MOCK_DISP_REQ_COMMUNICATION_02.copy(
- profile = CommunicationProfile.ErxCommunicationReply,
- consumed = false,
- payload = MOCK_PAYLOAD_02
- )
-
- private val MOCK_ORGANIZATION = SyncedTaskData.Organization(
- name = "TestOrganization",
- address = SyncedTaskData.Address(
- line1 = "123 Main Street",
- line2 = "Apt 4",
- postalCode = "12345",
- city = "City"
- ),
- uniqueIdentifier = "org123",
- phone = "123-456-7890",
- mail = "info@testorg.com"
- )
-
- private val MOCK_PATIENT = SyncedTaskData.Patient(
- name = "Jane",
- address = SyncedTaskData.Address(
- line1 = "",
- line2 = "",
- postalCode = "",
- city = ""
- ),
- birthdate = null,
- insuranceIdentifier = "ins123"
- )
-
- private val MOCK_MEDICATION_REQ = SyncedTaskData.MedicationRequest(
- null, null, null, SyncedTaskData.AccidentType.None,
- null, null, false, null,
- SyncedTaskData.MultiplePrescriptionInfo(false), 1, null, null, SyncedTaskData.AdditionalFee.None
- )
-
- private fun mockChargeItem(
- itemDescription: String,
- itemFactor: Double,
- itemPrice: Double
- ): InvoiceData.ChargeableItem {
- return InvoiceData.ChargeableItem(
- description = InvoiceData.ChargeableItem.Description.PZN("PZN123"),
- text = itemDescription,
- factor = itemFactor,
- price = InvoiceData.PriceComponent(value = itemPrice, tax = 0.0)
- )
- }
-
- private val MOCK_INVOICE = InvoiceData.Invoice(
- totalAdditionalFee = 10.0,
- totalBruttoAmount = 120.0,
- currency = "EUR",
- chargeableItems = listOf(
- mockChargeItem("Description1", 2.0, 30.0),
- mockChargeItem("Description2", 1.5, 50.0)
- ),
- additionalDispenseItems = emptyList(),
- additionalInformation = listOf("AdditionalInfo1", "AdditionalInfo2")
- )
-
- internal val MOCK_INVOICE_01 = InvoiceData.PKVInvoice(
- profileId = "testProfileId",
- taskId = MOCK_TASK_ID_01,
- accessCode = "testAccessCode",
- timestamp = Instant.fromEpochSeconds(123456),
- pharmacyOrganization = MOCK_ORGANIZATION,
- practitionerOrganization = MOCK_ORGANIZATION,
- practitioner = MOCK_PRACTITIONER,
- patient = MOCK_PATIENT,
- medicationRequest = MOCK_MEDICATION_REQ,
- whenHandedOver = null,
- invoice = MOCK_INVOICE,
- dmcPayload = "testDmcPayload"
- )
-
- internal val MOCK_INVOICE_02 = InvoiceData.PKVInvoice(
- profileId = "testProfileId",
- taskId = MOCK_TASK_ID_02,
- accessCode = "testAccessCode",
- timestamp = Instant.fromEpochSeconds(123456),
- pharmacyOrganization = MOCK_ORGANIZATION,
- practitionerOrganization = MOCK_ORGANIZATION,
- practitioner = MOCK_PRACTITIONER,
- patient = MOCK_PATIENT,
- medicationRequest = MOCK_MEDICATION_REQ,
- whenHandedOver = null,
- invoice = MOCK_INVOICE,
- dmcPayload = "testDmcPayload"
- )
-
- internal val MOCK_SYNCED_TASK_DATA_01 = SyncedTaskData.SyncedTask(
- profileId = "testProfileId",
- taskId = MOCK_TASK_ID_01,
- accessCode = "testAccessCode",
- lastModified = Instant.fromEpochSeconds(123456),
- organization = MOCK_ORGANIZATION,
- practitioner = MOCK_PRACTITIONER,
- patient = MOCK_PATIENT,
- insuranceInformation = SyncedTaskData.InsuranceInformation(
- name = "TestInsurance",
- status = "Active"
- ),
- expiresOn = Instant.fromEpochSeconds(123456),
- acceptUntil = Instant.fromEpochSeconds(123456),
- authoredOn = Instant.fromEpochSeconds(123456),
- status = SyncedTaskData.TaskStatus.Ready,
- isIncomplete = false,
- pvsIdentifier = "testPvsIdentifier",
- failureToReport = "testFailureToReport",
- medicationRequest = MOCK_MEDICATION_REQ,
- medicationDispenses = emptyList(),
- communications = emptyList()
- )
-
- internal val MOCK_SYNCED_TASK_DATA_02 = SyncedTaskData.SyncedTask(
- profileId = "testProfileId",
- taskId = MOCK_TASK_ID_02,
- accessCode = "testAccessCode",
- lastModified = Instant.fromEpochSeconds(123456),
- organization = MOCK_ORGANIZATION,
- practitioner = MOCK_PRACTITIONER,
- patient = MOCK_PATIENT,
- insuranceInformation = SyncedTaskData.InsuranceInformation(
- name = "TestInsurance",
- status = "Active"
- ),
- expiresOn = Instant.fromEpochSeconds(123456),
- acceptUntil = Instant.fromEpochSeconds(123456),
- authoredOn = Instant.fromEpochSeconds(123456),
- status = SyncedTaskData.TaskStatus.Ready,
- isIncomplete = false,
- pvsIdentifier = "testPvsIdentifier",
- failureToReport = "testFailureToReport",
- medicationRequest = MOCK_MEDICATION_REQ,
- medicationDispenses = emptyList(),
- communications = emptyList()
- )
-
- internal val MOCK_MESSAGE_01 = OrderUseCaseData.Message(
- communicationId = MOCK_COMMUNICATION_ID_01,
- sentOn = Instant.fromEpochSeconds(123456),
- message = "mock message.",
- code = "Test_01___Rezept_01___abcdefg12345",
- link = "https://www.tree.fm/forest/33",
- consumed = false,
- hasInvoice = true
- )
-
- internal val MOCK_MESSAGE_02 = OrderUseCaseData.Message(
- communicationId = MOCK_COMMUNICATION_ID_02,
- sentOn = Instant.fromEpochSeconds(123456),
- message = "mock message_02.",
- code = "Test_01___Rezept_02___abcdefg12345",
- link = "https://www.tree.fm/forest/35",
- consumed = false,
- hasInvoice = true
- )
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingOrderIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingOrderIdUseCaseTest.kt
deleted file mode 100644
index bd0c1e4a..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingOrderIdUseCaseTest.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_DISP_REQ_COMMUNICATION_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_INVOICE_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_INVOICE_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_ORDER_DETAIL
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_ORDER_ID
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_PHARMACY_O1
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_PHARMACY_O2
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_SYNCED_TASK_DATA_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_SYNCED_TASK_DATA_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_02
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import io.mockk.coEvery
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class GetOrdersUsingOrderIdUseCaseTest {
-
- private val dispatcher = StandardTestDispatcher()
-
- private val communicationRepository: CommunicationRepository = mockk()
- private val invoiceRepository: InvoiceRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: GetOrderUsingOrderIdUseCase
-
- @Before
- fun setup() {
- coEvery {
- communicationRepository.loadDispReqCommunications(any())
- } returns flowOf(listOf(MOCK_DISP_REQ_COMMUNICATION_01, MOCK_DISP_REQ_COMMUNICATION_02))
-
- coEvery {
- communicationRepository.loadPharmacies()
- } returns flowOf(listOf(MOCK_PHARMACY_O1, MOCK_PHARMACY_O2))
-
- coEvery {
- communicationRepository.taskIdsByOrder(any())
- } returns flowOf(listOf(MOCK_TASK_ID_01, MOCK_TASK_ID_02))
-
- coEvery {
- communicationRepository.hasUnreadPrescription(any(), any())
- } returns flowOf(true)
-
- coEvery {
- communicationRepository.loadSyncedByTaskId(MOCK_TASK_ID_01)
- } returns flowOf(MOCK_SYNCED_TASK_DATA_01)
-
- coEvery {
- communicationRepository.loadSyncedByTaskId(MOCK_TASK_ID_02)
- } returns flowOf(MOCK_SYNCED_TASK_DATA_02)
-
- coEvery {
- communicationRepository.downloadMissingPharmacy(any())
- } returns Unit
-
- coEvery { invoiceRepository.invoiceById(MOCK_TASK_ID_01) } returns flowOf(MOCK_INVOICE_01)
-
- coEvery { invoiceRepository.invoiceById(MOCK_TASK_ID_02) } returns flowOf(MOCK_INVOICE_02)
-
- useCase = GetOrderUsingOrderIdUseCase(
- communicationRepository = communicationRepository,
- invoiceRepository = invoiceRepository,
- dispatcher = dispatcher
- )
- }
-
- @Test
- fun `invoke should return order detail`() = runTest(dispatcher) {
- val expectedOrderDetail = MOCK_ORDER_DETAIL
-
- val resultOrderDetail = useCase(MOCK_ORDER_ID)
-
- assertEquals(expectedOrderDetail, resultOrderDetail.first())
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingProfileIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingProfileIdUseCaseTest.kt
deleted file mode 100644
index 862ef0d6..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetOrdersUsingProfileIdUseCaseTest.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_ORDER_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_PHARMACY_O1
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_PROFILE_IDENTIFIER
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_01
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import de.gematik.ti.erp.app.orders.usecase.model.OrderUseCaseData
-import io.mockk.coEvery
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class GetOrdersUsingProfileIdUseCaseTest {
-
- private val dispatcher = StandardTestDispatcher()
-
- private val communicationRepository: CommunicationRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: GetOrdersUsingProfileIdUseCase
-
- @Before
- fun setup() {
- coEvery {
- communicationRepository.loadFirstDispReqCommunications(any())
- } returns flowOf(listOf(MOCK_DISP_REQ_COMMUNICATION_01))
-
- coEvery {
- communicationRepository.loadPharmacies()
- } returns flowOf(listOf(MOCK_PHARMACY_O1))
-
- coEvery {
- communicationRepository.taskIdsByOrder(any())
- } returns flowOf(listOf(MOCK_TASK_ID_01))
-
- coEvery {
- communicationRepository.hasUnreadPrescription(any(), any())
- } returns flowOf(true)
-
- coEvery {
- communicationRepository.downloadMissingPharmacy(any())
- } returns Unit
-
- useCase = GetOrdersUsingProfileIdUseCase(
- repository = communicationRepository,
- dispatcher = dispatcher
- )
- }
-
- @Test
- fun `invoke should return list of orders`() = runTest(dispatcher) {
- val expectedOrders = listOf(MOCK_ORDER_01)
-
- val resultOrders: Flow> = useCase(MOCK_PROFILE_IDENTIFIER)
-
- assertEquals(expectedOrders, resultOrders.first())
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetRepliedMessagesUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetRepliedMessagesUseCaseTest.kt
deleted file mode 100644
index eda9ecec..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetRepliedMessagesUseCaseTest.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.invoice.repository.InvoiceRepository
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_DISP_REPLY_COMMUNICATION_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_DISP_REPLY_COMMUNICATION_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_INVOICE_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_INVOICE_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_MESSAGE_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_MESSAGE_02
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_ORDER_ID
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_02
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import de.gematik.ti.erp.app.orders.usecase.model.OrderUseCaseData
-import io.mockk.coEvery
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class GetRepliedMessagesUseCaseTest {
-
- private val dispatcher = StandardTestDispatcher()
-
- private val communicationRepository: CommunicationRepository = mockk()
- private val invoiceRepository: InvoiceRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: GetRepliedMessagesUseCase
-
- @Before
- fun setup() {
- coEvery {
- communicationRepository.taskIdsByOrder(any())
- } returns flowOf(listOf(MOCK_TASK_ID_01, MOCK_TASK_ID_02))
-
- coEvery {
- communicationRepository.loadRepliedCommunications(any())
- } returns flowOf(listOf(MOCK_DISP_REPLY_COMMUNICATION_01, MOCK_DISP_REPLY_COMMUNICATION_02))
-
- coEvery {
- invoiceRepository.invoiceById(MOCK_TASK_ID_01)
- } returns flowOf(MOCK_INVOICE_01)
-
- coEvery {
- invoiceRepository.invoiceById(MOCK_TASK_ID_02)
- } returns flowOf(MOCK_INVOICE_02)
-
- useCase = GetRepliedMessagesUseCase(
- communicationRepository = communicationRepository,
- invoiceRepository = invoiceRepository,
- dispatcher = dispatcher
- )
- }
-
- @Test
- fun `invoke should return list of replied messages`() = runTest(dispatcher) {
- val expectedRepliedMessages = listOf(MOCK_MESSAGE_01, MOCK_MESSAGE_02)
-
- val resultRepliedMessages: Flow> =
- useCase(MOCK_ORDER_ID)
-
- assertEquals(expectedRepliedMessages, resultRepliedMessages.first())
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetUnreadOrdersUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetUnreadOrdersUseCaseTest.kt
deleted file mode 100644
index 518f9128..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/GetUnreadOrdersUseCaseTest.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.CoroutineTestRule
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import de.gematik.ti.erp.app.profiles.usecase.model.ProfilesUseCaseData
-import io.mockk.coEvery
-import io.mockk.every
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.single
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class GetUnreadOrdersUseCaseTest {
- @get:Rule
- val coroutineRule = CoroutineTestRule()
-
- private val dispatcher = StandardTestDispatcher()
-
- private val repository: CommunicationRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: GetUnreadOrdersUseCase
-
- private val profile: ProfilesUseCaseData.Profile = mockk()
-
- @Before
- fun setup() {
- coEvery { repository.unreadOrders(any()) } returns flowOf(10L)
- every { profile.id } returns "12"
-
- useCase = GetUnreadOrdersUseCase(repository, dispatcher)
- }
-
- @Test
- fun `invoke should return flow of unread orders`() = runTest(dispatcher) {
- val expectedUnreadCount = 10L
-
- val resultOrders = useCase(profile.id).single()
-
- assertEquals(expectedUnreadCount, resultOrders)
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/OrderUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/OrderUseCaseTest.kt
deleted file mode 100644
index 96aa488a..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/OrderUseCaseTest.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.CoroutineTestRule
-import de.gematik.ti.erp.app.orders.mappers.toMessage
-import de.gematik.ti.erp.app.orders.usecase.model.OrderUseCaseData
-import de.gematik.ti.erp.app.prescription.model.Communication
-import de.gematik.ti.erp.app.prescription.model.CommunicationProfile
-import kotlinx.datetime.Instant
-import org.junit.Rule
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-class OrderUseCaseTest {
- @get:Rule
- val coroutineRule = CoroutineTestRule()
-
- @Test
- fun `communication to message - normal`() {
- val communication = Communication(
- taskId = "",
- orderId = "",
- communicationId = "CID123456",
- profile = CommunicationProfile.ErxCommunicationReply,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "ABC123456",
- recipient = "ABC654321",
- payload = """
- {
- "version": 1,
- "info_text": "Hi!",
- "supplyOptionsType": "shipment",
- "url": "https://example.org"
- }
- """.trimIndent(),
- consumed = false
- )
- val expected = OrderUseCaseData.Message(
- communicationId = "CID123456",
- sentOn = Instant.fromEpochSeconds(123456),
- message = "Hi!",
- code = null,
- link = "https://example.org",
- consumed = false,
- hasInvoice = false
- )
- assertEquals(expected, communication.toMessage())
- }
-
- @Test
- fun `communication to message - payload partially empty`() {
- val communication = Communication(
- taskId = "",
- orderId = "",
- communicationId = "CID123456",
- profile = CommunicationProfile.ErxCommunicationReply,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "ABC123456",
- recipient = "ABC654321",
- payload = """{ "version": 1, "supplyOptionsType": "shipment", "url": " ", "pickUpCodeHR": "" }""",
- consumed = false
- )
- val expected = OrderUseCaseData.Message(
- communicationId = "CID123456",
- sentOn = Instant.fromEpochSeconds(123456),
- message = null,
- code = null,
- link = null,
- consumed = false,
- hasInvoice = false
- )
- assertEquals(expected, communication.toMessage())
- }
-
- @Test
- fun `communication to message - payload broken`() {
- val communication = Communication(
- taskId = "",
- orderId = "",
- communicationId = "CID123456",
- profile = CommunicationProfile.ErxCommunicationReply,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "ABC123456",
- recipient = "ABC654321",
- payload = """{ - """,
- consumed = false
- )
- val expected = OrderUseCaseData.Message(
- communicationId = "CID123456",
- sentOn = Instant.fromEpochSeconds(123456),
- message = null,
- code = null,
- link = null,
- consumed = false,
- hasInvoice = false
- )
- assertEquals(expected, communication.toMessage())
- }
-
- @Test
- fun `communication to message - invalid url`() {
- val communication = Communication(
- taskId = "",
- orderId = "",
- communicationId = "CID123456",
- profile = CommunicationProfile.ErxCommunicationReply,
- sentOn = Instant.fromEpochSeconds(123456),
- sender = "ABC123456",
- recipient = "ABC654321",
- payload = """{ "version": 1, "supplyOptionsType": "shipment", "url": "ftp://example.org" }""",
- consumed = false
- )
- val expected = OrderUseCaseData.Message(
- communicationId = "CID123456",
- sentOn = Instant.fromEpochSeconds(123456),
- message = null,
- code = null,
- link = null,
- consumed = false,
- hasInvoice = false
- )
- assertEquals(expected, communication.toMessage())
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/SaveLocalCommunicationUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/SaveLocalCommunicationUseCaseTest.kt
deleted file mode 100644
index cb21a060..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/SaveLocalCommunicationUseCaseTest.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.CoroutineTestRule
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_PHARMACY_O1
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TASK_ID_01
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks.MOCK_TRANSACTION_ID
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import io.mockk.coEvery
-import io.mockk.coVerify
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-@ExperimentalCoroutinesApi
-class SaveLocalCommunicationUseCaseTest {
-
- @get:Rule
- val coroutineRule = CoroutineTestRule()
-
- private val dispatcher = StandardTestDispatcher()
-
- private val communicationRepository: CommunicationRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: SaveLocalCommunicationUseCase
-
- @Before
- fun setup() {
- coEvery {
- communicationRepository.saveLocalCommunication(
- MOCK_TASK_ID_01,
- MOCK_PHARMACY_O1.telematikId,
- MOCK_TRANSACTION_ID
- )
- } returns Unit
-
- useCase = SaveLocalCommunicationUseCase(
- repository = communicationRepository,
- dispatcher = dispatcher
- )
- }
-
- @Test
- fun `invoke should save local communication`() = runTest(dispatcher) {
- val mockTaskId = MOCK_TASK_ID_01
- val mockPharmacyId = MOCK_PHARMACY_O1.telematikId
-
- useCase.invoke(mockTaskId, mockPharmacyId, MOCK_TRANSACTION_ID)
-
- coVerify(exactly = 1) {
- communicationRepository.saveLocalCommunication(mockTaskId, mockPharmacyId, MOCK_TRANSACTION_ID)
- }
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt
deleted file mode 100644
index 1e7772ae..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByCommunicationIdUseCaseTest.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import io.mockk.coEvery
-import io.mockk.coVerify
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-
-@ExperimentalCoroutinesApi
-class UpdateCommunicationByCommunicationIdUseCaseTest {
-
- private val dispatcher = StandardTestDispatcher()
-
- private val communicationRepository: CommunicationRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: UpdateCommunicationByCommunicationIdUseCase
-
- @Before
- fun setup() {
- useCase = UpdateCommunicationByCommunicationIdUseCase(
- repository = communicationRepository,
- dispatcher = dispatcher
- )
- }
-
- @Test
- fun `invoke should update communication status`() = runTest(dispatcher) {
- val communicationId = OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01.communicationId
- coEvery {
- communicationRepository.setCommunicationStatus(communicationId, true)
- } returns Unit
-
- useCase(communicationId)
-
- coVerify(exactly = 1) {
- communicationRepository.setCommunicationStatus(communicationId, true)
- }
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt
deleted file mode 100644
index fe155b8f..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/orders/usecase/UpdateCommunicationByOrderIdUseCaseTest.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.orders.usecase
-
-import de.gematik.ti.erp.app.orders.mocks.OrderMocks
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import io.mockk.coEvery
-import io.mockk.impl.annotations.InjectMockKs
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class UpdateCommunicationByOrderIdUseCaseTest {
-
- private val dispatcher = StandardTestDispatcher()
-
- private val repository: CommunicationRepository = mockk()
-
- @InjectMockKs
- private lateinit var useCase: UpdateCommunicationByOrderIdUseCase
-
- @Before
- fun setup() {
- coEvery {
- repository.loadDispReqCommunications(any())
- } returns flowOf(
- listOf(
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01,
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_02
- )
- )
-
- coEvery {
- repository.setCommunicationStatus(any(), any())
- } returns Unit
-
- useCase = UpdateCommunicationByOrderIdUseCase(repository, dispatcher)
- }
-
- @Test
- fun `invoke should update communication status`() = runTest(dispatcher) {
- val communicationIdsCaptured = mutableListOf()
-
- coEvery {
- repository.loadDispReqCommunications(any())
- } returns flowOf(
- listOf(
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01,
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_02
- )
- )
-
- coEvery {
- repository.setCommunicationStatus(capture(communicationIdsCaptured), true)
- } returns Unit
-
- useCase(OrderMocks.MOCK_ORDER_ID)
-
- assertEquals(
- communicationIdsCaptured,
- listOf(
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_01.communicationId,
- OrderMocks.MOCK_DISP_REQ_COMMUNICATION_02.communicationId
- )
- )
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/PharmacyDirectCommunicationTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/PharmacyDirectCommunicationTest.kt
index f8982198..28945cb2 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/PharmacyDirectCommunicationTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/PharmacyDirectCommunicationTest.kt
@@ -1,26 +1,26 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.pharmacy
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.util.encoders.Base64
-import kotlin.test.Test
+import org.junit.Test
import kotlin.test.assertEquals
private val testCert = """
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/mocks/PharmacyMocks.kt b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/mocks/PharmacyMocks.kt
new file mode 100644
index 00000000..f4249f6a
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/mocks/PharmacyMocks.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.pharmacy.mocks
+
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_02
+import de.gematik.ti.erp.app.pharmacy.model.PharmacyData
+import de.gematik.ti.erp.app.prescription.model.Quantity
+import de.gematik.ti.erp.app.prescription.model.Ratio
+import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
+import de.gematik.ti.erp.app.utils.FhirTemporal
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+import kotlin.time.Duration.Companion.days
+
+internal val MOCK_ACTIVE_PROFILE = ProfilesData.Profile(
+ id = "1",
+ name = "Mustermann",
+ color = ProfilesData.ProfileColorNames.PINK,
+ avatar = ProfilesData.Avatar.FemaleDoctor,
+ insuranceIdentifier = "12345567890",
+ insuranceType = ProfilesData.InsuranceType.GKV,
+ insurantName = "Mustermann",
+ insuranceName = "GesundheitsVersichert AG",
+ singleSignOnTokenScope = null,
+ active = false,
+ isConsentDrawerShown = false,
+ lastAuthenticated = null
+)
+
+internal val MOCK_SHIPPING_CONTACT = PharmacyData.ShippingContact(
+ name = "Max Mustermann",
+ line1 = "Musterstraße 1",
+ line2 = "",
+ postalCode = "12345",
+ city = "Musterstadt",
+ telephoneNumber = "0123456789",
+ mail = "",
+ deliveryInformation = ""
+)
+
+internal val MOCK_SCANNED_TASK_DATA_REDEEMABLE_01 = ScannedTaskData.ScannedTask(
+ index = 1,
+ name = "ScannedTaskName",
+ profileId = "1",
+ taskId = "1",
+ accessCode = "1",
+ redeemedOn = null,
+ scannedOn = Clock.System.now()
+)
+
+internal val MOCK_SYNCED_TASK_DATA_REDEEMABLE_01 = MOCK_SYNCED_TASK_DATA_01.copy(
+ expiresOn = Clock.System.now().plus(1.days),
+ acceptUntil = Clock.System.now().plus(1.days)
+)
+
+internal val MOCK_SCANNED_TASK_DATA_REDEEMABLE_02 = MOCK_SCANNED_TASK_DATA_REDEEMABLE_01.copy(
+ index = 2
+)
+
+internal val MOCK_SCANNED_TASK_DATA_REDEEMED_01 = MOCK_SCANNED_TASK_DATA_REDEEMABLE_01.copy(
+ index = 3,
+ redeemedOn = Clock.System.now().minus(1.days)
+)
+
+internal val MOCK_SYNCED_TASK_DATA_REDEEMABLE_02 = MOCK_SYNCED_TASK_DATA_02.copy(
+ expiresOn = Clock.System.now().plus(1.days),
+ acceptUntil = Clock.System.now().plus(1.days)
+)
+
+internal val MEDICATION = SyncedTaskData.Medication(
+ category = SyncedTaskData.MedicationCategory.entries[0],
+ vaccine = true,
+ text = "MedicationName",
+ form = "AEO",
+ lotNumber = "1234567890",
+ expirationDate = FhirTemporal.Instant(Instant.DISTANT_PAST),
+ identifier = SyncedTaskData.Identifier("1234567890"),
+ normSizeCode = "N1",
+ ingredientMedications = emptyList(),
+ manufacturingInstructions = null,
+ packaging = null,
+ ingredients = emptyList(),
+ amount = Ratio(
+ numerator = Quantity(
+ value = "1",
+ unit = "oz"
+ ),
+ denominator = null
+ )
+)
+
+internal val MOCK_SYNCED_TASK_DATA_REDEEMABLE_SELF_PAYER_03 = MOCK_SYNCED_TASK_DATA_02.copy(
+ expiresOn = Clock.System.now().plus(1.days),
+ acceptUntil = Clock.System.now().plus(1.days),
+ insuranceInformation = SyncedTaskData.InsuranceInformation(
+ name = "TestInsurance",
+ status = "Active",
+ coverageType = SyncedTaskData.CoverageType.SEL
+ ),
+ medicationRequest = SyncedTaskData.MedicationRequest(
+ MEDICATION, null, null, SyncedTaskData.AccidentType.None,
+ null, null, false, null,
+ SyncedTaskData.MultiplePrescriptionInfo(false), 1, null, null, SyncedTaskData.AdditionalFee.None
+ )
+)
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/ui/PharmacyControllerTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/ui/PharmacyControllerTest.kt
deleted file mode 100644
index c1d5fcf2..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/ui/PharmacyControllerTest.kt
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.pharmacy.ui
-
-import de.gematik.ti.erp.app.CoroutineTestRule
-import de.gematik.ti.erp.app.fhir.model.PharmacyContacts
-import de.gematik.ti.erp.app.pharmacy.presentation.PharmacyOrderController
-import de.gematik.ti.erp.app.pharmacy.model.PharmacyScreenData
-import de.gematik.ti.erp.app.pharmacy.usecase.GetOrderStateUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.GetShippingContactValidationUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacyOverviewUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.PharmacySearchUseCase
-import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
-import de.gematik.ti.erp.app.profiles.model.ProfilesData
-import de.gematik.ti.erp.app.profiles.usecase.GetActiveProfileUseCase
-import de.gematik.ti.erp.app.profiles.usecase.ProfilesUseCase
-import de.gematik.ti.erp.app.profiles.usecase.model.ProfileInsuranceInformation
-import de.gematik.ti.erp.app.profiles.usecase.model.ProfilesUseCaseData
-import io.mockk.coEvery
-import io.mockk.coVerify
-import io.mockk.every
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runTest
-import kotlinx.datetime.Instant
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-class PharmacySearchViewModelTest {
- @get:Rule
- val coroutineRule = CoroutineTestRule()
-
- private lateinit var pharmacyOrderController: PharmacyOrderController
- private lateinit var pharmacySearchUseCase: PharmacySearchUseCase
- private lateinit var pharmacyOverviewUseCase: PharmacyOverviewUseCase
- private lateinit var profileUseCase: ProfilesUseCase
- private lateinit var getActiveProfileUseCase: GetActiveProfileUseCase
- private lateinit var getOrderStateUseCase: GetOrderStateUseCase
- private lateinit var getShippingContactValidationUseCase: GetShippingContactValidationUseCase
-
- @Before
- fun setUp() {
- pharmacySearchUseCase = mockk()
- profileUseCase = mockk()
- getActiveProfileUseCase = mockk()
- pharmacyOverviewUseCase = mockk()
- getOrderStateUseCase = mockk()
- getShippingContactValidationUseCase = mockk()
- every { pharmacySearchUseCase.prescriptionDetailsForOrdering(any()) } returns flowOf(orderState)
- every { getActiveProfileUseCase.invoke() } returns flowOf(activeProfile)
- every { profileUseCase.profiles } returns flowOf(listOf(profile))
- every { getOrderStateUseCase.invoke() } returns flowOf(orderState)
-
- pharmacyOrderController = PharmacyOrderController(
- getActiveProfileUseCase = getActiveProfileUseCase,
- pharmacySearchUseCase = pharmacySearchUseCase,
- getOrderStateUseCase = getOrderStateUseCase,
- getShippingContactValidationUseCase = getShippingContactValidationUseCase,
- scope = TestScope()
- )
-
- pharmacyOrderController.onSelectPharmacy(pharmacy, orderOption)
- }
-
- @Test
- fun `order screen state - default`() = runTest {
- val result = pharmacyOrderController.updatedOrdersForTest.first()
- assertEquals(contacts, result.contact)
- assertEquals(prescriptions, result.orders)
- }
-
- @Test
- fun `order screen state - select prescriptions`() = runTest {
- pharmacyOrderController.onSelectPrescription(prescriptions[0])
- pharmacyOrderController.onSelectPrescription(prescriptions[1])
- pharmacyOrderController.onSelectPrescription(prescriptions[2])
-
- pharmacyOrderController.onDeselectPrescription(prescriptions[0])
-
- val state = pharmacyOrderController.updatedOrdersForTest.first()
-
- assertEquals(contacts, state.contact)
- assertEquals(
- listOf(prescriptions[1], prescriptions[2]),
- state.orders
- )
- }
-
- @Test
- fun `order screen state - set contacts`() = runTest {
- coEvery { pharmacySearchUseCase.saveShippingContact(any()) } answers { Unit }
- coEvery { pharmacySearchUseCase.prescriptionDetailsForOrdering("") } returns flowOf(
- PharmacyUseCaseData.OrderState(
- orders = prescriptions,
- contact = contacts
- )
- )
-
- pharmacyOrderController.onSaveContact(contacts)
-
- coroutineRule.testDispatcher.scheduler.runCurrent()
- coVerify(exactly = 1) { pharmacySearchUseCase.saveShippingContact(contacts) }
-
- val state = pharmacyOrderController.updatedOrdersForTest.first()
-
- assertEquals(contacts, state.contact)
- assertEquals(prescriptions, state.orders)
- }
-
- companion object {
- private val activeProfile = ProfilesUseCaseData.Profile(
- id = "test-active-profile",
- name = "Active Profile User",
- insurance = ProfileInsuranceInformation(),
- active = true,
- color = ProfilesData.ProfileColorNames.PINK,
- lastAuthenticated = null,
- ssoTokenScope = null,
- image = null,
- avatar = ProfilesData.Avatar.PersonalizedImage
- )
- private val profile = ProfilesUseCaseData.Profile(
- id = "test-inactive-profile",
- name = "Inactive Profile User",
- insurance = ProfileInsuranceInformation(
- insuranceType = ProfilesUseCaseData.InsuranceType.NONE
- ),
- active = false,
- color = ProfilesData.ProfileColorNames.SPRING_GRAY,
- avatar = ProfilesData.Avatar.PersonalizedImage,
- lastAuthenticated = null,
- ssoTokenScope = null
- )
-
- private val prescriptions = listOf(
- PharmacyUseCaseData.PrescriptionOrder(
- taskId = "A",
- accessCode = "1234",
- title = "Test",
- timestamp = Instant.fromEpochSeconds(0, 0),
- substitutionsAllowed = false,
- index = 0
- ),
- PharmacyUseCaseData.PrescriptionOrder(
- taskId = "B",
- accessCode = "1234",
- title = "Test",
- timestamp = Instant.fromEpochSeconds(0, 0),
- substitutionsAllowed = false,
- index = 0
-
- ),
- PharmacyUseCaseData.PrescriptionOrder(
- taskId = "C",
- accessCode = "1234",
- title = "Test",
- timestamp = Instant.fromEpochSeconds(0, 0),
- substitutionsAllowed = false,
- index = 0
-
- )
- )
-
- private val pharmacy = PharmacyUseCaseData.Pharmacy(
- id = "pharmacy",
- name = "Test - Pharmacy",
- address = null,
- location = null,
- distance = null,
- contacts = PharmacyContacts(
- phone = "0123456",
- mail = "mail@mail.com",
- url = "https://website.com",
- pickUpUrl = "https://pickup.com",
- deliveryUrl = "https://delivery.com",
- onlineServiceUrl = "https://online.com"
- ),
- provides = listOf(),
- openingHours = null,
- telematikId = "telematik-id"
- )
-
- private val orderOption = PharmacyScreenData.OrderOption.PickupService
-
- private val contacts = PharmacyUseCaseData.ShippingContact(
- name = "Beate Muster",
- line1 = "Friedrichstraße 136",
- line2 = "",
- postalCode = "10117",
- city = "Berlin",
- telephoneNumber = "0123456789",
- mail = "mail@mail.com",
- deliveryInformation = "Bitte!"
- )
-
- private val orderState = PharmacyUseCaseData.OrderState(
- orders = prescriptions,
- contact = contacts
- )
- }
-}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/usecase/GetOrderStateUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/usecase/GetOrderStateUseCaseTest.kt
new file mode 100644
index 00000000..cd90066c
--- /dev/null
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/pharmacy/usecase/GetOrderStateUseCaseTest.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.pharmacy.usecase
+
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_01
+import de.gematik.ti.erp.app.messages.mocks.MessageMocks.MOCK_SYNCED_TASK_DATA_02
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_ACTIVE_PROFILE
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SCANNED_TASK_DATA_REDEEMABLE_01
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SCANNED_TASK_DATA_REDEEMABLE_02
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SCANNED_TASK_DATA_REDEEMED_01
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SHIPPING_CONTACT
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SYNCED_TASK_DATA_REDEEMABLE_01
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SYNCED_TASK_DATA_REDEEMABLE_02
+import de.gematik.ti.erp.app.pharmacy.mocks.MOCK_SYNCED_TASK_DATA_REDEEMABLE_SELF_PAYER_03
+import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
+import de.gematik.ti.erp.app.pharmacy.usecase.mapper.toModel
+import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData.OrderState
+import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData.ShippingContact
+import de.gematik.ti.erp.app.prescription.repository.PrescriptionRepository
+import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
+import io.mockk.coEvery
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.mockk
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class GetOrderStateUseCaseTest {
+ private val dispatcher = StandardTestDispatcher()
+
+ private val profileRepository: ProfileRepository = mockk()
+ private val prescriptionRepository: PrescriptionRepository = mockk()
+ private val shippingContactRepository: ShippingContactRepository = mockk()
+
+ @InjectMockKs
+ private lateinit var useCase: GetOrderStateUseCase
+
+ @Before
+ fun setup() {
+ useCase = GetOrderStateUseCase(
+ profileRepository,
+ prescriptionRepository,
+ shippingContactRepository,
+ dispatcher
+ )
+ coEvery { profileRepository.activeProfile() } returns flowOf(MOCK_ACTIVE_PROFILE)
+ }
+
+ @Test
+ fun `invoke should return OrderState with 5 orders (3 synced, 2 scanned, 1 SelfPayer) and shippingContact`() {
+ coEvery { shippingContactRepository.shippingContact() } returns flowOf(MOCK_SHIPPING_CONTACT)
+ coEvery { prescriptionRepository.syncedTasks(any()) } returns flowOf(
+ listOf(
+ MOCK_SYNCED_TASK_DATA_REDEEMABLE_01,
+ MOCK_SYNCED_TASK_DATA_REDEEMABLE_02,
+ MOCK_SYNCED_TASK_DATA_REDEEMABLE_SELF_PAYER_03,
+ MOCK_SYNCED_TASK_DATA_01,
+ MOCK_SYNCED_TASK_DATA_02
+ )
+ )
+ coEvery { prescriptionRepository.scannedTasks(any()) } returns flowOf(
+ listOf(
+ MOCK_SCANNED_TASK_DATA_REDEEMABLE_01,
+ MOCK_SCANNED_TASK_DATA_REDEEMABLE_02,
+ MOCK_SCANNED_TASK_DATA_REDEEMED_01
+ )
+ )
+ runTest(dispatcher) {
+ val orderState = useCase().first()
+ assert(orderState.prescriptionOrders.size == 5)
+ assertEquals(MOCK_SHIPPING_CONTACT.toModel(), orderState.contact)
+ assertEquals(1, orderState.selfPayerPrescriptionIds.size)
+ }
+ }
+
+ @Test
+ fun `invoke should return OrderState with empty Orders and shippingContact`() {
+ coEvery { shippingContactRepository.shippingContact() } returns flowOf(null)
+ coEvery { prescriptionRepository.syncedTasks(any()) } returns flowOf(
+ listOf()
+ )
+ coEvery { prescriptionRepository.scannedTasks(any()) } returns flowOf(
+ listOf()
+ )
+ runTest(dispatcher) {
+ val orderState = useCase().first()
+
+ assertEquals(
+ OrderState(
+ prescriptionOrders = emptyList(),
+ selfPayerPrescriptionIds = emptyList(),
+ contact = ShippingContact.EmptyShippingContact
+ ),
+ orderState
+ )
+ }
+ }
+}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/MapperTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/MapperTest.kt
deleted file mode 100644
index 95d5a831..00000000
--- a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/MapperTest.kt
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-// TODO: work in progress - replace fhir parser
-
-//
-// package de.gematik.ti.erp.app.prescription
-//
-// import ca.uhn.fhir.context.FhirContext
-// import de.gematik.ti.erp.app.db.entities.v1.task.OrganizationEntityV1
-// import de.gematik.ti.erp.app.prescription.repository.FhirOrganization
-// import de.gematik.ti.erp.app.prescription.repository.extractResources
-// import de.gematik.ti.erp.app.prescription.repository.toOrganizationEntityV1
-// import org.hl7.fhir.r4.model.Bundle
-// import org.hl7.fhir.r4.model.Organization
-// import org.hl7.fhir.r4.model.Property
-// import java.util.zip.ZipEntry
-// import java.util.zip.ZipFile
-// import java.util.zip.ZipInputStream
-// import kotlin.test.BeforeTest
-// import kotlin.test.Test
-// import kotlin.test.assertEquals
-//
-// private typealias FlatBundle = Map
-//
-// class MapperTest {
-//
-// @BeforeTest
-// fun setUp() {
-// }
-//
-// @Test
-// fun `medication request`() {
-// val parser = FhirContext.forR4().newXmlParser()
-//
-// ZipFile("src/test/res/KBV_1.0.2_1000_Auswahl.zip").use { zip ->
-// zip.entries().asSequence().forEach { entry ->
-// println(entry.name)
-// zip.getInputStream(entry).use { input ->
-// val bundle = try {
-// parser.parseResource(input) as Bundle
-// } catch (e : Exception) {
-// println(e)
-// null
-// }
-//
-// if (bundle != null) {
-// val flatBundle = walkBundle(bundle)
-//
-// flatBundle.print()
-//
-// testOrganizationEntityV1(
-// flatBundle,
-// bundle.extractResources().firstOrNull()!!.toOrganizationEntityV1()
-// )
-//
-// flatBundle.print()
-// }
-// }
-// return@use
-// }
-// }
-// }
-//
-// private fun testOrganizationEntityV1(flatBundle: FlatBundle, organization: OrganizationEntityV1) {
-// val (organizationIndex) = flatBundle.indicesFor("resource","Organization")
-//
-// assertEquals(flatBundle["entry{$organizationIndex}.resource{0}.name"], organization.name)
-//
-// val (phoneIndex) = flatBundle.indicesFor("system", "phone", "entry{$organizationIndex}.resource{0}.telecom")
-//
-// val telecomPrefix = "entry{$organizationIndex}.resource{0}"
-// assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.system"], "phone")
-// assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.value"], organization.phone)
-// // assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.system"], "fax")
-// // assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.value"], organization.fax)
-// assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.system"], "email")
-// assertEquals(flatBundle["$telecomPrefix.telecom{$phoneIndex}.value"], organization.mail)
-// // entry{5}.resource{0}.telecom{0}.value: 0301234567
-// // entry{5}.resource{0}.telecom{1}.system: fax
-// // entry{5}.resource{0}.telecom{1}.value: 030123456789
-// // entry{5}.resource{0}.telecom{2}.system: email
-// // entry{5}.resource{0}.telecom{2}.value: mvz@e-mail.de
-// // entry{5}.resource{0}.address{0}.type: both
-// // entry{5}.resource{0}.address{0}.line: Herbert-Lewin-Platz 2
-//
-// }
-//
-//
-//
-// // fun List>.valueOf(path: String) = find { (p, _) -> p == path }?.second
-// //
-// // fun List>.pathPrefixForResource(type: String, prefix: String = ""): String? =
-// // this.find { (name, value) ->
-// // name.startsWith(prefix) && name.endsWith("resource") && value == type
-// // }?.let { (name) ->
-// // name
-// // }
-//
-//
-// //
-// // fun List>.pathPrefixFor(path: String, value: String, prefix: String = ""): String? {
-// // val pathRegex = path.replace("{?}", "\\{\\d}").toRegex()
-// //
-// // return find { (name, v) ->
-// // if (name.startsWith(prefix)) {
-// // name.removePrefix(prefix).matches(pathRegex) && v == value
-// // } else {
-// // false
-// // }
-// // }?.let { (name) ->
-// // name
-// // }
-// // }
-// //
-// // fun String.popPath() =
-// // this@popPath.substringBeforeLast('.')
-//
-//
-// }
-//
-// private fun FlatBundle.print() {
-// forEach { (k, v) ->
-// println("$k: $v")
-// }
-// }
-//
-// private val rg = """\{(\d)}""".toRegex()
-//
-// private fun FlatBundle.indicesFor(type: String, value: String, prefix: String = ""): List {
-// // find matching entry
-// val entry = entries.find { (name, v) ->
-// name.startsWith(prefix) && name.endsWith(type) && v == value
-// }
-//
-// // return all indices contained in `{?}`
-// return entry?.let { (name) ->
-// rg.findAll(name.removePrefix(prefix)).map { match ->
-// match.groupValues[1].toInt()
-// }.toList()
-// } ?: emptyList()
-// }
-//
-// private fun walkBundle(bundle: Bundle): FlatBundle {
-// val out = mutableMapOf()
-// bundle.children().forEach {
-// walk(property = it, name = null, out = out)
-// }
-// return out
-// }
-//
-// private fun walk(property: Property, name: String?, out: MutableMap) {
-// val prefix = name?.let { "$name.${property.name}" } ?: property.name
-//
-// property.values.forEachIndexed { index, base ->
-// if (base.isPrimitive) {
-// out[prefix] = base.primitiveValue()
-// }
-// if (base.isResource) {
-// out[prefix] = base.fhirType()
-// }
-// base.children().forEach {
-// walk(it, "$prefix{$index}", out)
-// }
-// }
-// }
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/TwoDCodeValidatorTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/TwoDCodeValidatorTest.kt
index 8353c610..59a56d20 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/TwoDCodeValidatorTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/TwoDCodeValidatorTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("ktlint:max-line-length")
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/model/SentOrCompletedTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/model/SentOrCompletedTest.kt
index 8542d1a1..ecc6c250 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/model/SentOrCompletedTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/ui/model/SentOrCompletedTest.kt
@@ -1,25 +1,25 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.prescription.ui.model
import kotlinx.datetime.Clock
-import kotlin.test.Test
+import org.junit.Test
import kotlin.test.assertEquals
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes
@@ -104,4 +104,14 @@ class SentOrCompletedTest {
assertEquals(SentOrCompletedPhrase.SentOn(lastModified), result)
}
+
+ @Test
+ fun `not Completed but provided`() {
+ val now = Clock.System.now()
+ val lastModified = now - 1.days
+
+ val result = sentOrCompleted(lastModified = lastModified, now = now, completed = false, provided = true)
+
+ assertEquals(SentOrCompletedPhrase.ProvidedOn(lastModified), result)
+ }
}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/usecase/PrescriptionUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/usecase/PrescriptionUseCaseTest.kt
index ec440b8e..f4dd8246 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/prescription/usecase/PrescriptionUseCaseTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/prescription/usecase/PrescriptionUseCaseTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("ktlint:max-line-length", "ktlint:argument-list-wrapping")
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/profiles/usecase/ProfilesUseCaseTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/profiles/usecase/ProfilesUseCaseTest.kt
index 6ab256ac..d32ea9de 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/profiles/usecase/ProfilesUseCaseTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/profiles/usecase/ProfilesUseCaseTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.profiles.usecase
@@ -55,7 +55,7 @@ class ProfilesUseCaseTest {
id = "1234567890",
name = "Test",
insurance = ProfileInsuranceInformation(),
- active = false,
+ isActive = false,
color = ProfilesData.ProfileColorNames.PINK,
lastAuthenticated = null,
ssoTokenScope = null,
@@ -88,11 +88,4 @@ class ProfilesUseCaseTest {
coVerify(exactly = 0) { profilesRepository.updateProfileName(any(), any()) }
}
-
- @Test
- fun `replace last profile`() = runTest {
- assertFails {
- profilesUseCase.removeAndSaveProfile(profile, "")
- }
- }
}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/utils/DateTimeTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/utils/DateTimeTest.kt
index 42d90097..422e6169 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/utils/DateTimeTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/utils/DateTimeTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.utils
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/utils/Proxy.kt b/app/android/src/test/java/de/gematik/ti/erp/app/utils/Proxy.kt
index 4ff42a72..334c36ec 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/utils/Proxy.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/utils/Proxy.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.utils
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestData.kt b/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestData.kt
index 645d91eb..8ff5234d 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestData.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestData.kt
@@ -1,23 +1,28 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
+@file:Suppress("UnusedPrivateMember", "MayBeConstant", "MagicNumber")
+
package de.gematik.ti.erp.app.utils
+import de.gematik.ti.erp.app.pharmacy.mocks.MEDICATION
+import de.gematik.ti.erp.app.prescription.model.Quantity
+import de.gematik.ti.erp.app.prescription.model.Ratio
import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
import kotlinx.datetime.Clock
@@ -66,29 +71,34 @@ fun syncedTask(
),
insuranceInformation = SyncedTaskData.InsuranceInformation(
name = null,
- status = null
+ status = null,
+ coverageType = SyncedTaskData.CoverageType.GKV
),
expiresOn = expiresOn,
acceptUntil = acceptUntil,
authoredOn = authoredOn,
status = status,
medicationRequest = SyncedTaskData.MedicationRequest(
- medication = SyncedTaskData.MedicationPZN(
+ medication = SyncedTaskData.Medication(
category = SyncedTaskData.MedicationCategory.ARZNEI_UND_VERBAND_MITTEL,
vaccine = false,
text = medicationName,
form = null,
lotNumber = null,
expirationDate = null,
- uniqueIdentifier = "",
+ identifier = SyncedTaskData.Identifier(),
normSizeCode = null,
- amount = SyncedTaskData.Ratio(
- numerator = SyncedTaskData.Quantity(
+ amount = Ratio(
+ numerator = Quantity(
value = "",
unit = ""
),
denominator = null
- )
+ ),
+ ingredientMedications = emptyList(),
+ manufacturingInstructions = null,
+ packaging = null,
+ ingredients = emptyList()
),
dateOfAccident = null,
location = null,
@@ -103,7 +113,7 @@ fun syncedTask(
SyncedTaskData.MedicationDispense(
dispenseId = null,
patientIdentifier = "",
- medication = null,
+ medication = MEDICATION,
wasSubstituted = false,
dosageInstruction = "",
performer = "",
@@ -114,6 +124,7 @@ fun syncedTask(
emptyList()
},
communications = listOf(),
+ lastMedicationDispense = medicationDispenseWhenHandedOver?.toInstant(),
failureToReport = "abcdefg"
)
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestExtensions.kt b/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestExtensions.kt
index bf1ad4c3..17548a38 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestExtensions.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/utils/TestExtensions.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.utils
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TestData.kt b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TestData.kt
index 03c09cd2..e8f6e71e 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TestData.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TestData.kt
@@ -1,29 +1,28 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
-@file:Suppress("ktlint:max-line-length", "ktlint:argument-list-wrapping")
+@file:Suppress("ktlint:max-line-length", "ktlint:argument-list-wrapping", "MayBeConst", "UnusedPrivateMember")
package de.gematik.ti.erp.app.vau
import de.gematik.ti.erp.app.vau.api.model.UntrustedCertList
import de.gematik.ti.erp.app.vau.api.model.UntrustedOCSPList
import kotlinx.datetime.Instant
-import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okio.ByteString.Companion.decodeBase64
import org.bouncycastle.cert.X509CertificateHolder
@@ -58,7 +57,7 @@ object TestCertificates {
const val SerialNumber = "347632017809591"
- // FIXME second ca is ocsp response only; production ocsp uses same ca as vau/idp
+ // TODO second ca is ocsp response only; production ocsp uses same ca as vau/idp
val JsonCertList = """
{
"add_roots": [],
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreIntegrationTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreIntegrationTest.kt
index 246a53c9..f328dc7c 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreIntegrationTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreIntegrationTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.vau
@@ -46,10 +46,10 @@ import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.bouncycastle.cert.X509CertificateHolder
import org.junit.Assume
+import org.junit.Before
import org.junit.Rule
+import org.junit.Test
import retrofit2.Retrofit
-import kotlin.test.BeforeTest
-import kotlin.test.Test
import kotlin.time.Duration
@OptIn(ExperimentalCoroutinesApi::class)
@@ -67,7 +67,7 @@ class TruststoreIntegrationTest {
encodeDefaults = true
}.asConverterFactory("application/json".toMediaType())
- @BeforeTest
+ @Before
fun setup() {
MockKAnnotations.init(this)
}
@@ -87,6 +87,7 @@ class TruststoreIntegrationTest {
chain.proceed(
chain.request().newBuilder()
.addHeader("User-Agent", BuildKonfig.USER_AGENT)
+ .header("X-Api-Key", BuildKonfig.ERP_API_KEY)
.addHeader("Accept", "application/json")
.build()
)
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreTest.kt
index 4b82e807..d0df1f62 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/vau/TruststoreTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("ktlint:max-line-length")
@@ -223,7 +223,7 @@ class TruststoreTest {
// use case tests
- @Test
+ /* @Test
fun `new instance of truststore contains no cached store - fetches and creates store from repository`() =
runTest {
coEvery { repository.withUntrusted(any()) } coAnswers {
@@ -348,7 +348,7 @@ class TruststoreTest {
coVerify(exactly = 1) { repository.invalidate() }
verify(exactly = 2) { trustedTruststore.vauPublicKey }
coVerify(exactly = 1) { trustedTruststore.checkValidity(any(), any()) }
- }
+ }*/
@Test(expected = Exception::class)
fun `truststore creation finally fails`() =
@@ -390,7 +390,7 @@ class TruststoreTest {
}
}
- @Test(expected = Exception::class)
+ /* @Test(expected = Exception::class)
fun `truststore creation succeeds - block throws exception`() =
runTest {
coEvery {
@@ -546,5 +546,5 @@ class TruststoreTest {
verify(exactly = 0) { trustedTruststore.vauPublicKey }
coVerify(exactly = 0) { trustedTruststore.checkValidity(any(), any()) }
}
- }
+ }*/
}
diff --git a/app/android/src/test/java/de/gematik/ti/erp/app/vau/repository/VauRepositoryTest.kt b/app/android/src/test/java/de/gematik/ti/erp/app/vau/repository/VauRepositoryTest.kt
index aa16593c..512c36a3 100644
--- a/app/android/src/test/java/de/gematik/ti/erp/app/vau/repository/VauRepositoryTest.kt
+++ b/app/android/src/test/java/de/gematik/ti/erp/app/vau/repository/VauRepositoryTest.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.vau.repository
diff --git a/app/demo-mode/build.gradle.kts b/app/demo-mode/build.gradle.kts
index 92f9ea0e..e46f351c 100644
--- a/app/demo-mode/build.gradle.kts
+++ b/app/demo-mode/build.gradle.kts
@@ -1,131 +1,20 @@
-@file:Suppress("UnstableApiUsage")
-
-import de.gematik.ti.erp.Dependencies
-import de.gematik.ti.erp.inject
-import org.owasp.dependencycheck.reporting.ReportGenerator.Format
+import de.gematik.ti.erp.app.plugins.names.AppDependencyNamesPlugin
plugins {
- id("com.android.library")
- kotlin("android")
- kotlin("plugin.serialization")
- id("org.jetbrains.compose")
- id("io.realm.kotlin")
- id("kotlin-parcelize")
- id("org.owasp.dependencycheck")
- id("com.jaredsburrows.license")
- id("de.gematik.ti.erp.dependencies")
- id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
- id("de.gematik.ti.erp.technical-requirements")
+ id("base-android-library")
+ id("de.gematik.ti.erp.names")
}
-licenseReport {
- generateCsvReport = false
- generateHtmlReport = false
- generateJsonReport = true
- copyJsonReportToAssets = true
-}
+val gematik = AppDependencyNamesPlugin()
android {
- namespace = "${de.gematik.ti.erp.AppDependenciesPlugin.APP_NAME_SPACE}.demomode"
+ namespace = gematik.moduleName("demomode")
defaultConfig {
- testApplicationId = "${de.gematik.ti.erp.AppDependenciesPlugin.APP_NAME_SPACE}.demomode.test"
- }
- kotlinOptions {
- jvmTarget = Dependencies.Versions.JavaVersion.KOTLIN_OPTIONS_JVM_TARGET
- freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
- }
- dependencyCheck {
- analyzers.assemblyEnabled = false
- suppressionFile = "${project.rootDir}" + "/config/dependency-check/suppressions.xml"
- formats = listOf(Format.HTML, Format.XML)
- scanConfigurations = configurations.filter {
- it.name.startsWith("api") ||
- it.name.startsWith("implementation") ||
- it.name.startsWith("kapt")
- }.map { it.name }
- }
- buildTypes {
- create("minifiedDebug")
- }
- // disable build config for demo-mode since we use only from features.
- // If needed we need a new-namespace
- buildFeatures {
- buildConfig = false
- resValues = false
+ testApplicationId = gematik.moduleName("demomode.test")
}
}
dependencies {
- implementation(project(":common"))
- implementation(kotlin("stdlib"))
- implementation(kotlin("reflect"))
- inject {
- coroutines {
- implementation(coroutinesCore)
- implementation(coroutinesAndroid)
- }
- dateTime {
- implementation(datetime)
- }
- androidX {
- implementation(legacySupport)
- implementation(appcompat)
- implementation(coreKtx)
- implementation(datastorePreferences)
- implementation(security)
- implementation(lifecycleViewmodel)
- implementation(lifecycleComposeRuntime)
- implementation(lifecycleProcess)
- implementation(composeNavigation)
- implementation(composeActivity)
- implementation(composePaging)
- implementation(camerax2)
- implementation(cameraxLifecycle)
- implementation(cameraxView)
- }
- accompanist {
- implementation(systemUiController)
- }
- dependencyInjection {
- compileOnly(kodeinCompose)
- }
- logging {
- implementation(napier)
- }
- lottie {
- implementation(lottie)
- }
- serialization {
- implementation(kotlinXJson)
- }
- crypto {
- implementation(bouncycastleBcprov)
- implementation(bouncycastleBcpkix)
- }
- compose {
- implementation(runtime)
- implementation(foundation)
- implementation(animation)
- implementation(uiTooling)
- implementation(preview)
- }
- material {
- implementation(material)
- implementation(material3)
- implementation(materialIcons)
- implementation(materialIconsExtended)
- }
- tracking {
- implementation(contentSquare)
- }
- }
-}
-
-secrets {
- defaultPropertiesFileName = if (project.rootProject.file("ci-overrides.properties").exists()
- ) {
- "ci-overrides.properties"
- } else {
- "gradle.properties"
- }
+ implementation(project(gematik.multiplatform))
+ implementation(project(gematik.uiComponents))
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeIntent.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeIntent.kt
index 575826f2..7b9d10ce 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeIntent.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeIntent.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode
@@ -31,6 +31,7 @@ object DemoModeIntent {
) = Intent(context, T::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
action = demoModeAction.name
+ `package` = context.packageName
}
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeObserver.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeObserver.kt
index c7c6db09..e4b3b37c 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeObserver.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/DemoModeObserver.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/DemoModeDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/DemoModeDataSource.kt
index 787204dc..9e547b68 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/DemoModeDataSource.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/DemoModeDataSource.kt
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource
+import de.gematik.ti.erp.app.db.entities.v1.changelogs.InAppMessageEntity
import de.gematik.ti.erp.app.demomode.datasource.data.DemoAuditEventInfo
import de.gematik.ti.erp.app.demomode.datasource.data.DemoPharmacyInfo.demoFavouritePharmacy
import de.gematik.ti.erp.app.demomode.datasource.data.DemoPrescriptionInfo.DemoScannedPrescription.demoScannedTask01
@@ -25,18 +26,23 @@ import de.gematik.ti.erp.app.demomode.datasource.data.DemoPrescriptionInfo.DemoS
import de.gematik.ti.erp.app.demomode.datasource.data.DemoPrescriptionInfo.DemoSyncedPrescription.syncedTask
import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo.demoProfile01
import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo.demoProfile02
+import de.gematik.ti.erp.app.demomode.datasource.data.inAppMessageEntity
import de.gematik.ti.erp.app.demomode.model.DemoModeProfile
import de.gematik.ti.erp.app.demomode.model.DemoModeProfileLinkedCommunication
import de.gematik.ti.erp.app.idp.api.models.PairingData
import de.gematik.ti.erp.app.idp.api.models.PairingResponseEntry
-import de.gematik.ti.erp.app.orders.repository.CachedPharmacy
+import de.gematik.ti.erp.app.messages.repository.CachedPharmacy
import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
+import de.gematik.ti.erp.app.prescription.model.CommunicationProfile.ErxCommunicationDispReq
+import de.gematik.ti.erp.app.prescription.model.CommunicationProfile.ErxCommunicationReply
import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
import de.gematik.ti.erp.app.protocol.model.AuditEventData
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.datetime.Clock
+import java.util.UUID
import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.hours
const val INDEX_OUT_OF_BOUNDS = -1
@@ -48,27 +54,47 @@ class DemoModeDataSource {
val profiles: MutableStateFlow> =
MutableStateFlow(mutableListOf(demoProfile01, demoProfile02))
+ private val syncedTasksList = listOf(
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Completed, index = 1),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Completed, index = 2),
+ syncedTask(
+ demoProfile01.id,
+ status = SyncedTaskData.TaskStatus.Ready,
+ index = 3,
+ isDirectAssignment = true
+ ),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Canceled, index = 4),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 5),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 6),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 7),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 8),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 9),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 10),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 11),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 12),
+ syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 13),
+
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 14),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 15),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 16),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 17),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 18),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 19),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Completed, index = 20),
+ syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Completed, index = 21),
+ syncedTask(
+ demoProfile02.id,
+ status = SyncedTaskData.TaskStatus.Completed,
+ index = 22,
+ isDirectAssignment = true
+ )
+ )
+
/**
* Data sources for the [syncedTasks] created in the demo-mode
*/
val syncedTasks: MutableStateFlow> =
- MutableStateFlow(
- mutableListOf(
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 1),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Completed, index = 2),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.InProgress, index = 3),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Canceled, index = 4),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 5),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 6),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 7),
- syncedTask(demoProfile01.id, status = SyncedTaskData.TaskStatus.Ready, index = 8),
-
- syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Ready, index = 9),
- syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Completed, index = 10),
- syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.Completed, index = 11),
- syncedTask(demoProfile02.id, status = SyncedTaskData.TaskStatus.InProgress, index = 12)
- )
- )
+ MutableStateFlow(syncedTasksList.toMutableList())
/**
* Data sources for the [scannedTasks] created in the demo-mode
@@ -110,12 +136,27 @@ class DemoModeDataSource {
)
/**
- * Data sources for the [communications] created in the demo-mode,
+ * Data sources for the [requestCommunication] created in the demo-mode,
* this is used as the source for communication between the user, pharmacy and the doctor
*/
val communications: MutableStateFlow> =
MutableStateFlow(mutableListOf())
+ val inAppMessages: MutableStateFlow> =
+ MutableStateFlow(mutableListOf(inAppMessageEntity))
+
+ val counter: MutableStateFlow =
+ MutableStateFlow(1)
+
+ val lastVersion: MutableStateFlow =
+ MutableStateFlow("1.26.0")
+
+ val lastUpdatedVersion: MutableStateFlow =
+ MutableStateFlow("1.26.0")
+
+ val showWelcomeMessage: MutableStateFlow =
+ MutableStateFlow(false)
+
/**
* Data source for the a [profileCommunicationLog] communication log that a particular profile has downloaded the information
*/
@@ -150,4 +191,115 @@ class DemoModeDataSource {
)
)
)
+
+ companion object {
+ val communicationPayload: String = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "info_text":"Beispieltext für die Kommunikation zwischen Patient und Apotheke"
+ "pickUpCodeHR":"1234567890" ,
+ "pickUpCodeDMC":"0123456789" ,
+ "url":"https://www.gematik.de/"
+ }
+ """.trimIndent()
+
+ fun replyCommunications(
+ profileId: String,
+ taskId: String,
+ communicationId: String,
+ pharmacyId: String,
+ orderId: String,
+ consumed: Boolean = false
+ ) = listOf(
+ // T-01
+ DemoModeProfileLinkedCommunication(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = communicationId,
+ sentOn = Clock.System.now().minus(3.days).minus(2.hours),
+ sender = pharmacyId,
+ consumed = consumed,
+ profile = ErxCommunicationReply,
+ // these values are kept empty while saving them
+ orderId = orderId,
+ payload = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "info_text":"Eine Beispielnachricht, wie eine Nachricht aus der Apotheke aussieht" ,
+ "pickUpCodeHR":"T01" ,
+ "pickUpCodeDMC":"DMC01" ,
+ "url":"https://github.com/gematik/E-Rezept-App-Android"
+ }
+ """.trimIndent(),
+ recipient = "Erika Mustermann"
+ ),
+ // T-02
+ DemoModeProfileLinkedCommunication(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = communicationId,
+ sentOn = Clock.System.now().minus(4.days).minus(3.hours),
+ sender = pharmacyId,
+ consumed = consumed,
+ profile = ErxCommunicationReply,
+ // these values are kept empty while saving them
+ orderId = orderId,
+ payload = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "info_text":"" ,
+ "pickUpCodeHR":"",
+ "pickUpCodeDMC":""
+ }
+ """.trimIndent(),
+ recipient = "Max Mustermann"
+ ),
+ // T-03
+ DemoModeProfileLinkedCommunication(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = communicationId,
+ sentOn = Clock.System.now().minus(5.days),
+ sender = pharmacyId,
+ consumed = consumed,
+ profile = ErxCommunicationReply,
+ orderId = orderId,
+ payload = """
+ {
+ "version":1 ,
+ "supplyOptionsType":"onPremise" ,
+ "pickUpCodeHR":"T03",
+ "pickUpCodeDMC":""
+ }
+ """.trimIndent(),
+ recipient = "Mustermann"
+ )
+ )
+
+ fun requestCommunication(
+ profileId: String,
+ taskId: String,
+ communicationId: String,
+ pharmacyId: String,
+ consumed: Boolean = false
+ ): DemoModeProfileLinkedCommunication {
+ val orderId = UUID.randomUUID().toString()
+ return DemoModeProfileLinkedCommunication(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = communicationId,
+ sentOn = Clock.System.now().minus(2.days).minus(1.hours),
+ sender = pharmacyId,
+ consumed = consumed,
+ profile = ErxCommunicationDispReq,
+ // these values are kept empty while saving them
+ orderId = orderId,
+ payload = "",
+ recipient = "Max Mustermann"
+ )
+ }
+ }
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoAuditEventInfo.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoAuditEventInfo.kt
index 793da09e..03b6967e 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoAuditEventInfo.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoAuditEventInfo.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource.data
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConsentInfo.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConsentInfo.kt
index 9be3337c..4c89e692 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConsentInfo.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConsentInfo.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource.data
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConstants.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConstants.kt
index 84520423..b50d0930 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConstants.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoConstants.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource.data
@@ -27,8 +27,9 @@ object DemoConstants {
internal val longerRandomTimeToday = Clock.System.now().minus((2..58).random().minutes)
internal const val PHARMACY_TELEMATIK_ID = "3-03.2.1006210000.10.795"
internal const val SYNCED_TASK_PRESET = "110.000.002.345.863"
+ internal const val DIRECT_ASSIGNMENT_TASK_PRESET = "169.000.002.345.863"
internal val NOW = Clock.System.now()
internal val START_DATE = Clock.System.now().minus(5.minutes)
internal val EXPIRY_DATE = Clock.System.now().plus(200.days)
- internal val SHORT_EXPIRY_DATE = Clock.System.now().plus(20.days)
+ internal val SHORT_EXPIRY_DATE = Clock.System.now().plus(30.days)
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoInAppMessageEntityDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoInAppMessageEntityDataSource.kt
new file mode 100644
index 00000000..6ac06e0d
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoInAppMessageEntityDataSource.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.datasource.data
+
+import de.gematik.ti.erp.app.db.entities.v1.changelogs.InAppMessageEntity
+
+val inAppMessageEntity = InAppMessageEntity().apply {
+ id = "01"
+ this.version = "1.27.1"
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPharmacyInfo.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPharmacyInfo.kt
index 2811d773..1d0e370d 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPharmacyInfo.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPharmacyInfo.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource.data
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPrescriptionInfo.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPrescriptionInfo.kt
index 48608340..58096ed2 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPrescriptionInfo.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoPrescriptionInfo.kt
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.datasource.data
+import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.DIRECT_ASSIGNMENT_TASK_PRESET
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.EXPIRY_DATE
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.NOW
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.SHORT_EXPIRY_DATE
@@ -25,16 +26,16 @@ import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.SYNCED_TASK_
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.longerRandomTimeToday
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.randomTimeToday
import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo.demoProfile01
+import de.gematik.ti.erp.app.prescription.model.Quantity
+import de.gematik.ti.erp.app.prescription.model.Ratio
import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationDispense
-import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationPZN
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Medication
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.MedicationRequest
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Organization
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Patient
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Practitioner
-import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Quantity
-import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.Ratio
import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
import de.gematik.ti.erp.app.utils.FhirTemporal
import java.util.UUID
@@ -42,9 +43,13 @@ import kotlin.random.Random
object DemoPrescriptionInfo {
- private val SYNCED_MEDICATION_NAMES = listOf(
+ private val BOOLEAN = listOf(true, false)
+
+ private val SYNCED_MEDICATION_NAMES = setOf(
"Ibuprofen 600", "Meloxicam", "Indomethacin", "Celebrex", "Ketoprofen", "Piroxicam", "Etodolac", "Toradol",
- "Aspirin", "Voltaren"
+ "Aspirin", "Voltaren", "Naproxen", "Mobic", "Aleve", "Motrin", "Advil", "Relafen", "Feldene", "Daypro",
+ "Clinoril", "Ansaid", "Orudis", "Dolobid", "Tolectin", "Lodine", "Nalfon", "Indocin", "Arthrotec", "Vimovo",
+ "Cataflam", "Pennsaid", "Zipsor", "Voltaren Gel"
)
val SCANNED_MEDICINE_NAMES = listOf(
@@ -242,37 +247,66 @@ object DemoPrescriptionInfo {
denominator = null
)
- private val MEDICATION = MedicationPZN(
- category = SyncedTaskData.MedicationCategory.values().random(),
+ private val MEDICATION = Medication(
+ category = SyncedTaskData.MedicationCategory.entries.toTypedArray().random(),
vaccine = Random.nextBoolean(),
text = SYNCED_MEDICATION_NAMES.random(),
form = codeToFormMapping.random(),
lotNumber = DEMO_MODE_IDENTIFIER,
expirationDate = FhirTemporal.Instant(EXPIRY_DATE),
- uniqueIdentifier = DEMO_MODE_IDENTIFIER,
+ identifier = SyncedTaskData.Identifier(DEMO_MODE_IDENTIFIER),
normSizeCode = normSizeMappings.random(),
- amount = RATIO
+ amount = RATIO,
+ ingredientMedications = emptyList(),
+ ingredients = emptyList(),
+ manufacturingInstructions = null,
+ packaging = null
+ )
+
+ private val COVERAGE_TYPE = SyncedTaskData.CoverageType.entries
+ .toTypedArray().random()
+
+ private fun medication(index: Int) = Medication(
+ category = SyncedTaskData.MedicationCategory.entries.toTypedArray().random(),
+ vaccine = Random.nextBoolean(),
+ text = SYNCED_MEDICATION_NAMES.elementAtOrElse(index) { SYNCED_MEDICATION_NAMES.random() },
+ form = codeToFormMapping.random(),
+ lotNumber = DEMO_MODE_IDENTIFIER,
+ expirationDate = FhirTemporal.Instant(EXPIRY_DATE),
+ identifier = SyncedTaskData.Identifier(DEMO_MODE_IDENTIFIER),
+ normSizeCode = normSizeMappings.random(),
+ amount = RATIO,
+ ingredientMedications = emptyList(),
+ ingredients = emptyList(),
+ manufacturingInstructions = null,
+ packaging = null
)
internal val MEDICATION_DISPENSE = MedicationDispense(
dispenseId = UUID.randomUUID().toString(),
patientIdentifier = PATIENT.insuranceIdentifier ?: "",
medication = MEDICATION,
- wasSubstituted = false,
+ wasSubstituted = BOOLEAN.random(),
dosageInstruction = DOSAGE.random(),
performer = PERFORMERS.random(),
whenHandedOver = null
)
- internal val MEDICATION_REQUEST = MedicationRequest(
- medication = MEDICATION,
+ internal val INSURANCE_INFORMATION = SyncedTaskData.InsuranceInformation(
+ name = null,
+ status = null,
+ coverageType = COVERAGE_TYPE
+ )
+
+ internal fun medicationRequest(index: Int) = MedicationRequest(
+ medication = medication(index),
dateOfAccident = null,
location = CITY_NAMES.random(),
- emergencyFee = Random.nextBoolean(),
+ emergencyFee = BOOLEAN.random(),
dosageInstruction = DOSAGE.random(),
multiplePrescriptionInfo = SyncedTaskData.MultiplePrescriptionInfo(),
note = DOCTORS_NOTES.random(),
- substitutionAllowed = Random.nextBoolean()
+ substitutionAllowed = BOOLEAN.random()
)
internal object DemoScannedPrescription {
@@ -302,29 +336,32 @@ object DemoPrescriptionInfo {
internal fun syncedTask(
profileIdentifier: ProfileIdentifier,
status: SyncedTaskData.TaskStatus = SyncedTaskData.TaskStatus.Ready,
+ isDirectAssignment: Boolean = false,
index: Int
- ) = SyncedTaskData.SyncedTask(
- profileId = profileIdentifier,
- taskId = "$SYNCED_TASK_PRESET.$index",
- isIncomplete = false,
- pvsIdentifier = DEMO_MODE_IDENTIFIER,
- accessCode = DEMO_MODE_IDENTIFIER,
- lastModified = longerRandomTimeToday,
- organization = ORGANIZATION,
- practitioner = PRACTITIONER,
- patient = PATIENT,
- insuranceInformation = SyncedTaskData.InsuranceInformation(
- name = null,
- status = null
- ),
- expiresOn = EXPIRY_DATE,
- acceptUntil = SHORT_EXPIRY_DATE,
- authoredOn = NOW,
- status = status,
- medicationRequest = MEDICATION_REQUEST,
- medicationDispenses = listOf(MEDICATION_DISPENSE),
- communications = emptyList(),
- failureToReport = ""
- )
+ ): SyncedTaskData.SyncedTask {
+ val taskId =
+ if (isDirectAssignment) "$DIRECT_ASSIGNMENT_TASK_PRESET.$index" else "$SYNCED_TASK_PRESET.$index"
+ return SyncedTaskData.SyncedTask(
+ profileId = profileIdentifier,
+ taskId = taskId,
+ isIncomplete = false, // making this true makes the prescription defective
+ pvsIdentifier = DEMO_MODE_IDENTIFIER,
+ accessCode = DEMO_MODE_IDENTIFIER,
+ lastModified = longerRandomTimeToday,
+ organization = ORGANIZATION,
+ practitioner = PRACTITIONER,
+ patient = PATIENT,
+ insuranceInformation = INSURANCE_INFORMATION,
+ expiresOn = EXPIRY_DATE,
+ acceptUntil = SHORT_EXPIRY_DATE,
+ authoredOn = NOW,
+ status = status,
+ medicationRequest = medicationRequest(index),
+ lastMedicationDispense = null,
+ medicationDispenses = listOf(MEDICATION_DISPENSE),
+ communications = emptyList(),
+ failureToReport = ""
+ )
+ }
}
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoProfileInfo.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoProfileInfo.kt
index e95773ae..cbc06687 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoProfileInfo.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/datasource/data/DemoProfileInfo.kt
@@ -1,40 +1,35 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("MagicNumber")
package de.gematik.ti.erp.app.demomode.datasource.data
-import de.gematik.ti.erp.app.BuildKonfig
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.EXPIRY_DATE
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.START_DATE
import de.gematik.ti.erp.app.demomode.model.DemoModeProfile
import de.gematik.ti.erp.app.idp.model.IdpData
import de.gematik.ti.erp.app.profiles.model.ProfilesData
import kotlinx.datetime.Instant
-import org.bouncycastle.cert.X509CertificateHolder
-import org.bouncycastle.util.encoders.Base64
import java.util.UUID
object DemoProfileInfo {
- private const val CAN = "123123"
- private val byteArray = Base64.decode(BuildKonfig.DEFAULT_VIRTUAL_HEALTH_CARD_CERTIFICATE)
- private val HEALTH_CERTIFICATE = X509CertificateHolder(byteArray)
+ private const val AUTHENTICATOR_NAME = "Gematik Versicherung"
private val singleSignOnToken = IdpData.SingleSignOnToken(
token = UUID.randomUUID().toString(),
expiresOn = EXPIRY_DATE,
@@ -42,10 +37,10 @@ object DemoProfileInfo {
)
// TODO: Add demo mode for different modes of sign-on scopes
- private val cardToken = IdpData.DefaultToken(
+ private val token = IdpData.ExternalAuthenticationToken(
token = singleSignOnToken,
- cardAccessNumber = CAN,
- healthCardCertificate = HEALTH_CERTIFICATE
+ authenticatorName = AUTHENTICATOR_NAME,
+ authenticatorId = UUID.randomUUID().toString()
)
private val HEALTH_INSURANCE_COMPANIES = listOf(
"GesundheitsVersichert AG",
@@ -70,7 +65,7 @@ object DemoProfileInfo {
profileName = "Erika Mustermann",
isActive = true,
color = ProfilesData.ProfileColorNames.SUN_DEW,
- insuranceType = ProfilesData.InsuranceType.PKV, // Note: Private insurance account
+ insuranceType = ProfilesData.InsuranceType.GKV,
avatar = listOf(
ProfilesData.Avatar.FemaleDoctor,
ProfilesData.Avatar.FemaleDoctorWithPhone,
@@ -99,14 +94,18 @@ object DemoProfileInfo {
lastAuthenticated = null
)
+ internal fun demoEmptyProfile(name: String) = profile(
+ name
+ )
+
private fun profile(
profileName: String,
isActive: Boolean = true,
- color: ProfilesData.ProfileColorNames = ProfilesData.ProfileColorNames.values().random(),
- avatar: ProfilesData.Avatar = ProfilesData.Avatar.values().random(),
+ color: ProfilesData.ProfileColorNames = ProfilesData.ProfileColorNames.entries.toTypedArray().random(),
+ avatar: ProfilesData.Avatar = ProfilesData.Avatar.entries.toTypedArray().random(),
insuranceType: ProfilesData.InsuranceType = ProfilesData.InsuranceType.GKV,
lastAuthenticated: Instant? = null,
- singleSignOnTokenScope: IdpData.SingleSignOnTokenScope? = cardToken
+ singleSignOnTokenScope: IdpData.SingleSignOnTokenScope? = token
): DemoModeProfile {
val uuid = UUID.randomUUID()
return DemoModeProfile(
@@ -125,5 +124,5 @@ object DemoProfileInfo {
)
}
- internal fun String.create() = profile(profileName = this)
+ internal fun String.create(): DemoModeProfile = profile(profileName = this)
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/di/DemoModeModule.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/di/DemoModeModule.kt
index 93c90dd9..70b72f14 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/di/DemoModeModule.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/di/DemoModeModule.kt
@@ -1,43 +1,51 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.di
import de.gematik.ti.erp.app.authentication.mapper.PromptAuthenticationProvider
+import de.gematik.ti.erp.app.changelogs.InAppMessageRepository
import de.gematik.ti.erp.app.consent.repository.ConsentRepository
import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
import de.gematik.ti.erp.app.demomode.mapper.authentication.DemoPromptAuthenticationProvider
import de.gematik.ti.erp.app.demomode.repository.consent.DemoConsentRepository
import de.gematik.ti.erp.app.demomode.repository.orders.DemoCommunicationRepository
import de.gematik.ti.erp.app.demomode.repository.orders.DemoDownloadCommunicationResource
-import de.gematik.ti.erp.app.demomode.repository.pharmacy.DemoPharmacyLocalDataSource
+import de.gematik.ti.erp.app.demomode.repository.orders.DemoInAppMessageRepository
+import de.gematik.ti.erp.app.demomode.repository.pharmacy.DemoFavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.demomode.repository.pharmacy.DemoOftenUsePharmacyLocalDataSource
+import de.gematik.ti.erp.app.demomode.repository.pharmacy.DemoRedeemLocalDataSource
+import de.gematik.ti.erp.app.demomode.repository.pharmacy.DemoShippingContactRepository
import de.gematik.ti.erp.app.demomode.repository.prescriptions.DemoPrescriptionsRepository
import de.gematik.ti.erp.app.demomode.repository.prescriptions.DemoTaskRepository
import de.gematik.ti.erp.app.demomode.repository.profiles.DemoProfilesRepository
import de.gematik.ti.erp.app.demomode.repository.protocol.DemoAuditEventsRepository
import de.gematik.ti.erp.app.demomode.usecase.idp.DemoIdpUseCase
import de.gematik.ti.erp.app.idp.usecase.IdpUseCase
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
-import de.gematik.ti.erp.app.pharmacy.repository.PharmacyLocalDataSource
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
+import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.FavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.OftenUsedPharmacyLocalDataSource
import de.gematik.ti.erp.app.prescription.repository.PrescriptionRepository
import de.gematik.ti.erp.app.prescription.repository.TaskRepository
import de.gematik.ti.erp.app.profiles.repository.ProfileRepository
import de.gematik.ti.erp.app.protocol.repository.AuditEventsRepository
+import de.gematik.ti.erp.app.redeem.repository.datasource.RedeemLocalDataSource
import org.kodein.di.DI
import org.kodein.di.bindProvider
import org.kodein.di.bindSingleton
@@ -49,15 +57,21 @@ val demoModeModule = DI.Module("demoModeModule") {
bindSingleton { DemoModeDataSource() }
}
+// TODO DemoMode
fun DI.MainBuilder.demoModeOverrides() {
bindProvider(overrides = true) { DemoProfilesRepository(instance()) }
bindProvider(overrides = true) { DemoConsentRepository() }
bindProvider(overrides = true) { DemoPrescriptionsRepository(instance()) }
bindProvider(overrides = true) { DemoAuditEventsRepository(instance()) }
- bindProvider(overrides = true) { DemoPharmacyLocalDataSource(instance()) }
+ bindProvider(overrides = true) { DemoRedeemLocalDataSource(instance()) }
+ bindProvider(overrides = true) { DemoFavouritePharmacyLocalDataSource(instance()) }
+ bindProvider(overrides = true) { DemoOftenUsePharmacyLocalDataSource(instance()) }
bindProvider(overrides = true) { DemoCommunicationRepository(instance(), instance()) }
+ bindProvider(overrides = true) { DemoInAppMessageRepository(instance()) }
bindProvider(overrides = true) { DemoTaskRepository() }
bindProvider(overrides = true) { DemoIdpUseCase(instance()) }
+ bindProvider(overrides = true) { DemoShippingContactRepository() }
+
// these two are added for future functions
bindProvider(overrides = true) { DemoPromptAuthenticationProvider() }
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/extensions/NapierExtensions.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/extensions/NapierExtensions.kt
new file mode 100644
index 00000000..24cdebb5
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/extensions/NapierExtensions.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.extensions
+
+import io.github.aakira.napier.Napier
+
+internal fun Napier.demo(throwable: Throwable? = null, message: () -> String) = i(throwable, "Demo-mode", message)
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/mapper/authentication/DemoPromptAuthenticationProvider.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/mapper/authentication/DemoPromptAuthenticationProvider.kt
index 4f4fed66..960fc994 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/mapper/authentication/DemoPromptAuthenticationProvider.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/mapper/authentication/DemoPromptAuthenticationProvider.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.mapper.authentication
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfile.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfile.kt
index 4dfb8e9c..e6657da4 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfile.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfile.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.model
@@ -48,7 +48,7 @@ fun DemoModeProfile.toProfile() = ProfilesData.Profile(
id = id,
color = color,
avatar = avatar,
- personalizedImage = personalizedImage,
+ image = personalizedImage,
name = name,
insurantName = insurantName,
insuranceIdentifier = insuranceIdentifier,
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfileLinkedCommunication.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfileLinkedCommunication.kt
index 8189c541..d4fed8a6 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfileLinkedCommunication.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeProfileLinkedCommunication.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.model
@@ -24,6 +24,7 @@ import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import java.util.UUID
+import kotlin.time.Duration.Companion.minutes
/**
* This is created to link the communication with a particular profile
@@ -54,6 +55,7 @@ fun DemoModeProfileLinkedCommunication.toSyncedTaskDataCommunication() =
consumed = consumed
)
+@Suppress("MagicNumber")
internal fun DemoModeSentCommunicationJson.toDemoModeProfileLinkedCommunication(
profileId: ProfileIdentifier
) =
@@ -66,7 +68,7 @@ internal fun DemoModeSentCommunicationJson.toDemoModeProfileLinkedCommunication(
true -> CommunicationProfile.ErxCommunicationDispReq
false -> CommunicationProfile.ErxCommunicationReply
},
- sentOn = Clock.System.now(),
+ sentOn = Clock.System.now().minus((1..20).random().minutes),
sender = payload.firstNotNullOfOrNull { it.name } ?: "",
recipient = recipient.firstNotNullOfOrNull { it.identifier.value } ?: "",
payload = payload.firstNotNullOfOrNull { it.contentString },
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeSentCommunicationJson.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeSentCommunicationJson.kt
index c24b3ec5..f5ef60e7 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeSentCommunicationJson.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/model/DemoModeSentCommunicationJson.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.model
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/consent/DemoConsentRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/consent/DemoConsentRepository.kt
index aad18896..660f2f74 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/consent/DemoConsentRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/consent/DemoConsentRepository.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.repository.consent
@@ -45,4 +45,6 @@ class DemoConsentRepository : ConsentRepository {
override fun isConsentDrawerShown(profileId: ProfileIdentifier): Boolean = true
override fun isConsentGranted(it: JsonElement): Boolean = true
+
+ override fun getInsuranceId(profileId: ProfileIdentifier): String = "X1234567890"
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoCommunicationRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoCommunicationRepository.kt
index 0311b6a1..2815b72e 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoCommunicationRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoCommunicationRepository.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("TooManyFunctions", "MagicNumber")
@@ -26,26 +26,32 @@ import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
import de.gematik.ti.erp.app.demomode.datasource.data.DemoConstants.longerRandomTimeToday
import de.gematik.ti.erp.app.demomode.datasource.data.DemoPharmacyInfo.PHARMACY_NAMES
import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo
+import de.gematik.ti.erp.app.demomode.extensions.demo
import de.gematik.ti.erp.app.demomode.model.DemoModeProfileLinkedCommunication
+import de.gematik.ti.erp.app.demomode.model.toProfile
import de.gematik.ti.erp.app.demomode.model.toSyncedTaskDataCommunication
-import de.gematik.ti.erp.app.orders.repository.CachedPharmacy
-import de.gematik.ti.erp.app.orders.repository.CommunicationRepository
+import de.gematik.ti.erp.app.fhir.model.Pharmacy
+import de.gematik.ti.erp.app.messages.repository.CachedPharmacy
+import de.gematik.ti.erp.app.messages.repository.CommunicationRepository
import de.gematik.ti.erp.app.prescription.model.Communication
import de.gematik.ti.erp.app.prescription.model.CommunicationProfile.ErxCommunicationDispReq
import de.gematik.ti.erp.app.prescription.model.CommunicationProfile.ErxCommunicationReply
import de.gematik.ti.erp.app.prescription.model.ScannedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
+import de.gematik.ti.erp.app.profiles.model.ProfilesData
import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
+import io.github.aakira.napier.Napier
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
+import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
@@ -53,7 +59,10 @@ import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.withContext
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
+import java.util.UUID
import kotlin.random.Random
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.minutes
class DemoCommunicationRepository(
private val dataSource: DemoModeDataSource,
@@ -62,9 +71,68 @@ class DemoCommunicationRepository(
) : CommunicationRepository {
private val scope = CoroutineScope(dispatcher)
- override val pharmacyCacheError = MutableSharedFlow()
+ override val pharmacyCacheError = Channel()
+ override val pharmacyDownloaded = Channel()
override suspend fun downloadCommunications(profileId: ProfileIdentifier) = withContext(dispatcher) {
+ Napier.demo { "Simulating communication download" }
+ dataSource.communications.value = dataSource.communications.updateAndGet { communications ->
+ val taskIds = dataSource.syncedTasks.first()
+ .filter { it.profileId == profileId }
+ .filter { it.status == SyncedTaskData.TaskStatus.InProgress }
+ .map { it.taskId }
+ communications.all { it.taskId in taskIds }
+
+ taskIds.map { taskId ->
+ when {
+ // if the task is not already in the list
+ communications.none { it.taskId == taskId && it.profile == ErxCommunicationReply } -> {
+ communications.add(
+ DemoModeDataSource.replyCommunications(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = UUID.randomUUID().toString(),
+ orderId = UUID.randomUUID().toString(),
+ pharmacyId = UUID.randomUUID().toString()
+ )[0]
+ )
+ }
+
+ communications.filter { it.taskId == taskId && it.profile == ErxCommunicationReply }.size == 1 -> {
+ val firstCommunication =
+ communications.first { it.taskId == taskId && it.profile == ErxCommunicationReply }
+
+ communications.add(
+ DemoModeDataSource.replyCommunications(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = UUID.randomUUID().toString(),
+ orderId = firstCommunication.orderId,
+ pharmacyId = firstCommunication.sender
+ )[1]
+ )
+ }
+
+ communications.filter { it.taskId == taskId && it.profile == ErxCommunicationReply }.size == 2 -> {
+ val firstCommunication =
+ communications.first { it.taskId == taskId && it.profile == ErxCommunicationReply }
+
+ communications.add(
+ DemoModeDataSource.replyCommunications(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = UUID.randomUUID().toString(),
+ orderId = firstCommunication.orderId,
+ pharmacyId = firstCommunication.sender
+ )[2]
+ )
+ }
+
+ else -> communications
+ }
+ }
+ communications
+ }
delay(1000) // simulates a network delay of one second
Result.success(Unit)
}
@@ -91,86 +159,111 @@ class DemoCommunicationRepository(
override fun loadPharmacies(): Flow> = dataSource.cachedPharmacies
- override suspend fun downloadMissingPharmacy(telematikId: String) {
+ override suspend fun downloadMissingPharmacy(telematikId: String): Result {
+ val addedPharmacy = CachedPharmacy(
+ telematikId = telematikId,
+ name = PHARMACY_NAMES.random()
+ )
withContext(dispatcher) {
dataSource.cachedPharmacies.value = dataSource.cachedPharmacies.updateAndGet { cachedPharmacies ->
- cachedPharmacies.add(
- CachedPharmacy(
- telematikId = telematikId,
- name = PHARMACY_NAMES.random()
- )
- )
+ cachedPharmacies.add(addedPharmacy)
cachedPharmacies
}
}
+ return Result.success(addedPharmacy)
}
override fun loadSyncedByTaskId(taskId: String): Flow =
- dataSource.syncedTasks.map { syncedTasks ->
- syncedTasks.find { it.taskId == taskId }
- }.flowOn(dispatcher)
+ try {
+ dataSource.syncedTasks.map { syncedTasks ->
+ syncedTasks.find { it.taskId == taskId }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(null)
+ }
override fun loadScannedByTaskId(taskId: String): Flow =
- dataSource.scannedTasks.map { scannedTask ->
- scannedTask.find { it.taskId == taskId }
- }.flowOn(dispatcher)
-
- override fun loadDispReqCommunications(orderId: String) =
- dataSource.communications.mapNotNull { communications ->
- communications
- .filter { it.orderId == orderId && it.profile == ErxCommunicationDispReq }
- .map { it.toSyncedTaskDataCommunication() }
- }.flowOn(dispatcher)
+ try {
+ dataSource.scannedTasks.map { scannedTask ->
+ scannedTask.find { it.taskId == taskId }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(null)
+ }
- override fun loadFirstDispReqCommunications(profileId: ProfileIdentifier): Flow> {
- return loadOrdersByProfileId(profileId).mapNotNull { communications ->
- communications.asSequence().filter {
- it.profileId == profileId && it.profile == ErxCommunicationDispReq
- }
- .map { it.toSyncedTaskDataCommunication() }
- .sortedByDescending { it.sentOn }
- .distinctBy { it.orderId }
- .toList()
- }.flowOn(dispatcher)
- }
+ override fun loadDispReqCommunications(orderId: String): Flow> =
+ try {
+ dataSource.communications.mapNotNull { communications ->
+ communications
+ .also { Napier.demo { "LoadDispReqCommunications ${it.size}" } }
+ .filter { it.orderId == orderId && it.profile == ErxCommunicationDispReq }
+ .map { it.toSyncedTaskDataCommunication() }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(emptyList())
+ }
- override fun loadRepliedCommunications(taskIds: List) =
- dataSource.communications.mapNotNull { communications ->
- taskIds.mapNotNull { taskId ->
- communications.find { it.taskId == taskId && it.profile == ErxCommunicationReply }
- }.sortedByDescending { it.sentOn }
- .map { it.toSyncedTaskDataCommunication() }
- }.flowOn(dispatcher)
+ override fun loadFirstDispReqCommunications(profileId: ProfileIdentifier): Flow> =
+ try {
+ loadOrdersByProfileId(profileId).mapNotNull { communications ->
+ communications.asSequence().filter {
+ it.profileId == profileId && it.profile == ErxCommunicationDispReq
+ }
+ .map { it.toSyncedTaskDataCommunication() }
+ .sortedByDescending { it.sentOn }
+ .distinctBy { it.orderId }
+ .toList()
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(emptyList())
+ }
- override fun loadCommunicationsWithTaskId(taskIds: List): Flow> =
- dataSource.communications.mapNotNull { communications ->
- taskIds.mapNotNull { taskId ->
- communications.find { it.taskId == taskId }
- }.map { it.toSyncedTaskDataCommunication() }
+ override fun loadRepliedCommunications(taskIds: List, telematikId: String): Flow> =
+ try {
+ dataSource.communications
+ .mapNotNull { communications ->
+ communications
+ .filter { it.taskId in taskIds && it.profile == ErxCommunicationReply }
+ .sortedByDescending { it.sentOn }
+ .map { it.toSyncedTaskDataCommunication() }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(emptyList())
}
- override fun hasUnreadPrescription(taskIds: List, orderId: String): Flow =
- dataSource.communications.mapNotNull { communications ->
- val booleans = taskIds.map { taskId ->
- communications.find { it.taskId == taskId && !it.consumed }?.consumed == false
- }
- booleans.any { it }
- }.flowOn(dispatcher)
+ override fun hasUnreadDispenseMessage(taskIds: List, orderId: String): Flow =
+ try {
+ dataSource.communications.mapNotNull { communications ->
+ val booleans = taskIds.map { taskId ->
+ communications.find { it.taskId == taskId && !it.consumed }?.consumed == false
+ }
+ booleans.any { it }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(false)
+ }
- override fun hasUnreadPrescription(profileId: ProfileIdentifier): Flow =
- dataSource.communications.mapNotNull { communications ->
- communications.any { it.profileId == profileId && !it.consumed }
- }.flowOn(dispatcher)
+ override fun hasUnreadDispenseMessage(profileId: ProfileIdentifier): Flow =
+ try {
+ dataSource.communications.mapNotNull { communications ->
+ communications.any { it.profileId == profileId && !it.consumed }
+ }.flowOn(dispatcher)
+ } catch (e: Throwable) {
+ flowOf(false)
+ }
- override fun unreadOrders(profileId: ProfileIdentifier): Flow =
- dataSource.communications.mapNotNull { communications ->
- communications.filter {
- it.profileId == profileId &&
+ override fun unreadMessagesCount(consumed: Boolean): Flow =
+ try {
+ dataSource.communications.mapNotNull { communications ->
+ communications.filter {
!it.consumed &&
- it.profile == ErxCommunicationDispReq
+ it.profile == ErxCommunicationDispReq
+ }
+ .distinctBy { it.orderId }
+ .size.toLong()
}
- .distinctBy { it.orderId }
- .size.toLong()
+ } catch (e: Throwable) {
+ flowOf(0L)
}
override fun unreadPrescriptionsInAllOrders(profileId: ProfileIdentifier): Flow =
@@ -184,6 +277,16 @@ class DemoCommunicationRepository(
.map { it.taskId }
}.flowOn(dispatcher)
+ @OptIn(ExperimentalCoroutinesApi::class)
+ override fun profileByOrderId(orderId: String): Flow =
+ dataSource.communications.mapNotNull { communications ->
+ communications.find { communication -> communication.orderId == orderId }
+ }.flatMapLatest { communication ->
+ dataSource.profiles.mapNotNull { profiles ->
+ profiles.find { it.id == communication.profileId }?.toProfile()
+ }.flowOn(dispatcher)
+ }
+
override suspend fun setCommunicationStatus(communicationId: String, consumed: Boolean) {
withContext(dispatcher) {
dataSource.communications.value = scope.async {
@@ -214,35 +317,53 @@ class DemoCommunicationRepository(
.mapNotNull { scannedTasks ->
scannedTasks.find { it.taskId == taskId }
}.first()
- val communicationForTask = DemoModeProfileLinkedCommunication(
- profileId = task.profileId,
- taskId = taskId,
- communicationId = transactionId,
- sentOn = Clock.System.now(),
- sender = pharmacyId,
- consumed = false,
- profile = ErxCommunicationDispReq,
- // these values are kept empty while saving them
- orderId = "",
- payload = "",
- recipient = ""
+ val requestMessage = task.makeRequestCommunication(transactionId, pharmacyId)
+ val replyCommunication = requestMessage.copy(
+ communicationId = UUID.randomUUID().toString(),
+ sentOn = Clock.System.now().plus(1.hours),
+ payload = DemoModeDataSource.communicationPayload,
+ profile = ErxCommunicationDispReq
)
dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet { scannedTasks ->
val index = scannedTasks.indexOfFirst { it.taskId == taskId }.takeIf { it != INDEX_OUT_OF_BOUNDS }
index?.let { nonNullIndex ->
scannedTasks[nonNullIndex] = scannedTasks[nonNullIndex].copy(
- communications = emptyList()
+ communications = listOf()
)
}
scannedTasks
}
dataSource.communications.value = dataSource.communications.updateAndGet { communications ->
- communications.add(communicationForTask)
+ communications.add(requestMessage)
+ communications.add(replyCommunication)
communications
}
}
}
+ override suspend fun hasUnreadRepliedMessages(taskIds: List, telematikId: String): Flow {
+ return flowOf(false)
+ }
+
+ private fun ScannedTaskData.ScannedTask.makeRequestCommunication(
+ id: String,
+ pharmacyId: String,
+ consumed: Boolean = false
+ ): DemoModeProfileLinkedCommunication =
+ DemoModeProfileLinkedCommunication(
+ profileId = profileId,
+ taskId = taskId,
+ communicationId = id,
+ sentOn = Clock.System.now().minus(1.minutes),
+ sender = pharmacyId,
+ consumed = consumed,
+ profile = ErxCommunicationDispReq,
+ // these values are kept empty while saving them
+ orderId = UUID.randomUUID().toString(),
+ payload = "",
+ recipient = "Mustermann"
+ )
+
@OptIn(ExperimentalCoroutinesApi::class)
private fun loadOrdersForActiveProfile() = findActiveProfile().flatMapLatest { loadOrdersByProfileId(it.id) }
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoDownloadCommunicationResource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoDownloadCommunicationResource.kt
index 88fe20b7..ca0340c8 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoDownloadCommunicationResource.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoDownloadCommunicationResource.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.repository.orders
@@ -48,6 +48,7 @@ class DemoDownloadCommunicationResource(
private val dataSource: DemoModeDataSource,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
+ @Suppress("CyclomaticComplexMethod")
operator fun invoke(
profileId: ProfileIdentifier
): Flow> =
@@ -69,7 +70,7 @@ class DemoDownloadCommunicationResource(
.copy(
profileId = profileId,
recipient = "recipient",
- payload = "payload",
+ payload = DemoModeDataSource.communicationPayload,
consumed = false,
sender = profileId,
sentOn = Clock.System.now().minus(45.minutes),
@@ -88,7 +89,7 @@ class DemoDownloadCommunicationResource(
orderId = UUID.randomUUID().toString(),
consumed = false,
recipient = "recipient",
- payload = "payload",
+ payload = DemoModeDataSource.communicationPayload,
sender = "sender",
sentOn = Clock.System.now().minus(3.days),
profile = when (isCommunicationRequest) {
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoInAppMessageRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoInAppMessageRepository.kt
new file mode 100644
index 00000000..f8351160
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/orders/DemoInAppMessageRepository.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+@file:Suppress("TooManyFunctions", "MagicNumber")
+
+package de.gematik.ti.erp.app.demomode.repository.orders
+
+import de.gematik.ti.erp.app.changelogs.InAppMessageRepository
+import de.gematik.ti.erp.app.db.entities.v1.changelogs.InAppMessageEntity
+import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
+import io.realm.kotlin.types.RealmList
+import kotlinx.coroutines.flow.Flow
+
+class DemoInAppMessageRepository(
+ private val demoModeDataSource: DemoModeDataSource
+) : InAppMessageRepository {
+ override val inAppMessages: Flow>
+ get() = demoModeDataSource.inAppMessages
+
+ override val counter: Flow
+ get() = demoModeDataSource.counter
+
+ override val lastVersion: Flow
+ get() = demoModeDataSource.lastVersion
+
+ override val lastUpdatedVersion: Flow
+ get() = demoModeDataSource.lastUpdatedVersion
+
+ override val showWelcomeMessage: Flow
+ get() = demoModeDataSource.showWelcomeMessage
+
+ override suspend fun setInternalMessageAsRead() {
+ // No-op
+ }
+
+ override suspend fun setShowWelcomeMessage() {
+ // No-op
+ }
+
+ override suspend fun updateChangeLogs(newChangeLogs: RealmList, lastVersion: String, inAppLastVersion: String) {
+ // No-op
+ }
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoFavouritePharmacyLocalDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoFavouritePharmacyLocalDataSource.kt
new file mode 100644
index 00000000..6d291f17
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoFavouritePharmacyLocalDataSource.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.repository.pharmacy
+
+import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
+import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
+import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.FavouritePharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Clock
+
+class DemoFavouritePharmacyLocalDataSource(
+ private val dataSource: DemoModeDataSource,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : FavouritePharmacyLocalDataSource {
+
+ override suspend fun deleteFavoritePharmacy(favoritePharmacy: PharmacyUseCaseData.Pharmacy) {
+ withContext(dispatcher) {
+ dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
+ val pharmacies = it.toMutableList()
+ pharmacies.removeIf { item -> item.telematikId == favoritePharmacy.telematikId }
+ pharmacies
+ }
+ }
+ }
+
+ override fun loadFavoritePharmacies(): Flow> =
+ dataSource.favoritePharmacies
+
+ override suspend fun markPharmacyAsFavourite(pharmacy: PharmacyUseCaseData.Pharmacy) {
+ withContext(dispatcher) {
+ dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
+ val favoritePharmacies = it.toMutableList()
+ favoritePharmacies
+ .indexOfFirst { existingPharmacy -> existingPharmacy.telematikId == pharmacy.telematikId }
+ .takeIf { index -> index != INDEX_OUT_OF_BOUNDS }?.let { index ->
+ favoritePharmacies[index] = favoritePharmacies[index].copy(lastUsed = Clock.System.now())
+ favoritePharmacies
+ } ?: run {
+ val overviewPharmacy = OverviewPharmacyData.OverviewPharmacy(
+ lastUsed = Clock.System.now(),
+ usageCount = 1,
+ isFavorite = true,
+ telematikId = pharmacy.telematikId,
+ pharmacyName = pharmacy.name,
+ address = pharmacy.address ?: "---"
+ )
+ favoritePharmacies.add(overviewPharmacy)
+ favoritePharmacies
+ }
+ }
+ }
+ }
+
+ override fun isPharmacyInFavorites(pharmacy: PharmacyUseCaseData.Pharmacy): Flow =
+ dataSource.favoritePharmacies.mapNotNull {
+ val favoritePharmacy = it.find { it.telematikId == pharmacy.telematikId }
+ favoritePharmacy != null
+ }.flowOn(dispatcher)
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoOftenUsePharmacyLocalDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoOftenUsePharmacyLocalDataSource.kt
new file mode 100644
index 00000000..9e81146c
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoOftenUsePharmacyLocalDataSource.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.repository.pharmacy
+
+import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
+import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
+import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
+import de.gematik.ti.erp.app.pharmacy.repository.datasource.OftenUsedPharmacyLocalDataSource
+import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Clock
+
+class DemoOftenUsePharmacyLocalDataSource(
+ private val dataSource: DemoModeDataSource,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : OftenUsedPharmacyLocalDataSource {
+ override suspend fun deleteOverviewPharmacy(overviewPharmacy: OverviewPharmacyData.OverviewPharmacy) {
+ withContext(dispatcher) {
+ dataSource.oftenUsedPharmacies.value = dataSource.oftenUsedPharmacies.updateAndGet {
+ val pharmacies = it.toMutableList()
+ pharmacies.removeIf { item -> item.telematikId == overviewPharmacy.telematikId }
+ pharmacies
+ }
+ dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
+ val pharmacies = it.toMutableList()
+ pharmacies.removeIf { item -> item.telematikId == overviewPharmacy.telematikId }
+ pharmacies
+ }
+ }
+ }
+
+ override fun loadOftenUsedPharmacies(): Flow> =
+ dataSource.oftenUsedPharmacies
+
+ override suspend fun markPharmacyAsOftenUsed(pharmacy: PharmacyUseCaseData.Pharmacy) {
+ withContext(dispatcher) {
+ dataSource.oftenUsedPharmacies.value = dataSource.oftenUsedPharmacies.updateAndGet {
+ val oftenUsedPharmacies = it.toMutableList()
+ oftenUsedPharmacies.indexOfFirst { item -> item.telematikId == pharmacy.telematikId }
+ .takeIf { index -> index != INDEX_OUT_OF_BOUNDS }
+ ?.let { index ->
+ oftenUsedPharmacies[index] = oftenUsedPharmacies[index].copy(
+ lastUsed = Clock.System.now(),
+ usageCount = oftenUsedPharmacies[index].usageCount + 1
+ )
+ oftenUsedPharmacies
+ } ?: run {
+ val isFavourite = dataSource.favoritePharmacies.value
+ .find { item -> item.telematikId == pharmacy.telematikId } != null
+ val overviewPharmacy = OverviewPharmacyData.OverviewPharmacy(
+ lastUsed = Clock.System.now(),
+ usageCount = 1,
+ isFavorite = isFavourite,
+ telematikId = pharmacy.telematikId,
+ pharmacyName = pharmacy.name,
+ address = pharmacy.address ?: "---"
+ )
+ oftenUsedPharmacies.add(overviewPharmacy)
+ oftenUsedPharmacies
+ }
+ }
+ }
+ }
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoPharmacyLocalDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoPharmacyLocalDataSource.kt
deleted file mode 100644
index 98d689bf..00000000
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoPharmacyLocalDataSource.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- */
-
-package de.gematik.ti.erp.app.demomode.repository.pharmacy
-
-import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
-import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
-import de.gematik.ti.erp.app.pharmacy.model.OverviewPharmacyData
-import de.gematik.ti.erp.app.pharmacy.repository.PharmacyLocalDataSource
-import de.gematik.ti.erp.app.pharmacy.usecase.model.PharmacyUseCaseData
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.mapNotNull
-import kotlinx.coroutines.flow.updateAndGet
-import kotlinx.coroutines.withContext
-import kotlinx.datetime.Clock
-
-class DemoPharmacyLocalDataSource(
- private val dataSource: DemoModeDataSource,
- private val dispatcher: CoroutineDispatcher = Dispatchers.IO
-) : PharmacyLocalDataSource {
- override suspend fun deleteOverviewPharmacy(overviewPharmacy: OverviewPharmacyData.OverviewPharmacy) {
- withContext(dispatcher) {
- dataSource.oftenUsedPharmacies.value = dataSource.oftenUsedPharmacies.updateAndGet {
- val pharmacies = it.toMutableList()
- pharmacies.removeIf { item -> item.telematikId == overviewPharmacy.telematikId }
- pharmacies
- }
- dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
- val pharmacies = it.toMutableList()
- pharmacies.removeIf { item -> item.telematikId == overviewPharmacy.telematikId }
- pharmacies
- }
- }
- }
-
- override fun loadOftenUsedPharmacies(): Flow> =
- dataSource.oftenUsedPharmacies
-
- override suspend fun saveOrUpdateOftenUsedPharmacy(pharmacy: PharmacyUseCaseData.Pharmacy) {
- withContext(dispatcher) {
- dataSource.oftenUsedPharmacies.value = dataSource.oftenUsedPharmacies.updateAndGet {
- val oftenUsedPharmacies = it.toMutableList()
- oftenUsedPharmacies.indexOfFirst { item -> item.telematikId == pharmacy.telematikId }
- .takeIf { index -> index != INDEX_OUT_OF_BOUNDS }
- ?.let { index ->
- oftenUsedPharmacies[index] = oftenUsedPharmacies[index].copy(
- lastUsed = Clock.System.now(),
- usageCount = oftenUsedPharmacies[index].usageCount + 1
- )
- oftenUsedPharmacies
- } ?: run {
- val isFavourite = dataSource.favoritePharmacies.value
- .find { item -> item.telematikId == pharmacy.telematikId } != null
- val overviewPharmacy = OverviewPharmacyData.OverviewPharmacy(
- lastUsed = Clock.System.now(),
- usageCount = 1,
- isFavorite = isFavourite,
- telematikId = pharmacy.telematikId,
- pharmacyName = pharmacy.name,
- address = pharmacy.address ?: "---"
- )
- oftenUsedPharmacies.add(overviewPharmacy)
- oftenUsedPharmacies
- }
- }
- }
- }
-
- override suspend fun deleteFavoritePharmacy(favoritePharmacy: PharmacyUseCaseData.Pharmacy) {
- withContext(dispatcher) {
- dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
- val pharmacies = it.toMutableList()
- pharmacies.removeIf { item -> item.telematikId == favoritePharmacy.telematikId }
- pharmacies
- }
- }
- }
-
- override fun loadFavoritePharmacies(): Flow> =
- dataSource.favoritePharmacies
-
- override suspend fun saveOrUpdateFavoritePharmacy(pharmacy: PharmacyUseCaseData.Pharmacy) {
- withContext(dispatcher) {
- dataSource.favoritePharmacies.value = dataSource.favoritePharmacies.updateAndGet {
- val favoritePharmacies = it.toMutableList()
- favoritePharmacies
- .indexOfFirst { existingPharmacy -> existingPharmacy.telematikId == pharmacy.telematikId }
- .takeIf { index -> index != INDEX_OUT_OF_BOUNDS }?.let { index ->
- favoritePharmacies[index] = favoritePharmacies[index].copy(lastUsed = Clock.System.now())
- favoritePharmacies
- } ?: run {
- val overviewPharmacy = OverviewPharmacyData.OverviewPharmacy(
- lastUsed = Clock.System.now(),
- usageCount = 1,
- isFavorite = true,
- telematikId = pharmacy.telematikId,
- pharmacyName = pharmacy.name,
- address = pharmacy.address ?: "---"
- )
- favoritePharmacies.add(overviewPharmacy)
- favoritePharmacies
- }
- }
- }
- }
-
- override fun isPharmacyInFavorites(pharmacy: PharmacyUseCaseData.Pharmacy): Flow =
- dataSource.favoritePharmacies.mapNotNull {
- val favoritePharmacy = it.find { it.telematikId == pharmacy.telematikId }
- favoritePharmacy != null
- }.flowOn(dispatcher)
-
- override suspend fun markAsRedeemed(taskId: String) {
- withContext(dispatcher) {
- dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
- val scannedTasks = it.toMutableList()
- val index = scannedTasks.indexOfFirst { item -> item.taskId == taskId }
- scannedTasks[index] = scannedTasks[index].copy(redeemedOn = Clock.System.now())
- scannedTasks
- }
- }
- }
-}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoRedeemLocalDataSource.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoRedeemLocalDataSource.kt
new file mode 100644
index 00000000..ce1f9bcb
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoRedeemLocalDataSource.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.repository.pharmacy
+
+import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
+import de.gematik.ti.erp.app.redeem.repository.datasource.RedeemLocalDataSource
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.withContext
+import kotlinx.datetime.Clock
+
+class DemoRedeemLocalDataSource(
+ private val dataSource: DemoModeDataSource,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
+) : RedeemLocalDataSource {
+
+ override suspend fun markAsRedeemed(taskId: String) {
+ withContext(dispatcher) {
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
+ val scannedTasks = it.toMutableList()
+ val index = scannedTasks.indexOfFirst { item -> item.taskId == taskId }
+ scannedTasks[index] = scannedTasks[index].copy(redeemedOn = Clock.System.now())
+ scannedTasks
+ }
+ }
+ }
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoShippingContactRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoShippingContactRepository.kt
new file mode 100644
index 00000000..ad6a1067
--- /dev/null
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/pharmacy/DemoShippingContactRepository.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package de.gematik.ti.erp.app.demomode.repository.pharmacy
+
+import de.gematik.ti.erp.app.pharmacy.model.PharmacyData
+import de.gematik.ti.erp.app.pharmacy.repository.ShippingContactRepository
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+class DemoShippingContactRepository : ShippingContactRepository {
+ override fun shippingContact(): Flow {
+ return flowOf(
+ PharmacyData.ShippingContact(
+ name = "Helga Schmetterling",
+ line1 = "Schmetterlingweg 1",
+ line2 = "2 Stockwerk rechts",
+ postalCode = "12345",
+ city = "Berlin",
+ telephoneNumber = "123456789",
+ mail = "schmetterling@butterfly.com",
+ deliveryInformation = "Bitte klingeln"
+ )
+ )
+ }
+
+ override suspend fun saveShippingContact(contact: PharmacyData.ShippingContact) {
+ // do nothing
+ }
+}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoPrescriptionsRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoPrescriptionsRepository.kt
index eda63295..000d2b18 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoPrescriptionsRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoPrescriptionsRepository.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.repository.prescriptions
@@ -23,6 +23,7 @@ import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
import de.gematik.ti.erp.app.demomode.model.DemoModeSentCommunicationJson
import de.gematik.ti.erp.app.demomode.model.toDemoModeProfileLinkedCommunication
import de.gematik.ti.erp.app.prescription.model.ScannedTaskData.ScannedTask
+import de.gematik.ti.erp.app.prescription.model.SyncedTaskData
import de.gematik.ti.erp.app.prescription.model.SyncedTaskData.SyncedTask
import de.gematik.ti.erp.app.prescription.repository.PrescriptionRepository
import de.gematik.ti.erp.app.profiles.repository.ProfileIdentifier
@@ -35,23 +36,31 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.withContext
+import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.decodeFromJsonElement
+private const val NOT_FOUND = -1
+
class DemoPrescriptionsRepository(
private val dataSource: DemoModeDataSource,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : PrescriptionRepository {
override suspend fun saveScannedTasks(
profileId: ProfileIdentifier,
- tasks: List
+ tasks: List,
+ medicationString: String
) {
+ val updatedTasksWithNames = tasks.mapIndexed { index, scannedTask ->
+ scannedTask.copy(name = "$medicationString ${index + 1}")
+ }
withContext(dispatcher) {
dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet {
val scannedList = it.toMutableList()
- scannedList.addAll(tasks)
+ scannedList.addAll(updatedTasksWithNames)
scannedList
}
}
@@ -68,8 +77,8 @@ class DemoPrescriptionsRepository(
override suspend fun redeemPrescription(
profileId: ProfileIdentifier,
communication: JsonElement,
- accessCode: String?
- ): Result =
+ accessCode: String
+ ): Result =
withContext(dispatcher) {
val decodedCommunication = Json
.decodeFromJsonElement(communication)
@@ -78,10 +87,35 @@ class DemoPrescriptionsRepository(
communications.add(decodedCommunication)
communications
}
- Result.success(Unit)
+ // change the status of the prescription to in progress
+ dataSource.syncedTasks.value = dataSource.syncedTasks.updateAndGet { syncedList ->
+ val index = syncedList.indexOfFirst { profileId == it.profileId && it.taskId == decodedCommunication.taskId }
+ if (index != NOT_FOUND) {
+ val updatedItem = syncedList[index].copy(
+ status = SyncedTaskData.TaskStatus.InProgress,
+ lastModified = Clock.System.now()
+ )
+ syncedList[index] = updatedItem
+ }
+ syncedList
+ }
+ dataSource.scannedTasks.value = dataSource.scannedTasks.updateAndGet { scannedList ->
+ val index = scannedList.indexOfFirst { profileId == it.profileId && it.taskId == decodedCommunication.taskId }
+ if (index != NOT_FOUND) {
+ val updatedItem = scannedList[index].copy(
+ redeemedOn = Clock.System.now()
+ )
+ scannedList[index] = updatedItem
+ }
+ scannedList
+ }
+ Result.success(JsonPrimitive(true)) // sending some random json response
}
- override suspend fun deleteTaskByTaskId(profileId: ProfileIdentifier, taskId: String): Result =
+ override suspend fun deleteRemoteTaskById(
+ profileId: ProfileIdentifier,
+ taskId: String
+ ): Result =
withContext(dispatcher) {
dataSource.syncedTasks.value = dataSource.syncedTasks.updateAndGet { syncedList ->
syncedList.removeIf { it.taskId == taskId && it.profileId == profileId }
@@ -93,7 +127,7 @@ class DemoPrescriptionsRepository(
.removeIf { scannedItem -> scannedItem.taskId == taskId && scannedItem.profileId == profileId }
scannedList
}
- Result.success(Unit)
+ Result.success(null)
}
// used only for scanned
@@ -142,4 +176,22 @@ class DemoPrescriptionsRepository(
syncedTasks.mapNotNull { it.taskId }
)
}.flowOn(dispatcher)
+
+ override suspend fun deleteLocalTaskById(taskId: String) {
+ // do nothing
+ }
+
+ override suspend fun wasProfileEverAuthenticated(profileId: ProfileIdentifier): Boolean {
+ return true
+ }
+
+ override suspend fun redeemScannedTasks(taskIds: List) {
+ // do nothing
+ }
+
+ override fun loadAllTaskIds(profileId: ProfileIdentifier): Flow> = loadTaskIds()
+
+ override suspend fun deleteLocalInvoicesById(taskId: String) {
+ // do nothing
+ }
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoTaskRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoTaskRepository.kt
index 1188026d..cc821da9 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoTaskRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/prescriptions/DemoTaskRepository.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
@file:Suppress("MagicNumber")
@@ -34,7 +34,7 @@ class DemoTaskRepository(
) : TaskRepository {
override suspend fun downloadTasks(profileId: ProfileIdentifier): Result =
withContext(dispatcher) {
- delay(500)
+ delay(250)
Result.success(0)
}
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/profiles/DemoProfilesRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/profiles/DemoProfilesRepository.kt
index 4f267f03..7c2c1fa7 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/profiles/DemoProfilesRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/profiles/DemoProfilesRepository.kt
@@ -1,25 +1,27 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
+
package de.gematik.ti.erp.app.demomode.repository.profiles
import de.gematik.ti.erp.app.demomode.datasource.DemoModeDataSource
import de.gematik.ti.erp.app.demomode.datasource.INDEX_OUT_OF_BOUNDS
import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo.create
+import de.gematik.ti.erp.app.demomode.datasource.data.DemoProfileInfo.demoEmptyProfile
import de.gematik.ti.erp.app.demomode.model.DemoModeProfile
import de.gematik.ti.erp.app.demomode.model.toProfile
import de.gematik.ti.erp.app.demomode.model.toProfiles
@@ -33,6 +35,7 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.withContext
@@ -63,6 +66,17 @@ class DemoProfilesRepository(
}
}
+ override suspend fun createNewProfile(profileName: String) {
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet { profileList ->
+ val profiles = profileList.deactivateAllProfiles()
+ profiles.add(profileName.create())
+ profiles
+ }
+ }
+ }
+
override suspend fun activateProfile(profileId: ProfileIdentifier) {
withContext(dispatcher) {
dataSource.profiles.value = dataSource.profiles
@@ -74,10 +88,13 @@ class DemoProfilesRepository(
}
}
- override suspend fun removeProfile(profileId: ProfileIdentifier) {
+ override suspend fun removeProfile(profileId: ProfileIdentifier, profileName: String) {
withContext(dispatcher) {
dataSource.profiles.value = dataSource.profiles
.updateAndGet { profiles ->
+ if (profiles.size == 1) {
+ profiles.add(demoEmptyProfile(profileName))
+ }
profiles.removeIf { profile -> profile.id == profileId }
profiles
}
@@ -90,7 +107,18 @@ class DemoProfilesRepository(
insuranceIdentifier: String,
insuranceName: String
) {
- // Not used in demo mode
+ withContext(dispatcher) {
+ dataSource.profiles.value = dataSource.profiles
+ .updateAndGet {
+ it.replace(
+ profileId = profileId,
+ insurantName = insurantName,
+ insuranceIdentifier = insuranceIdentifier,
+ insuranceName = insuranceName
+ )
+ }
+ .updateUUIDForChangeVisibility()
+ }
}
override suspend fun updateProfileName(profileId: ProfileIdentifier, profileName: String) {
@@ -146,12 +174,29 @@ class DemoProfilesRepository(
}
}
- override suspend fun switchProfileToPKV(profileId: ProfileIdentifier) {
- // Not for demo mode, will come later
+ override suspend fun switchProfileToPKV(profileId: ProfileIdentifier): Boolean {
+ // cannot switch to PKV in demo mode
+ return false
+ }
+
+ override suspend fun switchProfileToGKV(profileId: ProfileIdentifier): Boolean {
+ return true
}
override suspend fun checkIsProfilePKV(profileId: ProfileIdentifier): Boolean = false
+ override fun getProfileById(profileId: ProfileIdentifier): Flow =
+ demoModeProfiles().mapNotNull {
+ it.find {
+ profile ->
+ profile.id == profileId
+ }?.toProfile()
+ }
+
+ override suspend fun isSsoTokenValid(profileId: ProfileIdentifier): Flow {
+ return flowOf(true)
+ }
+
private fun MutableList.index(profileId: ProfileIdentifier) =
indexOfFirst { profile -> profile.id == profileId }
.takeIf { it != INDEX_OUT_OF_BOUNDS }
@@ -164,7 +209,10 @@ class DemoProfilesRepository(
lastAuthenticated: Instant? = null,
avatar: ProfilesData.Avatar? = null,
profileImage: ByteArray? = null,
- imageAction: ImageActions = NoAction
+ imageAction: ImageActions = NoAction,
+ insurantName: String? = null,
+ insuranceIdentifier: String? = null,
+ insuranceName: String? = null
): MutableList =
index(profileId)?.let { index ->
val existingProfile = this[index]
@@ -174,6 +222,9 @@ class DemoProfilesRepository(
name = name ?: existingProfile.name,
color = color ?: existingProfile.color,
lastAuthenticated = lastAuthenticated,
+ insurantName = insurantName ?: existingProfile.insurantName,
+ insuranceIdentifier = insuranceIdentifier ?: existingProfile.insuranceIdentifier,
+ insuranceName = insuranceName ?: existingProfile.insuranceName,
avatar = avatar ?: existingProfile.avatar,
personalizedImage = when (imageAction) {
Add -> profileImage
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/protocol/DemoAuditEventsRepository.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/protocol/DemoAuditEventsRepository.kt
index 4c1767a0..94d3fc37 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/protocol/DemoAuditEventsRepository.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/repository/protocol/DemoAuditEventsRepository.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.repository.protocol
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/ui/DemoModeTopAppBar.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/ui/DemoModeTopAppBar.kt
index ec5dbf85..3a63bb86 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/ui/DemoModeTopAppBar.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/ui/DemoModeTopAppBar.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.ui
diff --git a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/usecase/idp/DemoIdpUseCase.kt b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/usecase/idp/DemoIdpUseCase.kt
index f455ab86..02c4eaaa 100644
--- a/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/usecase/idp/DemoIdpUseCase.kt
+++ b/app/demo-mode/src/main/kotlin/de/gematik/ti/erp/app/demomode/usecase/idp/DemoIdpUseCase.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.demomode.usecase.idp
diff --git a/app/features/build.gradle.kts b/app/features/build.gradle.kts
index 5287d387..c0def240 100644
--- a/app/features/build.gradle.kts
+++ b/app/features/build.gradle.kts
@@ -1,217 +1,28 @@
-@file:Suppress("UnstableApiUsage")
-
-import de.gematik.ti.erp.Dependencies
-import de.gematik.ti.erp.inject
-import org.owasp.dependencycheck.reporting.ReportGenerator.Format
+import de.gematik.ti.erp.app.plugins.names.AppDependencyNamesPlugin
plugins {
- id("com.android.library")
- kotlin("android")
- kotlin("plugin.serialization")
- id("org.jetbrains.compose")
- id("io.realm.kotlin")
- id("kotlin-parcelize")
- id("org.owasp.dependencycheck")
- id("com.jaredsburrows.license")
- id("de.gematik.ti.erp.dependencies")
- id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
- id("de.gematik.ti.erp.technical-requirements")
+ id("base-android-library")
+ id("de.gematik.ti.erp.names")
+ id("jacoco")
+ alias(libs.plugins.paparazzi)
}
-licenseReport {
- generateCsvReport = false
- generateHtmlReport = false
- generateJsonReport = true
- copyJsonReportToAssets = true
-}
+val namesPlugin = AppDependencyNamesPlugin()
android {
- namespace = "${de.gematik.ti.erp.AppDependenciesPlugin.APP_NAME_SPACE}.features"
+ namespace = namesPlugin.moduleName("features")
defaultConfig {
- testApplicationId = "de.gematik.ti.erp.app.test"
- }
- kotlinOptions {
- jvmTarget = Dependencies.Versions.JavaVersion.KOTLIN_OPTIONS_JVM_TARGET
- freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
- }
- dependencyCheck {
- analyzers.assemblyEnabled = false
- suppressionFile = "${project.rootDir}" + "/config/dependency-check/suppressions.xml"
- formats = listOf(Format.HTML, Format.XML)
- scanConfigurations = configurations.filter {
- it.name.startsWith("api") ||
- it.name.startsWith("implementation") ||
- it.name.startsWith("kapt")
- }.map { it.name }
- }
- buildTypes {
- val debug by getting {
- isJniDebuggable = true
- }
- create("minifiedDebug") {
- initWith(debug)
- }
- }
- buildFeatures {
- compose = true
+ testApplicationId = namesPlugin.moduleName("test")
}
}
dependencies {
- implementation(project(":common"))
- implementation(project(":app:demo-mode"))
- implementation("com.google.android.material:material:1.10.0")
- testImplementation(project(":common"))
- implementation(kotlin("stdlib"))
- implementation(kotlin("reflect"))
- testImplementation(kotlin("test"))
- implementation("com.tom-roush:pdfbox-android:2.0.27.0") {
- exclude(group = "org.bouncycastle")
- }
- // TODO: Make a common inject for all libs that we don't need to copy again and again
- inject {
- dataMatrix {
- implementation(mlkitBarcodeScanner)
- implementation(zxing)
- }
- coroutines {
- implementation(coroutinesCore)
- implementation(coroutinesAndroid)
- implementation(coroutinesPlayServices)
- }
- dateTime {
- implementation(datetime)
- testCompileOnly(datetime)
- }
- accompanist {
- implementation(navigationMaterial)
- implementation(swipeRefresh)
- implementation(flowLayout)
- implementation(pager)
- implementation(pageIndicator)
- implementation(systemUiController)
- }
- android {
- implementation(imageCropper)
- debugImplementation(processPhoenix)
- }
- androidX {
- implementation(legacySupport)
- implementation(appcompat)
- implementation(coreKtx)
- implementation(datastorePreferences)
- implementation(security)
- implementation(biometric)
- implementation(webkit)
-
- implementation(lifecycleViewmodel)
- implementation(lifecycleComposeRuntime)
- implementation(lifecycleProcess)
- implementation(composeNavigation)
- implementation(composeActivity)
- implementation(composePaging)
- implementation(camerax2)
- implementation(cameraxLifecycle)
- implementation(cameraxView)
- }
- dependencyInjection {
- compileOnly(kodeinCompose)
- implementation(kodeinCompose)
- implementation(kodeinViewModel)
- implementation(kodeinAndroid)
- implementation(kodein)
- androidTestImplementation(kodeinCompose)
- }
- imageLoad {
- implementation(coil)
- }
- logging {
- implementation(napier)
- }
- lottie {
- implementation(lottie)
- }
- serialization {
- implementation(kotlinXJson)
- }
- crypto {
- implementation(jose4j)
- implementation(bouncycastleBcprov)
- implementation(bouncycastleBcpkix)
- testImplementation(bouncycastleBcprov)
- testImplementation(bouncycastleBcpkix)
- }
- network {
- implementation(retrofit)
- implementation(retrofit2KotlinXSerialization)
- implementation(okhttp3)
- implementation(okhttpLogging)
- // Work around vulnerable Okio version 3.1.0 (CVE-2023-3635).
- // Can be removed as soon as Retrofit releases a new version >2.9.0.
- implementation(okio)
- androidTestImplementation(okhttp3)
- }
- database {
- compileOnly(realm)
- testCompileOnly(realm)
- }
- compose {
- implementation(runtime)
- implementation(foundation)
- implementation(animation)
- implementation(uiTooling)
- implementation(preview)
- }
- material {
- implementation(material)
- implementation(material3)
- implementation(materialIcons)
- implementation(materialIconsExtended)
- }
- passwordStrength {
- implementation(zxcvbn)
- }
- stateManagement {
- implementation(reactiveState)
- }
- tracking {
- implementation(contentSquare)
- implementation(contentSquareCompose)
- implementation(contentSquareErrorAnalysis)
- }
- maps {
- implementation(location)
- implementation(maps)
- implementation(mapsAndroidUtils)
- implementation(mapsKtx)
- implementation(mapsCompose)
- }
- playServices {
- implementation(integrity)
- implementation(appReview)
- implementation(appUpdate)
- }
- shimmer {
- implementation(shimmer)
- }
- networkTest {
- testImplementation(mockWebServer)
- }
- test {
- testImplementation(junit4)
- testImplementation(snakeyaml)
- testImplementation(json)
- testImplementation(mockk)
- androidTestImplementation(mockkAndroid)
- }
- }
-}
-
-secrets {
- defaultPropertiesFileName = if (project.rootProject.file("ci-overrides.properties").exists()
- ) {
- "ci-overrides.properties"
- } else {
- "gradle.properties"
- }
+ implementation(project(namesPlugin.demoMode))
+ implementation(project(namesPlugin.testTags))
+ implementation(project(namesPlugin.multiplatform))
+ implementation(project(namesPlugin.uiComponents))
+ implementation(libs.androidx.work)
+ implementation(libs.certificatetransparency.android)
+ testImplementation(libs.test.turbine) // to test flows
+ testImplementation(project(namesPlugin.multiplatform))
}
diff --git a/app/features/src/debug/kotlin/de/gematik/ti/erp/app/di/EndpointHelper.kt b/app/features/src/debug/kotlin/de/gematik/ti/erp/app/di/EndpointHelper.kt
index ed05ed2f..e50ab6d8 100644
--- a/app/features/src/debug/kotlin/de/gematik/ti/erp/app/di/EndpointHelper.kt
+++ b/app/features/src/debug/kotlin/de/gematik/ti/erp/app/di/EndpointHelper.kt
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
package de.gematik.ti.erp.app.di
@@ -23,6 +23,9 @@ import androidx.core.content.edit
import de.gematik.ti.erp.app.BuildKonfig
import de.gematik.ti.erp.app.debugsettings.data.Environment
+/**
+ * Documentation: documentation-internal/variants/build_variants.adoc
+ */
class EndpointHelper(
private val networkPrefs: SharedPreferences
) {
@@ -57,12 +60,17 @@ class EndpointHelper(
url = networkPrefs.getString(
uri.preferenceKey,
uri.original
- )!!
+ ) ?: ""
}
- if (url.last() != '/') {
- url += '/'
+ return when {
+ url.isEmpty() -> "https://github.com/gematik/E-Rezept-App-Android/"
+ url.last() != '/' -> {
+ url += '/'
+ url
+ }
+
+ else -> return url
}
- return url
}
private fun overrideSwitchKey(uri: EndpointUri): String {
@@ -80,6 +88,7 @@ class EndpointHelper(
}
}
+ @Suppress("CyclomaticComplexMethod")
fun getCurrentEnvironment(): Environment {
return when {
eRezeptServiceUri == BuildKonfig.BASE_SERVICE_URI_PU &&
@@ -87,32 +96,46 @@ class EndpointHelper(
pharmacySearchBaseUri == BuildKonfig.PHARMACY_SERVICE_URI_PU -> {
Environment.PU
}
+
eRezeptServiceUri == BuildKonfig.BASE_SERVICE_URI_RU &&
idpServiceUri == BuildKonfig.IDP_SERVICE_URI_RU &&
pharmacySearchBaseUri == BuildKonfig.PHARMACY_SERVICE_URI_RU -> {
Environment.RU
}
+
eRezeptServiceUri == BuildKonfig.BASE_SERVICE_URI_RU_DEV &&
idpServiceUri == BuildKonfig.IDP_SERVICE_URI_RU_DEV &&
pharmacySearchBaseUri == BuildKonfig.PHARMACY_SERVICE_URI_RU -> {
Environment.RUDEV
}
+
eRezeptServiceUri == BuildKonfig.BASE_SERVICE_URI_TU &&
idpServiceUri == BuildKonfig.IDP_SERVICE_URI_TU &&
pharmacySearchBaseUri == BuildKonfig.PHARMACY_SERVICE_URI_RU -> {
Environment.TU
}
+
eRezeptServiceUri == BuildKonfig.BASE_SERVICE_URI_TR &&
idpServiceUri == BuildKonfig.IDP_SERVICE_URI_TR &&
pharmacySearchBaseUri == BuildKonfig.PHARMACY_SERVICE_URI_RU -> {
Environment.TR
}
+
else -> {
return Environment.PU
}
}
}
+ fun getOrganDonationRegisterIntentHost() =
+ if (getCurrentEnvironment() == Environment.PU) {
+ BuildKonfig.ORGAN_DONATION_REGISTER_PU
+ } else {
+ BuildKonfig.ORGAN_DONATION_REGISTER_RU
+ }
+
+ fun getOrganDonationRegisterInfoHost() = BuildKonfig.ORGAN_DONATION_INFO
+
fun getErpApiKey(): String {
return if (BuildKonfig.INTERNAL) {
when (getCurrentEnvironment()) {
diff --git a/app/features/src/debug/kotlin/de/gematik/ti/erp/app/ui/DebugScreen.kt b/app/features/src/debug/kotlin/de/gematik/ti/erp/app/ui/DebugScreen.kt
index e2ee35eb..07a1f755 100644
--- a/app/features/src/debug/kotlin/de/gematik/ti/erp/app/ui/DebugScreen.kt
+++ b/app/features/src/debug/kotlin/de/gematik/ti/erp/app/ui/DebugScreen.kt
@@ -1,25 +1,28 @@
/*
- * Copyright (c) 2024 gematik GmbH
- *
- * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the Licence);
+ * Copyright 2024, gematik GmbH
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+ * European Commission – subsequent versions of the EUPL (the "Licence").
* You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- *
- * https://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
+ *
+ * You find a copy of the Licence in the "Licence" file or at
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
+ * In case of changes by gematik find details in the "Readme" file.
+ *
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
*/
+@file: Suppress("UnusedPrivateMember", "MagicNumber")
+
package de.gematik.ti.erp.app.ui
import android.content.Intent
import android.net.Uri
+import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -45,13 +48,17 @@ import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetValue
-import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Switch
import androidx.compose.material.Text
-import androidx.compose.material.TextField
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.Adb
import androidx.compose.material.icons.rounded.Refresh
import androidx.compose.material.rememberModalBottomSheetState
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Switch
+import androidx.compose.material3.SwitchDefaults
+import androidx.compose.material3.TextButton
+import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -74,23 +81,30 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import de.gematik.ti.erp.app.TestTag
+import de.gematik.ti.erp.app.debugsettings.logger.ui.screens.LoggerScreen
import de.gematik.ti.erp.app.debugsettings.navigation.DebugScreenNavigation
+import de.gematik.ti.erp.app.debugsettings.pkv.ui.DebugScreenPKV
+import de.gematik.ti.erp.app.debugsettings.qrcode.QrCodeScannerScreen
import de.gematik.ti.erp.app.debugsettings.timeout.DebugTimeoutScreen
-import de.gematik.ti.erp.app.debugsettings.ui.DebugScreenPKV
-import de.gematik.ti.erp.app.debugsettings.ui.EnvironmentSelector
-import de.gematik.ti.erp.app.debugsettings.ui.LoadingButton
+import de.gematik.ti.erp.app.debugsettings.ui.components.ClearTextTrafficSection
+import de.gematik.ti.erp.app.debugsettings.ui.components.ClientIdsSection
+import de.gematik.ti.erp.app.debugsettings.ui.components.EnvironmentSelector
+import de.gematik.ti.erp.app.debugsettings.ui.components.LoadingButton
import de.gematik.ti.erp.app.features.R
-import de.gematik.ti.erp.app.settings.ui.LabelButton
import de.gematik.ti.erp.app.theme.AppTheme
import de.gematik.ti.erp.app.theme.PaddingDefaults
+import de.gematik.ti.erp.app.utils.SpacerMedium
+import de.gematik.ti.erp.app.utils.SpacerSmall
import de.gematik.ti.erp.app.utils.compose.AlertDialog
import de.gematik.ti.erp.app.utils.compose.AnimatedElevationScaffold
+import de.gematik.ti.erp.app.utils.compose.ErezeptOutlineText
+import de.gematik.ti.erp.app.utils.compose.LabelButton
import de.gematik.ti.erp.app.utils.compose.NavigationAnimation
import de.gematik.ti.erp.app.utils.compose.NavigationBarMode
import de.gematik.ti.erp.app.utils.compose.OutlinedDebugButton
-import de.gematik.ti.erp.app.utils.compose.SpacerMedium
-import de.gematik.ti.erp.app.utils.compose.SpacerSmall
+import de.gematik.ti.erp.app.utils.compose.erezeptTextFieldColors
import de.gematik.ti.erp.app.utils.compose.navigationModeState
+import de.gematik.ti.erp.app.utils.extensions.erezeptColors
import kotlinx.coroutines.launch
import org.bouncycastle.util.encoders.Base64
import org.kodein.di.bindProvider
@@ -187,6 +201,7 @@ fun EditablePathComponentWithControl(
onValueChange = { onValueChange(it, false) },
label = { Text(label) },
maxLines = 3,
+ colors = erezeptTextFieldColors(),
modifier = Modifier
.weight(1f)
.padding(end = PaddingDefaults.Medium)
@@ -210,7 +225,7 @@ fun DebugScreen(
endpointHelper = instance(),
cardWallUseCase = instance(),
prescriptionUseCase = instance(),
- invoiceRepository = instance(),
+ saveInvoiceUseCase = instance(),
vauRepository = instance(),
idpRepository = instance(),
idpUseCase = instance(),
@@ -223,6 +238,7 @@ fun DebugScreen(
)
}
}) {
+ val viewModel by rememberViewModel()
NavHost(
navController,
startDestination = DebugScreenNavigation.DebugMain.path()
@@ -230,6 +246,7 @@ fun DebugScreen(
composable(DebugScreenNavigation.DebugMain.route) {
NavigationAnimation(mode = navMode) {
DebugScreenMain(
+ viewModel = viewModel,
onBack = {
settingsNavController.popBackStack()
},
@@ -241,6 +258,12 @@ fun DebugScreen(
},
onClickBioMetricSettings = {
navController.navigate(DebugScreenNavigation.DebugTimeout.path())
+ },
+ onScanQrCode = {
+ navController.navigate(DebugScreenNavigation.QrCodeScannerScreen.path())
+ },
+ onClickLogger = {
+ navController.navigate(DebugScreenNavigation.LoggerScreen.path())
}
)
}
@@ -248,6 +271,7 @@ fun DebugScreen(
composable(DebugScreenNavigation.DebugRedeemWithoutFD.route) {
NavigationAnimation(mode = navMode) {
DebugScreenDirectRedeem(
+ viewModel = viewModel,
onBack = {
navController.popBackStack()
}
@@ -255,7 +279,6 @@ fun DebugScreen(
}
}
composable(DebugScreenNavigation.DebugPKV.route) {
- val viewModel by rememberViewModel()
NavigationAnimation(mode = navMode) {
DebugScreenPKV(
onSaveInvoiceBundle = {
@@ -272,13 +295,32 @@ fun DebugScreen(
navController.popBackStack()
}
}
+ composable(DebugScreenNavigation.QrCodeScannerScreen.route) {
+ QrCodeScannerScreen.Content(
+ onSaveCertificate = { viewModel.onSetVirtualHealthCardCertificate(it) },
+ onSavePrivateKey = { viewModel.onSetVirtualHealthCardPrivateKey(it) },
+ onBack = {
+ navController.popBackStack()
+ }
+ )
+ }
+ composable(DebugScreenNavigation.LoggerScreen.route) {
+ LoggerScreen.Content(
+ onBack = {
+ navController.popBackStack()
+ }
+ )
+ }
}
}
}
+// TODO: Change to use the correct use-cases
@Composable
-fun DebugScreenDirectRedeem(onBack: () -> Unit) {
- val viewModel by rememberViewModel()
+fun DebugScreenDirectRedeem(
+ viewModel: DebugSettingsViewModel,
+ onBack: () -> Unit
+) {
val listState = rememberLazyListState()
AnimatedElevationScaffold(
@@ -307,26 +349,29 @@ fun DebugScreenDirectRedeem(onBack: () -> Unit) {
DebugCard(
title = "Endpoints"
) {
- OutlinedTextField(
+ ErezeptOutlineText(
modifier = Modifier.fillMaxWidth(),
value = shipmentUrl,
- label = { Text("Shipment URL") },
+ label = "Shipment URL",
+ placeholder = "Shipment URL",
onValueChange = {
shipmentUrl = it
}
)
- OutlinedTextField(
+ ErezeptOutlineText(
modifier = Modifier.fillMaxWidth(),
value = deliveryUrl,
- label = { Text("Delivery URL") },
+ label = "Delivery URL",
+ placeholder = "Delivery URL",
onValueChange = {
deliveryUrl = it
}
)
- OutlinedTextField(
+ ErezeptOutlineText(
modifier = Modifier.fillMaxWidth(),
value = onPremiseUrl,
- label = { Text("OnPremise URL") },
+ label = "OnPremise URL",
+ placeholder = "OnPremise URL",
onValueChange = {
onPremiseUrl = it
}
@@ -360,12 +405,13 @@ fun DebugScreenDirectRedeem(onBack: () -> Unit) {
DebugCard(
title = "Message"
) {
- OutlinedTextField(
+ ErezeptOutlineText(
modifier = Modifier
.heightIn(max = 400.dp)
.fillMaxWidth(),
value = message,
- label = { Text("Any Message") },
+ label = "Any Message",
+ placeholder = "Any Message",
onValueChange = {
message = it
}
@@ -376,12 +422,13 @@ fun DebugScreenDirectRedeem(onBack: () -> Unit) {
DebugCard(
title = "Certificates"
) {
- OutlinedTextField(
+ ErezeptOutlineText(
modifier = Modifier
.heightIn(max = 400.dp)
.fillMaxWidth(),
value = certificates,
- label = { Text("Certificate as PEM") },
+ label = "Certificate as PEM",
+ placeholder = "Certificate as PEM",
onValueChange = {
certificates = it
}
@@ -410,12 +457,14 @@ private fun RedeemButton(
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DebugScreenMain(
+ viewModel: DebugSettingsViewModel,
onBack: () -> Unit,
onClickDirectRedemption: () -> Unit,
onClickPKV: () -> Unit,
- onClickBioMetricSettings: () -> Unit
+ onClickBioMetricSettings: () -> Unit,
+ onScanQrCode: () -> Unit,
+ onClickLogger: () -> Unit
) {
- val viewModel by rememberViewModel()
val listState = rememberLazyListState()
val modal = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
@@ -473,7 +522,7 @@ fun DebugScreenMain(
}
LabelButton(
icon = painterResource(R.drawable.ic_pkv),
- text = "PKV"
+ text = "PKV / GKV Switch"
) {
onClickPKV()
}
@@ -483,6 +532,12 @@ fun DebugScreenMain(
) {
viewModel.refreshPrescriptions()
}
+ LabelButton(
+ icon = Icons.Rounded.Adb,
+ text = "Logger"
+ ) {
+ onClickLogger()
+ }
}
}
item {
@@ -495,11 +550,11 @@ fun DebugScreenMain(
) {
Text(
text = "Original app update",
- modifier = Modifier
- .weight(1f)
+ modifier = Modifier.weight(1f)
)
Switch(
modifier = Modifier.testTag(TestTag.DebugMenu.FakeAppUpdate),
+ colors = SwitchDefaults.erezeptColors(),
checked = appUpdateManager,
onCheckedChange = { viewModel.changeAppUpdateManager(it) }
)
@@ -521,6 +576,7 @@ fun DebugScreenMain(
)
Switch(
modifier = Modifier.testTag(TestTag.DebugMenu.FakeNFCCapabilities),
+ colors = SwitchDefaults.erezeptColors(),
checked = viewModel.debugSettingsData.fakeNFCCapabilities,
onCheckedChange = { viewModel.allowNfc(it) }
)
@@ -565,7 +621,11 @@ fun DebugScreenMain(
}
}
item {
- VirtualHealthCard(viewModel = viewModel)
+ VirtualHealthCard(
+ viewModel = viewModel
+ ) {
+ onScanQrCode()
+ }
}
item {
FeatureToggles(viewModel = viewModel)
@@ -573,6 +633,18 @@ fun DebugScreenMain(
item {
RotatingLog(viewModel = viewModel)
}
+ item {
+ HorizontalDivider()
+ }
+ item {
+ ClearTextTrafficSection()
+ }
+ item {
+ HorizontalDivider()
+ }
+ item {
+ ClientIdsSection()
+ }
}
}
}
@@ -614,7 +686,11 @@ private fun RotatingLog(modifier: Modifier = Modifier, viewModel: DebugSettingsV
}
@Composable
-private fun VirtualHealthCard(modifier: Modifier = Modifier, viewModel: DebugSettingsViewModel) {
+private fun VirtualHealthCard(
+ modifier: Modifier = Modifier,
+ viewModel: DebugSettingsViewModel,
+ onScanQrCode: () -> Unit
+) {
var virtualHealthCardLoading by remember { mutableStateOf(false) }
var virtualHealthCardError by remember { mutableStateOf