diff --git a/app/build.gradle b/app/build.gradle index 04216c3..2e3c1c1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,6 +52,7 @@ android { unitTests.all { useJUnitPlatform() } + unitTests.includeAndroidResources = true unitTests.returnDefaultValues = true } } @@ -63,18 +64,22 @@ dependencies { implementation "androidx.compose.ui:ui:$compose_ui_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version" implementation 'androidx.compose.material:material:1.6.8' + implementation 'androidx.test:core-ktx:1.6.1' + implementation 'com.google.ar:core:1.44.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' // Testing androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version" + testImplementation "junit:junit:4.13.2" testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.1" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.1" // Mockito testing testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0" - testImplementation "org.robolectric:robolectric:3.4.2" + testImplementation "org.robolectric:robolectric:4.4" + testImplementation "androidx.test.ext:junit-ktx:1.1.5" testImplementation 'org.powermock:powermock-api-mockito:1.4.12' testImplementation 'org.powermock:powermock-module-junit4:1.6.2' diff --git a/app/src/androidTest/java/be/re/writand/TOSRepoTest.kt b/app/src/androidTest/java/be/re/writand/TOSRepoTest.kt new file mode 100644 index 0000000..7cc0bfa --- /dev/null +++ b/app/src/androidTest/java/be/re/writand/TOSRepoTest.kt @@ -0,0 +1,22 @@ +package be.re.writand + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import be.re.writand.data.repos.tos.TOSRepository +import be.re.writand.utils.Version +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class TOSRepoTest { + private val context: Context = ApplicationProvider.getApplicationContext() + private val repo: TOSRepository = TOSRepository(context, "tos_testfile.txt") + + @Test + fun simpleTest() { + var tos = repo.getTOS() + assertTrue(tos.version == Version(1, 0, 0)) + } +} \ No newline at end of file diff --git a/app/src/main/assets/tos.txt b/app/src/main/assets/tos.txt new file mode 100644 index 0000000..0fa1afb --- /dev/null +++ b/app/src/main/assets/tos.txt @@ -0,0 +1,66 @@ +Version: 0.0.0 + +Terms of Service + +Effective Date: [Insert Date] + +Terms of Service for Writand. + +These Terms of Service ("Terms") govern your access to and use of Writand ("the App"), provided by [Your Company Name] ("we," "our," or "us"). By downloading, installing, or using the App, you agree to be bound by these Terms. If you do not agree to these Terms, do not use the App. + +1. Use of the App + +1.1 License: We grant you a non-exclusive, non-transferable, limited license to download, install, and use the App on your Android device for personal or commercial use in accordance with these Terms. + +1.2 Access to Filesystem: The App requires access to your device's filesystem to read, modify, and save files as part of its functionality. By using the App, you consent to this access. + +2. User Responsibilities + +2.1 Compliance: You agree to use the App in compliance with all applicable laws and regulations. + +2.2 Prohibited Activities: You agree not to: + + Use the App for any illegal purpose. + Distribute, modify, create derivative works of, or publicly display any part of the App without our prior written consent. + Interfere with or disrupt the operation of the App. + +3. Privacy + +3.1 Data Collection: The App does not collect or store any personal data from your device other than the necessary access to the filesystem for its functionality. + +3.2 Permissions: The App will request permission to access your device's filesystem. This access is solely for the purpose of reading, modifying, and saving files. + +4. Intellectual Property + +4.1 Ownership: All intellectual property rights in and to the App are owned by us or our licensors. Nothing in these Terms transfers any ownership rights to you. + +4.2 Feedback: If you provide us with feedback or suggestions regarding the App, you grant us a worldwide, perpetual, irrevocable, royalty-free license to use and incorporate such feedback into the App. + +5. Disclaimers and Limitation of Liability + +5.1 Disclaimer of Warranties: The App is provided "as is" and "as available," without warranties of any kind, either express or implied. We do not warrant that the App will be uninterrupted or error-free. + +5.2 Limitation of Liability: To the fullest extent permitted by law, we shall not be liable for any indirect, incidental, special, consequential, or punitive damages, or any loss of profits or revenues, whether incurred directly or indirectly, or any loss of data, use, goodwill, or other intangible losses, resulting from: + + Your use of or inability to use the App. + Any unauthorized access to or use of our servers and/or any personal information stored therein. + +6. Changes to These Terms + +We may revise these Terms from time to time. The most current version will always be available in the App. By continuing to use the App after changes become effective, you agree to be bound by the revised Terms. + +7. Termination + +We reserve the right to terminate or suspend your access to the App at any time, without notice, for conduct that we believe violates these Terms or is harmful to other users of the App or us. + +8. Governing Law + +These Terms shall be governed by and construed in accordance with the laws of [Your Jurisdiction], without regard to its conflict of law principles. + +9. Contact Us + +If you have any questions about these Terms, please contact us at [Your Contact Information]. + +[Your Company Name] +[Your Address] +[Your Email Address] \ No newline at end of file diff --git a/app/src/main/assets/tos_testfile.txt b/app/src/main/assets/tos_testfile.txt new file mode 100644 index 0000000..0de64a5 --- /dev/null +++ b/app/src/main/assets/tos_testfile.txt @@ -0,0 +1,3 @@ +Version: 1.0.0 + +Test file for TOSRepository. \ No newline at end of file diff --git a/app/src/main/java/be/re/writand/data/local/models/TermsOfService.kt b/app/src/main/java/be/re/writand/data/local/models/TermsOfService.kt new file mode 100644 index 0000000..e017310 --- /dev/null +++ b/app/src/main/java/be/re/writand/data/local/models/TermsOfService.kt @@ -0,0 +1,10 @@ +package be.re.writand.data.local.models + +import be.re.writand.utils.Version + +/** + * Data class to store information about the TOS. + * @param[version] the version for the current Terms Of Service. + * @param[text] the Terms Of Service itself as a list of the lines. + */ +data class TermsOfService(val version: Version, val text: List) diff --git a/app/src/main/java/be/re/writand/data/repos/tos/ITOSRepository.kt b/app/src/main/java/be/re/writand/data/repos/tos/ITOSRepository.kt new file mode 100644 index 0000000..b95e240 --- /dev/null +++ b/app/src/main/java/be/re/writand/data/repos/tos/ITOSRepository.kt @@ -0,0 +1,14 @@ +package be.re.writand.data.repos.tos + +import be.re.writand.data.local.models.TermsOfService + +/** + * Repository that handles the Terms Of Service in the datastore. + */ +interface ITOSRepository { + + /** + * Get the current version of the TOS from the datastore. + */ + fun getTOS(): TermsOfService +} \ No newline at end of file diff --git a/app/src/main/java/be/re/writand/data/repos/tos/TOSRepository.kt b/app/src/main/java/be/re/writand/data/repos/tos/TOSRepository.kt new file mode 100644 index 0000000..1eae875 --- /dev/null +++ b/app/src/main/java/be/re/writand/data/repos/tos/TOSRepository.kt @@ -0,0 +1,37 @@ +package be.re.writand.data.repos.tos + +import android.content.Context +import android.util.Log +import be.re.writand.data.local.models.TermsOfService +import be.re.writand.utils.Version +import java.io.File +import java.io.InputStream +import java.util.concurrent.Flow +import javax.inject.Inject + +class TOSRepository @Inject constructor( + private val context: Context, + private val sourceFile: String = "tos.txt" +) : ITOSRepository { + /** + * Read the tos.txt file from the assets directory. + */ + private fun readSourceLines(): List { + val tos: InputStream = context.assets.open(sourceFile) + val bytes = tos.readBytes() + tos.close() + + // NOTE: might not be efficient enough if the file is large + return String(bytes).lines() + } + + override fun getTOS(): TermsOfService { + + // if the file gets too large, change the method of reading in the data here + val file = readSourceLines() + + val version = Version.fromString(file[0].removePrefix("Version: ").trim()) + + return TermsOfService(version = version, text = file.subList(2, file.size)) + } +} \ No newline at end of file diff --git a/app/src/main/java/be/re/writand/di/DatabaseModule.kt b/app/src/main/java/be/re/writand/di/DatabaseModule.kt index 1a99ab2..aa9e9f6 100644 --- a/app/src/main/java/be/re/writand/di/DatabaseModule.kt +++ b/app/src/main/java/be/re/writand/di/DatabaseModule.kt @@ -1,8 +1,11 @@ package be.re.writand.di import android.content.Context +import android.content.res.AssetManager import be.re.writand.data.local.db.ProjectsDao import be.re.writand.data.local.db.ProjectsDatabase +import be.re.writand.data.repos.tos.ITOSRepository +import be.re.writand.data.repos.tos.TOSRepository import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -11,7 +14,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton /** - * Module necessary to enable dependency injection for databases and DAO's. + * Module necessary to enable dependency injection for datalayer classes. */ @InstallIn(SingletonComponent::class) @Module @@ -26,4 +29,16 @@ class DatabaseModule { return projectsDatabase.projectsDao() } + /** + * Provide the application context for TOSRepo. + */ + @Provides + fun provideContext(@ApplicationContext context: Context): Context { + return context + } + + @Provides + fun provideTOSRepository(repo: TOSRepository): ITOSRepository { + return repo + } } \ No newline at end of file diff --git a/app/src/main/java/be/re/writand/utils/Version.kt b/app/src/main/java/be/re/writand/utils/Version.kt new file mode 100644 index 0000000..c2137b4 --- /dev/null +++ b/app/src/main/java/be/re/writand/utils/Version.kt @@ -0,0 +1,34 @@ +package be.re.writand.utils + +import android.util.Log + +data class Version(var major: Int, var minor: Int, var patch: Int) { + companion object { + + /** + * Parses a semantic version-string into the Version data class. + * Semantic version defined as major.minor.patch where major, minor, and patch non-negative + * numbers. + * [More details](https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions) + * @param[version] the string in the format mentioned above. + * @throws IllegalArgumentException if [version] is not in the correct format. + */ + fun fromString(version: String): Version { + val split = version.split('.') + Log.d("VERSION", split.toString()) + val errorMsg = + "Input must be of the form major.minor.patch where major, minor and patch are non-negative numbers" + + if (split.size != 3) throw IllegalArgumentException(errorMsg) + return try { + Version( + major = split[0].toInt(), + minor = split[1].toInt(), + patch = split[2].toInt() + ) + } catch (e: NumberFormatException) { + throw IllegalArgumentException(errorMsg) + } + } + } +}