1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-19 22:29:09 -05:00

SDK update (#2168)

This commit is contained in:
Mikołaj Pich 2023-05-07 23:21:59 +02:00 committed by GitHub
parent b195fda026
commit f8431d7ad6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 260 additions and 321 deletions

1
.gitignore vendored
View File

@ -119,3 +119,4 @@ Thumbs.db
app/src/release/agconnect-services.json app/src/release/agconnect-services.json
app/src/release/agconnect-credentials.json app/src/release/agconnect-credentials.json
.idea/deploymentTargetDropDown.xml .idea/deploymentTargetDropDown.xml
.idea/kotlinc.xml

View File

@ -186,7 +186,7 @@ ext {
} }
dependencies { 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' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'

View File

@ -20,7 +20,6 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.RemoteConfigHelper import io.github.wulkanowy.utils.RemoteConfigHelper
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -81,7 +80,6 @@ internal class DataModule {
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.build() .build()
@OptIn(ExperimentalSerializationApi::class)
@Singleton @Singleton
@Provides @Provides
fun provideRetrofit( fun provideRetrofit(

View File

@ -22,6 +22,7 @@ data class Exam(
val subject: String, val subject: String,
@Deprecated("not available anymore")
val group: String, val group: String,
val type: String, val type: String,

View File

@ -10,9 +10,9 @@ fun List<SdkConference>.mapToEntities(semester: Semester) = map {
diaryId = semester.diaryId, diaryId = semester.diaryId,
agenda = it.agenda, agenda = it.agenda,
conferenceId = it.id, conferenceId = it.id,
date = it.dateZoned.toInstant(), date = it.date.toInstant(),
presentOnConference = it.presentOnConference, presentOnConference = it.presentOnConference,
subject = it.subject, subject = it.topic,
title = it.title title = it.place,
) )
} }

View File

@ -11,7 +11,7 @@ fun List<SdkExam>.mapToEntities(semester: Semester) = map {
date = it.date, date = it.date,
entryDate = it.entryDate, entryDate = it.entryDate,
subject = it.subject, subject = it.subject,
group = it.group, group = "",
type = it.type, type = it.type,
description = it.description, description = it.description,
teacher = it.teacher, teacher = it.teacher,

View File

@ -26,7 +26,7 @@ fun List<SdkMessage>.mapToEntities(
messageId = it.id, messageId = it.id,
correspondents = it.correspondents, correspondents = it.correspondents,
subject = it.subject.trim(), subject = it.subject.trim(),
date = it.dateZoned.toInstant(), date = it.date.toInstant(),
folderId = it.folderId, folderId = it.folderId,
unread = it.unread, unread = it.unread,
unreadBy = it.unreadBy, unreadBy = it.unreadBy,

View File

@ -9,7 +9,7 @@ import io.github.wulkanowy.sdk.pojo.Token as SdkToken
fun List<SdkDevice>.mapToEntities(student: Student) = map { fun List<SdkDevice>.mapToEntities(student: Student) = map {
MobileDevice( MobileDevice(
userLoginId = student.userLoginId, userLoginId = student.userLoginId,
date = it.createDateZoned.toInstant(), date = it.createDate.toInstant(),
deviceId = it.id, deviceId = it.id,
name = it.name name = it.name
) )

View File

@ -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.Student
import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.pojos.* import io.github.wulkanowy.data.pojos.*
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.mapper.mapSemesters
import java.time.Instant import java.time.Instant
import io.github.wulkanowy.sdk.scrapper.register.RegisterStudent as SdkRegisterStudent import io.github.wulkanowy.sdk.pojo.RegisterStudent as SdkRegisterStudent
import io.github.wulkanowy.sdk.scrapper.register.RegisterUser as SdkRegisterUser import io.github.wulkanowy.sdk.pojo.RegisterUser as SdkRegisterUser
fun SdkRegisterUser.mapToPojo(password: String) = RegisterUser( fun SdkRegisterUser.mapToPojo(password: String?) = RegisterUser(
email = email, email = email,
login = login, login = login,
password = password, password = password,
baseUrl = baseUrl, scrapperBaseUrl = scrapperBaseUrl,
loginMode = loginMode,
loginType = loginType, loginType = loginType,
symbols = symbols.map { registerSymbol -> symbols = symbols.map { registerSymbol ->
RegisterSymbol( RegisterSymbol(
symbol = registerSymbol.symbol, symbol = registerSymbol.symbol,
error = registerSymbol.error, error = registerSymbol.error,
hebeBaseUrl = registerSymbol.hebeBaseUrl,
keyId = registerSymbol.keyId,
privatePem = registerSymbol.privatePem,
userName = registerSymbol.userName, userName = registerSymbol.userName,
schools = registerSymbol.schools.map { schools = registerSymbol.schools.map {
RegisterUnit( RegisterUnit(
@ -42,14 +44,13 @@ fun SdkRegisterUser.mapToPojo(password: String) = RegisterUser(
classId = registerSubject.classId, classId = registerSubject.classId,
isParent = registerSubject.isParent, isParent = registerSubject.isParent,
semesters = registerSubject.semesters semesters = registerSubject.semesters
.mapSemesters()
.mapToEntities(registerSubject.studentId), .mapToEntities(registerSubject.studentId),
) )
}, },
) )
} }
) )
} },
) )
fun RegisterStudent.mapToStudentWithSemesters( fun RegisterStudent.mapToStudentWithSemesters(
@ -68,17 +69,17 @@ fun RegisterStudent.mapToStudentWithSemesters(
classId = classId, classId = classId,
studentId = studentId, studentId = studentId,
symbol = symbol.symbol, symbol = symbol.symbol,
loginType = user.loginType.name, loginType = user.loginType?.name.orEmpty(),
schoolName = unit.schoolName, schoolName = unit.schoolName,
schoolShortName = unit.schoolShortName, schoolShortName = unit.schoolShortName,
schoolSymbol = unit.schoolId, schoolSymbol = unit.schoolId,
studentName = "$studentName $studentSurname", studentName = "$studentName $studentSurname",
loginMode = Sdk.Mode.SCRAPPER.name, loginMode = user.loginMode.name,
scrapperBaseUrl = user.baseUrl, scrapperBaseUrl = user.scrapperBaseUrl.orEmpty(),
mobileBaseUrl = "", mobileBaseUrl = symbol.hebeBaseUrl.orEmpty(),
certificateKey = "", certificateKey = symbol.keyId.orEmpty(),
privateKey = "", privateKey = symbol.privatePem.orEmpty(),
password = user.password, password = user.password.orEmpty(),
isCurrent = false, isCurrent = false,
registrationDate = Instant.now(), registrationDate = Instant.now(),
).apply { ).apply {

View File

@ -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)
)
}

View File

@ -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.TimetableAdditional
import io.github.wulkanowy.data.db.entities.TimetableHeader import io.github.wulkanowy.data.db.entities.TimetableHeader
import io.github.wulkanowy.data.pojos.TimetableFull 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.TimetableDayHeader as SdkTimetableHeader
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable import io.github.wulkanowy.sdk.pojo.Lesson as SdkLesson
import io.github.wulkanowy.sdk.pojo.TimetableAdditional as SdkTimetableAdditional import io.github.wulkanowy.sdk.pojo.LessonAdditional as SdkTimetableAdditional
fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull( fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull(
lessons = lessons.mapToEntities(semester), lessons = lessons.mapToEntities(semester),
@ -16,13 +16,13 @@ fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull(
headers = headers.mapToEntities(semester) headers = headers.mapToEntities(semester)
) )
fun List<SdkTimetable>.mapToEntities(semester: Semester) = map { fun List<SdkLesson>.mapToEntities(semester: Semester) = map {
Timetable( Timetable(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
number = it.number, number = it.number,
start = it.startZoned.toInstant(), start = it.start.toInstant(),
end = it.endZoned.toInstant(), end = it.end.toInstant(),
date = it.date, date = it.date,
subject = it.subject, subject = it.subject,
subjectOld = it.subjectOld, subjectOld = it.subjectOld,
@ -45,8 +45,8 @@ fun List<SdkTimetableAdditional>.mapToEntities(semester: Semester) = map {
diaryId = semester.diaryId, diaryId = semester.diaryId,
subject = it.subject, subject = it.subject,
date = it.date, date = it.date,
start = it.startZoned.toInstant(), start = it.start.toInstant(),
end = it.endZoned.toInstant(), end = it.end.toInstant(),
) )
} }

View File

@ -1,20 +1,25 @@
package io.github.wulkanowy.data.pojos package io.github.wulkanowy.data.pojos
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
data class RegisterUser( data class RegisterUser(
val email: String, val email: String,
val password: String, val password: String?,
val login: String, // may be the same as email val login: String, // may be the same as email
val baseUrl: String, val scrapperBaseUrl: String?,
val loginType: Scrapper.LoginType, val loginType: Scrapper.LoginType?,
val loginMode: Sdk.Mode,
val symbols: List<RegisterSymbol>, val symbols: List<RegisterSymbol>,
) : java.io.Serializable ) : java.io.Serializable
data class RegisterSymbol( data class RegisterSymbol(
val symbol: String, val symbol: String,
val error: Throwable?, val error: Throwable?,
val hebeBaseUrl: String?,
val keyId: String?,
val privatePem: String?,
val userName: String, val userName: String,
val schools: List<RegisterUnit>, val schools: List<RegisterUnit>,
) : java.io.Serializable ) : java.io.Serializable

View File

@ -19,7 +19,6 @@ class AppCreatorRepository @Inject constructor(
) { ) {
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
@Suppress("BlockingMethodInNonBlockingContext")
suspend fun getAppCreators() = withContext(dispatchers.io) { suspend fun getAppCreators() = withContext(dispatchers.io) {
val inputStream = context.assets.open("contributors.json").buffered() val inputStream = context.assets.open("contributors.json").buffered()
json.decodeFromStream<List<Contributor>>(inputStream) json.decodeFromStream<List<Contributor>>(inputStream)

View File

@ -59,7 +59,7 @@ class AttendanceRepository @Inject constructor(
} }
sdk.init(student) sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear) .switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getAttendance(start.monday, end.sunday, semester.semesterId) .getAttendance(start.monday, end.sunday)
.mapToEntities(semester, lessons) .mapToEntities(semester, lessons)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->

View File

@ -52,7 +52,7 @@ class ExamRepository @Inject constructor(
fetch = { fetch = {
sdk.init(student) sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear) .switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getExams(start.startExamsDay, start.endExamsDay, semester.semesterId) .getExams(start.startExamsDay, start.endExamsDay)
.mapToEntities(semester) .mapToEntities(semester)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->

View File

@ -42,7 +42,7 @@ class NoteRepository @Inject constructor(
fetch = { fetch = {
sdk.init(student) sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear) .switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getNotes(semester.semesterId) .getNotes()
.mapToEntities(semester) .mapToEntities(semester)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->

View File

@ -40,7 +40,7 @@ class SemesterRepository @Inject constructor(
val isNoSemesters = semesters.isEmpty() val isNoSemesters = semesters.isEmpty()
val isRefreshOnModeChangeRequired = when { val isRefreshOnModeChangeRequired = when {
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> { Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE -> {
semesters.firstOrNull { it.isCurrent }?.let { semesters.firstOrNull { it.isCurrent }?.let {
0 == it.diaryId && 0 == it.kindergartenDiaryId 0 == it.diaryId && 0 == it.kindergartenDiaryId
} == true } == true

View File

@ -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.StudentNickAndAvatar
import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.mappers.mapToPojo import io.github.wulkanowy.data.mappers.mapToPojo
import io.github.wulkanowy.data.pojos.RegisterUser import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.DispatchersProvider import io.github.wulkanowy.utils.DispatchersProvider
import io.github.wulkanowy.utils.security.decrypt import io.github.wulkanowy.utils.security.decrypt
import io.github.wulkanowy.utils.security.encrypt import io.github.wulkanowy.utils.security.encrypt
@ -29,37 +27,35 @@ class StudentRepository @Inject constructor(
private val studentDb: StudentDao, private val studentDb: StudentDao,
private val semesterDb: SemesterDao, private val semesterDb: SemesterDao,
private val sdk: Sdk, private val sdk: Sdk,
private val appInfo: AppInfo,
private val appDatabase: AppDatabase private val appDatabase: AppDatabase
) { ) {
suspend fun isStudentSaved() = getSavedStudents(false).isNotEmpty()
suspend fun isCurrentStudentSet() = studentDb.loadCurrent()?.isCurrent ?: false suspend fun isCurrentStudentSet() = studentDb.loadCurrent()?.isCurrent ?: false
suspend fun getStudentsApi( suspend fun getStudentsApi(
pin: String, pin: String,
symbol: String, symbol: String,
token: String token: String
): List<StudentWithSemesters> = ): RegisterUser = sdk
sdk.getStudentsFromMobileApi(token, pin, symbol, "") .getStudentsFromHebe(token, pin, symbol, "")
.mapToEntities(colors = appInfo.defaultColorsForAvatar) .mapToPojo(null)
suspend fun getStudentsScrapper( suspend fun getStudentsScrapper(
email: String, email: String,
password: String, password: String,
scrapperBaseUrl: String, scrapperBaseUrl: String,
symbol: String symbol: String
): List<StudentWithSemesters> = ): RegisterUser = sdk
sdk.getStudentsFromScrapper(email, password, scrapperBaseUrl, symbol) .getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
.mapToEntities(password, appInfo.defaultColorsForAvatar) .mapToPojo(password)
suspend fun getUserSubjectsFromScrapper( suspend fun getUserSubjectsFromScrapper(
email: String, email: String,
password: String, password: String,
scrapperBaseUrl: String, scrapperBaseUrl: String,
symbol: String symbol: String
): RegisterUser = sdk.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol) ): RegisterUser = sdk
.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
.mapToPojo(password) .mapToPojo(password)
suspend fun getStudentsHybrid( suspend fun getStudentsHybrid(
@ -67,15 +63,15 @@ class StudentRepository @Inject constructor(
password: String, password: String,
scrapperBaseUrl: String, scrapperBaseUrl: String,
symbol: String symbol: String
): List<StudentWithSemesters> = ): RegisterUser = sdk
sdk.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol) .getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol)
.mapToEntities(password, appInfo.defaultColorsForAvatar) .mapToPojo(password)
suspend fun getSavedStudents(decryptPass: Boolean = true) = suspend fun getSavedStudents(decryptPass: Boolean = true) =
studentDb.loadStudentsWithSemesters() studentDb.loadStudentsWithSemesters()
.map { .map {
it.apply { 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) { student.password = withContext(dispatchers.io) {
decrypt(student.password) decrypt(student.password)
} }
@ -85,7 +81,7 @@ class StudentRepository @Inject constructor(
suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true) = suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true) =
studentDb.loadStudentWithSemestersById(id)?.apply { 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) { student.password = withContext(dispatchers.io) {
decrypt(student.password) decrypt(student.password)
} }
@ -95,7 +91,7 @@ class StudentRepository @Inject constructor(
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student { suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
val student = studentDb.loadById(id) ?: throw NoCurrentStudentException() val student = studentDb.loadById(id) ?: throw 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) { student.password = withContext(dispatchers.io) {
decrypt(student.password) decrypt(student.password)
} }
@ -106,7 +102,7 @@ class StudentRepository @Inject constructor(
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student { suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException() 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) { student.password = withContext(dispatchers.io) {
decrypt(student.password) decrypt(student.password)
} }
@ -119,7 +115,7 @@ class StudentRepository @Inject constructor(
val students = studentsWithSemesters.map { it.student } val students = studentsWithSemesters.map { it.student }
.map { .map {
it.apply { it.apply {
if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.API) { if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.HEBE) {
password = withContext(dispatchers.io) { password = withContext(dispatchers.io) {
encrypt(password, context) encrypt(password, context)
} }

View File

@ -40,7 +40,7 @@ class TeacherRepository @Inject constructor(
fetch = { fetch = {
sdk.init(student) sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear) .switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getTeachers(semester.semesterId) .getTeachers()
.mapToEntities(semester) .mapToEntities(semester)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->

View File

@ -66,7 +66,7 @@ class TimetableRepository @Inject constructor(
fetch = { fetch = {
val timetableFull = sdk.init(student) val timetableFull = sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear) .switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getTimetableFull(start.monday, end.sunday) .getTimetable(start.monday, end.sunday)
timetableFull.mapToEntities(semester) timetableFull.mapToEntities(semester)
}, },

View File

@ -4,13 +4,15 @@ import android.content.Context
import android.database.sqlite.SQLiteConstraintException import android.database.sqlite.SQLiteConstraintException
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.mobile.exception.InvalidPinException import io.github.wulkanowy.sdk.hebe.exception.InvalidPinException
import io.github.wulkanowy.sdk.mobile.exception.InvalidSymbolException import io.github.wulkanowy.sdk.hebe.exception.InvalidTokenException
import io.github.wulkanowy.sdk.mobile.exception.InvalidTokenException import io.github.wulkanowy.sdk.hebe.exception.TokenDeadException
import io.github.wulkanowy.sdk.mobile.exception.TokenDeadException import io.github.wulkanowy.sdk.hebe.exception.UnknownTokenException
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.base.ErrorHandler
import javax.inject.Inject 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( class LoginErrorHandler @Inject constructor(
@ApplicationContext context: Context, @ApplicationContext context: Context,
@ -32,9 +34,11 @@ class LoginErrorHandler @Inject constructor(
is BadCredentialsException -> onBadCredentials(error.message) is BadCredentialsException -> onBadCredentials(error.message)
is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student)) is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student))
is TokenDeadException -> onInvalidToken(resources.getString(R.string.login_expired_token)) is TokenDeadException -> onInvalidToken(resources.getString(R.string.login_expired_token))
is UnknownTokenException,
is InvalidTokenException -> onInvalidToken(resources.getString(R.string.login_invalid_token)) is InvalidTokenException -> onInvalidToken(resources.getString(R.string.login_invalid_token))
is InvalidPinException -> onInvalidPin(resources.getString(R.string.login_invalid_pin)) 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) else -> super.proceed(error)
} }
} }

View File

@ -34,9 +34,9 @@ class LoginAdvancedFragment :
override val formLoginType: String override val formLoginType: String
get() = when (binding.loginTypeSwitch.checkedRadioButtonId) { get() = when (binding.loginTypeSwitch.checkedRadioButtonId) {
R.id.loginTypeApi -> "API" R.id.loginTypeApi -> Sdk.Mode.HEBE.name
R.id.loginTypeScrapper -> "SCRAPPER" R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER.name
else -> "HYBRID" else -> Sdk.Mode.HYBRID.name
} }
override val formUsernameValue: String override val formUsernameValue: String
@ -99,7 +99,7 @@ class LoginAdvancedFragment :
loginTypeSwitch.setOnCheckedChangeListener { _, checkedId -> loginTypeSwitch.setOnCheckedChangeListener { _, checkedId ->
presenter.onLoginModeSelected( presenter.onLoginModeSelected(
when (checkedId) { when (checkedId) {
R.id.loginTypeApi -> Sdk.Mode.API R.id.loginTypeApi -> Sdk.Mode.HEBE
R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER
else -> Sdk.Mode.HYBRID else -> Sdk.Mode.HYBRID
} }

View File

@ -1,17 +1,12 @@
package io.github.wulkanowy.ui.modules.login.advanced package io.github.wulkanowy.ui.modules.login.advanced
import io.github.wulkanowy.data.Resource 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.logResourceStatus
import io.github.wulkanowy.data.onResourceNotLoading 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.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginData
@ -97,14 +92,16 @@ class LoginAdvancedPresenter @Inject constructor(
fun onLoginModeSelected(type: Sdk.Mode) { fun onLoginModeSelected(type: Sdk.Mode) {
view?.run { view?.run {
when (type) { when (type) {
Sdk.Mode.API -> { Sdk.Mode.HEBE -> {
showOnlyMobileApiModeInputs() showOnlyMobileApiModeInputs()
showMobileApiWarningMessage() showMobileApiWarningMessage()
} }
Sdk.Mode.SCRAPPER -> { Sdk.Mode.SCRAPPER -> {
showOnlyScrapperModeInputs() showOnlyScrapperModeInputs()
showScraperWarningMessage() showScraperWarningMessage()
} }
Sdk.Mode.HYBRID -> { Sdk.Mode.HYBRID -> {
showOnlyHybridModeInputs() showOnlyHybridModeInputs()
showHybridWarningMessage() showHybridWarningMessage()
@ -145,11 +142,12 @@ class LoginAdvancedPresenter @Inject constructor(
showProgress(true) showProgress(true)
showContent(false) showContent(false)
} }
is Resource.Success -> { is Resource.Success -> {
analytics.logEvent( analytics.logEvent(
"registration_form", "registration_form",
"success" to true, "success" to true,
"students" to it.data.size, "scrapperBaseUrl" to view?.formHostValue.orEmpty(),
"error" to "No error" "error" to "No error"
) )
val loginData = LoginData( val loginData = LoginData(
@ -158,14 +156,15 @@ class LoginAdvancedPresenter @Inject constructor(
baseUrl = view?.formHostValue.orEmpty().trim(), baseUrl = view?.formHostValue.orEmpty().trim(),
symbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(), symbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(),
) )
when (it.data.size) { when (it.data.symbols.size) {
0 -> view?.navigateToSymbol(loginData) 0 -> view?.navigateToSymbol(loginData)
else -> view?.navigateToStudentSelect( else -> view?.navigateToStudentSelect(
loginData = loginData, loginData = loginData,
registerUser = it.data.toRegisterUser(loginData), registerUser = it.data,
) )
} }
} }
is Resource.Error -> { is Resource.Error -> {
analytics.logEvent( analytics.logEvent(
"registration_form", "registration_form",
@ -183,59 +182,7 @@ class LoginAdvancedPresenter @Inject constructor(
}.launch("login") }.launch("login")
} }
private fun List<StudentWithSemesters>.toRegisterUser(loginData: LoginData) = RegisterUser( private suspend fun getStudentsAppropriatesToLoginType(): 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> {
val email = view?.formUsernameValue.orEmpty() val email = view?.formUsernameValue.orEmpty()
val password = view?.formPassValue.orEmpty() val password = view?.formPassValue.orEmpty()
val endpoint = view?.formHostValue.orEmpty() val endpoint = view?.formHostValue.orEmpty()
@ -245,10 +192,11 @@ class LoginAdvancedPresenter @Inject constructor(
val token = view?.formTokenValue.orEmpty() val token = view?.formTokenValue.orEmpty()
return when (Sdk.Mode.valueOf(view?.formLoginType.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( Sdk.Mode.SCRAPPER -> studentRepository.getStudentsScrapper(
email, password, endpoint, symbol email, password, endpoint, symbol
) )
Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid( Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid(
email, password, endpoint, symbol email, password, endpoint, symbol
) )
@ -267,8 +215,8 @@ class LoginAdvancedPresenter @Inject constructor(
var isCorrect = true var isCorrect = true
when (Sdk.Mode.valueOf(view?.formLoginType ?: "")) { when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) {
Sdk.Mode.API -> { Sdk.Mode.HEBE -> {
if (pin.isEmpty()) { if (pin.isEmpty()) {
view?.setErrorPinRequired() view?.setErrorPinRequired()
isCorrect = false isCorrect = false
@ -284,17 +232,17 @@ class LoginAdvancedPresenter @Inject constructor(
isCorrect = false isCorrect = false
} }
} }
Sdk.Mode.HYBRID, Sdk.Mode.SCRAPPER -> { Sdk.Mode.HYBRID, Sdk.Mode.SCRAPPER -> {
if (login.isEmpty()) { if (login.isEmpty()) {
view?.setErrorUsernameRequired() view?.setErrorUsernameRequired()
isCorrect = false isCorrect = false
} else { } else {
if ("@" in login && "standard" !in host) { if ("@" in login && "login" in host) {
view?.setErrorLoginRequired() view?.setErrorLoginRequired()
isCorrect = false isCorrect = false
} }
if ("@" !in login && "email" in host) {
if ("@" !in login && "standard" in host) {
view?.setErrorEmailRequired() view?.setErrorEmailRequired()
isCorrect = false isCorrect = false
} }

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.login.advanced 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.data.pojos.RegisterUser
import io.github.wulkanowy.ui.base.BaseView import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginData

View File

@ -204,6 +204,10 @@ class LoginFormFragment : BaseFragment<FragmentLoginFormBinding>(R.layout.fragme
binding.loginFormContainer.visibility = if (show) VISIBLE else GONE binding.loginFormContainer.visibility = if (show) VISIBLE else GONE
} }
override fun showOtherOptionsButton(show: Boolean) {
binding.loginFormAdvancedButton.isVisible = show
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun showVersion() { override fun showVersion() {
binding.loginFormVersion.text = "v${appInfo.versionName}" binding.loginFormVersion.text = "v${appInfo.versionName}"

View File

@ -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.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.ifNullOrBlank import io.github.wulkanowy.utils.ifNullOrBlank
import timber.log.Timber import timber.log.Timber
import java.net.URL import java.net.URL
@ -15,6 +16,7 @@ import javax.inject.Inject
class LoginFormPresenter @Inject constructor( class LoginFormPresenter @Inject constructor(
studentRepository: StudentRepository, studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler, private val loginErrorHandler: LoginErrorHandler,
private val appInfo: AppInfo,
private val analytics: AnalyticsHelper private val analytics: AnalyticsHelper
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository) { ) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository) {
@ -25,6 +27,7 @@ class LoginFormPresenter @Inject constructor(
view.run { view.run {
initView() initView()
showContact(false) showContact(false)
showOtherOptionsButton(appInfo.isDebug)
showVersion() showVersion()
loginErrorHandler.onBadCredentials = { loginErrorHandler.onBadCredentials = {

View File

@ -56,6 +56,8 @@ interface LoginFormView : BaseView {
fun showContent(show: Boolean) fun showContent(show: Boolean)
fun showOtherOptionsButton(show: Boolean)
fun showVersion() fun showVersion()
fun navigateToSymbol(loginData: LoginData) fun navigateToSymbol(loginData: LoginData)

View File

@ -55,7 +55,6 @@ class LoginStudentSelectFragment :
} }
} }
@Suppress("UNCHECKED_CAST")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginStudentSelectBinding.bind(view) binding = FragmentLoginStudentSelectBinding.bind(view)

View File

@ -12,18 +12,17 @@ fun Sdk.init(student: Student): Sdk {
studentId = student.studentId studentId = student.studentId
classId = student.classId 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 scrapperBaseUrl = student.scrapperBaseUrl
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType) loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
} }
loginId = student.userLoginId
mode = Sdk.Mode.valueOf(student.loginMode) mode = Sdk.Mode.valueOf(student.loginMode)
mobileBaseUrl = student.mobileBaseUrl mobileBaseUrl = student.mobileBaseUrl
certKey = student.certificateKey keyId = student.certificateKey
privateKey = student.privateKey privatePem = student.privateKey
emptyCookieJarInterceptor = true
Timber.d("Sdk in ${student.loginMode} mode reinitialized") Timber.d("Sdk in ${student.loginMode} mode reinitialized")

View File

@ -247,7 +247,6 @@
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:text="@string/login_advanced" android:text="@string/login_advanced"
android:textAppearance="?android:textAppearance" android:textAppearance="?android:textAppearance"
android:visibility="gone"
app:backgroundTint="?android:windowBackground" app:backgroundTint="?android:windowBackground"
app:fontFamily="sans-serif-medium" app:fontFamily="sans-serif-medium"
app:layout_constraintBottom_toBottomOf="@id/loginFormSignIn" app:layout_constraintBottom_toBottomOf="@id/loginFormSignIn"

View File

@ -48,7 +48,7 @@ fun getSemesterPojo(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalD
end = end, end = end,
) )
fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.API) = Student( fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.HEBE) = Student(
scrapperBaseUrl = "http://fakelog.cf", scrapperBaseUrl = "http://fakelog.cf",
email = "jan@fakelog.cf", email = "jan@fakelog.cf",
certificateKey = "", certificateKey = "",

View File

@ -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.Semester
import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.sdk.pojo.Attendance 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 org.junit.Test
import java.time.Instant import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
@ -98,7 +98,7 @@ class AttendanceMapperTest {
timeId = 1, timeId = 1,
categoryId = 1, categoryId = 1,
deleted = false, deleted = false,
excuseStatus = SentExcuse.Status.WAITING, excuseStatus = SentExcuseStatus.WAITING,
excusable = false, excusable = false,
absence = false, absence = false,
excused = false, excused = false,

View File

@ -63,7 +63,7 @@ class AttendanceRepositoryTest {
@Test @Test
fun `force refresh without difference`() { fun `force refresh without difference`() {
// prepare // 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( coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
flowOf(remoteList.mapToEntities(semester, emptyList())), flowOf(remoteList.mapToEntities(semester, emptyList())),
flowOf(remoteList.mapToEntities(semester, emptyList())) flowOf(remoteList.mapToEntities(semester, emptyList()))
@ -77,7 +77,7 @@ class AttendanceRepositoryTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(2, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, endDate) }
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) } coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) } coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) }
@ -86,7 +86,7 @@ class AttendanceRepositoryTest {
@Test @Test
fun `force refresh with more items in remote`() { fun `force refresh with more items in remote`() {
// prepare // 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( coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())),
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), // after fetch end before save result flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), // after fetch end before save result
@ -101,7 +101,7 @@ class AttendanceRepositoryTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(2, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, endDate) }
coVerify { coVerify {
attendanceDb.insertAll(match { attendanceDb.insertAll(match {
@ -114,7 +114,7 @@ class AttendanceRepositoryTest {
@Test @Test
fun `force refresh with more items in local`() { fun `force refresh with more items in local`() {
// prepare // 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( coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
flowOf(remoteList.mapToEntities(semester, emptyList())), flowOf(remoteList.mapToEntities(semester, emptyList())),
flowOf(remoteList.mapToEntities(semester, emptyList())), // after fetch end before save result flowOf(remoteList.mapToEntities(semester, emptyList())), // after fetch end before save result
@ -129,7 +129,7 @@ class AttendanceRepositoryTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(1, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, endDate) }
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) } coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
coVerify { coVerify {

View File

@ -59,7 +59,7 @@ class ExamRemoteTest {
@Test @Test
fun `force refresh without difference`() { fun `force refresh without difference`() {
// prepare // 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( coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
flowOf(remoteList.mapToEntities(semester)), flowOf(remoteList.mapToEntities(semester)),
flowOf(remoteList.mapToEntities(semester)) flowOf(remoteList.mapToEntities(semester))
@ -73,7 +73,7 @@ class ExamRemoteTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(2, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, realEndDate) }
coVerify { examDb.insertAll(match { it.isEmpty() }) } coVerify { examDb.insertAll(match { it.isEmpty() }) }
coVerify { examDb.deleteAll(match { it.isEmpty() }) } coVerify { examDb.deleteAll(match { it.isEmpty() }) }
@ -82,7 +82,7 @@ class ExamRemoteTest {
@Test @Test
fun `force refresh with more items in remote`() { fun `force refresh with more items in remote`() {
// prepare // 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( coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
flowOf(remoteList.dropLast(1).mapToEntities(semester)), flowOf(remoteList.dropLast(1).mapToEntities(semester)),
flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result
@ -97,7 +97,7 @@ class ExamRemoteTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(2, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, realEndDate) }
coVerify { coVerify {
examDb.insertAll(match { examDb.insertAll(match {
@ -110,7 +110,7 @@ class ExamRemoteTest {
@Test @Test
fun `force refresh with more items in local`() { fun `force refresh with more items in local`() {
// prepare // 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( coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
flowOf(remoteList.mapToEntities(semester)), flowOf(remoteList.mapToEntities(semester)),
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
@ -125,7 +125,7 @@ class ExamRemoteTest {
// verify // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(1, res.dataOrNull?.size) 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.loadAll(1, 1, startDate, realEndDate) }
coVerify { examDb.insertAll(match { it.isEmpty() }) } coVerify { examDb.insertAll(match { it.isEmpty() }) }
coVerify { coVerify {
@ -137,7 +137,6 @@ class ExamRemoteTest {
private fun getExam(date: LocalDate) = SdkExam( private fun getExam(date: LocalDate) = SdkExam(
subject = "", subject = "",
group = "",
type = "", type = "",
description = "", description = "",
teacher = "", teacher = "",

View File

@ -9,13 +9,21 @@ import io.github.wulkanowy.data.toFirstResult
import io.github.wulkanowy.getSemesterEntity import io.github.wulkanowy.getSemesterEntity
import io.github.wulkanowy.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Grades
import io.github.wulkanowy.utils.AutoRefreshHelper 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.MockK
import io.mockk.impl.annotations.SpyK import io.mockk.impl.annotations.SpyK
import io.mockk.just
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking 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.Before
import org.junit.Test import org.junit.Test
import java.time.LocalDate 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, 27), "Ocena z dnia logowania"),
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza") 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( coEvery { gradeDb.loadAll(1, 1) } returnsMany listOf(
flowOf(listOf()), // empty because it is new user 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") 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( val localList = listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Jedna ocena"), 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(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna 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( val localList = listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), 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(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), // will be added...
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna 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( val localList = listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), 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(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna 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( coEvery { gradeDb.loadAll(1, 1) } returnsMany listOf(
flowOf(listOf()), flowOf(listOf()),
@ -250,7 +258,7 @@ class GradeRepositoryTest {
fun `force refresh when remote is empty`() { fun `force refresh when remote is empty`() {
// prepare // prepare
val remoteList = emptyList<SdkGrade>() val remoteList = emptyList<SdkGrade>()
coEvery { sdk.getGrades(semester.semesterId) } returns (remoteList to emptyList()) coEvery { sdk.getGrades(semester.semesterId) } returns createGrades(remoteList)
val localList = listOf( val localList = listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
@ -284,4 +292,13 @@ class GradeRepositoryTest {
weight = weight.toString(), weight = weight.toString(),
weightValue = weight weightValue = weight
) )
private fun createGrades(grades: List<SdkGrade>): Grades = Grades(
details = grades,
summary = listOf(),
isAverage = false,
isPoints = false,
isForAdults = false,
type = 0,
)
} }

View File

@ -224,7 +224,7 @@ class MessageRepositoryTest {
recipients = listOf(), recipients = listOf(),
subject = "", subject = "",
content = "Test", content = "Test",
dateZoned = Instant.EPOCH.atZone(ZoneOffset.UTC), date = Instant.EPOCH.atZone(ZoneOffset.UTC),
folderId = 1, folderId = 1,
unread = true, unread = true,
readBy = 1, readBy = 1,

View File

@ -10,16 +10,21 @@ import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Device import io.github.wulkanowy.sdk.pojo.Device
import io.github.wulkanowy.utils.AutoRefreshHelper 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.MockK
import io.mockk.impl.annotations.SpyK import io.mockk.impl.annotations.SpyK
import io.mockk.just
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.time.LocalDateTime.of import java.time.ZoneOffset
import java.time.ZoneId import java.time.ZonedDateTime.of
class MobileDeviceRepositoryTest { class MobileDeviceRepositoryTest {
@ -134,9 +139,7 @@ class MobileDeviceRepositoryTest {
id = 0, id = 0,
name = "", name = "",
deviceId = "", deviceId = "",
createDate = of(2019, 5, day, 0, 0, 0), createDate = of(2019, 5, day, 0, 0, 0, 0, ZoneOffset.UTC),
modificationDate = of(2019, 5, day, 0, 0, 0), modificationDate = of(2019, 5, day, 0, 0, 0, 0, ZoneOffset.UTC),
createDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault()),
modificationDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault())
) )
} }

View File

@ -75,7 +75,7 @@ class SemesterRepositoryTest {
coEvery { semesterDb.deleteAll(any()) } just Runs coEvery { semesterDb.deleteAll(any()) } just Runs
coEvery { semesterDb.insertSemesters(any()) } returns listOf() 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(2, items.size)
assertEquals(0, items[0].diaryId) assertEquals(0, items[0].diaryId)
} }
@ -215,6 +215,7 @@ class SemesterRepositoryTest {
@Test(expected = RuntimeException::class) @Test(expected = RuntimeException::class)
fun getCurrentSemester_emptyList() { fun getCurrentSemester_emptyList() {
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList() coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
coEvery { sdk.getSemesters() } returns emptyList()
runBlocking { semesterRepository.getCurrentSemester(student) } runBlocking { semesterRepository.getCurrentSemester(student) }
} }

View File

@ -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()
)
}
}

View File

@ -10,12 +10,17 @@ import io.github.wulkanowy.data.toFirstResult
import io.github.wulkanowy.getSemesterEntity import io.github.wulkanowy.getSemesterEntity
import io.github.wulkanowy.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.TimetableFull
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
import io.github.wulkanowy.utils.AutoRefreshHelper 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.MockK
import io.mockk.impl.annotations.SpyK import io.mockk.impl.annotations.SpyK
import io.mockk.just
import io.mockk.mockk
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -25,7 +30,7 @@ import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.LocalDateTime.of import java.time.LocalDateTime.of
import java.time.ZoneId import java.time.ZoneId
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable import io.github.wulkanowy.sdk.pojo.Lesson as SdkLesson
class TimetableRepositoryTest { class TimetableRepositoryTest {
@ -62,18 +67,43 @@ class TimetableRepositoryTest {
MockKAnnotations.init(this) MockKAnnotations.init(this)
every { refreshHelper.shouldBeRefreshed(any()) } returns false every { refreshHelper.shouldBeRefreshed(any()) } returns false
timetableRepository = TimetableRepository(timetableDb, timetableAdditionalDao, timetableHeaderDao, sdk, timetableNotificationSchedulerHelper, refreshHelper) timetableRepository = TimetableRepository(
timetableDb,
timetableAdditionalDao,
timetableHeaderDao,
sdk,
timetableNotificationSchedulerHelper,
refreshHelper
)
} }
@Test @Test
fun `force refresh without difference`() { fun `force refresh without difference`() {
val remoteList = listOf( val remoteList = listOf(
createTimetableRemote(of(2021, 1, 4, 8, 0), 1, "123", "Język polski", "Jan Kowalski", false), createTimetableRemote(
createTimetableRemote(of(2021, 1, 4, 8, 50), 2, "124", "Język niemiecki", "Joanna Czarniecka", true) 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 // 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( coEvery { timetableDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
flowOf(remoteList.mapToEntities(semester)), flowOf(remoteList.mapToEntities(semester)),
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.insertAll(any()) } returns listOf(1, 2, 3)
coEvery { timetableDb.deleteAll(any()) } just Runs 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.deleteAll(emptyList()) } just Runs
coEvery { timetableAdditionalDao.insertAll(emptyList()) } returns listOf(1, 2, 3) coEvery { timetableAdditionalDao.insertAll(emptyList()) } returns listOf(1, 2, 3)
@ -90,23 +127,36 @@ class TimetableRepositoryTest {
coEvery { timetableHeaderDao.deleteAll(emptyList()) } just Runs coEvery { timetableHeaderDao.deleteAll(emptyList()) } just Runs
// execute // 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 // verify
assertEquals(null, res.errorOrNull) assertEquals(null, res.errorOrNull)
assertEquals(2, res.dataOrNull!!.lessons.size) 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.loadAll(1, 1, startDate, endDate) }
coVerify { timetableDb.insertAll(match { it.isEmpty() }) } coVerify { timetableDb.insertAll(match { it.isEmpty() }) }
coVerify { timetableDb.deleteAll(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, number = number,
start = start, start = start.atZone(ZoneId.systemDefault()),
end = start.plusMinutes(45), end = start.plusMinutes(45).atZone(ZoneId.systemDefault()),
startZoned = start.atZone(ZoneId.systemDefault()),
endZoned = start.plusMinutes(45).atZone(ZoneId.systemDefault()),
date = start.toLocalDate(), date = start.toLocalDate(),
subject = subject, subject = subject,
group = "", group = "",

View File

@ -207,7 +207,7 @@ class GetMailboxByStudentUseCaseTest {
className = "", className = "",
isCurrent = false, isCurrent = false,
isParent = false, isParent = false,
loginMode = Sdk.Mode.API.name, loginMode = Sdk.Mode.HEBE.name,
loginType = Sdk.ScrapperLoginType.STANDARD.name, loginType = Sdk.ScrapperLoginType.STANDARD.name,
mobileBaseUrl = "", mobileBaseUrl = "",
password = "", password = "",

View File

@ -456,7 +456,7 @@ class GradeAverageProviderTest {
@Test @Test
fun `force calc current semester average with custom modifiers in api mode`() { 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.gradeAverageForceCalcFlow } returns flowOf(true)
every { preferencesRepository.isOptionalArithmeticAverageFlow } returns flowOf(false) every { preferencesRepository.isOptionalArithmeticAverageFlow } returns flowOf(false)

View File

@ -3,11 +3,18 @@ package io.github.wulkanowy.ui.modules.login.form
import io.github.wulkanowy.MainCoroutineRule import io.github.wulkanowy.MainCoroutineRule
import io.github.wulkanowy.data.pojos.RegisterUser import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper 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.impl.annotations.MockK
import io.mockk.just
import io.mockk.verify
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -30,13 +37,17 @@ class LoginFormPresenterTest {
@MockK(relaxed = true) @MockK(relaxed = true)
lateinit var analytics: AnalyticsHelper lateinit var analytics: AnalyticsHelper
@MockK
lateinit var appInfo: AppInfo
private lateinit var presenter: LoginFormPresenter private lateinit var presenter: LoginFormPresenter
private val registerUser = RegisterUser( private val registerUser = RegisterUser(
email = "", email = "",
password = "", password = "",
login = "", login = "",
baseUrl = "", scrapperBaseUrl = "",
loginMode = Sdk.Mode.HEBE,
loginType = Scrapper.LoginType.AUTO, loginType = Scrapper.LoginType.AUTO,
symbols = listOf(), symbols = listOf(),
) )
@ -54,8 +65,14 @@ class LoginFormPresenterTest {
every { loginFormView.setErrorPassInvalid(any()) } just Runs every { loginFormView.setErrorPassInvalid(any()) } just Runs
every { loginFormView.setErrorPassRequired(any()) } just Runs every { loginFormView.setErrorPassRequired(any()) } just Runs
every { loginFormView.setErrorUsernameRequired() } 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) presenter.onAttachView(loginFormView)
} }

View File

@ -6,14 +6,22 @@ import io.github.wulkanowy.data.pojos.RegisterSymbol
import io.github.wulkanowy.data.pojos.RegisterUnit import io.github.wulkanowy.data.pojos.RegisterUnit
import io.github.wulkanowy.data.pojos.RegisterUser import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo 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.impl.annotations.MockK
import io.mockk.just
import io.mockk.slot
import io.mockk.verify
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -76,6 +84,9 @@ class LoginStudentSelectPresenterTest {
symbol = "", symbol = "",
error = null, error = null,
userName = "", userName = "",
keyId = null,
privatePem = null,
hebeBaseUrl = null,
schools = listOf(school), schools = listOf(school),
) )
@ -83,7 +94,8 @@ class LoginStudentSelectPresenterTest {
email = "", email = "",
password = "", password = "",
login = "", login = "",
baseUrl = "", scrapperBaseUrl = "",
loginMode = Sdk.Mode.SCRAPPER,
loginType = Scrapper.LoginType.AUTO, loginType = Scrapper.LoginType.AUTO,
symbols = listOf(symbol), symbols = listOf(symbol),
) )