diff --git a/.gitignore b/.gitignore index cd5ff7146..921bd0a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,4 @@ Thumbs.db app/src/release/agconnect-services.json app/src/release/agconnect-credentials.json .idea/deploymentTargetDropDown.xml +.idea/kotlinc.xml diff --git a/app/build.gradle b/app/build.gradle index 79cb37ff8..22de4b8b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/java/io/github/wulkanowy/data/DataModule.kt b/app/src/main/java/io/github/wulkanowy/data/DataModule.kt index e538b2b2f..c9e4990f9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/DataModule.kt +++ b/app/src/main/java/io/github/wulkanowy/data/DataModule.kt @@ -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( diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt index 50299e607..2292c3e62 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt @@ -22,6 +22,7 @@ data class Exam( val subject: String, + @Deprecated("not available anymore") val group: String, val type: String, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt index 17a9e5cdb..add6439d4 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt @@ -10,9 +10,9 @@ fun List.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, ) } diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt index bdb5efbba..173dfebf9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt @@ -11,7 +11,7 @@ fun List.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, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt index 6fc5dc950..a26d76651 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt @@ -26,7 +26,7 @@ fun List.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, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt index 1a1c501f6..1f4178fae 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt @@ -9,7 +9,7 @@ import io.github.wulkanowy.sdk.pojo.Token as SdkToken fun List.mapToEntities(student: Student) = map { MobileDevice( userLoginId = student.userLoginId, - date = it.createDateZoned.toInstant(), + date = it.createDate.toInstant(), deviceId = it.id, name = it.name ) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt index 2dfd7e062..bcf26a5e1 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt @@ -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 { diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt deleted file mode 100644 index a2110d7f5..000000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt +++ /dev/null @@ -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.mapToEntities(password: String = "", colors: List) = 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) - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt index e55aa3cf7..ee525e108 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt @@ -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.mapToEntities(semester: Semester) = map { +fun List.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.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(), ) } diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt index 4aea33771..98bf1402b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt +++ b/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt @@ -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, ) : 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, ) : java.io.Serializable diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt index cbaa12bd3..bec2797db 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt @@ -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>(inputStream) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt index fd5d8bd16..3afb99077 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt @@ -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 -> diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt index faa80b93e..013c0951d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt @@ -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 -> diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt index e5d7bc5cb..4101803f3 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt @@ -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 -> diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt index 96f019223..92bb37081 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt @@ -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 diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt index b1d1ba832..4c7069ef6 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt @@ -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 = - 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 = - 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 = - 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) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt index acd71e1f4..4e3b40f96 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt @@ -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 -> diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt index 26e1f3fff..136fb8d5b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt @@ -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) }, diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt index 37ab71dce..4f709438a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt @@ -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) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt index 8c90623e1..ead2d71af 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt @@ -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 } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt index 33a76e5f9..ab56bd786 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt @@ -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.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 { + 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 } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt index 824fa0288..34062d938 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt @@ -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 diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index bbc382190..43ba3fe1d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -204,6 +204,10 @@ class LoginFormFragment : BaseFragment(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}" diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index 8035ea0ad..ed70eb128 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -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(loginErrorHandler, studentRepository) { @@ -25,6 +27,7 @@ class LoginFormPresenter @Inject constructor( view.run { initView() showContact(false) + showOtherOptionsButton(appInfo.isDebug) showVersion() loginErrorHandler.onBadCredentials = { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 5a816fb32..e5c680d6f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -56,6 +56,8 @@ interface LoginFormView : BaseView { fun showContent(show: Boolean) + fun showOtherOptionsButton(show: Boolean) + fun showVersion() fun navigateToSymbol(loginData: LoginData) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt index 169702151..c33d12faa 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt @@ -55,7 +55,6 @@ class LoginStudentSelectFragment : } } - @Suppress("UNCHECKED_CAST") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentLoginStudentSelectBinding.bind(view) diff --git a/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt index 63a30db8c..481cad113 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt @@ -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") diff --git a/app/src/main/res/layout/fragment_login_form.xml b/app/src/main/res/layout/fragment_login_form.xml index fac3960e9..3bfe0c34f 100644 --- a/app/src/main/res/layout/fragment_login_form.xml +++ b/app/src/main/res/layout/fragment_login_form.xml @@ -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" diff --git a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt index 84a0cb405..c8d95829e 100644 --- a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt +++ b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt @@ -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 = "", diff --git a/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt b/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt index a35e5d303..ac73becdc 100644 --- a/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt @@ -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, diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt index 896491ef0..d0e500f19 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt @@ -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 { diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/ExamRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/ExamRemoteTest.kt index e3790662e..fb037a87e 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/ExamRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/ExamRemoteTest.kt @@ -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 = "", diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt index e8d0b6c8f..1d6dfaff0 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt @@ -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() - 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): Grades = Grades( + details = grades, + summary = listOf(), + isAverage = false, + isPoints = false, + isForAdults = false, + type = 0, + ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt index 9a2c22fd6..3a18ee979 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt @@ -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, diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt index 6865aa7da..1a3f96795 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt @@ -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), ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/SemesterRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/SemesterRepositoryTest.kt index 0ed008851..d8256869f 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/SemesterRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/SemesterRepositoryTest.kt @@ -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) } } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/StudentTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/StudentTest.kt deleted file mode 100644 index 9d3d7a2ec..000000000 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/StudentTest.kt +++ /dev/null @@ -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() - ) - } -} diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt index e56aaa5d0..92ad01b18 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt @@ -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 = "", diff --git a/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt b/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt index 6db16d2f5..f58a5381d 100644 --- a/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt +++ b/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt @@ -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 = "", diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt index 10c84efcf..b94002c0d 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt @@ -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) diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt index bf2d9f2cc..eb1f53006 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt @@ -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) } diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt index cf426a50b..da292c51c 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt @@ -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), )