mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-18 13:26:44 -06:00
SDK update (#2168)
This commit is contained in:
parent
b195fda026
commit
f8431d7ad6
1
.gitignore
vendored
1
.gitignore
vendored
@ -119,3 +119,4 @@ Thumbs.db
|
||||
app/src/release/agconnect-services.json
|
||||
app/src/release/agconnect-credentials.json
|
||||
.idea/deploymentTargetDropDown.xml
|
||||
.idea/kotlinc.xml
|
||||
|
@ -186,7 +186,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:1.9.2"
|
||||
implementation "io.github.wulkanowy:sdk:14267a9a"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||
|
||||
|
@ -20,7 +20,6 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.RemoteConfigHelper
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
@ -81,7 +80,6 @@ internal class DataModule {
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideRetrofit(
|
||||
|
@ -22,6 +22,7 @@ data class Exam(
|
||||
|
||||
val subject: String,
|
||||
|
||||
@Deprecated("not available anymore")
|
||||
val group: String,
|
||||
|
||||
val type: String,
|
||||
|
@ -10,9 +10,9 @@ fun List<SdkConference>.mapToEntities(semester: Semester) = map {
|
||||
diaryId = semester.diaryId,
|
||||
agenda = it.agenda,
|
||||
conferenceId = it.id,
|
||||
date = it.dateZoned.toInstant(),
|
||||
date = it.date.toInstant(),
|
||||
presentOnConference = it.presentOnConference,
|
||||
subject = it.subject,
|
||||
title = it.title
|
||||
subject = it.topic,
|
||||
title = it.place,
|
||||
)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ fun List<SdkExam>.mapToEntities(semester: Semester) = map {
|
||||
date = it.date,
|
||||
entryDate = it.entryDate,
|
||||
subject = it.subject,
|
||||
group = it.group,
|
||||
group = "",
|
||||
type = it.type,
|
||||
description = it.description,
|
||||
teacher = it.teacher,
|
||||
|
@ -26,7 +26,7 @@ fun List<SdkMessage>.mapToEntities(
|
||||
messageId = it.id,
|
||||
correspondents = it.correspondents,
|
||||
subject = it.subject.trim(),
|
||||
date = it.dateZoned.toInstant(),
|
||||
date = it.date.toInstant(),
|
||||
folderId = it.folderId,
|
||||
unread = it.unread,
|
||||
unreadBy = it.unreadBy,
|
||||
|
@ -9,7 +9,7 @@ import io.github.wulkanowy.sdk.pojo.Token as SdkToken
|
||||
fun List<SdkDevice>.mapToEntities(student: Student) = map {
|
||||
MobileDevice(
|
||||
userLoginId = student.userLoginId,
|
||||
date = it.createDateZoned.toInstant(),
|
||||
date = it.createDate.toInstant(),
|
||||
deviceId = it.id,
|
||||
name = it.name
|
||||
)
|
||||
|
@ -3,22 +3,24 @@ package io.github.wulkanowy.data.mappers
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.pojos.*
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.mapper.mapSemesters
|
||||
import java.time.Instant
|
||||
import io.github.wulkanowy.sdk.scrapper.register.RegisterStudent as SdkRegisterStudent
|
||||
import io.github.wulkanowy.sdk.scrapper.register.RegisterUser as SdkRegisterUser
|
||||
import io.github.wulkanowy.sdk.pojo.RegisterStudent as SdkRegisterStudent
|
||||
import io.github.wulkanowy.sdk.pojo.RegisterUser as SdkRegisterUser
|
||||
|
||||
fun SdkRegisterUser.mapToPojo(password: String) = RegisterUser(
|
||||
fun SdkRegisterUser.mapToPojo(password: String?) = RegisterUser(
|
||||
email = email,
|
||||
login = login,
|
||||
password = password,
|
||||
baseUrl = baseUrl,
|
||||
scrapperBaseUrl = scrapperBaseUrl,
|
||||
loginMode = loginMode,
|
||||
loginType = loginType,
|
||||
symbols = symbols.map { registerSymbol ->
|
||||
RegisterSymbol(
|
||||
symbol = registerSymbol.symbol,
|
||||
error = registerSymbol.error,
|
||||
hebeBaseUrl = registerSymbol.hebeBaseUrl,
|
||||
keyId = registerSymbol.keyId,
|
||||
privatePem = registerSymbol.privatePem,
|
||||
userName = registerSymbol.userName,
|
||||
schools = registerSymbol.schools.map {
|
||||
RegisterUnit(
|
||||
@ -42,14 +44,13 @@ fun SdkRegisterUser.mapToPojo(password: String) = RegisterUser(
|
||||
classId = registerSubject.classId,
|
||||
isParent = registerSubject.isParent,
|
||||
semesters = registerSubject.semesters
|
||||
.mapSemesters()
|
||||
.mapToEntities(registerSubject.studentId),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
fun RegisterStudent.mapToStudentWithSemesters(
|
||||
@ -68,17 +69,17 @@ fun RegisterStudent.mapToStudentWithSemesters(
|
||||
classId = classId,
|
||||
studentId = studentId,
|
||||
symbol = symbol.symbol,
|
||||
loginType = user.loginType.name,
|
||||
loginType = user.loginType?.name.orEmpty(),
|
||||
schoolName = unit.schoolName,
|
||||
schoolShortName = unit.schoolShortName,
|
||||
schoolSymbol = unit.schoolId,
|
||||
studentName = "$studentName $studentSurname",
|
||||
loginMode = Sdk.Mode.SCRAPPER.name,
|
||||
scrapperBaseUrl = user.baseUrl,
|
||||
mobileBaseUrl = "",
|
||||
certificateKey = "",
|
||||
privateKey = "",
|
||||
password = user.password,
|
||||
loginMode = user.loginMode.name,
|
||||
scrapperBaseUrl = user.scrapperBaseUrl.orEmpty(),
|
||||
mobileBaseUrl = symbol.hebeBaseUrl.orEmpty(),
|
||||
certificateKey = symbol.keyId.orEmpty(),
|
||||
privateKey = symbol.privatePem.orEmpty(),
|
||||
password = user.password.orEmpty(),
|
||||
isCurrent = false,
|
||||
registrationDate = Instant.now(),
|
||||
).apply {
|
||||
|
@ -1,37 +0,0 @@
|
||||
package io.github.wulkanowy.data.mappers
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import java.time.Instant
|
||||
import io.github.wulkanowy.sdk.pojo.Student as SdkStudent
|
||||
|
||||
fun List<SdkStudent>.mapToEntities(password: String = "", colors: List<Long>) = map {
|
||||
StudentWithSemesters(
|
||||
student = Student(
|
||||
email = it.email,
|
||||
password = password,
|
||||
isParent = it.isParent,
|
||||
symbol = it.symbol,
|
||||
studentId = it.studentId,
|
||||
userLoginId = it.userLoginId,
|
||||
userName = it.userName,
|
||||
studentName = it.studentName + " " + it.studentSurname,
|
||||
schoolSymbol = it.schoolSymbol,
|
||||
schoolShortName = it.schoolShortName,
|
||||
schoolName = it.schoolName,
|
||||
className = it.className,
|
||||
classId = it.classId,
|
||||
scrapperBaseUrl = it.scrapperBaseUrl,
|
||||
loginType = it.loginType.name,
|
||||
isCurrent = false,
|
||||
registrationDate = Instant.now(),
|
||||
mobileBaseUrl = it.mobileBaseUrl,
|
||||
privateKey = it.privateKey,
|
||||
certificateKey = it.certificateKey,
|
||||
loginMode = it.loginMode.name,
|
||||
).apply {
|
||||
avatarColor = colors.random()
|
||||
},
|
||||
semesters = it.semesters.mapToEntities(it.studentId)
|
||||
)
|
||||
}
|
@ -5,10 +5,10 @@ import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.db.entities.TimetableAdditional
|
||||
import io.github.wulkanowy.data.db.entities.TimetableHeader
|
||||
import io.github.wulkanowy.data.pojos.TimetableFull
|
||||
import io.github.wulkanowy.sdk.pojo.TimetableFull as SdkTimetableFull
|
||||
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetableFull
|
||||
import io.github.wulkanowy.sdk.pojo.TimetableDayHeader as SdkTimetableHeader
|
||||
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable
|
||||
import io.github.wulkanowy.sdk.pojo.TimetableAdditional as SdkTimetableAdditional
|
||||
import io.github.wulkanowy.sdk.pojo.Lesson as SdkLesson
|
||||
import io.github.wulkanowy.sdk.pojo.LessonAdditional as SdkTimetableAdditional
|
||||
|
||||
fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull(
|
||||
lessons = lessons.mapToEntities(semester),
|
||||
@ -16,13 +16,13 @@ fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull(
|
||||
headers = headers.mapToEntities(semester)
|
||||
)
|
||||
|
||||
fun List<SdkTimetable>.mapToEntities(semester: Semester) = map {
|
||||
fun List<SdkLesson>.mapToEntities(semester: Semester) = map {
|
||||
Timetable(
|
||||
studentId = semester.studentId,
|
||||
diaryId = semester.diaryId,
|
||||
number = it.number,
|
||||
start = it.startZoned.toInstant(),
|
||||
end = it.endZoned.toInstant(),
|
||||
start = it.start.toInstant(),
|
||||
end = it.end.toInstant(),
|
||||
date = it.date,
|
||||
subject = it.subject,
|
||||
subjectOld = it.subjectOld,
|
||||
@ -45,8 +45,8 @@ fun List<SdkTimetableAdditional>.mapToEntities(semester: Semester) = map {
|
||||
diaryId = semester.diaryId,
|
||||
subject = it.subject,
|
||||
date = it.date,
|
||||
start = it.startZoned.toInstant(),
|
||||
end = it.endZoned.toInstant(),
|
||||
start = it.start.toInstant(),
|
||||
end = it.end.toInstant(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,25 @@
|
||||
package io.github.wulkanowy.data.pojos
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.scrapper.Scrapper
|
||||
|
||||
data class RegisterUser(
|
||||
val email: String,
|
||||
val password: String,
|
||||
val password: String?,
|
||||
val login: String, // may be the same as email
|
||||
val baseUrl: String,
|
||||
val loginType: Scrapper.LoginType,
|
||||
val scrapperBaseUrl: String?,
|
||||
val loginType: Scrapper.LoginType?,
|
||||
val loginMode: Sdk.Mode,
|
||||
val symbols: List<RegisterSymbol>,
|
||||
) : java.io.Serializable
|
||||
|
||||
data class RegisterSymbol(
|
||||
val symbol: String,
|
||||
val error: Throwable?,
|
||||
val hebeBaseUrl: String?,
|
||||
val keyId: String?,
|
||||
val privatePem: String?,
|
||||
val userName: String,
|
||||
val schools: List<RegisterUnit>,
|
||||
) : java.io.Serializable
|
||||
|
@ -19,7 +19,6 @@ class AppCreatorRepository @Inject constructor(
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
suspend fun getAppCreators() = withContext(dispatchers.io) {
|
||||
val inputStream = context.assets.open("contributors.json").buffered()
|
||||
json.decodeFromStream<List<Contributor>>(inputStream)
|
||||
|
@ -59,7 +59,7 @@ class AttendanceRepository @Inject constructor(
|
||||
}
|
||||
sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getAttendance(start.monday, end.sunday, semester.semesterId)
|
||||
.getAttendance(start.monday, end.sunday)
|
||||
.mapToEntities(semester, lessons)
|
||||
},
|
||||
saveFetchResult = { old, new ->
|
||||
|
@ -52,7 +52,7 @@ class ExamRepository @Inject constructor(
|
||||
fetch = {
|
||||
sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getExams(start.startExamsDay, start.endExamsDay, semester.semesterId)
|
||||
.getExams(start.startExamsDay, start.endExamsDay)
|
||||
.mapToEntities(semester)
|
||||
},
|
||||
saveFetchResult = { old, new ->
|
||||
|
@ -42,7 +42,7 @@ class NoteRepository @Inject constructor(
|
||||
fetch = {
|
||||
sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getNotes(semester.semesterId)
|
||||
.getNotes()
|
||||
.mapToEntities(semester)
|
||||
},
|
||||
saveFetchResult = { old, new ->
|
||||
|
@ -40,7 +40,7 @@ class SemesterRepository @Inject constructor(
|
||||
val isNoSemesters = semesters.isEmpty()
|
||||
|
||||
val isRefreshOnModeChangeRequired = when {
|
||||
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> {
|
||||
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE -> {
|
||||
semesters.firstOrNull { it.isCurrent }?.let {
|
||||
0 == it.diaryId && 0 == it.kindergartenDiaryId
|
||||
} == true
|
||||
|
@ -10,11 +10,9 @@ import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.mappers.mapToPojo
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.DispatchersProvider
|
||||
import io.github.wulkanowy.utils.security.decrypt
|
||||
import io.github.wulkanowy.utils.security.encrypt
|
||||
@ -29,37 +27,35 @@ class StudentRepository @Inject constructor(
|
||||
private val studentDb: StudentDao,
|
||||
private val semesterDb: SemesterDao,
|
||||
private val sdk: Sdk,
|
||||
private val appInfo: AppInfo,
|
||||
private val appDatabase: AppDatabase
|
||||
) {
|
||||
|
||||
suspend fun isStudentSaved() = getSavedStudents(false).isNotEmpty()
|
||||
|
||||
suspend fun isCurrentStudentSet() = studentDb.loadCurrent()?.isCurrent ?: false
|
||||
|
||||
suspend fun getStudentsApi(
|
||||
pin: String,
|
||||
symbol: String,
|
||||
token: String
|
||||
): List<StudentWithSemesters> =
|
||||
sdk.getStudentsFromMobileApi(token, pin, symbol, "")
|
||||
.mapToEntities(colors = appInfo.defaultColorsForAvatar)
|
||||
): RegisterUser = sdk
|
||||
.getStudentsFromHebe(token, pin, symbol, "")
|
||||
.mapToPojo(null)
|
||||
|
||||
suspend fun getStudentsScrapper(
|
||||
email: String,
|
||||
password: String,
|
||||
scrapperBaseUrl: String,
|
||||
symbol: String
|
||||
): List<StudentWithSemesters> =
|
||||
sdk.getStudentsFromScrapper(email, password, scrapperBaseUrl, symbol)
|
||||
.mapToEntities(password, appInfo.defaultColorsForAvatar)
|
||||
): RegisterUser = sdk
|
||||
.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
|
||||
.mapToPojo(password)
|
||||
|
||||
suspend fun getUserSubjectsFromScrapper(
|
||||
email: String,
|
||||
password: String,
|
||||
scrapperBaseUrl: String,
|
||||
symbol: String
|
||||
): RegisterUser = sdk.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
|
||||
): RegisterUser = sdk
|
||||
.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
|
||||
.mapToPojo(password)
|
||||
|
||||
suspend fun getStudentsHybrid(
|
||||
@ -67,15 +63,15 @@ class StudentRepository @Inject constructor(
|
||||
password: String,
|
||||
scrapperBaseUrl: String,
|
||||
symbol: String
|
||||
): List<StudentWithSemesters> =
|
||||
sdk.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol)
|
||||
.mapToEntities(password, appInfo.defaultColorsForAvatar)
|
||||
): RegisterUser = sdk
|
||||
.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol)
|
||||
.mapToPojo(password)
|
||||
|
||||
suspend fun getSavedStudents(decryptPass: Boolean = true) =
|
||||
studentDb.loadStudentsWithSemesters()
|
||||
.map {
|
||||
it.apply {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
||||
student.password = withContext(dispatchers.io) {
|
||||
decrypt(student.password)
|
||||
}
|
||||
@ -85,7 +81,7 @@ class StudentRepository @Inject constructor(
|
||||
|
||||
suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true) =
|
||||
studentDb.loadStudentWithSemestersById(id)?.apply {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
||||
student.password = withContext(dispatchers.io) {
|
||||
decrypt(student.password)
|
||||
}
|
||||
@ -95,7 +91,7 @@ class StudentRepository @Inject constructor(
|
||||
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
|
||||
val student = studentDb.loadById(id) ?: throw NoCurrentStudentException()
|
||||
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
||||
student.password = withContext(dispatchers.io) {
|
||||
decrypt(student.password)
|
||||
}
|
||||
@ -106,7 +102,7 @@ class StudentRepository @Inject constructor(
|
||||
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
|
||||
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException()
|
||||
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) {
|
||||
student.password = withContext(dispatchers.io) {
|
||||
decrypt(student.password)
|
||||
}
|
||||
@ -119,7 +115,7 @@ class StudentRepository @Inject constructor(
|
||||
val students = studentsWithSemesters.map { it.student }
|
||||
.map {
|
||||
it.apply {
|
||||
if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.API) {
|
||||
if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.HEBE) {
|
||||
password = withContext(dispatchers.io) {
|
||||
encrypt(password, context)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class TeacherRepository @Inject constructor(
|
||||
fetch = {
|
||||
sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getTeachers(semester.semesterId)
|
||||
.getTeachers()
|
||||
.mapToEntities(semester)
|
||||
},
|
||||
saveFetchResult = { old, new ->
|
||||
|
@ -66,7 +66,7 @@ class TimetableRepository @Inject constructor(
|
||||
fetch = {
|
||||
val timetableFull = sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getTimetableFull(start.monday, end.sunday)
|
||||
.getTimetable(start.monday, end.sunday)
|
||||
|
||||
timetableFull.mapToEntities(semester)
|
||||
},
|
||||
|
@ -4,13 +4,15 @@ import android.content.Context
|
||||
import android.database.sqlite.SQLiteConstraintException
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.sdk.mobile.exception.InvalidPinException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.InvalidSymbolException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.InvalidTokenException
|
||||
import io.github.wulkanowy.sdk.mobile.exception.TokenDeadException
|
||||
import io.github.wulkanowy.sdk.hebe.exception.InvalidPinException
|
||||
import io.github.wulkanowy.sdk.hebe.exception.InvalidTokenException
|
||||
import io.github.wulkanowy.sdk.hebe.exception.TokenDeadException
|
||||
import io.github.wulkanowy.sdk.hebe.exception.UnknownTokenException
|
||||
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import javax.inject.Inject
|
||||
import io.github.wulkanowy.sdk.hebe.exception.InvalidSymbolException as InvalidHebeSymbolException
|
||||
import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException as InvalidScrapperSymbolException
|
||||
|
||||
class LoginErrorHandler @Inject constructor(
|
||||
@ApplicationContext context: Context,
|
||||
@ -32,9 +34,11 @@ class LoginErrorHandler @Inject constructor(
|
||||
is BadCredentialsException -> onBadCredentials(error.message)
|
||||
is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student))
|
||||
is TokenDeadException -> onInvalidToken(resources.getString(R.string.login_expired_token))
|
||||
is UnknownTokenException,
|
||||
is InvalidTokenException -> onInvalidToken(resources.getString(R.string.login_invalid_token))
|
||||
is InvalidPinException -> onInvalidPin(resources.getString(R.string.login_invalid_pin))
|
||||
is InvalidSymbolException -> onInvalidSymbol(resources.getString(R.string.login_invalid_symbol))
|
||||
is InvalidScrapperSymbolException,
|
||||
is InvalidHebeSymbolException -> onInvalidSymbol(resources.getString(R.string.login_invalid_symbol))
|
||||
else -> super.proceed(error)
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ class LoginAdvancedFragment :
|
||||
|
||||
override val formLoginType: String
|
||||
get() = when (binding.loginTypeSwitch.checkedRadioButtonId) {
|
||||
R.id.loginTypeApi -> "API"
|
||||
R.id.loginTypeScrapper -> "SCRAPPER"
|
||||
else -> "HYBRID"
|
||||
R.id.loginTypeApi -> Sdk.Mode.HEBE.name
|
||||
R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER.name
|
||||
else -> Sdk.Mode.HYBRID.name
|
||||
}
|
||||
|
||||
override val formUsernameValue: String
|
||||
@ -99,7 +99,7 @@ class LoginAdvancedFragment :
|
||||
loginTypeSwitch.setOnCheckedChangeListener { _, checkedId ->
|
||||
presenter.onLoginModeSelected(
|
||||
when (checkedId) {
|
||||
R.id.loginTypeApi -> Sdk.Mode.API
|
||||
R.id.loginTypeApi -> Sdk.Mode.HEBE
|
||||
R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER
|
||||
else -> Sdk.Mode.HYBRID
|
||||
}
|
||||
|
@ -1,17 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.login.advanced
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.logResourceStatus
|
||||
import io.github.wulkanowy.data.onResourceNotLoading
|
||||
import io.github.wulkanowy.data.pojos.RegisterStudent
|
||||
import io.github.wulkanowy.data.pojos.RegisterSymbol
|
||||
import io.github.wulkanowy.data.pojos.RegisterUnit
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.scrapper.Scrapper
|
||||
import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
@ -97,14 +92,16 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
fun onLoginModeSelected(type: Sdk.Mode) {
|
||||
view?.run {
|
||||
when (type) {
|
||||
Sdk.Mode.API -> {
|
||||
Sdk.Mode.HEBE -> {
|
||||
showOnlyMobileApiModeInputs()
|
||||
showMobileApiWarningMessage()
|
||||
}
|
||||
|
||||
Sdk.Mode.SCRAPPER -> {
|
||||
showOnlyScrapperModeInputs()
|
||||
showScraperWarningMessage()
|
||||
}
|
||||
|
||||
Sdk.Mode.HYBRID -> {
|
||||
showOnlyHybridModeInputs()
|
||||
showHybridWarningMessage()
|
||||
@ -145,11 +142,12 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
|
||||
is Resource.Success -> {
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to true,
|
||||
"students" to it.data.size,
|
||||
"scrapperBaseUrl" to view?.formHostValue.orEmpty(),
|
||||
"error" to "No error"
|
||||
)
|
||||
val loginData = LoginData(
|
||||
@ -158,14 +156,15 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
baseUrl = view?.formHostValue.orEmpty().trim(),
|
||||
symbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(),
|
||||
)
|
||||
when (it.data.size) {
|
||||
when (it.data.symbols.size) {
|
||||
0 -> view?.navigateToSymbol(loginData)
|
||||
else -> view?.navigateToStudentSelect(
|
||||
loginData = loginData,
|
||||
registerUser = it.data.toRegisterUser(loginData),
|
||||
registerUser = it.data,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is Resource.Error -> {
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
@ -183,59 +182,7 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
}.launch("login")
|
||||
}
|
||||
|
||||
private fun List<StudentWithSemesters>.toRegisterUser(loginData: LoginData) = RegisterUser(
|
||||
email = loginData.login,
|
||||
password = loginData.password,
|
||||
login = loginData.login,
|
||||
baseUrl = loginData.baseUrl,
|
||||
loginType = firstOrNull()?.student?.loginType?.let(
|
||||
Scrapper.LoginType::valueOf
|
||||
) ?: Scrapper.LoginType.AUTO,
|
||||
symbols = this
|
||||
.groupBy { students -> students.student.symbol }
|
||||
.map { (symbol, students) ->
|
||||
RegisterSymbol(
|
||||
symbol = symbol,
|
||||
error = null,
|
||||
userName = "",
|
||||
schools = students
|
||||
.groupBy { student ->
|
||||
Triple(
|
||||
first = student.student.schoolSymbol,
|
||||
second = student.student.userLoginId,
|
||||
third = student.student.schoolShortName
|
||||
)
|
||||
}
|
||||
.map { (groupKey, students) ->
|
||||
val (schoolId, loginId, schoolName) = groupKey
|
||||
RegisterUnit(
|
||||
students = students.map {
|
||||
RegisterStudent(
|
||||
studentId = it.student.studentId,
|
||||
studentName = it.student.studentName,
|
||||
studentSecondName = it.student.studentName,
|
||||
studentSurname = it.student.studentName,
|
||||
className = it.student.className,
|
||||
classId = it.student.classId,
|
||||
isParent = it.student.isParent,
|
||||
semesters = it.semesters,
|
||||
)
|
||||
},
|
||||
userLoginId = loginId,
|
||||
schoolId = schoolId,
|
||||
schoolName = schoolName,
|
||||
schoolShortName = schoolName,
|
||||
parentIds = listOf(),
|
||||
studentIds = listOf(),
|
||||
employeeIds = listOf(),
|
||||
error = null
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private suspend fun getStudentsAppropriatesToLoginType(): List<StudentWithSemesters> {
|
||||
private suspend fun getStudentsAppropriatesToLoginType(): RegisterUser {
|
||||
val email = view?.formUsernameValue.orEmpty()
|
||||
val password = view?.formPassValue.orEmpty()
|
||||
val endpoint = view?.formHostValue.orEmpty()
|
||||
@ -245,10 +192,11 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
val token = view?.formTokenValue.orEmpty()
|
||||
|
||||
return when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) {
|
||||
Sdk.Mode.API -> studentRepository.getStudentsApi(pin, symbol, token)
|
||||
Sdk.Mode.HEBE -> studentRepository.getStudentsApi(pin, symbol, token)
|
||||
Sdk.Mode.SCRAPPER -> studentRepository.getStudentsScrapper(
|
||||
email, password, endpoint, symbol
|
||||
)
|
||||
|
||||
Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid(
|
||||
email, password, endpoint, symbol
|
||||
)
|
||||
@ -267,8 +215,8 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
|
||||
var isCorrect = true
|
||||
|
||||
when (Sdk.Mode.valueOf(view?.formLoginType ?: "")) {
|
||||
Sdk.Mode.API -> {
|
||||
when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) {
|
||||
Sdk.Mode.HEBE -> {
|
||||
if (pin.isEmpty()) {
|
||||
view?.setErrorPinRequired()
|
||||
isCorrect = false
|
||||
@ -284,17 +232,17 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
isCorrect = false
|
||||
}
|
||||
}
|
||||
|
||||
Sdk.Mode.HYBRID, Sdk.Mode.SCRAPPER -> {
|
||||
if (login.isEmpty()) {
|
||||
view?.setErrorUsernameRequired()
|
||||
isCorrect = false
|
||||
} else {
|
||||
if ("@" in login && "standard" !in host) {
|
||||
if ("@" in login && "login" in host) {
|
||||
view?.setErrorLoginRequired()
|
||||
isCorrect = false
|
||||
}
|
||||
|
||||
if ("@" !in login && "standard" in host) {
|
||||
if ("@" !in login && "email" in host) {
|
||||
view?.setErrorEmailRequired()
|
||||
isCorrect = false
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.login.advanced
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
|
@ -204,6 +204,10 @@ class LoginFormFragment : BaseFragment<FragmentLoginFormBinding>(R.layout.fragme
|
||||
binding.loginFormContainer.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
override fun showOtherOptionsButton(show: Boolean) {
|
||||
binding.loginFormAdvancedButton.isVisible = show
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun showVersion() {
|
||||
binding.loginFormVersion.text = "v${appInfo.versionName}"
|
||||
|
@ -7,6 +7,7 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||
import timber.log.Timber
|
||||
import java.net.URL
|
||||
@ -15,6 +16,7 @@ import javax.inject.Inject
|
||||
class LoginFormPresenter @Inject constructor(
|
||||
studentRepository: StudentRepository,
|
||||
private val loginErrorHandler: LoginErrorHandler,
|
||||
private val appInfo: AppInfo,
|
||||
private val analytics: AnalyticsHelper
|
||||
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository) {
|
||||
|
||||
@ -25,6 +27,7 @@ class LoginFormPresenter @Inject constructor(
|
||||
view.run {
|
||||
initView()
|
||||
showContact(false)
|
||||
showOtherOptionsButton(appInfo.isDebug)
|
||||
showVersion()
|
||||
|
||||
loginErrorHandler.onBadCredentials = {
|
||||
|
@ -56,6 +56,8 @@ interface LoginFormView : BaseView {
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun showOtherOptionsButton(show: Boolean)
|
||||
|
||||
fun showVersion()
|
||||
|
||||
fun navigateToSymbol(loginData: LoginData)
|
||||
|
@ -55,7 +55,6 @@ class LoginStudentSelectFragment :
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentLoginStudentSelectBinding.bind(view)
|
||||
|
@ -12,18 +12,17 @@ fun Sdk.init(student: Student): Sdk {
|
||||
studentId = student.studentId
|
||||
classId = student.classId
|
||||
|
||||
if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
||||
mobileBaseUrl = student.mobileBaseUrl
|
||||
} else {
|
||||
scrapperBaseUrl = student.scrapperBaseUrl
|
||||
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
|
||||
}
|
||||
loginId = student.userLoginId
|
||||
|
||||
mode = Sdk.Mode.valueOf(student.loginMode)
|
||||
mobileBaseUrl = student.mobileBaseUrl
|
||||
certKey = student.certificateKey
|
||||
privateKey = student.privateKey
|
||||
|
||||
emptyCookieJarInterceptor = true
|
||||
keyId = student.certificateKey
|
||||
privatePem = student.privateKey
|
||||
|
||||
Timber.d("Sdk in ${student.loginMode} mode reinitialized")
|
||||
|
||||
|
@ -247,7 +247,6 @@
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/login_advanced"
|
||||
android:textAppearance="?android:textAppearance"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="?android:windowBackground"
|
||||
app:fontFamily="sans-serif-medium"
|
||||
app:layout_constraintBottom_toBottomOf="@id/loginFormSignIn"
|
||||
|
@ -48,7 +48,7 @@ fun getSemesterPojo(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalD
|
||||
end = end,
|
||||
)
|
||||
|
||||
fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.API) = Student(
|
||||
fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.HEBE) = Student(
|
||||
scrapperBaseUrl = "http://fakelog.cf",
|
||||
email = "jan@fakelog.cf",
|
||||
certificateKey = "",
|
||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.data.mappers
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.sdk.pojo.Attendance
|
||||
import io.github.wulkanowy.sdk.scrapper.attendance.SentExcuse
|
||||
import io.github.wulkanowy.sdk.scrapper.attendance.SentExcuseStatus
|
||||
import org.junit.Test
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
@ -98,7 +98,7 @@ class AttendanceMapperTest {
|
||||
timeId = 1,
|
||||
categoryId = 1,
|
||||
deleted = false,
|
||||
excuseStatus = SentExcuse.Status.WAITING,
|
||||
excuseStatus = SentExcuseStatus.WAITING,
|
||||
excusable = false,
|
||||
absence = false,
|
||||
excused = false,
|
||||
|
@ -63,7 +63,7 @@ class AttendanceRepositoryTest {
|
||||
@Test
|
||||
fun `force refresh without difference`() {
|
||||
// prepare
|
||||
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList
|
||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
||||
flowOf(remoteList.mapToEntities(semester, emptyList()))
|
||||
@ -77,7 +77,7 @@ class AttendanceRepositoryTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) }
|
||||
@ -86,7 +86,7 @@ class AttendanceRepositoryTest {
|
||||
@Test
|
||||
fun `force refresh with more items in remote`() {
|
||||
// prepare
|
||||
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList
|
||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())),
|
||||
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), // after fetch end before save result
|
||||
@ -101,7 +101,7 @@ class AttendanceRepositoryTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify {
|
||||
attendanceDb.insertAll(match {
|
||||
@ -114,7 +114,7 @@ class AttendanceRepositoryTest {
|
||||
@Test
|
||||
fun `force refresh with more items in local`() {
|
||||
// prepare
|
||||
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList.dropLast(1)
|
||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList.dropLast(1)
|
||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
||||
flowOf(remoteList.mapToEntities(semester, emptyList())), // after fetch end before save result
|
||||
@ -129,7 +129,7 @@ class AttendanceRepositoryTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify {
|
||||
|
@ -59,7 +59,7 @@ class ExamRemoteTest {
|
||||
@Test
|
||||
fun `force refresh without difference`() {
|
||||
// prepare
|
||||
coEvery { sdk.getExams(startDate, realEndDate, 1) } returns remoteList
|
||||
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList
|
||||
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
||||
flowOf(remoteList.mapToEntities(semester)),
|
||||
flowOf(remoteList.mapToEntities(semester))
|
||||
@ -73,7 +73,7 @@ class ExamRemoteTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify { examDb.deleteAll(match { it.isEmpty() }) }
|
||||
@ -82,7 +82,7 @@ class ExamRemoteTest {
|
||||
@Test
|
||||
fun `force refresh with more items in remote`() {
|
||||
// prepare
|
||||
coEvery { sdk.getExams(startDate, realEndDate, 1) } returns remoteList
|
||||
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList
|
||||
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)),
|
||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result
|
||||
@ -97,7 +97,7 @@ class ExamRemoteTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify {
|
||||
examDb.insertAll(match {
|
||||
@ -110,7 +110,7 @@ class ExamRemoteTest {
|
||||
@Test
|
||||
fun `force refresh with more items in local`() {
|
||||
// prepare
|
||||
coEvery { sdk.getExams(startDate, realEndDate, 1) } returns remoteList.dropLast(1)
|
||||
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList.dropLast(1)
|
||||
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
||||
flowOf(remoteList.mapToEntities(semester)),
|
||||
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
|
||||
@ -125,7 +125,7 @@ class ExamRemoteTest {
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify {
|
||||
@ -137,7 +137,6 @@ class ExamRemoteTest {
|
||||
|
||||
private fun getExam(date: LocalDate) = SdkExam(
|
||||
subject = "",
|
||||
group = "",
|
||||
type = "",
|
||||
description = "",
|
||||
teacher = "",
|
||||
|
@ -9,13 +9,21 @@ import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Grades
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.mockk.*
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
@ -72,7 +80,7 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||
)
|
||||
coEvery { sdk.getGrades(1) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(1) } returns createGrades(remoteList)
|
||||
|
||||
coEvery { gradeDb.loadAll(1, 1) } returnsMany listOf(
|
||||
flowOf(listOf()), // empty because it is new user
|
||||
@ -122,7 +130,7 @@ class GradeRepositoryTest {
|
||||
),
|
||||
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||
)
|
||||
coEvery { sdk.getGrades(1) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(1) } returns createGrades(remoteList)
|
||||
|
||||
val localList = listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
|
||||
@ -169,7 +177,7 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
)
|
||||
coEvery { sdk.getGrades(1) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(1) } returns createGrades(remoteList)
|
||||
|
||||
val localList = listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
@ -200,7 +208,7 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), // will be added...
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
)
|
||||
coEvery { sdk.getGrades(1) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(1) } returns createGrades(remoteList)
|
||||
|
||||
val localList = listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
@ -230,7 +238,7 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
)
|
||||
coEvery { sdk.getGrades(1) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(1) } returns createGrades(remoteList)
|
||||
|
||||
coEvery { gradeDb.loadAll(1, 1) } returnsMany listOf(
|
||||
flowOf(listOf()),
|
||||
@ -250,7 +258,7 @@ class GradeRepositoryTest {
|
||||
fun `force refresh when remote is empty`() {
|
||||
// prepare
|
||||
val remoteList = emptyList<SdkGrade>()
|
||||
coEvery { sdk.getGrades(semester.semesterId) } returns (remoteList to emptyList())
|
||||
coEvery { sdk.getGrades(semester.semesterId) } returns createGrades(remoteList)
|
||||
|
||||
val localList = listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
@ -284,4 +292,13 @@ class GradeRepositoryTest {
|
||||
weight = weight.toString(),
|
||||
weightValue = weight
|
||||
)
|
||||
|
||||
private fun createGrades(grades: List<SdkGrade>): Grades = Grades(
|
||||
details = grades,
|
||||
summary = listOf(),
|
||||
isAverage = false,
|
||||
isPoints = false,
|
||||
isForAdults = false,
|
||||
type = 0,
|
||||
)
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ class MessageRepositoryTest {
|
||||
recipients = listOf(),
|
||||
subject = "",
|
||||
content = "Test",
|
||||
dateZoned = Instant.EPOCH.atZone(ZoneOffset.UTC),
|
||||
date = Instant.EPOCH.atZone(ZoneOffset.UTC),
|
||||
folderId = 1,
|
||||
unread = true,
|
||||
readBy = 1,
|
||||
|
@ -10,16 +10,21 @@ import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Device
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.mockk.*
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.time.LocalDateTime.of
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime.of
|
||||
|
||||
class MobileDeviceRepositoryTest {
|
||||
|
||||
@ -134,9 +139,7 @@ class MobileDeviceRepositoryTest {
|
||||
id = 0,
|
||||
name = "",
|
||||
deviceId = "",
|
||||
createDate = of(2019, 5, day, 0, 0, 0),
|
||||
modificationDate = of(2019, 5, day, 0, 0, 0),
|
||||
createDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault()),
|
||||
modificationDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault())
|
||||
createDate = of(2019, 5, day, 0, 0, 0, 0, ZoneOffset.UTC),
|
||||
modificationDate = of(2019, 5, day, 0, 0, 0, 0, ZoneOffset.UTC),
|
||||
)
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class SemesterRepositoryTest {
|
||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
||||
coEvery { semesterDb.insertSemesters(any()) } returns listOf()
|
||||
|
||||
val items = runBlocking { semesterRepository.getSemesters(student.copy(loginMode = Sdk.Mode.API.name)) }
|
||||
val items = runBlocking { semesterRepository.getSemesters(student.copy(loginMode = Sdk.Mode.HEBE.name)) }
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(0, items[0].diaryId)
|
||||
}
|
||||
@ -215,6 +215,7 @@ class SemesterRepositoryTest {
|
||||
@Test(expected = RuntimeException::class)
|
||||
fun getCurrentSemester_emptyList() {
|
||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
||||
coEvery { sdk.getSemesters() } returns emptyList()
|
||||
|
||||
runBlocking { semesterRepository.getCurrentSemester(student) }
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.TestDispatchersProvider
|
||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Student
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class StudentTest {
|
||||
|
||||
@MockK
|
||||
private lateinit var mockSdk: Sdk
|
||||
|
||||
@MockK
|
||||
private lateinit var studentDb: StudentDao
|
||||
|
||||
@MockK
|
||||
private lateinit var semesterDb: SemesterDao
|
||||
|
||||
private lateinit var studentRepository: StudentRepository
|
||||
|
||||
@Before
|
||||
fun initApi() {
|
||||
MockKAnnotations.init(this)
|
||||
studentRepository = StudentRepository(
|
||||
context = mockk(),
|
||||
dispatchers = TestDispatchersProvider(),
|
||||
studentDb = studentDb,
|
||||
semesterDb = semesterDb,
|
||||
sdk = mockSdk,
|
||||
appInfo = AppInfo(),
|
||||
appDatabase = mockk()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRemoteAll() {
|
||||
coEvery { mockSdk.getStudentsFromScrapper(any(), any(), any(), any()) } returns listOf(
|
||||
getStudent("test")
|
||||
)
|
||||
|
||||
val students = runBlocking { studentRepository.getStudentsScrapper("", "", "http://fakelog.cf", "") }
|
||||
assertEquals(1, students.size)
|
||||
assertEquals("test Kowalski", students.first().student.studentName)
|
||||
}
|
||||
|
||||
private fun getStudent(name: String): Student {
|
||||
return Student(
|
||||
email = "",
|
||||
symbol = "",
|
||||
studentId = 0,
|
||||
userLoginId = 0,
|
||||
userLogin = "",
|
||||
userName = "",
|
||||
studentName = name,
|
||||
studentSurname = "Kowalski",
|
||||
schoolSymbol = "",
|
||||
schoolShortName = "",
|
||||
schoolName = "",
|
||||
className = "",
|
||||
classId = 0,
|
||||
certificateKey = "",
|
||||
privateKey = "",
|
||||
loginMode = Sdk.Mode.SCRAPPER,
|
||||
mobileBaseUrl = "",
|
||||
loginType = Sdk.ScrapperLoginType.STANDARD,
|
||||
scrapperBaseUrl = "",
|
||||
isParent = false,
|
||||
semesters = emptyList()
|
||||
)
|
||||
}
|
||||
}
|
@ -10,12 +10,17 @@ import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.TimetableFull
|
||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.mockk.*
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -25,7 +30,7 @@ import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalDateTime.of
|
||||
import java.time.ZoneId
|
||||
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable
|
||||
import io.github.wulkanowy.sdk.pojo.Lesson as SdkLesson
|
||||
|
||||
class TimetableRepositoryTest {
|
||||
|
||||
@ -62,18 +67,43 @@ class TimetableRepositoryTest {
|
||||
MockKAnnotations.init(this)
|
||||
every { refreshHelper.shouldBeRefreshed(any()) } returns false
|
||||
|
||||
timetableRepository = TimetableRepository(timetableDb, timetableAdditionalDao, timetableHeaderDao, sdk, timetableNotificationSchedulerHelper, refreshHelper)
|
||||
timetableRepository = TimetableRepository(
|
||||
timetableDb,
|
||||
timetableAdditionalDao,
|
||||
timetableHeaderDao,
|
||||
sdk,
|
||||
timetableNotificationSchedulerHelper,
|
||||
refreshHelper
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `force refresh without difference`() {
|
||||
val remoteList = listOf(
|
||||
createTimetableRemote(of(2021, 1, 4, 8, 0), 1, "123", "Język polski", "Jan Kowalski", false),
|
||||
createTimetableRemote(of(2021, 1, 4, 8, 50), 2, "124", "Język niemiecki", "Joanna Czarniecka", true)
|
||||
createTimetableRemote(
|
||||
start = of(2021, 1, 4, 8, 0),
|
||||
number = 1,
|
||||
room = "123",
|
||||
subject = "Język polski",
|
||||
teacher = "Jan Kowalski",
|
||||
changes = false
|
||||
),
|
||||
createTimetableRemote(
|
||||
start = of(2021, 1, 4, 8, 50),
|
||||
number = 2,
|
||||
room = "124",
|
||||
subject = "Język niemiecki",
|
||||
teacher = "Joanna Czarniecka",
|
||||
changes = true
|
||||
)
|
||||
)
|
||||
|
||||
// prepare
|
||||
coEvery { sdk.getTimetableFull(startDate, endDate) } returns TimetableFull(emptyList(), remoteList, emptyList())
|
||||
coEvery { sdk.getTimetable(startDate, endDate) } returns mockk {
|
||||
every { headers } returns emptyList()
|
||||
every { lessons } returns remoteList
|
||||
every { additional } returns emptyList()
|
||||
}
|
||||
coEvery { timetableDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||
flowOf(remoteList.mapToEntities(semester)),
|
||||
flowOf(remoteList.mapToEntities(semester))
|
||||
@ -81,7 +111,14 @@ class TimetableRepositoryTest {
|
||||
coEvery { timetableDb.insertAll(any()) } returns listOf(1, 2, 3)
|
||||
coEvery { timetableDb.deleteAll(any()) } just Runs
|
||||
|
||||
coEvery { timetableAdditionalDao.loadAll(1, 1, startDate, endDate) } returns flowOf(listOf())
|
||||
coEvery {
|
||||
timetableAdditionalDao.loadAll(
|
||||
diaryId = 1,
|
||||
studentId = 1,
|
||||
from = startDate,
|
||||
end = endDate
|
||||
)
|
||||
} returns flowOf(listOf())
|
||||
coEvery { timetableAdditionalDao.deleteAll(emptyList()) } just Runs
|
||||
coEvery { timetableAdditionalDao.insertAll(emptyList()) } returns listOf(1, 2, 3)
|
||||
|
||||
@ -90,23 +127,36 @@ class TimetableRepositoryTest {
|
||||
coEvery { timetableHeaderDao.deleteAll(emptyList()) } just Runs
|
||||
|
||||
// execute
|
||||
val res = runBlocking { timetableRepository.getTimetable(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
val res = runBlocking {
|
||||
timetableRepository.getTimetable(
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = startDate,
|
||||
end = endDate,
|
||||
forceRefresh = true
|
||||
).toFirstResult()
|
||||
}
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull!!.lessons.size)
|
||||
coVerify { sdk.getTimetableFull(startDate, endDate) }
|
||||
coVerify { sdk.getTimetable(startDate, endDate) }
|
||||
coVerify { timetableDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { timetableDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify { timetableDb.deleteAll(match { it.isEmpty() }) }
|
||||
}
|
||||
|
||||
private fun createTimetableRemote(start: LocalDateTime, number: Int = 1, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false) = SdkTimetable(
|
||||
private fun createTimetableRemote(
|
||||
start: LocalDateTime,
|
||||
number: Int = 1,
|
||||
room: String = "",
|
||||
subject: String = "",
|
||||
teacher: String = "",
|
||||
changes: Boolean = false
|
||||
) = SdkLesson(
|
||||
number = number,
|
||||
start = start,
|
||||
end = start.plusMinutes(45),
|
||||
startZoned = start.atZone(ZoneId.systemDefault()),
|
||||
endZoned = start.plusMinutes(45).atZone(ZoneId.systemDefault()),
|
||||
start = start.atZone(ZoneId.systemDefault()),
|
||||
end = start.plusMinutes(45).atZone(ZoneId.systemDefault()),
|
||||
date = start.toLocalDate(),
|
||||
subject = subject,
|
||||
group = "",
|
||||
|
@ -207,7 +207,7 @@ class GetMailboxByStudentUseCaseTest {
|
||||
className = "",
|
||||
isCurrent = false,
|
||||
isParent = false,
|
||||
loginMode = Sdk.Mode.API.name,
|
||||
loginMode = Sdk.Mode.HEBE.name,
|
||||
loginType = Sdk.ScrapperLoginType.STANDARD.name,
|
||||
mobileBaseUrl = "",
|
||||
password = "",
|
||||
|
@ -456,7 +456,7 @@ class GradeAverageProviderTest {
|
||||
|
||||
@Test
|
||||
fun `force calc current semester average with custom modifiers in api mode`() {
|
||||
val student = student.copy(loginMode = Sdk.Mode.API.name)
|
||||
val student = student.copy(loginMode = Sdk.Mode.HEBE.name)
|
||||
|
||||
every { preferencesRepository.gradeAverageForceCalcFlow } returns flowOf(true)
|
||||
every { preferencesRepository.isOptionalArithmeticAverageFlow } returns flowOf(false)
|
||||
|
@ -3,11 +3,18 @@ package io.github.wulkanowy.ui.modules.login.form
|
||||
import io.github.wulkanowy.MainCoroutineRule
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.scrapper.Scrapper
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.mockk.*
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.verify
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -30,13 +37,17 @@ class LoginFormPresenterTest {
|
||||
@MockK(relaxed = true)
|
||||
lateinit var analytics: AnalyticsHelper
|
||||
|
||||
@MockK
|
||||
lateinit var appInfo: AppInfo
|
||||
|
||||
private lateinit var presenter: LoginFormPresenter
|
||||
|
||||
private val registerUser = RegisterUser(
|
||||
email = "",
|
||||
password = "",
|
||||
login = "",
|
||||
baseUrl = "",
|
||||
scrapperBaseUrl = "",
|
||||
loginMode = Sdk.Mode.HEBE,
|
||||
loginType = Scrapper.LoginType.AUTO,
|
||||
symbols = listOf(),
|
||||
)
|
||||
@ -54,8 +65,14 @@ class LoginFormPresenterTest {
|
||||
every { loginFormView.setErrorPassInvalid(any()) } just Runs
|
||||
every { loginFormView.setErrorPassRequired(any()) } just Runs
|
||||
every { loginFormView.setErrorUsernameRequired() } just Runs
|
||||
every { appInfo.isDebug } returns false
|
||||
|
||||
presenter = LoginFormPresenter(repository, errorHandler, analytics)
|
||||
presenter = LoginFormPresenter(
|
||||
studentRepository = repository,
|
||||
loginErrorHandler = errorHandler,
|
||||
appInfo = appInfo,
|
||||
analytics = analytics,
|
||||
)
|
||||
presenter.onAttachView(loginFormView)
|
||||
}
|
||||
|
||||
|
@ -6,14 +6,22 @@ import io.github.wulkanowy.data.pojos.RegisterSymbol
|
||||
import io.github.wulkanowy.data.pojos.RegisterUnit
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.scrapper.Scrapper
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.mockk.*
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.just
|
||||
import io.mockk.slot
|
||||
import io.mockk.verify
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -76,6 +84,9 @@ class LoginStudentSelectPresenterTest {
|
||||
symbol = "",
|
||||
error = null,
|
||||
userName = "",
|
||||
keyId = null,
|
||||
privatePem = null,
|
||||
hebeBaseUrl = null,
|
||||
schools = listOf(school),
|
||||
)
|
||||
|
||||
@ -83,7 +94,8 @@ class LoginStudentSelectPresenterTest {
|
||||
email = "",
|
||||
password = "",
|
||||
login = "",
|
||||
baseUrl = "",
|
||||
scrapperBaseUrl = "",
|
||||
loginMode = Sdk.Mode.SCRAPPER,
|
||||
loginType = Scrapper.LoginType.AUTO,
|
||||
symbols = listOf(symbol),
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user