From ed4895ac4759a0db84f51df0891513f6f7c1b640 Mon Sep 17 00:00:00 2001 From: "kristof.nemere" Date: Thu, 18 May 2023 14:00:15 +0200 Subject: [PATCH 01/32] Bumped version code and name --- apps/teacher/build.gradle | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/teacher/build.gradle b/apps/teacher/build.gradle index 98851a2f6f..e6ddb681f4 100644 --- a/apps/teacher/build.gradle +++ b/apps/teacher/build.gradle @@ -14,11 +14,8 @@ * along with this program. If not, see . */ -import com.instructure.android.buildtools.transform.LocaleTransformer -import com.instructure.android.buildtools.transform.MasqueradeUITransformer -import com.instructure.android.buildtools.transform.PageViewTransformer -import com.instructure.android.buildtools.transform.ProjectTransformer -import com.instructure.android.buildtools.transform.ScreenViewTransformer + +import com.instructure.android.buildtools.transform.* apply plugin: 'com.android.application' apply plugin: 'kotlin-android' @@ -42,8 +39,8 @@ android { defaultConfig { minSdkVersion Versions.MIN_SDK targetSdkVersion Versions.TARGET_SDK - versionCode = 57 - versionName = '1.23.1' + versionCode = 58 + versionName = '1.24.0' vectorDrawables.useSupportLibrary = true multiDexEnabled true testInstrumentationRunner 'com.instructure.teacher.ui.espresso.TeacherHiltTestRunner' From df409438f5d5470db7216c41a05a52a8a4d30271 Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Tue, 23 May 2023 13:03:43 +0200 Subject: [PATCH 02/32] [MBL-16708][Student][Teacher] Setup DB test environment (#1989) refs: MBL-16708 affects: Student, Teacher release note: none * AppDatabase tests. * Added db schemas and schema import gradle task. * Basic app database migration test. * Sync db changes with offline branch and extract common entities. --- apps/student/build.gradle | 1 - .../fragment/InboxComposeMessageFragment.kt | 2 +- apps/teacher/build.gradle | 1 - .../SpeedGraderCommentsPresenterFactory.kt | 4 + .../teacher/fragments/AddMessageFragment.kt | 2 +- .../fragments/SpeedGraderCommentsFragment.kt | 4 + .../SpeedGraderCommentsPresenter.kt | 6 +- .../src/main/java/RoomSchemaArgProvider.kt | 33 ++ libs/pandautils/build.gradle | 21 +- .../3.json | 436 ++++++++++++++++ .../4.json | 442 ++++++++++++++++ .../5.json | 466 +++++++++++++++++ .../6.json | 478 ++++++++++++++++++ .../appdatabase/AppDatabaseMigrationTest.kt | 58 +++ .../appdatabase/daos/AttachmentDaoTest.kt | 83 +++ .../daos/DashboardFileUploadDaoTest.kt | 90 ++++ .../daos/FileUploadInputDaoTest.kt | 62 +++ .../daos/PendingSubmissionCommentDaoTest.kt | 126 +++++ .../daos/SubmissionCommentDaoTest.kt | 98 ++++ .../pandautils/di/DatabaseModule.kt | 4 + .../DashboardNotificationsViewModel.kt | 2 +- .../file/upload/worker/FileUploadWorker.kt | 8 + .../room/appdatabase/AppDatabase.kt | 12 +- .../room/appdatabase/AppDatabaseMigrations.kt | 7 +- .../daos/DashboardFileUploadDao.kt | 2 +- .../room/{ => common}/Converters.kt | 10 +- .../room/{ => common}/MigrationUtils.kt | 2 +- .../daos/AttachmentDao.kt | 4 +- .../{appdatabase => common}/daos/AuthorDao.kt | 4 +- .../daos/MediaCommentDao.kt | 4 +- .../daos/SubmissionCommentDao.kt | 6 +- .../entities/AttachmentEntity.kt | 5 +- .../entities/AuthorEntity.kt | 2 +- .../entities/MediaCommentEntity.kt | 2 +- .../entities/SubmissionCommentEntity.kt | 5 +- .../model/SubmissionCommentWithAttachments.kt | 10 +- .../DashboardNotificationsViewModelTest.kt | 2 +- 37 files changed, 2466 insertions(+), 38 deletions(-) create mode 100644 buildSrc/src/main/java/RoomSchemaArgProvider.kt create mode 100644 libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/3.json create mode 100644 libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/4.json create mode 100644 libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/5.json create mode 100644 libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/6.json create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrationTest.kt create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDaoTest.kt create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDaoTest.kt create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/FileUploadInputDaoTest.kt create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/PendingSubmissionCommentDaoTest.kt create mode 100644 libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDaoTest.kt rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{ => common}/Converters.kt (74%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{ => common}/MigrationUtils.kt (95%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/daos/AttachmentDao.kt (80%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/daos/AuthorDao.kt (67%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/daos/MediaCommentDao.kt (72%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/daos/SubmissionCommentDao.kt (66%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/entities/AttachmentEntity.kt (90%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/entities/AuthorEntity.kt (91%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/entities/MediaCommentEntity.kt (92%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/entities/SubmissionCommentEntity.kt (86%) rename libs/pandautils/src/main/java/com/instructure/pandautils/room/{appdatabase => common}/model/SubmissionCommentWithAttachments.kt (76%) diff --git a/apps/student/build.gradle b/apps/student/build.gradle index fb269772e7..a05e86f8df 100644 --- a/apps/student/build.gradle +++ b/apps/student/build.gradle @@ -349,7 +349,6 @@ dependencies { implementation Libs.ROOM kapt Libs.ROOM_COMPILER implementation Libs.ROOM_COROUTINES - testImplementation Libs.ROOM_TEST } // Comment out this line if the reporting logic starts going wonky. diff --git a/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt b/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt index 3a478db30b..b6bb17abae 100644 --- a/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt +++ b/apps/student/src/main/java/com/instructure/student/fragment/InboxComposeMessageFragment.kt @@ -40,7 +40,7 @@ import com.instructure.pandautils.analytics.ScreenView import com.instructure.pandautils.binding.viewBinding import com.instructure.pandautils.features.file.upload.FileUploadDialogFragment import com.instructure.pandautils.features.file.upload.FileUploadDialogParent -import com.instructure.pandautils.room.appdatabase.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AttachmentDao import com.instructure.pandautils.utils.* import com.instructure.student.R import com.instructure.student.adapter.CanvasContextSpinnerAdapter diff --git a/apps/teacher/build.gradle b/apps/teacher/build.gradle index 98851a2f6f..0d85251210 100644 --- a/apps/teacher/build.gradle +++ b/apps/teacher/build.gradle @@ -313,7 +313,6 @@ dependencies { implementation Libs.ROOM kapt Libs.ROOM_COMPILER implementation Libs.ROOM_COROUTINES - testImplementation Libs.ROOM_TEST } apply plugin: 'com.google.gms.google-services' diff --git a/apps/teacher/src/main/java/com/instructure/teacher/factory/SpeedGraderCommentsPresenterFactory.kt b/apps/teacher/src/main/java/com/instructure/teacher/factory/SpeedGraderCommentsPresenterFactory.kt index dd5969218c..3dc1a8a619 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/factory/SpeedGraderCommentsPresenterFactory.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/factory/SpeedGraderCommentsPresenterFactory.kt @@ -20,6 +20,10 @@ import com.instructure.canvasapi2.models.Assignee import com.instructure.canvasapi2.models.Submission import com.instructure.canvasapi2.models.SubmissionComment import com.instructure.pandautils.room.appdatabase.daos.* +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao import com.instructure.teacher.presenters.SpeedGraderCommentsPresenter import com.instructure.teacher.viewinterface.SpeedGraderCommentsView import instructure.androidblueprint.PresenterFactory diff --git a/apps/teacher/src/main/java/com/instructure/teacher/fragments/AddMessageFragment.kt b/apps/teacher/src/main/java/com/instructure/teacher/fragments/AddMessageFragment.kt index a29ec17687..c624e78a75 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/fragments/AddMessageFragment.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/fragments/AddMessageFragment.kt @@ -36,7 +36,7 @@ import com.instructure.pandautils.dialogs.UnsavedChangesExitDialog import com.instructure.pandautils.features.file.upload.FileUploadDialogFragment import com.instructure.pandautils.features.file.upload.FileUploadDialogParent import com.instructure.pandautils.fragments.BasePresenterFragment -import com.instructure.pandautils.room.appdatabase.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AttachmentDao import com.instructure.pandautils.utils.* import com.instructure.pandautils.views.AttachmentView import com.instructure.teacher.R diff --git a/apps/teacher/src/main/java/com/instructure/teacher/fragments/SpeedGraderCommentsFragment.kt b/apps/teacher/src/main/java/com/instructure/teacher/fragments/SpeedGraderCommentsFragment.kt index 9e00e050d4..3faf388c36 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/fragments/SpeedGraderCommentsFragment.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/fragments/SpeedGraderCommentsFragment.kt @@ -41,6 +41,10 @@ import com.instructure.pandautils.features.file.upload.worker.FileUploadWorker import com.instructure.pandautils.fragments.BaseListFragment import com.instructure.pandautils.room.appdatabase.daos.* import com.instructure.pandautils.room.appdatabase.entities.FileUploadInputEntity +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao import com.instructure.pandautils.services.NotoriousUploadService import com.instructure.pandautils.utils.* import com.instructure.teacher.R diff --git a/apps/teacher/src/main/java/com/instructure/teacher/presenters/SpeedGraderCommentsPresenter.kt b/apps/teacher/src/main/java/com/instructure/teacher/presenters/SpeedGraderCommentsPresenter.kt index 71191aed4b..fbda9eddc2 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/presenters/SpeedGraderCommentsPresenter.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/presenters/SpeedGraderCommentsPresenter.kt @@ -32,7 +32,11 @@ import com.instructure.pandautils.features.file.upload.worker.FileUploadWorker import com.instructure.pandautils.room.appdatabase.daos.* import com.instructure.pandautils.room.appdatabase.entities.FileUploadInputEntity import com.instructure.pandautils.room.appdatabase.entities.PendingSubmissionCommentEntity -import com.instructure.pandautils.room.appdatabase.model.SubmissionCommentWithAttachments +import com.instructure.pandautils.room.common.model.SubmissionCommentWithAttachments +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao import com.instructure.teacher.events.SubmissionCommentsUpdated import com.instructure.teacher.events.SubmissionUpdatedEvent import com.instructure.teacher.events.post diff --git a/buildSrc/src/main/java/RoomSchemaArgProvider.kt b/buildSrc/src/main/java/RoomSchemaArgProvider.kt new file mode 100644 index 0000000000..6208be5ec3 --- /dev/null +++ b/buildSrc/src/main/java/RoomSchemaArgProvider.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.process.CommandLineArgumentProvider +import java.io.File + +class RoomSchemaArgProvider( + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + val schemaDir: File +) : CommandLineArgumentProvider { + + override fun asArguments(): Iterable { + return listOf("-Aroom.schemaLocation=${schemaDir.path}") + } +} \ No newline at end of file diff --git a/libs/pandautils/build.gradle b/libs/pandautils/build.gradle index 2944946864..f629e8248e 100644 --- a/libs/pandautils/build.gradle +++ b/libs/pandautils/build.gradle @@ -37,6 +37,14 @@ android { minSdkVersion Versions.MIN_SDK targetSdkVersion Versions.TARGET_SDK buildConfigField "boolean", "IS_TESTING", isTesting() + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + javaCompileOptions { + annotationProcessorOptions { + compilerArgumentProviders( + new RoomSchemaArgProvider(new File(projectDir, "schemas")) + ) + } + } } buildTypes { @@ -82,6 +90,10 @@ android { hilt { enableAggregatingTask = false } + + sourceSets { + debug.assets.srcDirs += files("$projectDir/schemas".toString()) + } } tasks.withType(Test) { @@ -180,7 +192,6 @@ dependencies { implementation Libs.ROOM kapt Libs.ROOM_COMPILER implementation Libs.ROOM_COROUTINES - testImplementation Libs.ROOM_TEST implementation Libs.FLEXBOX_LAYOUT @@ -189,4 +200,12 @@ dependencies { implementation 'com.google.guava:guava:29.0-android' kaptTest Libs.ANDROIDX_DATABINDING_COMPILER + + androidTestImplementation Libs.KOTLIN_COROUTINES_TEST + androidTestImplementation (project(':espresso')) { + exclude group: 'org.checkerframework', module: 'checker' + } + androidTestImplementation Libs.ANDROIDX_TEST_JUNIT + androidTestImplementation Libs.ANDROIDX_CORE_TESTING + androidTestImplementation Libs.ROOM_TEST } diff --git a/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/3.json b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/3.json new file mode 100644 index 0000000000..1b3dbd3925 --- /dev/null +++ b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/3.json @@ -0,0 +1,436 @@ +{ + "formatVersion": 1, + "database": { + "version": 3, + "identityHash": "ab4a2a7c1599b2adcf214ca77d6fec66", + "entities": [ + { + "tableName": "AttachmentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `contentType` TEXT, `filename` TEXT, `displayName` TEXT, `url` TEXT, `thumbnailUrl` TEXT, `previewUrl` TEXT, `createdAt` INTEGER, `size` INTEGER NOT NULL, `workerId` TEXT, `submissionCommentId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filename", + "columnName": "filename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnailUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "previewUrl", + "columnName": "previewUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "submissionCommentId", + "columnName": "submissionCommentId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AuthorEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `displayName` TEXT, `avatarImageUrl` TEXT, `htmlUrl` TEXT, `pronouns` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarImageUrl", + "columnName": "avatarImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "htmlUrl", + "columnName": "htmlUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pronouns", + "columnName": "pronouns", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "FileUploadInputEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `courseId` INTEGER, `assignmentId` INTEGER, `quizId` INTEGER, `quizQuestionId` INTEGER, `position` INTEGER, `parentFolderId` INTEGER, `action` TEXT NOT NULL, `userId` INTEGER, `attachments` TEXT NOT NULL, `submissionId` INTEGER, `filePaths` TEXT NOT NULL, `attemptId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizId", + "columnName": "quizId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizQuestionId", + "columnName": "quizQuestionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "parentFolderId", + "columnName": "parentFolderId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "filePaths", + "columnName": "filePaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MediaCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mediaId` TEXT NOT NULL, `displayName` TEXT, `url` TEXT, `mediaType` TEXT, `contentType` TEXT, PRIMARY KEY(`mediaId`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "mediaId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mediaType", + "columnName": "mediaType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "mediaId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `authorId` INTEGER NOT NULL, `authorName` TEXT, `authorPronouns` TEXT, `comment` TEXT, `createdAt` INTEGER, `mediaCommentId` TEXT, `attemptId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "authorId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorName", + "columnName": "authorName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "authorPronouns", + "columnName": "authorPronouns", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "mediaCommentId", + "columnName": "mediaCommentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "PendingSubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pageId` TEXT NOT NULL, `comment` TEXT, `date` INTEGER NOT NULL, `status` TEXT NOT NULL, `workerId` TEXT, `filePath` TEXT, `attemptId` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pageId", + "columnName": "pageId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "DashboardFileUploadEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `userId` INTEGER NOT NULL, `title` TEXT, `subtitle` TEXT, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ab4a2a7c1599b2adcf214ca77d6fec66')" + ] + } +} \ No newline at end of file diff --git a/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/4.json b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/4.json new file mode 100644 index 0000000000..77f9ec534a --- /dev/null +++ b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/4.json @@ -0,0 +1,442 @@ +{ + "formatVersion": 1, + "database": { + "version": 4, + "identityHash": "687d7d0f33a94588d5c0a3ca30356153", + "entities": [ + { + "tableName": "AttachmentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `contentType` TEXT, `filename` TEXT, `displayName` TEXT, `url` TEXT, `thumbnailUrl` TEXT, `previewUrl` TEXT, `createdAt` INTEGER, `size` INTEGER NOT NULL, `workerId` TEXT, `submissionCommentId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filename", + "columnName": "filename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnailUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "previewUrl", + "columnName": "previewUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "submissionCommentId", + "columnName": "submissionCommentId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AuthorEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `displayName` TEXT, `avatarImageUrl` TEXT, `htmlUrl` TEXT, `pronouns` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarImageUrl", + "columnName": "avatarImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "htmlUrl", + "columnName": "htmlUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pronouns", + "columnName": "pronouns", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "FileUploadInputEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `courseId` INTEGER, `assignmentId` INTEGER, `quizId` INTEGER, `quizQuestionId` INTEGER, `position` INTEGER, `parentFolderId` INTEGER, `action` TEXT NOT NULL, `userId` INTEGER, `attachments` TEXT NOT NULL, `submissionId` INTEGER, `filePaths` TEXT NOT NULL, `attemptId` INTEGER, `notificationId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizId", + "columnName": "quizId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizQuestionId", + "columnName": "quizQuestionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "parentFolderId", + "columnName": "parentFolderId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "filePaths", + "columnName": "filePaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notificationId", + "columnName": "notificationId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MediaCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mediaId` TEXT NOT NULL, `displayName` TEXT, `url` TEXT, `mediaType` TEXT, `contentType` TEXT, PRIMARY KEY(`mediaId`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "mediaId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mediaType", + "columnName": "mediaType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "mediaId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `authorId` INTEGER NOT NULL, `authorName` TEXT, `authorPronouns` TEXT, `comment` TEXT, `createdAt` INTEGER, `mediaCommentId` TEXT, `attemptId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "authorId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorName", + "columnName": "authorName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "authorPronouns", + "columnName": "authorPronouns", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "mediaCommentId", + "columnName": "mediaCommentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "PendingSubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pageId` TEXT NOT NULL, `comment` TEXT, `date` INTEGER NOT NULL, `status` TEXT NOT NULL, `workerId` TEXT, `filePath` TEXT, `attemptId` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pageId", + "columnName": "pageId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "DashboardFileUploadEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `userId` INTEGER NOT NULL, `title` TEXT, `subtitle` TEXT, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '687d7d0f33a94588d5c0a3ca30356153')" + ] + } +} \ No newline at end of file diff --git a/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/5.json b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/5.json new file mode 100644 index 0000000000..0047951845 --- /dev/null +++ b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/5.json @@ -0,0 +1,466 @@ +{ + "formatVersion": 1, + "database": { + "version": 5, + "identityHash": "a12c05da6108f2f24687fabccf1e22f7", + "entities": [ + { + "tableName": "AttachmentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `contentType` TEXT, `filename` TEXT, `displayName` TEXT, `url` TEXT, `thumbnailUrl` TEXT, `previewUrl` TEXT, `createdAt` INTEGER, `size` INTEGER NOT NULL, `workerId` TEXT, `submissionCommentId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filename", + "columnName": "filename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnailUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "previewUrl", + "columnName": "previewUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "submissionCommentId", + "columnName": "submissionCommentId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AuthorEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `displayName` TEXT, `avatarImageUrl` TEXT, `htmlUrl` TEXT, `pronouns` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarImageUrl", + "columnName": "avatarImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "htmlUrl", + "columnName": "htmlUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pronouns", + "columnName": "pronouns", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "FileUploadInputEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `courseId` INTEGER, `assignmentId` INTEGER, `quizId` INTEGER, `quizQuestionId` INTEGER, `position` INTEGER, `parentFolderId` INTEGER, `action` TEXT NOT NULL, `userId` INTEGER, `attachments` TEXT NOT NULL, `submissionId` INTEGER, `filePaths` TEXT NOT NULL, `attemptId` INTEGER, `notificationId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizId", + "columnName": "quizId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizQuestionId", + "columnName": "quizQuestionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "parentFolderId", + "columnName": "parentFolderId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "filePaths", + "columnName": "filePaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notificationId", + "columnName": "notificationId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MediaCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mediaId` TEXT NOT NULL, `displayName` TEXT, `url` TEXT, `mediaType` TEXT, `contentType` TEXT, PRIMARY KEY(`mediaId`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "mediaId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mediaType", + "columnName": "mediaType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "mediaId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `authorId` INTEGER NOT NULL, `authorName` TEXT, `authorPronouns` TEXT, `comment` TEXT, `createdAt` INTEGER, `mediaCommentId` TEXT, `attemptId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "authorId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorName", + "columnName": "authorName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "authorPronouns", + "columnName": "authorPronouns", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "mediaCommentId", + "columnName": "mediaCommentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "PendingSubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pageId` TEXT NOT NULL, `comment` TEXT, `date` INTEGER NOT NULL, `status` TEXT NOT NULL, `workerId` TEXT, `filePath` TEXT, `attemptId` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pageId", + "columnName": "pageId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "DashboardFileUploadEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `userId` INTEGER NOT NULL, `title` TEXT, `subtitle` TEXT, `courseId` INTEGER, `assignmentId` INTEGER, `attemptId` INTEGER, `folderId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "folderId", + "columnName": "folderId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a12c05da6108f2f24687fabccf1e22f7')" + ] + } +} \ No newline at end of file diff --git a/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/6.json b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/6.json new file mode 100644 index 0000000000..1832051edd --- /dev/null +++ b/libs/pandautils/schemas/com.instructure.pandautils.room.appdatabase.AppDatabase/6.json @@ -0,0 +1,478 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "c843a3949b0b11ce080d316a1f324e47", + "entities": [ + { + "tableName": "AttachmentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `contentType` TEXT, `filename` TEXT, `displayName` TEXT, `url` TEXT, `thumbnailUrl` TEXT, `previewUrl` TEXT, `createdAt` INTEGER, `size` INTEGER NOT NULL, `workerId` TEXT, `submissionCommentId` INTEGER, `submissionId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filename", + "columnName": "filename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnailUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "previewUrl", + "columnName": "previewUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "submissionCommentId", + "columnName": "submissionCommentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AuthorEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `displayName` TEXT, `avatarImageUrl` TEXT, `htmlUrl` TEXT, `pronouns` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarImageUrl", + "columnName": "avatarImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "htmlUrl", + "columnName": "htmlUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pronouns", + "columnName": "pronouns", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "FileUploadInputEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `courseId` INTEGER, `assignmentId` INTEGER, `quizId` INTEGER, `quizQuestionId` INTEGER, `position` INTEGER, `parentFolderId` INTEGER, `action` TEXT NOT NULL, `userId` INTEGER, `attachments` TEXT NOT NULL, `submissionId` INTEGER, `filePaths` TEXT NOT NULL, `attemptId` INTEGER, `notificationId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizId", + "columnName": "quizId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "quizQuestionId", + "columnName": "quizQuestionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "parentFolderId", + "columnName": "parentFolderId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "filePaths", + "columnName": "filePaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notificationId", + "columnName": "notificationId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MediaCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mediaId` TEXT NOT NULL, `displayName` TEXT, `url` TEXT, `mediaType` TEXT, `contentType` TEXT, PRIMARY KEY(`mediaId`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "mediaId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mediaType", + "columnName": "mediaType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "mediaId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `authorId` INTEGER NOT NULL, `authorName` TEXT, `authorPronouns` TEXT, `comment` TEXT, `createdAt` INTEGER, `mediaCommentId` TEXT, `attemptId` INTEGER, `submissionId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "authorId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorName", + "columnName": "authorName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "authorPronouns", + "columnName": "authorPronouns", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "mediaCommentId", + "columnName": "mediaCommentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "submissionId", + "columnName": "submissionId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "PendingSubmissionCommentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `pageId` TEXT NOT NULL, `comment` TEXT, `date` INTEGER NOT NULL, `status` TEXT NOT NULL, `workerId` TEXT, `filePath` TEXT, `attemptId` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pageId", + "columnName": "pageId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "DashboardFileUploadEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`workerId` TEXT NOT NULL, `userId` INTEGER NOT NULL, `title` TEXT, `subtitle` TEXT, `courseId` INTEGER, `assignmentId` INTEGER, `attemptId` INTEGER, `folderId` INTEGER, PRIMARY KEY(`workerId`))", + "fields": [ + { + "fieldPath": "workerId", + "columnName": "workerId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "courseId", + "columnName": "courseId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "assignmentId", + "columnName": "assignmentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attemptId", + "columnName": "attemptId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "folderId", + "columnName": "folderId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "workerId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c843a3949b0b11ce080d316a1f324e47')" + ] + } +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrationTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrationTest.kt new file mode 100644 index 0000000000..308efb812f --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrationTest.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase + +import androidx.room.Room +import androidx.room.testing.MigrationTestHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import java.io.IOException + +private const val TEST_DB = "migration-test" +// We don't have the schemas for version 1,2 so we only start testing from version 3. +private val ALL_MIGRATIONS = appDatabaseMigrations.takeLast(appDatabaseMigrations.size - 2).toTypedArray() + +@RunWith(AndroidJUnit4::class) +class AppDatabaseMigrationTest { + + @get:Rule + val helper: MigrationTestHelper = MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + AppDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() + ) + + @Test + @Throws(IOException::class) + fun migrateAll() { + // Create earliest version of the database. + // We don't have the schemas for version 1,2 so we only start testing from version 3. + helper.createDatabase(TEST_DB, 3).apply { + close() + } + + // Open latest version of the database. Room validates the schema once all migrations execute. + Room.databaseBuilder(InstrumentationRegistry.getInstrumentation().targetContext, AppDatabase::class.java, TEST_DB) + .addMigrations(*ALL_MIGRATIONS).build().apply { + openHelper.writableDatabase.close() + } + } +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDaoTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDaoTest.kt new file mode 100644 index 0000000000..3f91092fce --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDaoTest.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase.daos + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.instructure.pandautils.room.appdatabase.AppDatabase +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.entities.AttachmentEntity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.util.Date + +@ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class AttachmentDaoTest { + + private lateinit var db: AppDatabase + private lateinit var attachmentDao: AttachmentDao + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + attachmentDao = db.attachmentDao() + } + + @After + fun tearDoown() { + db.close() + } + + @Test + fun insertAndFindingByParentId() = runTest { + val attachmentEntity = AttachmentEntity(id = 1, contentType = "image/jpg", filename = "image.jpg", displayName = "File", + url = "file.com", createdAt = Date(), size = 10000, workerId = "123", submissionCommentId = 123 + ) + + val attachmentEntity2 = attachmentEntity.copy(id = 2, workerId = "124", filename = "image2.jpg") + + attachmentDao.insertAll(listOf(attachmentEntity, attachmentEntity2)) + val result = attachmentDao.findByParentId("123") + Assert.assertEquals(1, result!!.size) + Assert.assertEquals(attachmentEntity, result.first()) + } + + @Test + fun dontReturnAnyItemIfEntitiesAreDeleted() = runTest { + val attachmentEntity = AttachmentEntity(id = 1, contentType = "image/jpg", filename = "image.jpg", displayName = "File", + url = "file.com", createdAt = Date(), size = 10000, workerId = "123", submissionCommentId = 123 + ) + + val attachmentEntity2 = attachmentEntity.copy(id = 2, workerId = "124", filename = "image2.jpg") + + attachmentDao.insertAll(listOf(attachmentEntity, attachmentEntity2)) + attachmentDao.deleteAll(listOf(attachmentEntity, attachmentEntity2)) + val result = attachmentDao.findByParentId("123") + + Assert.assertEquals(0, result!!.size) + } + +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDaoTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDaoTest.kt new file mode 100644 index 0000000000..229d4b8cd5 --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDaoTest.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase.daos + +import android.content.Context +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.instructure.pandautils.room.appdatabase.AppDatabase +import com.instructure.pandautils.room.appdatabase.entities.DashboardFileUploadEntity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class DashboardFileUploadDaoTest { + + private lateinit var db: AppDatabase + private lateinit var dashboardFileUploadDao: DashboardFileUploadDao + + @get:Rule + var instantExecutorRule = InstantTaskExecutorRule() + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + dashboardFileUploadDao = db.dashboardFileUploadDao() + } + + @After + fun tearDoown() { + db.close() + } + + @Test + fun getCorrectDataForUserId() = runTest { + val uploadForUser1 = DashboardFileUploadEntity("1", 1, title = "Upload", null, null, null, null, null) + val upload2ForUser1 = DashboardFileUploadEntity("2", 1, title = "Upload 2", null, null, null, null, null) + val uploadForUser2 = DashboardFileUploadEntity("3", 2, title = "We don't need this", null, null, null, null, null) + dashboardFileUploadDao.insert(uploadForUser1) + dashboardFileUploadDao.insert(upload2ForUser1) + dashboardFileUploadDao.insert(uploadForUser2) + + val result = dashboardFileUploadDao.getAllForUser(1) + + result.observeForever { + Assert.assertEquals(2, it.size) + Assert.assertEquals(uploadForUser1, it.get(0)) + Assert.assertEquals(upload2ForUser1, it.get(1)) + } + } + + @Test + fun deleteByWorkerIdDeletesCorrectItem() = runTest { + val uploadForUser1 = DashboardFileUploadEntity("1", 1, title = "Upload", null, null, null, null, null) + val uploadForUser2 = DashboardFileUploadEntity("3", 2, title = "We don't need this", null, null, null, null, null) + dashboardFileUploadDao.insert(uploadForUser1) + dashboardFileUploadDao.insert(uploadForUser2) + + dashboardFileUploadDao.deleteByWorkerId("1") + val result = dashboardFileUploadDao.getAllForUser(1) + + result.observeForever { + Assert.assertEquals(0, it.size) + } + } +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/FileUploadInputDaoTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/FileUploadInputDaoTest.kt new file mode 100644 index 0000000000..5b98447cdb --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/FileUploadInputDaoTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase.daos + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.instructure.pandautils.room.appdatabase.AppDatabase +import com.instructure.pandautils.room.appdatabase.entities.FileUploadInputEntity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class FileUploadInputDaoTest { + + private lateinit var db: AppDatabase + private lateinit var fileUploadInputDao: FileUploadInputDao + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + fileUploadInputDao = db.fileUploadInputDao() + } + + @After + fun tearDoown() { + db.close() + } + + @Test + fun findCorrectEntityByWorkerId() = runTest { + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "2", action = "upload 2", filePaths = emptyList())) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "1", action = "upload", filePaths = emptyList())) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "3", action = "upload 3", filePaths = emptyList())) + + val result = fileUploadInputDao.findByWorkerId("1") + + Assert.assertEquals("upload", result!!.action) + } +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/PendingSubmissionCommentDaoTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/PendingSubmissionCommentDaoTest.kt new file mode 100644 index 0000000000..3efdddd201 --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/PendingSubmissionCommentDaoTest.kt @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase.daos + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.instructure.pandautils.room.appdatabase.AppDatabase +import com.instructure.pandautils.room.appdatabase.entities.FileUploadInputEntity +import com.instructure.pandautils.room.appdatabase.entities.PendingSubmissionCommentEntity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class PendingSubmissionCommentDaoTest { + + private lateinit var db: AppDatabase + private lateinit var pendingSubmissionCommentDao: PendingSubmissionCommentDao + + private lateinit var fileUploadInputDao: FileUploadInputDao + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + pendingSubmissionCommentDao = db.pendingSubmissionCommentDao() + fileUploadInputDao = db.fileUploadInputDao() + } + + @After + fun tearDoown() { + db.close() + } + + @Test + fun testFindCorrectItemByWorkedId() = runTest { + val itemToFind = PendingSubmissionCommentEntity(2, pageId = "12", workerId = "222") + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(1, pageId = "11", workerId = "111")) + pendingSubmissionCommentDao.insert(itemToFind) + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(3, pageId = "12", workerId = "333")) + + val result = pendingSubmissionCommentDao.findByWorkerId("222") + + Assert.assertEquals(itemToFind, result) + } + + @Test + fun testFindCorrectItemById() = runTest { + val itemToFind = PendingSubmissionCommentEntity(2, pageId = "12", workerId = "222") + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(1, pageId = "11", workerId = "111")) + pendingSubmissionCommentDao.insert(itemToFind) + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(3, pageId = "12", workerId = "333")) + + val result = pendingSubmissionCommentDao.findById(2) + + Assert.assertEquals(itemToFind, result) + } + + @Test + fun testFindCorrectItemByWorkedIdWithInputData() = runTest { + val itemToFind = PendingSubmissionCommentEntity(2, pageId = "12", workerId = "222") + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(1, pageId = "11", workerId = "111")) + pendingSubmissionCommentDao.insert(itemToFind) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "222", action = "File Upload", filePaths = emptyList())) + + val result = pendingSubmissionCommentDao.findByWorkerIdWithInputData("222") + + Assert.assertEquals(itemToFind, result!!.pendingSubmissionCommentEntity) + Assert.assertEquals("File Upload", result.fileUploadInput!!.action) + } + + @Test + fun testFindCorrectItemByPageIdWithInputData() = runTest { + val itemToFind = PendingSubmissionCommentEntity(2, pageId = "12", workerId = "222") + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(1, pageId = "11", workerId = "111")) + pendingSubmissionCommentDao.insert(itemToFind) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "222", action = "File Upload", filePaths = emptyList())) + + val result = pendingSubmissionCommentDao.findByPageId("12") + + Assert.assertEquals(1, result!!.size) + Assert.assertEquals(itemToFind, result.first().pendingSubmissionCommentEntity) + Assert.assertEquals("File Upload", result.first().fileUploadInput!!.action) + } + + @Test + fun testFindByStatusOnlyReturnsTheItemsWithCorrectStatusAndNonNullWorkerId() = runTest { + val itemToFind = PendingSubmissionCommentEntity(2, status = "progress", pageId = "12", workerId = "222") + val itemToFind2 = PendingSubmissionCommentEntity(4, status = "progress", pageId = "15", workerId = "333") + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(1, status = "finished", pageId = "11", workerId = "111")) + pendingSubmissionCommentDao.insert(itemToFind) + pendingSubmissionCommentDao.insert(PendingSubmissionCommentEntity(3, status = "progress", pageId = "19")) + pendingSubmissionCommentDao.insert(itemToFind2) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "222", action = "File Upload", filePaths = emptyList())) + fileUploadInputDao.insert(FileUploadInputEntity(workerId = "333", action = "File Upload 2", filePaths = emptyList())) + + val result = pendingSubmissionCommentDao.findByStatus("progress") + + Assert.assertEquals(2, result!!.size) + Assert.assertEquals(itemToFind, result.first().pendingSubmissionCommentEntity) + Assert.assertEquals(itemToFind2, result.get(1).pendingSubmissionCommentEntity) + Assert.assertEquals("File Upload", result.first().fileUploadInput!!.action) + Assert.assertEquals("File Upload 2", result.get(1).fileUploadInput!!.action) + } +} \ No newline at end of file diff --git a/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDaoTest.kt b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDaoTest.kt new file mode 100644 index 0000000000..3f143ee8c9 --- /dev/null +++ b/libs/pandautils/src/androidTest/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDaoTest.kt @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2023 - present Instructure, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.instructure.pandautils.room.appdatabase.daos + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.instructure.pandautils.room.appdatabase.AppDatabase +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao +import com.instructure.pandautils.room.common.entities.AttachmentEntity +import com.instructure.pandautils.room.common.entities.AuthorEntity +import com.instructure.pandautils.room.common.entities.MediaCommentEntity +import com.instructure.pandautils.room.common.entities.SubmissionCommentEntity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class SubmissionCommentDaoTest { + + private lateinit var db: AppDatabase + private lateinit var submissionCommentDao: SubmissionCommentDao + + private lateinit var attachmentDao: AttachmentDao + private lateinit var mediaCommentDao: MediaCommentDao + private lateinit var authorDao: AuthorDao + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + submissionCommentDao = db.submissionCommentDao() + + attachmentDao = db.attachmentDao() + mediaCommentDao = db.mediaCommentDao() + authorDao = db.authorDao() + } + + @After + fun tearDoown() { + db.close() + } + + @Test + fun getSubmissionCommentWithAttachmentsById() = runTest { + // Setup all DAOs with the data needed for the query + val id = 1L + val submissionComment = SubmissionCommentEntity( + id = id, + comment = "These are the droids you are looking for", + authorId = 1, + mediaCommentId = "66" + ) + + val submissionComment2 = SubmissionCommentEntity( + id = 2, + comment = "These are not the droids you are looking for", + ) + + submissionCommentDao.insert(submissionComment) + submissionCommentDao.insert(submissionComment2) + authorDao.insert(AuthorEntity(id = 1, displayName = "Obi-Wan")) + attachmentDao.insert(AttachmentEntity(id = 5, submissionCommentId = 1, filename = "droids.mp4")) + mediaCommentDao.insert(MediaCommentEntity(mediaId = "66", displayName = "Order 66")) + + // Verify correct query + val result = submissionCommentDao.findById(id) + + Assert.assertEquals(submissionComment, result!!.submissionComment) + Assert.assertEquals(1, result.attachments!!.size) + Assert.assertEquals("droids.mp4", result.attachments!!.first().filename) + Assert.assertEquals("Obi-Wan", result.author!!.displayName) + Assert.assertEquals("Order 66", result.mediaComment!!.displayName) + } +} \ No newline at end of file diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/di/DatabaseModule.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/di/DatabaseModule.kt index 5d7b3807eb..311a14c31e 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/di/DatabaseModule.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/di/DatabaseModule.kt @@ -2,6 +2,10 @@ package com.instructure.pandautils.di import com.instructure.pandautils.room.appdatabase.AppDatabase import com.instructure.pandautils.room.appdatabase.daos.* +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModel.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModel.kt index 73b4c351ef..c8e284b1eb 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModel.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModel.kt @@ -92,7 +92,7 @@ class DashboardNotificationsViewModel @Inject constructor( } } - private val fileUploads = dashboardFileUploadDao.getAll(apiPrefs.user?.id.orDefault()) + private val fileUploads = dashboardFileUploadDao.getAllForUser(apiPrefs.user?.id.orDefault()) init { fileUploads.observeForever(runningWorkersObserver) diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/upload/worker/FileUploadWorker.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/upload/worker/FileUploadWorker.kt index 4799e6bf9f..a0bc0b9c25 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/upload/worker/FileUploadWorker.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/features/file/upload/worker/FileUploadWorker.kt @@ -37,6 +37,14 @@ import com.instructure.pandautils.R import com.instructure.pandautils.features.file.upload.FileUploadUtilsHelper import com.instructure.pandautils.room.appdatabase.daos.* import com.instructure.pandautils.room.appdatabase.entities.* +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao +import com.instructure.pandautils.room.common.entities.AttachmentEntity +import com.instructure.pandautils.room.common.entities.AuthorEntity +import com.instructure.pandautils.room.common.entities.MediaCommentEntity +import com.instructure.pandautils.room.common.entities.SubmissionCommentEntity import com.instructure.pandautils.utils.FileUploadUtils import com.instructure.pandautils.utils.orDefault import com.instructure.pandautils.utils.toJson diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabase.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabase.kt index 403fd4631e..243e856f65 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabase.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabase.kt @@ -3,9 +3,17 @@ package com.instructure.pandautils.room.appdatabase import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters -import com.instructure.pandautils.room.Converters +import com.instructure.pandautils.room.common.Converters import com.instructure.pandautils.room.appdatabase.daos.* import com.instructure.pandautils.room.appdatabase.entities.* +import com.instructure.pandautils.room.common.daos.AttachmentDao +import com.instructure.pandautils.room.common.daos.AuthorDao +import com.instructure.pandautils.room.common.daos.MediaCommentDao +import com.instructure.pandautils.room.common.daos.SubmissionCommentDao +import com.instructure.pandautils.room.common.entities.AttachmentEntity +import com.instructure.pandautils.room.common.entities.AuthorEntity +import com.instructure.pandautils.room.common.entities.MediaCommentEntity +import com.instructure.pandautils.room.common.entities.SubmissionCommentEntity @Database( entities = [ @@ -16,7 +24,7 @@ import com.instructure.pandautils.room.appdatabase.entities.* SubmissionCommentEntity::class, PendingSubmissionCommentEntity::class, DashboardFileUploadEntity::class - ], version = 5 + ], version = 6 ) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrations.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrations.kt index a99980b688..fe79a15f37 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrations.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/AppDatabaseMigrations.kt @@ -17,7 +17,7 @@ package com.instructure.pandautils.room.appdatabase -import com.instructure.pandautils.room.createMigration +import com.instructure.pandautils.room.common.createMigration val appDatabaseMigrations = arrayOf( @@ -40,5 +40,10 @@ val appDatabaseMigrations = arrayOf( database.execSQL("ALTER TABLE DashboardFileUploadEntity ADD COLUMN assignmentId INTEGER") database.execSQL("ALTER TABLE DashboardFileUploadEntity ADD COLUMN attemptId INTEGER") database.execSQL("ALTER TABLE DashboardFileUploadEntity ADD COLUMN folderId INTEGER") + }, + + createMigration(5, 6) { database -> + database.execSQL("ALTER TABLE AttachmentEntity ADD COLUMN submissionId INTEGER") + database.execSQL("ALTER TABLE SubmissionCommentEntity ADD COLUMN submissionId INTEGER") } ) diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDao.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDao.kt index acc60f7d86..aafac868d8 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDao.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/DashboardFileUploadDao.kt @@ -14,7 +14,7 @@ interface DashboardFileUploadDao { suspend fun delete(dashboardFileUploadEntity: DashboardFileUploadEntity) @Query("SELECT * FROM DashboardFileUploadEntity WHERE userId = :userId") - fun getAll(userId: Long): LiveData> + fun getAllForUser(userId: Long): LiveData> @Query("DELETE FROM DashboardFileUploadEntity WHERE workerId = :workerId") suspend fun deleteByWorkerId(workerId: String) diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/Converters.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/Converters.kt similarity index 74% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/Converters.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/Converters.kt index 5b3b8e6259..061e9ddb56 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/Converters.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/Converters.kt @@ -1,4 +1,4 @@ -package com.instructure.pandautils.room +package com.instructure.pandautils.room.common import androidx.room.TypeConverter import java.util.* @@ -25,12 +25,12 @@ class Converters { } @TypeConverter - fun dateToLong(date: Date): Long { - return date.time + fun dateToLong(date: Date?): Long? { + return date?.time } @TypeConverter - fun longToDate(timestamp: Long): Date { - return Date(timestamp) + fun longToDate(timestamp: Long?): Date? { + return timestamp?.let { Date(it) } } } \ No newline at end of file diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/MigrationUtils.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/MigrationUtils.kt similarity index 95% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/MigrationUtils.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/MigrationUtils.kt index ae5918df5b..4ae2fd7468 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/MigrationUtils.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/MigrationUtils.kt @@ -15,7 +15,7 @@ * */ -package com.instructure.pandautils.room +package com.instructure.pandautils.room.common import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDao.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AttachmentDao.kt similarity index 80% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDao.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AttachmentDao.kt index 1851f4d314..8d2942bf75 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AttachmentDao.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AttachmentDao.kt @@ -1,7 +1,7 @@ -package com.instructure.pandautils.room.appdatabase.daos +package com.instructure.pandautils.room.common.daos import androidx.room.* -import com.instructure.pandautils.room.appdatabase.entities.AttachmentEntity +import com.instructure.pandautils.room.common.entities.AttachmentEntity @Dao interface AttachmentDao { diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AuthorDao.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AuthorDao.kt similarity index 67% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AuthorDao.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AuthorDao.kt index 629f056120..db2cd5ac8c 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/AuthorDao.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/AuthorDao.kt @@ -1,7 +1,7 @@ -package com.instructure.pandautils.room.appdatabase.daos +package com.instructure.pandautils.room.common.daos import androidx.room.* -import com.instructure.pandautils.room.appdatabase.entities.AuthorEntity +import com.instructure.pandautils.room.common.entities.AuthorEntity @Dao interface AuthorDao { diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/MediaCommentDao.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/MediaCommentDao.kt similarity index 72% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/MediaCommentDao.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/MediaCommentDao.kt index 615818d205..f10912ce14 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/MediaCommentDao.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/MediaCommentDao.kt @@ -1,10 +1,10 @@ -package com.instructure.pandautils.room.appdatabase.daos +package com.instructure.pandautils.room.common.daos import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.Update -import com.instructure.pandautils.room.appdatabase.entities.MediaCommentEntity +import com.instructure.pandautils.room.common.entities.MediaCommentEntity @Dao interface MediaCommentDao { diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDao.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/SubmissionCommentDao.kt similarity index 66% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDao.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/SubmissionCommentDao.kt index 0286854878..075ce58bb8 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/daos/SubmissionCommentDao.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/daos/SubmissionCommentDao.kt @@ -1,8 +1,8 @@ -package com.instructure.pandautils.room.appdatabase.daos +package com.instructure.pandautils.room.common.daos import androidx.room.* -import com.instructure.pandautils.room.appdatabase.entities.SubmissionCommentEntity -import com.instructure.pandautils.room.appdatabase.model.SubmissionCommentWithAttachments +import com.instructure.pandautils.room.common.entities.SubmissionCommentEntity +import com.instructure.pandautils.room.common.model.SubmissionCommentWithAttachments @Dao interface SubmissionCommentDao { diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AttachmentEntity.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AttachmentEntity.kt similarity index 90% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AttachmentEntity.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AttachmentEntity.kt index 97ba2e503d..e3f7333dfa 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AttachmentEntity.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AttachmentEntity.kt @@ -1,4 +1,4 @@ -package com.instructure.pandautils.room.appdatabase.entities +package com.instructure.pandautils.room.common.entities import androidx.room.Entity import androidx.room.PrimaryKey @@ -19,7 +19,8 @@ data class AttachmentEntity( //Used for file upload result val workerId: String? = null, //Used for Submission comments - val submissionCommentId: Long? = null + val submissionCommentId: Long? = null, + val submissionId: Long? = null ) { constructor(attachment: Attachment, workerId: String? = null, submissionCommentId: Long? = null) : this( attachment.id, diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AuthorEntity.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AuthorEntity.kt similarity index 91% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AuthorEntity.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AuthorEntity.kt index 81fbda4f72..43d0780318 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/AuthorEntity.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/AuthorEntity.kt @@ -1,4 +1,4 @@ -package com.instructure.pandautils.room.appdatabase.entities +package com.instructure.pandautils.room.common.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/MediaCommentEntity.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/MediaCommentEntity.kt similarity index 92% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/MediaCommentEntity.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/MediaCommentEntity.kt index a8a982385e..2a6de585ac 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/MediaCommentEntity.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/MediaCommentEntity.kt @@ -1,4 +1,4 @@ -package com.instructure.pandautils.room.appdatabase.entities +package com.instructure.pandautils.room.common.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/SubmissionCommentEntity.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/SubmissionCommentEntity.kt similarity index 86% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/SubmissionCommentEntity.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/SubmissionCommentEntity.kt index ebf984b4a5..6e477b4e19 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/entities/SubmissionCommentEntity.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/entities/SubmissionCommentEntity.kt @@ -1,4 +1,4 @@ -package com.instructure.pandautils.room.appdatabase.entities +package com.instructure.pandautils.room.common.entities import androidx.room.Entity import androidx.room.PrimaryKey @@ -14,7 +14,8 @@ data class SubmissionCommentEntity( val comment: String? = null, val createdAt: Date? = null, val mediaCommentId: String? = null, - val attemptId: Long? = null + val attemptId: Long? = null, + val submissionId: Long? = null ) { constructor(submissionComment: SubmissionComment): this( submissionComment.id, diff --git a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/model/SubmissionCommentWithAttachments.kt b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/model/SubmissionCommentWithAttachments.kt similarity index 76% rename from libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/model/SubmissionCommentWithAttachments.kt rename to libs/pandautils/src/main/java/com/instructure/pandautils/room/common/model/SubmissionCommentWithAttachments.kt index 40bd4de657..618ee58b54 100644 --- a/libs/pandautils/src/main/java/com/instructure/pandautils/room/appdatabase/model/SubmissionCommentWithAttachments.kt +++ b/libs/pandautils/src/main/java/com/instructure/pandautils/room/common/model/SubmissionCommentWithAttachments.kt @@ -1,12 +1,12 @@ -package com.instructure.pandautils.room.appdatabase.model +package com.instructure.pandautils.room.common.model import androidx.room.Embedded import androidx.room.Relation import com.instructure.canvasapi2.models.SubmissionComment -import com.instructure.pandautils.room.appdatabase.entities.AttachmentEntity -import com.instructure.pandautils.room.appdatabase.entities.AuthorEntity -import com.instructure.pandautils.room.appdatabase.entities.MediaCommentEntity -import com.instructure.pandautils.room.appdatabase.entities.SubmissionCommentEntity +import com.instructure.pandautils.room.common.entities.AttachmentEntity +import com.instructure.pandautils.room.common.entities.AuthorEntity +import com.instructure.pandautils.room.common.entities.MediaCommentEntity +import com.instructure.pandautils.room.common.entities.SubmissionCommentEntity data class SubmissionCommentWithAttachments( @Embedded diff --git a/libs/pandautils/src/test/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModelTest.kt b/libs/pandautils/src/test/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModelTest.kt index 4c048de31d..0c5ab21201 100644 --- a/libs/pandautils/src/test/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModelTest.kt +++ b/libs/pandautils/src/test/java/com/instructure/pandautils/features/dashboard/notifications/DashboardNotificationsViewModelTest.kt @@ -121,7 +121,7 @@ class DashboardNotificationsViewModelTest { every { apiPrefs.user } returns User(id = 1) uploadsLiveData = MutableLiveData(emptyList()) - every { dashboardFileUploadDao.getAll(1) } returns uploadsLiveData + every { dashboardFileUploadDao.getAllForUser(1) } returns uploadsLiveData viewModel = DashboardNotificationsViewModel( resources, From bb285177bd41c4beae6993ed21704a73705c1000 Mon Sep 17 00:00:00 2001 From: Kristof Nemere <109959688+kristofnemere@users.noreply.github.com> Date: Wed, 24 May 2023 10:16:54 +0200 Subject: [PATCH 03/32] [MBL-16652][Teacher] Show 'exceeded storage quota' toast when file upload storage is full refs: MBL-16652 affects: Teacher release note: Implemented storage quota limit error. --- .../activities/BaseAppCompatActivity.kt | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/teacher/src/main/java/com/instructure/teacher/activities/BaseAppCompatActivity.kt b/apps/teacher/src/main/java/com/instructure/teacher/activities/BaseAppCompatActivity.kt index 55f3eeb5f0..17ed4cf8c3 100644 --- a/apps/teacher/src/main/java/com/instructure/teacher/activities/BaseAppCompatActivity.kt +++ b/apps/teacher/src/main/java/com/instructure/teacher/activities/BaseAppCompatActivity.kt @@ -20,13 +20,15 @@ package com.instructure.teacher.activities import android.content.Intent import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat -import com.instructure.pandautils.utils.ActivityResult -import com.instructure.pandautils.utils.OnActivityResults -import com.instructure.pandautils.utils.PermissionReceiver +import com.instructure.canvasapi2.models.StorageQuotaExceededError +import com.instructure.pandautils.utils.* import com.instructure.pandautils.utils.RequestCodes.CAMERA_PIC_REQUEST import com.instructure.pandautils.utils.RequestCodes.PICK_FILE_FROM_DEVICE import com.instructure.pandautils.utils.RequestCodes.PICK_IMAGE_GALLERY -import com.instructure.pandautils.utils.postSticky +import com.instructure.teacher.R +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") abstract class BaseAppCompatActivity : AppCompatActivity(), @@ -42,4 +44,20 @@ abstract class BaseAppCompatActivity : AppCompatActivity(), OnActivityResults(ActivityResult(requestCode, resultCode, data), null).postSticky() } } + + override fun onStart() { + super.onStart() + EventBus.getDefault().register(this) + } + + override fun onStop() { + super.onStop() + EventBus.getDefault().unregister(this) + } + + @Suppress("unused", "UNUSED_PARAMETER") + @Subscribe(threadMode = ThreadMode.MAIN) + fun onQuotaExceeded(errorCode: StorageQuotaExceededError) { + toast(R.string.fileQuotaExceeded) + } } From d5b3cd37ac5a6db091476146629a244e06a911b1 Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Wed, 24 May 2023 15:52:44 +0200 Subject: [PATCH 04/32] [MBL-16807][Student][Teacher] Set up library integration tests on Bitrise #1995 refs: MBL-16807 affects: Student, Teacher release note: none --- libs/pandautils/build.gradle | 1 + libs/pandautils/flank.yml | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 libs/pandautils/flank.yml diff --git a/libs/pandautils/build.gradle b/libs/pandautils/build.gradle index f629e8248e..e0adde4efa 100644 --- a/libs/pandautils/build.gradle +++ b/libs/pandautils/build.gradle @@ -38,6 +38,7 @@ android { targetSdkVersion Versions.TARGET_SDK buildConfigField "boolean", "IS_TESTING", isTesting() testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + testApplicationId System.getProperty("testApplicationId", "com.instructure.pandautils.test") javaCompileOptions { annotationProcessorOptions { compilerArgumentProviders( diff --git a/libs/pandautils/flank.yml b/libs/pandautils/flank.yml new file mode 100644 index 0000000000..48bcce337e --- /dev/null +++ b/libs/pandautils/flank.yml @@ -0,0 +1,21 @@ +gcloud: + project: delta-essence-114723 + app: ./libs/pandautils/pandautils-app.apk + test: ./libs/pandautils/pandautils-test.apk + results-bucket: android-pandautils + auto-google-login: true + use-orchestrator: true + performance-metrics: false + timeout: 60m + test-targets: + - notAnnotation com.instructure.canvas.espresso.E2E, com.instructure.canvas.espresso.Stub, com.instructure.canvas.espresso.FlakyE2E, com.instructure.canvas.espresso.KnownBug + device: + - model: Nexus6P + version: 26 + locale: en_US + orientation: portrait + +flank: + testShards: 10 + testRuns: 1 + From adcd7cbf174b7b30f771099a83db8f741f828b0d Mon Sep 17 00:00:00 2001 From: Tamas Kozmer <72397075+tamaskozmer@users.noreply.github.com> Date: Wed, 24 May 2023 16:22:19 +0200 Subject: [PATCH 05/32] [MBL-16620][Student][Teacher] Update PSPDFKit (#1992) refs: MBL-16620 affects: Student, Teacher release note: Design changes on view PDF screen (Student only) * Updated dependencies. Fixed crashes after update. Fixed styles and refactored grouping rule for Student PDF view screen. * Fixed toolbar menu items. --- .../student/activity/CandroidPSPDFActivity.kt | 12 +- .../com/instructure/student/util/FileUtils.kt | 1 - .../src/main/res/menu/pspdf_activity_menu.xml | 18 +- .../src/main/res/values-night/styles.xml | 2 + apps/student/src/main/res/values/styles.xml | 4 +- buildSrc/src/main/java/GlobalDependencies.kt | 2 +- .../annotations/CanvasPdfMenuGrouping.kt | 192 ++++++++---------- 7 files changed, 100 insertions(+), 131 deletions(-) diff --git a/apps/student/src/main/java/com/instructure/student/activity/CandroidPSPDFActivity.kt b/apps/student/src/main/java/com/instructure/student/activity/CandroidPSPDFActivity.kt index 8d5f1f8e66..bee62d8765 100644 --- a/apps/student/src/main/java/com/instructure/student/activity/CandroidPSPDFActivity.kt +++ b/apps/student/src/main/java/com/instructure/student/activity/CandroidPSPDFActivity.kt @@ -95,17 +95,21 @@ class CandroidPSPDFActivity : PdfActivity(), ToolbarCoordinatorLayout.OnContextu ViewStyler.setStatusBarDark(this, color) } - override fun onPrepareOptionsMenu(menu: Menu): Boolean { - super.onPrepareOptionsMenu(menu) + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.pspdf_activity_menu, menu) if (submissionTarget != null) { // If targeted for submission, change the menu item title from "Upload to Canvas" to "Submit Assignment" - val item = menu.findItem(R.id.upload_item) - item.title = getString(R.string.submitAssignment) + val item = menu?.findItem(R.id.upload_item) + item?.title = getString(R.string.submitAssignment) } return true } + override fun onGetShowAsAction(menuItemId: Int, defaultShowAsAction: Int): Int { + return if (menuItemId != R.id.upload_item) MenuItem.SHOW_AS_ACTION_ALWAYS else super.onGetShowAsAction(menuItemId, defaultShowAsAction) + } + override fun onOptionsItemSelected(item: MenuItem): Boolean { super.onOptionsItemSelected(item) return if (item.itemId == R.id.upload_item) { diff --git a/apps/student/src/main/java/com/instructure/student/util/FileUtils.kt b/apps/student/src/main/java/com/instructure/student/util/FileUtils.kt index c50a961d90..73fb0b1066 100644 --- a/apps/student/src/main/java/com/instructure/student/util/FileUtils.kt +++ b/apps/student/src/main/java/com/instructure/student/util/FileUtils.kt @@ -85,7 +85,6 @@ object FileUtils { .scrollDirection(PageScrollDirection.HORIZONTAL) .showThumbnailGrid() .setDocumentInfoViewSeparated(false) - .setThumbnailBarMode(ThumbnailBarMode.THUMBNAIL_BAR_MODE_PINNED) .enableDocumentEditor() .enabledAnnotationTools(annotationCreationList) .editableAnnotationTypes(annotationEditList) diff --git a/apps/student/src/main/res/menu/pspdf_activity_menu.xml b/apps/student/src/main/res/menu/pspdf_activity_menu.xml index fc60fbaa75..ecadf9f40f 100644 --- a/apps/student/src/main/res/menu/pspdf_activity_menu.xml +++ b/apps/student/src/main/res/menu/pspdf_activity_menu.xml @@ -1,5 +1,4 @@ - - -