Compare commits
6 Commits
2.6.6
...
bugfix/cla
Author | SHA1 | Date | |
---|---|---|---|
2bae532f6d | |||
157e04b239 | |||
2a0ac7f91e | |||
d7b1a08098 | |||
985be92a4d | |||
6616a313e2 |
@ -27,8 +27,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 166
|
versionCode 161
|
||||||
versionName "2.6.6"
|
versionName "2.6.1"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
resValue "string", "app_name", "Wulkanowy"
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
@ -160,7 +160,7 @@ play {
|
|||||||
defaultToAppBundles = false
|
defaultToAppBundles = false
|
||||||
track = 'production'
|
track = 'production'
|
||||||
releaseStatus = ReleaseStatus.IN_PROGRESS
|
releaseStatus = ReleaseStatus.IN_PROGRESS
|
||||||
userFraction = 0.99d
|
userFraction = 0.25d
|
||||||
updatePriority = 1
|
updatePriority = 1
|
||||||
enabled.set(false)
|
enabled.set(false)
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.wulkanowy:sdk:2.6.5'
|
implementation 'io.github.wulkanowy:sdk:2.6.0'
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import dagger.Provides
|
|||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import io.github.wulkanowy.data.api.services.SchoolsService
|
import io.github.wulkanowy.data.api.AdminMessageService
|
||||||
import io.github.wulkanowy.data.api.services.WulkanowyService
|
import io.github.wulkanowy.data.api.SchoolsService
|
||||||
import io.github.wulkanowy.data.db.AppDatabase
|
import io.github.wulkanowy.data.db.AppDatabase
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
@ -71,7 +71,7 @@ internal class DataModule {
|
|||||||
okHttpClient: OkHttpClient,
|
okHttpClient: OkHttpClient,
|
||||||
json: Json,
|
json: Json,
|
||||||
appInfo: AppInfo
|
appInfo: AppInfo
|
||||||
): WulkanowyService = Retrofit.Builder()
|
): AdminMessageService = Retrofit.Builder()
|
||||||
.baseUrl(appInfo.messagesBaseUrl)
|
.baseUrl(appInfo.messagesBaseUrl)
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
||||||
|
@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.dao.StudentDao
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentIsEduOne
|
import io.github.wulkanowy.data.db.entities.StudentIsEduOne
|
||||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.RemoteConfigHelper
|
import io.github.wulkanowy.utils.RemoteConfigHelper
|
||||||
import io.github.wulkanowy.utils.WebkitCookieManagerProxy
|
import io.github.wulkanowy.utils.WebkitCookieManagerProxy
|
||||||
@ -21,7 +20,6 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
private val remoteConfig: RemoteConfigHelper,
|
private val remoteConfig: RemoteConfigHelper,
|
||||||
private val webkitCookieManagerProxy: WebkitCookieManagerProxy,
|
private val webkitCookieManagerProxy: WebkitCookieManagerProxy,
|
||||||
private val studentDb: StudentDao,
|
private val studentDb: StudentDao,
|
||||||
private val wulkanowyRepository: WulkanowyRepository,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val eduOneMutex = Mutex()
|
private val eduOneMutex = Mutex()
|
||||||
@ -38,30 +36,14 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
addInterceptor(chuckerInterceptor, network = true)
|
addInterceptor(chuckerInterceptor, network = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createBase() = sdk
|
fun create() = sdk
|
||||||
|
|
||||||
suspend fun create(): Sdk {
|
|
||||||
val mapping = wulkanowyRepository.getMapping()
|
|
||||||
|
|
||||||
return createBase().apply {
|
|
||||||
if (mapping != null) {
|
|
||||||
endpointsMapping = mapping.endpoints
|
|
||||||
vTokenMapping = mapping.vTokens
|
|
||||||
vTokenSchemeMapping = mapping.vTokenScheme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun create(student: Student, semester: Semester? = null): Sdk {
|
suspend fun create(student: Student, semester: Semester? = null): Sdk {
|
||||||
val overrideIsEduOne = checkEduOneAndMigrateIfNecessary(student)
|
val overrideIsEduOne = checkEduOneAndMigrateIfNecessary(student)
|
||||||
return buildSdk(student, semester, overrideIsEduOne)
|
return buildSdk(student, semester, overrideIsEduOne)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun buildSdk(
|
private fun buildSdk(student: Student, semester: Semester?, isStudentEduOne: Boolean): Sdk {
|
||||||
student: Student,
|
|
||||||
semester: Semester?,
|
|
||||||
isStudentEduOne: Boolean
|
|
||||||
): Sdk {
|
|
||||||
return create().apply {
|
return create().apply {
|
||||||
email = student.email
|
email = student.email
|
||||||
password = student.password
|
password = student.password
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package io.github.wulkanowy.data.api.services
|
package io.github.wulkanowy.data.api
|
||||||
|
|
||||||
import io.github.wulkanowy.data.api.models.Mapping
|
|
||||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
import io.github.wulkanowy.data.db.entities.AdminMessage
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
interface WulkanowyService {
|
interface AdminMessageService {
|
||||||
|
|
||||||
@GET("/v1.json")
|
@GET("/v1.json")
|
||||||
suspend fun getAdminMessages(): List<AdminMessage>
|
suspend fun getAdminMessages(): List<AdminMessage>
|
||||||
|
}
|
||||||
@GET("/mapping2.json")
|
|
||||||
suspend fun getMapping(): Mapping
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package io.github.wulkanowy.data.api.services
|
package io.github.wulkanowy.data.api
|
||||||
|
|
||||||
import io.github.wulkanowy.data.pojos.IntegrityRequest
|
import io.github.wulkanowy.data.pojos.IntegrityRequest
|
||||||
import io.github.wulkanowy.data.pojos.LoginEvent
|
import io.github.wulkanowy.data.pojos.LoginEvent
|
@ -1,17 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.api.models
|
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Mapping(
|
|
||||||
|
|
||||||
@SerialName("endpoints")
|
|
||||||
val endpoints: Map<String, Map<String, Map<String, String>>>,
|
|
||||||
|
|
||||||
@SerialName("vTokens")
|
|
||||||
val vTokens: Map<String, Map<String, Map<String, String>>>,
|
|
||||||
|
|
||||||
@SerialName("vTokenScheme")
|
|
||||||
val vTokenScheme: Map<String, Map<String, String>> = emptyMap(),
|
|
||||||
)
|
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import io.github.wulkanowy.data.db.entities.School
|
import io.github.wulkanowy.data.db.entities.School
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -11,5 +12,16 @@ import javax.inject.Singleton
|
|||||||
interface SchoolDao : BaseDao<School> {
|
interface SchoolDao : BaseDao<School> {
|
||||||
|
|
||||||
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
|
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
|
||||||
fun load(studentId: Int, classId: Int): Flow<School?>
|
fun loadWithClassId(studentId: Int, classId: Int): Flow<School?>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM School WHERE student_id = :studentId")
|
||||||
|
fun loadNoClassId(studentId: Int): Flow<School?>
|
||||||
|
|
||||||
|
fun load(student: Student): Flow<School?> {
|
||||||
|
return if (student.isEduOne == true) {
|
||||||
|
loadNoClassId(student.studentId)
|
||||||
|
} else {
|
||||||
|
loadWithClassId(student.studentId, student.classId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import androidx.room.Insert
|
|||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@ -14,6 +15,17 @@ interface SemesterDao : BaseDao<Semester> {
|
|||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
suspend fun insertSemesters(items: List<Semester>): List<Long>
|
suspend fun insertSemesters(items: List<Semester>): List<Long>
|
||||||
|
|
||||||
@Query("SELECT * FROM Semesters WHERE (student_id = :studentId AND class_id = :classId) OR (student_id = :studentId AND class_id = 0)")
|
@Query("SELECT * FROM Semesters WHERE (student_id = :studentId AND class_id = :classId)")
|
||||||
suspend fun loadAll(studentId: Int, classId: Int): List<Semester>
|
suspend fun loadAllWithClassId(studentId: Int, classId: Int): List<Semester>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Semesters WHERE student_id = :studentId")
|
||||||
|
suspend fun loadAllNoClassId(studentId: Int): List<Semester>
|
||||||
|
|
||||||
|
suspend fun loadAll(student: Student): List<Semester> {
|
||||||
|
return if (student.isEduOne == true) {
|
||||||
|
loadAllNoClassId(student.studentId)
|
||||||
|
} else {
|
||||||
|
loadAllWithClassId(student.studentId, student.classId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,9 @@ abstract class StudentDao {
|
|||||||
abstract suspend fun loadAll(): List<Student>
|
abstract suspend fun loadAll(): List<Student>
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0)")
|
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id)")
|
||||||
abstract suspend fun loadStudentsWithSemesters(): Map<Student, List<Semester>>
|
abstract suspend fun loadStudentsWithSemesters(): Map<Student, List<Semester>>
|
||||||
|
|
||||||
@Transaction
|
|
||||||
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0) WHERE Students.id = :id")
|
|
||||||
abstract suspend fun loadStudentWithSemestersById(id: Long): Map<Student, List<Semester>>
|
|
||||||
|
|
||||||
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
||||||
abstract suspend fun updateCurrent(id: Long)
|
abstract suspend fun updateCurrent(id: Long)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.Teacher
|
import io.github.wulkanowy.data.db.entities.Teacher
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,5 +12,16 @@ import javax.inject.Singleton
|
|||||||
interface TeacherDao : BaseDao<Teacher> {
|
interface TeacherDao : BaseDao<Teacher> {
|
||||||
|
|
||||||
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
|
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
|
||||||
fun loadAll(studentId: Int, classId: Int): Flow<List<Teacher>>
|
fun loadAllWithClassId(studentId: Int, classId: Int): Flow<List<Teacher>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Teachers WHERE student_id = :studentId")
|
||||||
|
fun loadAllNoClassId(studentId: Int): Flow<List<Teacher>>
|
||||||
|
|
||||||
|
fun loadAll(student: Student): Flow<List<Teacher>> {
|
||||||
|
return if (student.isEduOne == true) {
|
||||||
|
loadAllNoClassId(student.studentId)
|
||||||
|
} else {
|
||||||
|
loadAllWithClassId(student.studentId, student.classId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,15 @@ import androidx.sqlite.db.SupportSQLiteDatabase
|
|||||||
class Migration63 : AutoMigrationSpec {
|
class Migration63 : AutoMigrationSpec {
|
||||||
|
|
||||||
override fun onPostMigrate(db: SupportSQLiteDatabase) {
|
override fun onPostMigrate(db: SupportSQLiteDatabase) {
|
||||||
db.execSQL("UPDATE Students SET is_edu_one = NULL WHERE is_edu_one = 0")
|
db.execSQL("DROP TABLE IF EXISTS `Semesters`")
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS `School`")
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS `Teachers`")
|
||||||
|
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS `Semesters` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)")
|
||||||
|
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `Semesters` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)")
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS `School` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)")
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS `Teachers` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)")
|
||||||
|
|
||||||
|
db.execSQL("UPDATE Students SET is_edu_one = NULL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package io.github.wulkanowy.data.exceptions
|
||||||
|
|
||||||
|
class NoSuchStudentException(id: Long) :
|
||||||
|
Exception("There is no student with id $id in database")
|
@ -1,23 +1,20 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Resource
|
import io.github.wulkanowy.data.Resource
|
||||||
import io.github.wulkanowy.data.api.models.Mapping
|
import io.github.wulkanowy.data.api.AdminMessageService
|
||||||
import io.github.wulkanowy.data.api.services.WulkanowyService
|
|
||||||
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
||||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
import io.github.wulkanowy.data.db.entities.AdminMessage
|
||||||
import io.github.wulkanowy.data.networkBoundResource
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.filterNot
|
import kotlinx.coroutines.flow.filterNot
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class WulkanowyRepository @Inject constructor(
|
class AdminMessageRepository @Inject constructor(
|
||||||
private val wulkanowyService: WulkanowyService,
|
private val adminMessageService: AdminMessageService,
|
||||||
private val adminMessageDao: AdminMessageDao,
|
private val adminMessageDao: AdminMessageDao,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val saveFetchResultMutex = Mutex()
|
private val saveFetchResultMutex = Mutex()
|
||||||
@ -27,28 +24,11 @@ class WulkanowyRepository @Inject constructor(
|
|||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
isResultEmpty = { false },
|
isResultEmpty = { false },
|
||||||
query = { adminMessageDao.loadAll() },
|
query = { adminMessageDao.loadAll() },
|
||||||
fetch = { wulkanowyService.getAdminMessages() },
|
fetch = { adminMessageService.getAdminMessages() },
|
||||||
shouldFetch = { true },
|
shouldFetch = { true },
|
||||||
saveFetchResult = { oldItems, newItems ->
|
saveFetchResult = { oldItems, newItems ->
|
||||||
adminMessageDao.removeOldAndSaveNew(oldItems, newItems)
|
adminMessageDao.removeOldAndSaveNew(oldItems, newItems)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.filterNot { it is Resource.Intermediate }
|
.filterNot { it is Resource.Intermediate }
|
||||||
|
|
||||||
suspend fun getMapping(): Mapping? {
|
|
||||||
var savedMapping = preferencesRepository.mapping
|
|
||||||
|
|
||||||
if (savedMapping == null) {
|
|
||||||
fetchMapping()
|
|
||||||
savedMapping = preferencesRepository.mapping
|
|
||||||
}
|
|
||||||
|
|
||||||
return savedMapping
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun fetchMapping() {
|
|
||||||
runCatching { wulkanowyService.getMapping() }
|
|
||||||
.onFailure { Timber.e(it) }
|
|
||||||
.onSuccess { preferencesRepository.mapping = it }
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -9,7 +9,6 @@ import com.fredporciuncula.flow.preferences.Preference
|
|||||||
import com.fredporciuncula.flow.preferences.Serializer
|
import com.fredporciuncula.flow.preferences.Serializer
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.api.models.Mapping
|
|
||||||
import io.github.wulkanowy.data.enums.AppTheme
|
import io.github.wulkanowy.data.enums.AppTheme
|
||||||
import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode
|
import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode
|
||||||
import io.github.wulkanowy.data.enums.GradeColorTheme
|
import io.github.wulkanowy.data.enums.GradeColorTheme
|
||||||
@ -376,15 +375,6 @@ class PreferencesRepository @Inject constructor(
|
|||||||
get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
|
get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
|
||||||
private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }
|
private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }
|
||||||
|
|
||||||
var mapping: Mapping?
|
|
||||||
get() {
|
|
||||||
val value = sharedPref.getString("mapping", null)
|
|
||||||
return value?.let { json.decodeFromString(it) }
|
|
||||||
}
|
|
||||||
set(value) = sharedPref.edit(commit = true) {
|
|
||||||
putString("mapping", value?.let { json.encodeToString(it) })
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (installationId.isEmpty()) {
|
if (installationId.isEmpty()) {
|
||||||
installationId = UUID.randomUUID().toString()
|
installationId = UUID.randomUUID().toString()
|
||||||
|
@ -36,7 +36,7 @@ class SchoolRepository @Inject constructor(
|
|||||||
)
|
)
|
||||||
it == null || forceRefresh || isExpired
|
it == null || forceRefresh || isExpired
|
||||||
},
|
},
|
||||||
query = { schoolDb.load(semester.studentId, semester.classId) },
|
query = { schoolDb.load(student) },
|
||||||
fetch = {
|
fetch = {
|
||||||
wulkanowySdkFactory.create(student, semester)
|
wulkanowySdkFactory.create(student, semester)
|
||||||
.getSchool()
|
.getSchool()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
import io.github.wulkanowy.data.WulkanowySdkFactory
|
import io.github.wulkanowy.data.WulkanowySdkFactory
|
||||||
import io.github.wulkanowy.data.api.services.SchoolsService
|
import io.github.wulkanowy.data.api.SchoolsService
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
@ -27,11 +27,11 @@ class SemesterRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean = false,
|
forceRefresh: Boolean = false,
|
||||||
refreshOnNoCurrent: Boolean = false
|
refreshOnNoCurrent: Boolean = false
|
||||||
) = withContext(dispatchers.io) {
|
) = withContext(dispatchers.io) {
|
||||||
val semesters = semesterDb.loadAll(student.studentId, student.classId)
|
val semesters = semesterDb.loadAll(student)
|
||||||
|
|
||||||
if (isShouldFetch(student, semesters, forceRefresh, refreshOnNoCurrent)) {
|
if (isShouldFetch(student, semesters, forceRefresh, refreshOnNoCurrent)) {
|
||||||
refreshSemesters(student)
|
refreshSemesters(student)
|
||||||
semesterDb.loadAll(student.studentId, student.classId)
|
semesterDb.loadAll(student)
|
||||||
} else semesters
|
} else semesters
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ class SemesterRepository @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val old = semesterDb.loadAll(student.studentId, student.classId)
|
val old = semesterDb.loadAll(student)
|
||||||
semesterDb.removeOldAndSaveNew(
|
semesterDb.removeOldAndSaveNew(
|
||||||
oldItems = old uniqueSubtract new,
|
oldItems = old uniqueSubtract new,
|
||||||
newItems = new uniqueSubtract old,
|
newItems = new uniqueSubtract old,
|
||||||
|
@ -12,6 +12,7 @@ import io.github.wulkanowy.data.db.entities.StudentName
|
|||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
|
import io.github.wulkanowy.data.exceptions.NoSuchStudentException
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.data.mappers.mapToPojo
|
import io.github.wulkanowy.data.mappers.mapToPojo
|
||||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||||
@ -65,7 +66,8 @@ class StudentRepository @Inject constructor(
|
|||||||
.mapToPojo(password)
|
.mapToPojo(password)
|
||||||
.also { it.logErrors() }
|
.also { it.logErrors() }
|
||||||
|
|
||||||
suspend fun getSavedStudents(decryptPass: Boolean = true): List<StudentWithSemesters> {
|
@Deprecated("Semesters are not synced within this method and students with empty semesters are not returned")
|
||||||
|
suspend fun getSavedStudentsWithSemesters(decryptPass: Boolean = true): List<StudentWithSemesters> {
|
||||||
return studentDb.loadStudentsWithSemesters().map { (student, semesters) ->
|
return studentDb.loadStudentsWithSemesters().map { (student, semesters) ->
|
||||||
StudentWithSemesters(
|
StudentWithSemesters(
|
||||||
student = student.apply {
|
student = student.apply {
|
||||||
@ -80,22 +82,25 @@ class StudentRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true): StudentWithSemesters? =
|
suspend fun getSavedStudents(decryptPass: Boolean = true): List<Student> {
|
||||||
studentDb.loadStudentWithSemestersById(id).let { res ->
|
val students = studentDb.loadAll()
|
||||||
StudentWithSemesters(
|
if (!decryptPass) return students
|
||||||
student = res.keys.firstOrNull() ?: return null,
|
|
||||||
semesters = res.values.first(),
|
return students.map { student ->
|
||||||
)
|
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
||||||
}.apply {
|
return@map student
|
||||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
}
|
||||||
student.password = withContext(dispatchers.io) {
|
|
||||||
|
student.apply {
|
||||||
|
password = withContext(dispatchers.io) {
|
||||||
scrambler.decrypt(student.password)
|
scrambler.decrypt(student.password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
|
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
|
||||||
val student = studentDb.loadById(id) ?: throw NoCurrentStudentException()
|
val student = studentDb.loadById(id) ?: throw NoSuchStudentException(id)
|
||||||
|
|
||||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
||||||
student.password = withContext(dispatchers.io) {
|
student.password = withContext(dispatchers.io) {
|
||||||
@ -123,7 +128,7 @@ class StudentRepository @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentStudentSemesters = semesterDb.loadAll(student.studentId, student.classId)
|
val currentStudentSemesters = semesterDb.loadAll(student)
|
||||||
if (currentStudentSemesters.isEmpty()) {
|
if (currentStudentSemesters.isEmpty()) {
|
||||||
Timber.d("Check isAuthorized: apply empty semesters workaround")
|
Timber.d("Check isAuthorized: apply empty semesters workaround")
|
||||||
semesterDb.insertSemesters(
|
semesterDb.insertSemesters(
|
||||||
@ -181,8 +186,8 @@ class StudentRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun switchStudent(studentWithSemesters: StudentWithSemesters) {
|
suspend fun switchStudent(student: Student) {
|
||||||
studentDb.switchCurrent(studentWithSemesters.student.id)
|
studentDb.switchCurrent(student.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun logoutStudent(student: Student) = studentDb.delete(student)
|
suspend fun logoutStudent(student: Student) = studentDb.delete(student)
|
||||||
@ -190,8 +195,8 @@ class StudentRepository @Inject constructor(
|
|||||||
suspend fun updateStudentNickAndAvatar(studentNickAndAvatar: StudentNickAndAvatar) =
|
suspend fun updateStudentNickAndAvatar(studentNickAndAvatar: StudentNickAndAvatar) =
|
||||||
studentDb.update(studentNickAndAvatar)
|
studentDb.update(studentNickAndAvatar)
|
||||||
|
|
||||||
suspend fun isOneUniqueStudent() = getSavedStudents(false)
|
suspend fun isOneUniqueStudent() = studentDb.loadAll()
|
||||||
.distinctBy { it.student.studentName }.size == 1
|
.distinctBy { it.studentName }.size == 1
|
||||||
|
|
||||||
suspend fun authorizePermission(student: Student, semester: Semester, pesel: String) =
|
suspend fun authorizePermission(student: Student, semester: Semester, pesel: String) =
|
||||||
wulkanowySdkFactory.create(student, semester)
|
wulkanowySdkFactory.create(student, semester)
|
||||||
@ -199,7 +204,7 @@ class StudentRepository @Inject constructor(
|
|||||||
|
|
||||||
suspend fun refreshStudentAfterAuthorize(student: Student, semester: Semester) {
|
suspend fun refreshStudentAfterAuthorize(student: Student, semester: Semester) {
|
||||||
val wulkanowySdk = wulkanowySdkFactory.create(student, semester)
|
val wulkanowySdk = wulkanowySdkFactory.create(student, semester)
|
||||||
val newCurrentApiStudent = runCatching { wulkanowySdk.getCurrentStudent() }
|
val newCurrentApiStudent = runCatching { wulkanowySdk.getCurrentStudent() }
|
||||||
.onFailure { Timber.e(it, "Can't find student with id ${student.studentId}") }
|
.onFailure { Timber.e(it, "Can't find student with id ${student.studentId}") }
|
||||||
.getOrNull() ?: return
|
.getOrNull() ?: return
|
||||||
|
|
||||||
@ -209,7 +214,7 @@ class StudentRepository @Inject constructor(
|
|||||||
|
|
||||||
studentDb.update(studentName)
|
studentDb.update(studentName)
|
||||||
semesterDb.removeOldAndSaveNew(
|
semesterDb.removeOldAndSaveNew(
|
||||||
oldItems = semesterDb.loadAll(student.studentId, semester.classId),
|
oldItems = semesterDb.loadAll(student),
|
||||||
newItems = newCurrentApiStudent.semesters.mapToEntities(newCurrentApiStudent.studentId)
|
newItems = newCurrentApiStudent.semesters.mapToEntities(newCurrentApiStudent.studentId)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class TeacherRepository @Inject constructor(
|
|||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
},
|
},
|
||||||
query = { teacherDb.loadAll(semester.studentId, semester.classId) },
|
query = { teacherDb.loadAll(student) },
|
||||||
fetch = {
|
fetch = {
|
||||||
wulkanowySdkFactory.create(student, semester)
|
wulkanowySdkFactory.create(student, semester)
|
||||||
.getTeachers()
|
.getTeachers()
|
||||||
|
@ -5,14 +5,14 @@ import io.github.wulkanowy.data.db.entities.AdminMessage
|
|||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.enums.MessageType
|
import io.github.wulkanowy.data.enums.MessageType
|
||||||
import io.github.wulkanowy.data.mapResourceData
|
import io.github.wulkanowy.data.mapResourceData
|
||||||
|
import io.github.wulkanowy.data.repositories.AdminMessageRepository
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetAppropriateAdminMessageUseCase @Inject constructor(
|
class GetAppropriateAdminMessageUseCase @Inject constructor(
|
||||||
private val wulkanowyRepository: WulkanowyRepository,
|
private val adminMessageRepository: AdminMessageRepository,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val appInfo: AppInfo
|
private val appInfo: AppInfo
|
||||||
) {
|
) {
|
||||||
@ -22,7 +22,7 @@ class GetAppropriateAdminMessageUseCase @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator fun invoke(scrapperBaseUrl: String, type: MessageType): Flow<Resource<AdminMessage?>> {
|
operator fun invoke(scrapperBaseUrl: String, type: MessageType): Flow<Resource<AdminMessage?>> {
|
||||||
return wulkanowyRepository.getAdminMessages().mapResourceData { adminMessages ->
|
return adminMessageRepository.getAdminMessages().mapResourceData { adminMessages ->
|
||||||
adminMessages
|
adminMessages
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { it.isNotDismissed() }
|
.filter { it.isNotDismissed() }
|
||||||
|
@ -59,7 +59,7 @@ class GetMailboxByStudentUseCase @Inject constructor(
|
|||||||
private fun String.getUnauthorizedVersion(): String {
|
private fun String.getUnauthorizedVersion(): String {
|
||||||
return normalizeStudentName().split(" ")
|
return normalizeStudentName().split(" ")
|
||||||
.joinToString(" ") {
|
.joinToString(" ") {
|
||||||
it.firstOrNull()?.toString().orEmpty() + "*".repeat((it.length - 1).coerceAtLeast(0))
|
it.first() + "*".repeat(it.length - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class AccountPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
resourceFlow { studentRepository.getSavedStudents(false) }
|
resourceFlow { studentRepository.getSavedStudentsWithSemesters(false) }
|
||||||
.logResourceStatus("load account data")
|
.logResourceStatus("load account data")
|
||||||
.onResourceSuccess { view?.updateData(createAccountItems(it)) }
|
.onResourceSuccess { view?.updateData(createAccountItems(it)) }
|
||||||
.onResourceError(errorHandler::dispatch)
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account.accountdetails
|
package io.github.wulkanowy.ui.modules.account.accountdetails
|
||||||
|
|
||||||
import io.github.wulkanowy.data.*
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceLoading
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
@ -14,6 +20,7 @@ import javax.inject.Inject
|
|||||||
class AccountDetailsPresenter @Inject constructor(
|
class AccountDetailsPresenter @Inject constructor(
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
|
private val semeRepository: SemesterRepository,
|
||||||
private val syncManager: SyncManager
|
private val syncManager: SyncManager
|
||||||
) : BasePresenter<AccountDetailsView>(errorHandler, studentRepository) {
|
) : BasePresenter<AccountDetailsView>(errorHandler, studentRepository) {
|
||||||
|
|
||||||
@ -46,7 +53,12 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
resourceFlow { studentRepository.getSavedStudentById(studentId ?: -1) }
|
resourceFlow {
|
||||||
|
val student = studentRepository.getStudentById(studentId ?: -1)
|
||||||
|
val semesters = semeRepository.getSemesters(student)
|
||||||
|
|
||||||
|
StudentWithSemesters(student, semesters)
|
||||||
|
}
|
||||||
.logResourceStatus("loading account details view")
|
.logResourceStatus("loading account details view")
|
||||||
.onResourceLoading {
|
.onResourceLoading {
|
||||||
view?.run {
|
view?.run {
|
||||||
@ -85,7 +97,7 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
|
|
||||||
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
||||||
|
|
||||||
resourceFlow { studentRepository.switchStudent(studentWithSemesters!!) }
|
resourceFlow { studentRepository.switchStudent(studentWithSemesters!!.student) }
|
||||||
.logResourceStatus("change student")
|
.logResourceStatus("change student")
|
||||||
.onResourceSuccess { view?.recreateMainView() }
|
.onResourceSuccess { view?.recreateMainView() }
|
||||||
.onResourceNotLoading { view?.popViewToMain() }
|
.onResourceNotLoading { view?.popViewToMain() }
|
||||||
@ -122,10 +134,12 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
syncManager.stopSyncWorker()
|
syncManager.stopSyncWorker()
|
||||||
openClearLoginView()
|
openClearLoginView()
|
||||||
}
|
}
|
||||||
|
|
||||||
studentWithSemesters?.student?.isCurrent == true -> {
|
studentWithSemesters?.student?.isCurrent == true -> {
|
||||||
Timber.i("Logout result: Logout student and switch to another")
|
Timber.i("Logout result: Logout student and switch to another")
|
||||||
recreateMainView()
|
recreateMainView()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Timber.i("Logout result: Logout student")
|
Timber.i("Logout result: Logout student")
|
||||||
recreateMainView()
|
recreateMainView()
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account.accountquick
|
package io.github.wulkanowy.ui.modules.account.accountquick
|
||||||
|
|
||||||
import io.github.wulkanowy.data.*
|
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.ui.modules.account.AccountItem
|
import io.github.wulkanowy.ui.modules.account.AccountItem
|
||||||
@ -40,7 +44,7 @@ class AccountQuickPresenter @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceFlow { studentRepository.switchStudent(studentWithSemesters) }
|
resourceFlow { studentRepository.switchStudent(studentWithSemesters.student) }
|
||||||
.logResourceStatus("change student")
|
.logResourceStatus("change student")
|
||||||
.onResourceSuccess { view?.recreateMainView() }
|
.onResourceSuccess { view?.recreateMainView() }
|
||||||
.onResourceNotLoading { view?.popView() }
|
.onResourceNotLoading { view?.popView() }
|
||||||
|
@ -59,7 +59,7 @@ class CaptchaDialog : BaseDialogFragment<DialogCaptchaBinding>() {
|
|||||||
webView = this
|
webView = this
|
||||||
with(settings) {
|
with(settings) {
|
||||||
javaScriptEnabled = true
|
javaScriptEnabled = true
|
||||||
userAgentString = wulkanowySdkFactory.createBase().userAgent
|
userAgentString = wulkanowySdkFactory.create().userAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
webViewClient = object : WebViewClient() {
|
webViewClient = object : WebViewClient() {
|
||||||
|
@ -118,6 +118,5 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
inAppUpdateHelper.onResume()
|
inAppUpdateHelper.onResume()
|
||||||
presenter.updateSdkMappings()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login
|
package io.github.wulkanowy.ui.modules.login
|
||||||
|
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginPresenter @Inject constructor(
|
class LoginPresenter @Inject constructor(
|
||||||
private val wulkanowyRepository: WulkanowyRepository,
|
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository
|
studentRepository: StudentRepository
|
||||||
) : BasePresenter<LoginView>(errorHandler, studentRepository) {
|
) : BasePresenter<LoginView>(errorHandler, studentRepository) {
|
||||||
@ -19,11 +16,4 @@ class LoginPresenter @Inject constructor(
|
|||||||
view.initView()
|
view.initView()
|
||||||
Timber.i("Login view was initialized")
|
Timber.i("Login view was initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSdkMappings() {
|
|
||||||
presenterScope.launch {
|
|
||||||
runCatching { wulkanowyRepository.fetchMapping() }
|
|
||||||
.onFailure { Timber.e(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
resetSelectedState()
|
resetSelectedState()
|
||||||
|
|
||||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
resourceFlow { studentRepository.getSavedStudentsWithSemesters(false) }.onEach {
|
||||||
students = it.dataOrNull.orEmpty()
|
students = it.dataOrNull.orEmpty()
|
||||||
when (it) {
|
when (it) {
|
||||||
is Resource.Loading -> Timber.d("Login student select students load started")
|
is Resource.Loading -> Timber.d("Login student select students load started")
|
||||||
|
@ -35,7 +35,7 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
resourceFlow { studentRepository.getSavedStudentsWithSemesters(false) }.onEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Resource.Loading -> Timber.d("Lucky number widget configure students data load")
|
is Resource.Loading -> Timber.d("Lucky number widget configure students data load")
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
|
@ -132,7 +132,7 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
|||||||
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
|
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
|
||||||
try {
|
try {
|
||||||
val students = studentRepository.getSavedStudents()
|
val students = studentRepository.getSavedStudents()
|
||||||
val student = students.singleOrNull { it.student.id == studentId }?.student
|
val student = students.singleOrNull { it.id == studentId }
|
||||||
val currentStudent = when {
|
val currentStudent = when {
|
||||||
student != null -> student
|
student != null -> student
|
||||||
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
|
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
|
||||||
|
@ -138,7 +138,6 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
inAppUpdateHelper.onResume()
|
inAppUpdateHelper.onResume()
|
||||||
presenter.updateSdkMappings()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
@ -6,7 +6,6 @@ import io.github.wulkanowy.data.onResourceError
|
|||||||
import io.github.wulkanowy.data.onResourceSuccess
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
|
||||||
import io.github.wulkanowy.data.resourceFlow
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -30,7 +29,6 @@ class MainPresenter @Inject constructor(
|
|||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val wulkanowyRepository: WulkanowyRepository,
|
|
||||||
private val syncManager: SyncManager,
|
private val syncManager: SyncManager,
|
||||||
private val analytics: AnalyticsHelper,
|
private val analytics: AnalyticsHelper,
|
||||||
private val json: Json,
|
private val json: Json,
|
||||||
@ -87,7 +85,7 @@ class MainPresenter @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceFlow { studentRepository.getSavedStudents(false) }
|
resourceFlow { studentRepository.getSavedStudentsWithSemesters(false) }
|
||||||
.logResourceStatus("load student avatar")
|
.logResourceStatus("load student avatar")
|
||||||
.onResourceSuccess {
|
.onResourceSuccess {
|
||||||
studentsWitSemesters = it
|
studentsWitSemesters = it
|
||||||
@ -201,11 +199,4 @@ class MainPresenter @Inject constructor(
|
|||||||
.onFailure { errorHandler.dispatch(it) }
|
.onFailure { errorHandler.dispatch(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSdkMappings() {
|
|
||||||
presenterScope.launch {
|
|
||||||
runCatching { wulkanowyRepository.fetchMapping() }
|
|
||||||
.onFailure { Timber.e(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -42,22 +42,24 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
resourceFlow { studentRepository.getSavedStudentsWithSemesters(false) }
|
||||||
when (it) {
|
.onEach {
|
||||||
is Resource.Loading -> Timber.d("Timetable widget configure students data load")
|
when (it) {
|
||||||
is Resource.Success -> {
|
is Resource.Loading -> Timber.d("Timetable widget configure students data load")
|
||||||
val selectedStudentId = appWidgetId?.let { id ->
|
is Resource.Success -> {
|
||||||
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
val selectedStudentId = appWidgetId?.let { id ->
|
||||||
} ?: -1
|
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||||
when {
|
} ?: -1
|
||||||
it.data.isEmpty() -> view?.openLoginView()
|
when {
|
||||||
it.data.size == 1 && !isFromProvider -> onItemSelect(it.data.single().student)
|
it.data.isEmpty() -> view?.openLoginView()
|
||||||
else -> view?.updateData(it.data, selectedStudentId)
|
it.data.size == 1 && !isFromProvider -> onItemSelect(it.data.single().student)
|
||||||
|
else -> view?.updateData(it.data, selectedStudentId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Resource.Error -> errorHandler.dispatch(it.error)
|
||||||
}
|
}
|
||||||
is Resource.Error -> errorHandler.dispatch(it.error)
|
}.launch()
|
||||||
}
|
|
||||||
}.launch()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerStudent(student: Student?) {
|
private fun registerStudent(student: Student?) {
|
||||||
|
@ -95,7 +95,7 @@ class TimetableWidgetFactory(
|
|||||||
|
|
||||||
private suspend fun getStudent(studentId: Long): Student? {
|
private suspend fun getStudent(studentId: Long): Student? {
|
||||||
val students = studentRepository.getSavedStudents()
|
val students = studentRepository.getSavedStudents()
|
||||||
return students.singleOrNull { it.student.id == studentId }?.student
|
return students.singleOrNull { it.id == studentId }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getLessons(
|
private suspend fun getLessons(
|
||||||
|
@ -2,7 +2,11 @@ package io.github.wulkanowy.ui.modules.timetablewidget
|
|||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.appwidget.AppWidgetManager.*
|
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED
|
||||||
|
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
|
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
|
||||||
|
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
|
||||||
|
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -22,7 +26,14 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
|||||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||||
import io.github.wulkanowy.ui.modules.Destination
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||||
|
import io.github.wulkanowy.utils.capitalise
|
||||||
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.nickOrName
|
||||||
|
import io.github.wulkanowy.utils.previousSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -244,7 +255,7 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
|
|
||||||
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
||||||
val students = studentRepository.getSavedStudents(false)
|
val students = studentRepository.getSavedStudents(false)
|
||||||
val student = students.singleOrNull { it.student.id == studentId }?.student
|
val student = students.singleOrNull { it.id == studentId }
|
||||||
when {
|
when {
|
||||||
student != null -> student
|
student != null -> student
|
||||||
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
|
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
|
||||||
@ -263,7 +274,10 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupAccountView(
|
private fun setupAccountView(
|
||||||
context: Context, student: Student, remoteViews: RemoteViews, widgetId: Int
|
context: Context,
|
||||||
|
student: Student,
|
||||||
|
remoteViews: RemoteViews,
|
||||||
|
widgetId: Int
|
||||||
) {
|
) {
|
||||||
val accountInitials = getAccountInitials(student.nickOrName)
|
val accountInitials = getAccountInitials(student.nickOrName)
|
||||||
val accountPickerPendingIntent = createAccountPickerPendingIntent(context, widgetId)
|
val accountPickerPendingIntent = createAccountPickerPendingIntent(context, widgetId)
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
Wersja 2.6.6
|
Wersja 2.6.1
|
||||||
|
|
||||||
— to tylko kolejna aktualizacja, która obchodzi blokadę firmy, której nazwy nie napiszemy. Pewnie zaraz znowu zostaniemy zablokowani, ale co tam
|
— dodaliśmy kalkulator frekwencji
|
||||||
|
— dodaliśmy wyświetlanie lekcji dodatkowych w planie lekcji
|
||||||
|
— ulepszyliśmy wyjaśnienie na ekranie z miejscem na wpisanie numeru PESEL
|
||||||
|
— naprawiliśmy rzadkie sytuacje, gdy plan lekcji nakładał się na informację o jego braku
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<string name="student_info_title">Student info</string>
|
<string name="student_info_title">Student info</string>
|
||||||
<string name="dashboard_title">Dashboard</string>
|
<string name="dashboard_title">Dashboard</string>
|
||||||
<string name="notifications_center_title">Notifications center</string>
|
<string name="notifications_center_title">Notifications center</string>
|
||||||
<string name="menu_order_title">Menu configuration</string>
|
<string name="menu_order_title">Menu configuartion</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Subtitles-->
|
<!--Subtitles-->
|
||||||
|
@ -8,7 +8,6 @@ import io.mockk.mockk
|
|||||||
|
|
||||||
fun createWulkanowySdkFactoryMock(sdk: Sdk) = mockk<WulkanowySdkFactory>()
|
fun createWulkanowySdkFactoryMock(sdk: Sdk) = mockk<WulkanowySdkFactory>()
|
||||||
.apply {
|
.apply {
|
||||||
every { createBase() } returns sdk
|
every { create() } returns sdk
|
||||||
coEvery { create() } returns sdk
|
|
||||||
coEvery { create(any(), any()) } returns sdk
|
coEvery { create(any(), any()) } returns sdk
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import io.github.wulkanowy.sdk.pojo.RegisterStudent
|
|||||||
import io.mockk.Runs
|
import io.mockk.Runs
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
@ -39,12 +40,11 @@ class WulkanowySdkFactoryTest {
|
|||||||
chuckerInterceptor = mockk(),
|
chuckerInterceptor = mockk(),
|
||||||
remoteConfig = mockk(relaxed = true),
|
remoteConfig = mockk(relaxed = true),
|
||||||
webkitCookieManagerProxy = mockk(),
|
webkitCookieManagerProxy = mockk(),
|
||||||
studentDb = studentDao,
|
studentDb = studentDao
|
||||||
wulkanowyRepository = mockk(relaxed = true),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { wulkanowySdkFactory.create() } returns sdk
|
every { wulkanowySdkFactory.create() } returns sdk
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -0,0 +1,161 @@
|
|||||||
|
package io.github.wulkanowy.data.db.dao
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import dagger.hilt.android.testing.HiltTestApplication
|
||||||
|
import io.github.wulkanowy.data.db.AppDatabase
|
||||||
|
import io.github.wulkanowy.getSemesterEntity
|
||||||
|
import io.github.wulkanowy.getStudentEntity
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.annotation.Config
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class)
|
||||||
|
class StudentDaoTest {
|
||||||
|
|
||||||
|
private lateinit var studentDao: StudentDao
|
||||||
|
private lateinit var semesterDao: SemesterDao
|
||||||
|
private lateinit var db: AppDatabase
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun createDb() {
|
||||||
|
val context: Context = ApplicationProvider.getApplicationContext()
|
||||||
|
db = Room.inMemoryDatabaseBuilder(
|
||||||
|
context = context,
|
||||||
|
klass = AppDatabase::class.java
|
||||||
|
).build()
|
||||||
|
studentDao = db.studentDao
|
||||||
|
semesterDao = db.semesterDao
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `get students associated with correct semester with same studentId`() = runTest {
|
||||||
|
val notEduOneStudent = getStudentEntity()
|
||||||
|
.copy(
|
||||||
|
isEduOne = false,
|
||||||
|
classId = 42,
|
||||||
|
studentId = 100
|
||||||
|
)
|
||||||
|
.apply { id = 1 }
|
||||||
|
val eduOneStudent = getStudentEntity()
|
||||||
|
.copy(
|
||||||
|
isEduOne = true,
|
||||||
|
classId = 0,
|
||||||
|
studentId = 100
|
||||||
|
)
|
||||||
|
.apply { id = 2 }
|
||||||
|
|
||||||
|
val semesterAssociatedWithNotEduOneStudent = getSemesterEntity()
|
||||||
|
.copy(
|
||||||
|
studentId = notEduOneStudent.studentId,
|
||||||
|
classId = notEduOneStudent.classId,
|
||||||
|
diaryId = 1 // make semester unique
|
||||||
|
)
|
||||||
|
.apply { id = 0 }
|
||||||
|
val semesterAssociatedWithEduOneStudent = getSemesterEntity()
|
||||||
|
.copy(
|
||||||
|
studentId = eduOneStudent.studentId,
|
||||||
|
classId = eduOneStudent.classId,
|
||||||
|
diaryId = 2 // make semester unique
|
||||||
|
)
|
||||||
|
.apply { id = 0 }
|
||||||
|
|
||||||
|
studentDao.insertAll(listOf(notEduOneStudent, eduOneStudent))
|
||||||
|
semesterDao.insertAll(
|
||||||
|
listOf(
|
||||||
|
semesterAssociatedWithNotEduOneStudent,
|
||||||
|
semesterAssociatedWithEduOneStudent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val studentsWithSemesters = studentDao.loadStudentsWithSemesters()
|
||||||
|
val notEduOneSemestersResult = studentsWithSemesters.entries
|
||||||
|
.find { (student, _) -> student.id == notEduOneStudent.id }
|
||||||
|
?.value
|
||||||
|
val eduOneSemestersResult = studentsWithSemesters.entries
|
||||||
|
.find { (student, _) -> student.id == eduOneStudent.id }
|
||||||
|
?.value
|
||||||
|
|
||||||
|
assertEquals(2, studentsWithSemesters.size)
|
||||||
|
|
||||||
|
assertEquals(1, notEduOneSemestersResult?.size)
|
||||||
|
assertEquals(1, eduOneSemestersResult?.size)
|
||||||
|
|
||||||
|
assertEquals(semesterAssociatedWithEduOneStudent, eduOneSemestersResult?.firstOrNull())
|
||||||
|
assertEquals(
|
||||||
|
semesterAssociatedWithNotEduOneStudent,
|
||||||
|
notEduOneSemestersResult?.firstOrNull()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `get students associated with correct semester with different studentId`() = runTest {
|
||||||
|
val notEduOneStudent = getStudentEntity()
|
||||||
|
.copy(
|
||||||
|
isEduOne = false,
|
||||||
|
classId = 42,
|
||||||
|
studentId = 100
|
||||||
|
)
|
||||||
|
.apply { id = 1 }
|
||||||
|
val eduOneStudent = getStudentEntity()
|
||||||
|
.copy(
|
||||||
|
isEduOne = true,
|
||||||
|
classId = 0,
|
||||||
|
studentId = 101
|
||||||
|
)
|
||||||
|
.apply { id = 2 }
|
||||||
|
|
||||||
|
val semesterAssociatedWithNotEduOneStudent = getSemesterEntity()
|
||||||
|
.copy(
|
||||||
|
studentId = notEduOneStudent.studentId,
|
||||||
|
classId = notEduOneStudent.classId,
|
||||||
|
)
|
||||||
|
.apply { id = 0 }
|
||||||
|
val semesterAssociatedWithEduOneStudent = getSemesterEntity()
|
||||||
|
.copy(
|
||||||
|
studentId = eduOneStudent.studentId,
|
||||||
|
classId = eduOneStudent.classId,
|
||||||
|
)
|
||||||
|
.apply { id = 0 }
|
||||||
|
|
||||||
|
studentDao.insertAll(listOf(notEduOneStudent, eduOneStudent))
|
||||||
|
semesterDao.insertAll(
|
||||||
|
listOf(
|
||||||
|
semesterAssociatedWithNotEduOneStudent,
|
||||||
|
semesterAssociatedWithEduOneStudent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val studentsWithSemesters = studentDao.loadStudentsWithSemesters()
|
||||||
|
val notEduOneSemestersResult = studentsWithSemesters.entries
|
||||||
|
.find { (student, _) -> student.id == notEduOneStudent.id }
|
||||||
|
?.value
|
||||||
|
val eduOneSemestersResult = studentsWithSemesters.entries
|
||||||
|
.find { (student, _) -> student.id == eduOneStudent.id }
|
||||||
|
?.value
|
||||||
|
|
||||||
|
assertEquals(2, studentsWithSemesters.size)
|
||||||
|
|
||||||
|
assertEquals(1, notEduOneSemestersResult?.size)
|
||||||
|
assertEquals(1, eduOneSemestersResult?.size)
|
||||||
|
|
||||||
|
assertEquals(semesterAssociatedWithEduOneStudent, eduOneSemestersResult?.firstOrNull())
|
||||||
|
assertEquals(
|
||||||
|
semesterAssociatedWithNotEduOneStudent,
|
||||||
|
notEduOneSemestersResult?.firstOrNull()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun closeDb() {
|
||||||
|
db.close()
|
||||||
|
}
|
||||||
|
}
|
@ -12,9 +12,7 @@ import org.robolectric.RobolectricTestRunner
|
|||||||
import org.robolectric.annotation.Config
|
import org.robolectric.annotation.Config
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertNotNull
|
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
@HiltAndroidTest
|
@HiltAndroidTest
|
||||||
@RunWith(RobolectricTestRunner::class)
|
@RunWith(RobolectricTestRunner::class)
|
||||||
@ -22,9 +20,10 @@ import kotlin.test.assertTrue
|
|||||||
class Migration63Test : AbstractMigrationTest() {
|
class Migration63Test : AbstractMigrationTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `update is_edu_one to null if 0`() = runTest {
|
fun `update is_edu_one to null`() = runTest {
|
||||||
with(helper.createDatabase(dbName, 62)) {
|
with(helper.createDatabase(dbName, 62)) {
|
||||||
createStudent(1, 0)
|
createStudent(1, 0)
|
||||||
|
createStudent(2, 1)
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,31 +31,15 @@ class Migration63Test : AbstractMigrationTest() {
|
|||||||
|
|
||||||
val database = getMigratedRoomDatabase()
|
val database = getMigratedRoomDatabase()
|
||||||
val studentDb = database.studentDao
|
val studentDb = database.studentDao
|
||||||
val student = studentDb.loadById(1)
|
val student1 = studentDb.loadById(1)
|
||||||
|
val student2 = studentDb.loadById(2)
|
||||||
|
|
||||||
assertNull(student!!.isEduOne)
|
assertNull(student1!!.isEduOne)
|
||||||
|
assertNull(student2!!.isEduOne)
|
||||||
|
|
||||||
database.close()
|
database.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `check is_edu_one is stay same`() = runTest {
|
|
||||||
with(helper.createDatabase(dbName, 62)) {
|
|
||||||
createStudent(1, 1)
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.runMigrationsAndValidate(dbName, 63, true)
|
|
||||||
|
|
||||||
val database = getMigratedRoomDatabase()
|
|
||||||
val studentDb = database.studentDao
|
|
||||||
val student = studentDb.loadById(1)
|
|
||||||
|
|
||||||
val isEduOne = assertNotNull(student!!.isEduOne)
|
|
||||||
assertTrue(isEduOne)
|
|
||||||
database.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun SupportSQLiteDatabase.createStudent(id: Long, isEduOneValue: Int) {
|
private fun SupportSQLiteDatabase.createStudent(id: Long, isEduOneValue: Int) {
|
||||||
insert("Students", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
|
insert("Students", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
|
||||||
put("scrapper_base_url", "https://fakelog.cf")
|
put("scrapper_base_url", "https://fakelog.cf")
|
||||||
|
@ -50,7 +50,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterPojo(1, 2, now().minusMonths(3), now())
|
getSemesterPojo(1, 2, now().minusMonths(3), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
coEvery { semesterDb.loadAll(student) } returns emptyList()
|
||||||
coEvery { sdk.getSemesters() } returns semesters
|
coEvery { sdk.getSemesters() } returns semesters
|
||||||
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
|
|
||||||
@ -77,10 +77,7 @@ class SemesterRepositoryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
semesterDb.loadAll(
|
semesterDb.loadAll(student)
|
||||||
student.studentId,
|
|
||||||
student.classId
|
|
||||||
)
|
|
||||||
} returns badSemesters.mapToEntities(student.studentId)
|
} returns badSemesters.mapToEntities(student.studentId)
|
||||||
coEvery { sdk.getSemesters() } returns goodSemesters
|
coEvery { sdk.getSemesters() } returns goodSemesters
|
||||||
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
@ -103,7 +100,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterPojo(2, 3, now(), now().plusMonths(6)),
|
getSemesterPojo(2, 3, now(), now().plusMonths(6)),
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returnsMany listOf(
|
coEvery { semesterDb.loadAll(any()) } returnsMany listOf(
|
||||||
badSemesters.mapToEntities(student.studentId),
|
badSemesters.mapToEntities(student.studentId),
|
||||||
badSemesters.mapToEntities(student.studentId),
|
badSemesters.mapToEntities(student.studentId),
|
||||||
goodSemesters.mapToEntities(student.studentId)
|
goodSemesters.mapToEntities(student.studentId)
|
||||||
@ -125,7 +122,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
|
getSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semesters
|
coEvery { semesterDb.loadAll(student) } returns semesters
|
||||||
|
|
||||||
val items = runBlocking { semesterRepository.getSemesters(student) }
|
val items = runBlocking { semesterRepository.getSemesters(student) }
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
@ -138,7 +135,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterEntity(1, 2, now().minusMonths(3), now())
|
getSemesterEntity(1, 2, now().minusMonths(3), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semesters
|
coEvery { semesterDb.loadAll(student) } returns semesters
|
||||||
|
|
||||||
val items = runBlocking { semesterRepository.getSemesters(student) }
|
val items = runBlocking { semesterRepository.getSemesters(student) }
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
@ -151,7 +148,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterEntity(1, 2, now(), now())
|
getSemesterEntity(1, 2, now(), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semesters
|
coEvery { semesterDb.loadAll(student) } returns semesters
|
||||||
|
|
||||||
val items = runBlocking { semesterRepository.getSemesters(student) }
|
val items = runBlocking { semesterRepository.getSemesters(student) }
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
@ -164,7 +161,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterPojo(1, 2, now().minusMonths(3), now())
|
getSemesterPojo(1, 2, now().minusMonths(3), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
coEvery { semesterDb.loadAll(student) } returns emptyList()
|
||||||
coEvery { sdk.getSemesters() } returns semesters
|
coEvery { sdk.getSemesters() } returns semesters
|
||||||
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
|
|
||||||
@ -194,10 +191,7 @@ class SemesterRepositoryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
semesterDb.loadAll(
|
semesterDb.loadAll(student)
|
||||||
student.studentId,
|
|
||||||
student.classId
|
|
||||||
)
|
|
||||||
} returns semestersWithNoCurrent
|
} returns semestersWithNoCurrent
|
||||||
coEvery { sdk.getSemesters() } returns newSemesters
|
coEvery { sdk.getSemesters() } returns newSemesters
|
||||||
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
@ -214,7 +208,7 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterEntity(1, 2, now().minusMonths(1), now().plusMonths(1))
|
getSemesterEntity(1, 2, now().minusMonths(1), now().plusMonths(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semesters
|
coEvery { semesterDb.loadAll(student) } returns semesters
|
||||||
|
|
||||||
val items = semesterRepository.getSemesters(student, refreshOnNoCurrent = true)
|
val items = semesterRepository.getSemesters(student, refreshOnNoCurrent = true)
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
@ -227,14 +221,14 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterEntity(1, 1, now(), now())
|
getSemesterEntity(1, 1, now(), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semesters
|
coEvery { semesterDb.loadAll(student) } returns semesters
|
||||||
|
|
||||||
runBlocking { semesterRepository.getCurrentSemester(student) }
|
runBlocking { semesterRepository.getCurrentSemester(student) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = RuntimeException::class)
|
@Test(expected = RuntimeException::class)
|
||||||
fun getCurrentSemester_emptyList() {
|
fun getCurrentSemester_emptyList() {
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
coEvery { semesterDb.loadAll(student) } returns emptyList()
|
||||||
coEvery { sdk.getSemesters() } returns emptyList()
|
coEvery { sdk.getSemesters() } returns emptyList()
|
||||||
|
|
||||||
runBlocking { semesterRepository.getCurrentSemester(student) }
|
runBlocking { semesterRepository.getCurrentSemester(student) }
|
||||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.ui.modules.main
|
|||||||
import io.github.wulkanowy.MainCoroutineRule
|
import io.github.wulkanowy.MainCoroutineRule
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.AdsHelper
|
import io.github.wulkanowy.utils.AdsHelper
|
||||||
@ -32,9 +31,6 @@ class MainPresenterTest {
|
|||||||
@MockK
|
@MockK
|
||||||
lateinit var studentRepository: StudentRepository
|
lateinit var studentRepository: StudentRepository
|
||||||
|
|
||||||
@MockK(relaxed = true)
|
|
||||||
lateinit var wulkanowyRepository: WulkanowyRepository
|
|
||||||
|
|
||||||
@MockK(relaxed = true)
|
@MockK(relaxed = true)
|
||||||
lateinit var prefRepository: PreferencesRepository
|
lateinit var prefRepository: PreferencesRepository
|
||||||
|
|
||||||
@ -69,8 +65,7 @@ class MainPresenterTest {
|
|||||||
analytics = analytics,
|
analytics = analytics,
|
||||||
json = Json,
|
json = Json,
|
||||||
appInfo = appInfo,
|
appInfo = appInfo,
|
||||||
adsHelper = adsHelper,
|
adsHelper = adsHelper
|
||||||
wulkanowyRepository = wulkanowyRepository
|
|
||||||
)
|
)
|
||||||
presenter.onAttachView(mainView, null)
|
presenter.onAttachView(mainView, null)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user