1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-19 20:29:08 -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-credentials.json
.idea/deploymentTargetDropDown.xml
.idea/kotlinc.xml

View File

@ -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'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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.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 {

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,17 +1,12 @@
package io.github.wulkanowy.ui.modules.login.advanced
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.onResourceNotLoading
import io.github.wulkanowy.data.pojos.RegisterStudent
import io.github.wulkanowy.data.pojos.RegisterSymbol
import io.github.wulkanowy.data.pojos.RegisterUnit
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginData
@ -97,14 +92,16 @@ class LoginAdvancedPresenter @Inject constructor(
fun onLoginModeSelected(type: Sdk.Mode) {
view?.run {
when (type) {
Sdk.Mode.API -> {
Sdk.Mode.HEBE -> {
showOnlyMobileApiModeInputs()
showMobileApiWarningMessage()
}
Sdk.Mode.SCRAPPER -> {
showOnlyScrapperModeInputs()
showScraperWarningMessage()
}
Sdk.Mode.HYBRID -> {
showOnlyHybridModeInputs()
showHybridWarningMessage()
@ -145,11 +142,12 @@ class LoginAdvancedPresenter @Inject constructor(
showProgress(true)
showContent(false)
}
is Resource.Success -> {
analytics.logEvent(
"registration_form",
"success" to true,
"students" to it.data.size,
"scrapperBaseUrl" to view?.formHostValue.orEmpty(),
"error" to "No error"
)
val loginData = LoginData(
@ -158,14 +156,15 @@ class LoginAdvancedPresenter @Inject constructor(
baseUrl = view?.formHostValue.orEmpty().trim(),
symbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(),
)
when (it.data.size) {
when (it.data.symbols.size) {
0 -> view?.navigateToSymbol(loginData)
else -> view?.navigateToStudentSelect(
loginData = loginData,
registerUser = it.data.toRegisterUser(loginData),
registerUser = it.data,
)
}
}
is Resource.Error -> {
analytics.logEvent(
"registration_form",
@ -183,59 +182,7 @@ class LoginAdvancedPresenter @Inject constructor(
}.launch("login")
}
private fun List<StudentWithSemesters>.toRegisterUser(loginData: LoginData) = RegisterUser(
email = loginData.login,
password = loginData.password,
login = loginData.login,
baseUrl = loginData.baseUrl,
loginType = firstOrNull()?.student?.loginType?.let(
Scrapper.LoginType::valueOf
) ?: Scrapper.LoginType.AUTO,
symbols = this
.groupBy { students -> students.student.symbol }
.map { (symbol, students) ->
RegisterSymbol(
symbol = symbol,
error = null,
userName = "",
schools = students
.groupBy { student ->
Triple(
first = student.student.schoolSymbol,
second = student.student.userLoginId,
third = student.student.schoolShortName
)
}
.map { (groupKey, students) ->
val (schoolId, loginId, schoolName) = groupKey
RegisterUnit(
students = students.map {
RegisterStudent(
studentId = it.student.studentId,
studentName = it.student.studentName,
studentSecondName = it.student.studentName,
studentSurname = it.student.studentName,
className = it.student.className,
classId = it.student.classId,
isParent = it.student.isParent,
semesters = it.semesters,
)
},
userLoginId = loginId,
schoolId = schoolId,
schoolName = schoolName,
schoolShortName = schoolName,
parentIds = listOf(),
studentIds = listOf(),
employeeIds = listOf(),
error = null
)
}
)
},
)
private suspend fun getStudentsAppropriatesToLoginType(): List<StudentWithSemesters> {
private suspend fun getStudentsAppropriatesToLoginType(): RegisterUser {
val email = view?.formUsernameValue.orEmpty()
val password = view?.formPassValue.orEmpty()
val endpoint = view?.formHostValue.orEmpty()
@ -245,10 +192,11 @@ class LoginAdvancedPresenter @Inject constructor(
val token = view?.formTokenValue.orEmpty()
return when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) {
Sdk.Mode.API -> studentRepository.getStudentsApi(pin, symbol, token)
Sdk.Mode.HEBE -> studentRepository.getStudentsApi(pin, symbol, token)
Sdk.Mode.SCRAPPER -> studentRepository.getStudentsScrapper(
email, password, endpoint, symbol
)
Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid(
email, password, endpoint, symbol
)
@ -267,8 +215,8 @@ class LoginAdvancedPresenter @Inject constructor(
var isCorrect = true
when (Sdk.Mode.valueOf(view?.formLoginType ?: "")) {
Sdk.Mode.API -> {
when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) {
Sdk.Mode.HEBE -> {
if (pin.isEmpty()) {
view?.setErrorPinRequired()
isCorrect = false
@ -284,17 +232,17 @@ class LoginAdvancedPresenter @Inject constructor(
isCorrect = false
}
}
Sdk.Mode.HYBRID, Sdk.Mode.SCRAPPER -> {
if (login.isEmpty()) {
view?.setErrorUsernameRequired()
isCorrect = false
} else {
if ("@" in login && "standard" !in host) {
if ("@" in login && "login" in host) {
view?.setErrorLoginRequired()
isCorrect = false
}
if ("@" !in login && "standard" in host) {
if ("@" !in login && "email" in host) {
view?.setErrorEmailRequired()
isCorrect = false
}

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@ -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"

View File

@ -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 = "",

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.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,

View File

@ -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 {

View File

@ -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 = "",

View File

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

View File

@ -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,

View File

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

View File

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

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.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 = "",

View File

@ -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 = "",

View File

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

View File

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

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.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),
)