Migrate scraper module to coroutines

This commit is contained in:
Mikołaj Pich 2020-06-14 18:26:58 +02:00
parent 48b7ed8955
commit 0165e05aae
47 changed files with 1352 additions and 1659 deletions

View file

@ -83,6 +83,8 @@ subprojects {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.3.7'
implementation "io.reactivex.rxjava2:rxjava:2.2.19" implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp3" implementation "com.squareup.okhttp3:logging-interceptor:$okhttp3"

View file

@ -14,7 +14,6 @@ import io.github.wulkanowy.sdk.scrapper.repository.StudentAndParentStartReposito
import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository
import io.github.wulkanowy.sdk.scrapper.repository.StudentStartRepository import io.github.wulkanowy.sdk.scrapper.repository.StudentStartRepository
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.reactivex.Single
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
@ -219,74 +218,74 @@ class Scrapper {
HomepageRepository(serviceManager.getHomepageService()) HomepageRepository(serviceManager.getHomepageService())
} }
fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String) = account.getPasswordResetCaptcha(registerBaseUrl, symbol) suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String) = account.getPasswordResetCaptcha(registerBaseUrl, symbol)
fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): Single<String> { suspend fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): String {
return account.sendPasswordResetRequest(registerBaseUrl, symbol, email.trim(), captchaCode) return account.sendPasswordResetRequest(registerBaseUrl, symbol, email.trim(), captchaCode)
} }
fun getStudents() = register.getStudents() suspend fun getStudents() = register.getStudents()
fun getSemesters() = if (useNewStudent) studentStart.getSemesters() else snpStart.getSemesters() suspend fun getSemesters() = if (useNewStudent) studentStart.getSemesters() else snpStart.getSemesters()
fun getAttendance(startDate: LocalDate, endDate: LocalDate? = null) = suspend fun getAttendance(startDate: LocalDate, endDate: LocalDate? = null) =
if (useNewStudent) student.getAttendance(startDate, endDate) else snp.getAttendance(startDate, endDate) if (useNewStudent) student.getAttendance(startDate, endDate) else snp.getAttendance(startDate, endDate)
fun getAttendanceSummary(subjectId: Int? = -1) = if (useNewStudent) student.getAttendanceSummary(subjectId) else snp.getAttendanceSummary(subjectId) suspend fun getAttendanceSummary(subjectId: Int? = -1) = if (useNewStudent) student.getAttendanceSummary(subjectId) else snp.getAttendanceSummary(subjectId)
fun excuseForAbsence(absents: List<Absent>, content: String? = null) = student.excuseForAbsence(absents, content) suspend fun excuseForAbsence(absents: List<Absent>, content: String? = null) = student.excuseForAbsence(absents, content)
fun getSubjects() = if (useNewStudent) student.getSubjects() else snp.getSubjects() suspend fun getSubjects() = if (useNewStudent) student.getSubjects() else snp.getSubjects()
fun getExams(startDate: LocalDate, endDate: LocalDate? = null) = suspend fun getExams(startDate: LocalDate, endDate: LocalDate? = null) =
if (useNewStudent) student.getExams(startDate, endDate) else snp.getExams(startDate, endDate) if (useNewStudent) student.getExams(startDate, endDate) else snp.getExams(startDate, endDate)
fun getGrades(semesterId: Int) = if (useNewStudent) student.getGrades(semesterId) else snp.getGrades(semesterId) suspend fun getGrades(semesterId: Int) = if (useNewStudent) student.getGrades(semesterId) else snp.getGrades(semesterId)
fun getGradesDetails(semesterId: Int? = null) = if (useNewStudent) student.getGradesDetails(semesterId) else snp.getGradesDetails(semesterId) suspend fun getGradesDetails(semesterId: Int? = null) = if (useNewStudent) student.getGradesDetails(semesterId) else snp.getGradesDetails(semesterId)
fun getGradesSummary(semesterId: Int? = null) = if (useNewStudent) student.getGradesSummary(semesterId) else snp.getGradesSummary(semesterId) suspend fun getGradesSummary(semesterId: Int? = null) = if (useNewStudent) student.getGradesSummary(semesterId) else snp.getGradesSummary(semesterId)
fun getGradesPartialStatistics(semesterId: Int) = suspend fun getGradesPartialStatistics(semesterId: Int) =
if (useNewStudent) student.getGradesPartialStatistics(semesterId) else snp.getGradesStatistics(semesterId, false) if (useNewStudent) student.getGradesPartialStatistics(semesterId) else snp.getGradesStatistics(semesterId, false)
fun getGradesPointsStatistics(semesterId: Int) = student.getGradesPointsStatistics(semesterId) suspend fun getGradesPointsStatistics(semesterId: Int) = student.getGradesPointsStatistics(semesterId)
fun getGradesAnnualStatistics(semesterId: Int) = suspend fun getGradesAnnualStatistics(semesterId: Int) =
if (useNewStudent) student.getGradesAnnualStatistics(semesterId) else snp.getGradesStatistics(semesterId, true) if (useNewStudent) student.getGradesAnnualStatistics(semesterId) else snp.getGradesStatistics(semesterId, true)
fun getHomework(startDate: LocalDate, endDate: LocalDate? = null) = suspend fun getHomework(startDate: LocalDate, endDate: LocalDate? = null) =
if (useNewStudent) student.getHomework(startDate, endDate) else snp.getHomework(startDate, endDate) if (useNewStudent) student.getHomework(startDate, endDate) else snp.getHomework(startDate, endDate)
fun getNotes() = if (useNewStudent) student.getNotes() else snp.getNotes() suspend fun getNotes() = if (useNewStudent) student.getNotes() else snp.getNotes()
fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null) = suspend fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null) =
if (useNewStudent) student.getTimetable(startDate, endDate) else snp.getTimetable(startDate, endDate) if (useNewStudent) student.getTimetable(startDate, endDate) else snp.getTimetable(startDate, endDate)
fun getCompletedLessons(startDate: LocalDate, endDate: LocalDate? = null, subjectId: Int = -1) = suspend fun getCompletedLessons(startDate: LocalDate, endDate: LocalDate? = null, subjectId: Int = -1) =
if (useNewStudent) student.getCompletedLessons(startDate, endDate, subjectId) else snp.getCompletedLessons(startDate, endDate, subjectId) if (useNewStudent) student.getCompletedLessons(startDate, endDate, subjectId) else snp.getCompletedLessons(startDate, endDate, subjectId)
fun getRegisteredDevices() = if (useNewStudent) student.getRegisteredDevices() else snp.getRegisteredDevices() suspend fun getRegisteredDevices() = if (useNewStudent) student.getRegisteredDevices() else snp.getRegisteredDevices()
fun getToken() = if (useNewStudent) student.getToken() else snp.getToken() suspend fun getToken() = if (useNewStudent) student.getToken() else snp.getToken()
fun unregisterDevice(id: Int) = if (useNewStudent) student.unregisterDevice(id) else snp.unregisterDevice(id) suspend fun unregisterDevice(id: Int) = if (useNewStudent) student.unregisterDevice(id) else snp.unregisterDevice(id)
fun getTeachers() = if (useNewStudent) student.getTeachers() else snp.getTeachers() suspend fun getTeachers() = if (useNewStudent) student.getTeachers() else snp.getTeachers()
fun getSchool() = if (useNewStudent) student.getSchool() else snp.getSchool() suspend fun getSchool() = if (useNewStudent) student.getSchool() else snp.getSchool()
fun getStudentInfo() = snp.getStudentInfo() suspend fun getStudentInfo() = snp.getStudentInfo()
fun getReportingUnits() = messages.getReportingUnits() suspend fun getReportingUnits() = messages.getReportingUnits()
fun getRecipients(unitId: Int, role: Int = 2) = messages.getRecipients(unitId, role) suspend fun getRecipients(unitId: Int, role: Int = 2) = messages.getRecipients(unitId, role)
fun getMessages( suspend fun getMessages(
folder: Folder, folder: Folder,
startDate: LocalDateTime? = null, startDate: LocalDateTime? = null,
endDate: LocalDateTime? = null endDate: LocalDateTime? = null
): Single<List<Message>> { ): List<Message> {
return when (folder) { return when (folder) {
Folder.RECEIVED -> messages.getReceivedMessages(startDate, endDate) Folder.RECEIVED -> messages.getReceivedMessages(startDate, endDate)
Folder.SENT -> messages.getSentMessages(startDate, endDate) Folder.SENT -> messages.getSentMessages(startDate, endDate)
@ -294,39 +293,39 @@ class Scrapper {
} }
} }
fun getReceivedMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getReceivedMessages(startDate, endDate) suspend fun getReceivedMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getReceivedMessages(startDate, endDate)
fun getSentMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getSentMessages(startDate, endDate) suspend fun getSentMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getSentMessages(startDate, endDate)
fun getDeletedMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getDeletedMessages(startDate, endDate) suspend fun getDeletedMessages(startDate: LocalDateTime? = null, endDate: LocalDateTime? = null) = messages.getDeletedMessages(startDate, endDate)
fun getMessageRecipients(messageId: Int, loginId: Int = 0) = messages.getMessageRecipients(messageId, loginId) suspend fun getMessageRecipients(messageId: Int, loginId: Int = 0) = messages.getMessageRecipients(messageId, loginId)
fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null) = messages.getMessageDetails(messageId, folderId, read, id) suspend fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null) = messages.getMessageDetails(messageId, folderId, read, id)
fun getMessageContent(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null) = messages.getMessage(messageId, folderId, read, id) suspend fun getMessageContent(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null) = messages.getMessage(messageId, folderId, read, id)
fun sendMessage(subject: String, content: String, recipients: List<Recipient>) = messages.sendMessage(subject, content, recipients) suspend fun sendMessage(subject: String, content: String, recipients: List<Recipient>) = messages.sendMessage(subject, content, recipients)
fun deleteMessages(messagesToDelete: List<Pair<Int, Int>>) = messages.deleteMessages(messagesToDelete) suspend fun deleteMessages(messagesToDelete: List<Pair<Int, Int>>) = messages.deleteMessages(messagesToDelete)
fun getSelfGovernments() = homepage.getSelfGovernments() suspend fun getSelfGovernments() = homepage.getSelfGovernments()
fun getStudentThreats() = homepage.getStudentThreats() suspend fun getStudentThreats() = homepage.getStudentThreats()
fun getStudentsTrips() = homepage.getStudentsTrips() suspend fun getStudentsTrips() = homepage.getStudentsTrips()
fun getLastGrades() = homepage.getLastGrades() suspend fun getLastGrades() = homepage.getLastGrades()
fun getFreeDays() = homepage.getFreeDays() suspend fun getFreeDays() = homepage.getFreeDays()
fun getKidsLuckyNumbers() = homepage.getKidsLuckyNumbers() suspend fun getKidsLuckyNumbers() = homepage.getKidsLuckyNumbers()
fun getKidsLessonPlan() = homepage.getKidsLessonPlan() suspend fun getKidsLessonPlan() = homepage.getKidsLessonPlan()
fun getLastHomework() = homepage.getLastHomework() suspend fun getLastHomework() = homepage.getLastHomework()
fun getLastTests() = homepage.getLastTests() suspend fun getLastTests() = homepage.getLastTests()
fun getLastStudentLessons() = homepage.getLastStudentLessons() suspend fun getLastStudentLessons() = homepage.getLastStudentLessons()
} }

View file

@ -14,42 +14,28 @@ import io.github.wulkanowy.sdk.scrapper.attendance.Attendance.Category.UNKNOWN
import io.github.wulkanowy.sdk.scrapper.attendance.Attendance.Category.values import io.github.wulkanowy.sdk.scrapper.attendance.Attendance.Category.values
import io.github.wulkanowy.sdk.scrapper.timetable.CacheResponse.Time import io.github.wulkanowy.sdk.scrapper.timetable.CacheResponse.Time
import io.github.wulkanowy.sdk.scrapper.toLocalDate import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.reactivex.Observable
import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.Month import org.threeten.bp.Month
fun Single<AttendanceResponse?>.mapAttendanceList(start: LocalDate, end: LocalDate?, getTimes: () -> Single<List<Time>>): Single<List<Attendance>> { fun AttendanceResponse.mapAttendanceList(start: LocalDate, end: LocalDate?, times: List<Time>): List<Attendance> {
val endDate = end ?: start.plusDays(4) val endDate = end ?: start.plusDays(4)
var excuseActive = false return lessons.map {
var sentExcuses = emptyList<SentExcuse>() val sentExcuse = sentExcuses.firstOrNull { excuse -> excuse.date == it.date && excuse.timeId == it.timeId }
return map { it.apply {
it.run { presence = it.categoryId == PRESENCE.id || it.categoryId == ABSENCE_FOR_SCHOOL_REASONS.id
excuseActive = this.excuseActive absence = it.categoryId == ABSENCE_UNEXCUSED.id || it.categoryId == ABSENCE_EXCUSED.id
sentExcuses = this.sentExcuses lateness = it.categoryId == EXCUSED_LATENESS.id || it.categoryId == UNEXCUSED_LATENESS.id
lessons excused = it.categoryId == ABSENCE_EXCUSED.id || it.categoryId == EXCUSED_LATENESS.id
} exemption = it.categoryId == EXEMPTION.id
}.flatMapObservable { Observable.fromIterable(it) }.flatMap { a -> excusable = excuseActive && (absence || lateness) && !excused && sentExcuse == null
getTimes().flatMapObservable { times -> name = (values().singleOrNull { category -> category.id == categoryId } ?: UNKNOWN).title
Observable.fromIterable(times.filter { time -> time.id == a.timeId }) number = times.single { time -> time.id == it.timeId }.number
}.map { if (sentExcuse != null)
val sentExcuse = sentExcuses.firstOrNull { excuse -> excuse.date == a.date && excuse.timeId == a.timeId } excuseStatus = SentExcuse.Status.getByValue(sentExcuse.status)
a.apply {
presence = a.categoryId == PRESENCE.id || a.categoryId == ABSENCE_FOR_SCHOOL_REASONS.id
absence = a.categoryId == ABSENCE_UNEXCUSED.id || a.categoryId == ABSENCE_EXCUSED.id
lateness = a.categoryId == EXCUSED_LATENESS.id || a.categoryId == UNEXCUSED_LATENESS.id
excused = a.categoryId == ABSENCE_EXCUSED.id || a.categoryId == EXCUSED_LATENESS.id
exemption = a.categoryId == EXEMPTION.id
excusable = excuseActive && (absence || lateness) && !excused && sentExcuse == null
name = (values().singleOrNull { category -> category.id == categoryId } ?: UNKNOWN).title
number = it.number
if (sentExcuse != null)
excuseStatus = SentExcuse.Status.getByValue(sentExcuse.status)
}
} }
}.filter { }.filter {
it.date.toLocalDate() >= start && it.date.toLocalDate() <= endDate it.date.toLocalDate() >= start && it.date.toLocalDate() <= endDate
}.toList().map { list -> list.sortedWith(compareBy({ it.date }, { it.number })) } }.sortedWith(compareBy({ it.date }, { it.number }))
} }
fun AttendanceSummaryResponse.mapAttendanceSummaryList(gson: GsonBuilder): List<AttendanceSummary> { fun AttendanceSummaryResponse.mapAttendanceSummaryList(gson: GsonBuilder): List<AttendanceSummary> {

View file

@ -6,26 +6,18 @@ import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.scrapper.exception.InvalidPathException import io.github.wulkanowy.sdk.scrapper.exception.InvalidPathException
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException
import io.reactivex.Single
import io.reactivex.SingleSource
import io.reactivex.SingleTransformer
class ErrorHandlerTransformer<T : Any?> : SingleTransformer<ApiResponse<T>, ApiResponse<T>> { fun <T> ApiResponse<T>.handleErrors(): ApiResponse<T> {
return if (!success && feedback != null) throw feedback.run {
override fun apply(upstream: Single<ApiResponse<T>>): SingleSource<ApiResponse<T>> { when {
return upstream.map { res -> message.contains("niespójność danych") -> ScrapperException(message)
if (!res.success && res.feedback != null) throw res.feedback.run { message.contains("Brak uprawnień") -> AccountPermissionException(message)
when { message.contains("wyłączony") -> FeatureDisabledException(message)
message.contains("niespójność danych") -> ScrapperException(message) message.contains("DB_ERROR") -> VulcanException(message)
message.contains("Brak uprawnień") -> AccountPermissionException(message) message.contains("błąd") -> VulcanException(message)
message.contains("wyłączony") -> FeatureDisabledException(message) message.contains("The controller for path") -> InvalidPathException(message)
message.contains("DB_ERROR") -> VulcanException(message) message.contains("The parameters dictionary contains a null entry for parameter") -> InvalidPathException(message)
message.contains("błąd") -> VulcanException(message) else -> VulcanException(message)
message.contains("The controller for path") -> InvalidPathException(message)
message.contains("The parameters dictionary contains a null entry for parameter") -> InvalidPathException(message)
else -> VulcanException(message)
}
} else res
} }
} } else this
} }

View file

@ -12,7 +12,6 @@ import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse
import io.github.wulkanowy.sdk.scrapper.service.LoginService import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.reactivex.Single
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.threeten.bp.LocalDateTime.now import org.threeten.bp.LocalDateTime.now
import org.threeten.bp.ZoneId import org.threeten.bp.ZoneId
@ -31,7 +30,8 @@ class LoginHelper(
) { ) {
companion object { companion object {
@JvmStatic private val logger = LoggerFactory.getLogger(this::class.java) @JvmStatic
private val logger = LoggerFactory.getLogger(this::class.java)
} }
init { init {
@ -49,22 +49,20 @@ class LoginHelper(
} }
@Synchronized @Synchronized
fun login(email: String, password: String): Single<SendCertificateResponse> { suspend fun login(email: String, password: String): SendCertificateResponse {
return sendCredentials(email, password).flatMap { val res = sendCredentials(email, password)
logger.info("Login started") logger.info("Login started")
when { when {
it.title.startsWith("Witryna ucznia i rodzica") -> return@flatMap Single.just(SendCertificateResponse()) res.title.startsWith("Witryna ucznia i rodzica") -> return SendCertificateResponse()
it.action.isBlank() -> throw VulcanException("Invalid certificate page: '${it.title}'. Try again") res.action.isBlank() -> throw VulcanException("Invalid certificate page: '${res.title}'. Try again")
}
sendCertificate(it, email)
}.map {
logger.debug("Login completed")
it
} }
val cert = sendCertificate(res, email)
logger.debug("Login completed")
return cert
} }
fun sendCredentials(email: String, password: String): Single<CertificateResponse> { suspend fun sendCredentials(email: String, password: String): CertificateResponse {
email.substringBefore("||").let { email.substringBefore("||").let {
return when (loginType) { return when (loginType) {
AUTO -> throw ScrapperException("You must first specify Api.loginType before logging in") AUTO -> throw ScrapperException("You must first specify Api.loginType before logging in")
@ -76,94 +74,95 @@ class LoginHelper(
} }
} }
fun sendCertificate(cert: CertificateResponse, email: String, url: String = cert.action): Single<SendCertificateResponse> { suspend fun sendCertificate(cert: CertificateResponse, email: String, url: String = cert.action): SendCertificateResponse {
cookies.cookieStore.removeAll() cookies.cookieStore.removeAll()
return api.sendCertificate(url, mapOf( val res = api.sendCertificate(url, mapOf(
"wa" to cert.wa, "wa" to cert.wa,
"wresult" to cert.wresult, "wresult" to cert.wresult,
"wctx" to cert.wctx "wctx" to cert.wctx
)).flatMap { ))
if (email.contains("||")) api.switchLogin("$url?rebuild=${email.substringAfter("||", "")}")
else Single.just(it) if (email.contains("||")) api.switchLogin("$url?rebuild=${email.substringAfter("||", "")}")
}
return res
} }
private fun sendStandard(email: String, password: String): Single<CertificateResponse> { private suspend fun sendStandard(email: String, password: String): CertificateResponse {
return api.sendCredentials(firstStepReturnUrl, mapOf( return certificateAdapter.fromHtml(api.sendCredentials(firstStepReturnUrl, mapOf(
"LoginName" to email, "LoginName" to email,
"Password" to password "Password" to password
)).map { certificateAdapter.fromHtml(it) } )))
} }
private fun sendADFSLightGeneric(email: String, password: String, type: Scrapper.LoginType): Single<CertificateResponse> { private suspend fun sendADFSLightGeneric(email: String, password: String, type: Scrapper.LoginType): CertificateResponse {
return api.sendADFSForm( val res = certificateAdapter.fromHtml(api.sendADFSForm(
getADFSUrl(type), mapOf( getADFSUrl(type), mapOf(
"Username" to email, "Username" to email,
"Password" to password, "Password" to password,
"x" to "0", "x" to "0",
"y" to "0" "y" to "0"
) )
).map { certificateAdapter.fromHtml(it) }.flatMap { ))
api.sendADFSForm(
it.action, mapOf( return certificateAdapter.fromHtml(api.sendADFSForm(
"wa" to it.wa, res.action, mapOf(
"wresult" to it.wresult, "wa" to res.wa,
"wctx" to it.wctx "wresult" to res.wresult,
) "wctx" to res.wctx
) )
}.map { certificateAdapter.fromHtml(it) } ))
} }
private fun sendADFS(email: String, password: String): Single<CertificateResponse> { private suspend fun sendADFS(email: String, password: String): CertificateResponse {
return api.getForm(getADFSUrl(ADFS)).flatMap { val res = api.getForm(getADFSUrl(ADFS))
if (it.formAction.isBlank()) throw VulcanException("Invalid ADFS login page: '${it.title}'. Try again")
api.sendADFSForm("$schema://adfs.$host/${it.formAction.removePrefix("/")}", mapOf( if (res.formAction.isBlank()) throw VulcanException("Invalid ADFS login page: '${res.title}'. Try again")
"__db" to it.db, val form = certificateAdapter.fromHtml(api.sendADFSForm("$schema://adfs.$host/${res.formAction.removePrefix("/")}", mapOf(
"__VIEWSTATE" to it.viewstate, "__db" to res.db,
"__VIEWSTATEGENERATOR" to it.viewStateGenerator, "__VIEWSTATE" to res.viewstate,
"__EVENTVALIDATION" to it.eventValidation, "__VIEWSTATEGENERATOR" to res.viewStateGenerator,
"UsernameTextBox" to email, "__EVENTVALIDATION" to res.eventValidation,
"PasswordTextBox" to password, "UsernameTextBox" to email,
"SubmitButton.x" to "0", "PasswordTextBox" to password,
"SubmitButton.y" to "0" "SubmitButton.x" to "0",
)) "SubmitButton.y" to "0"
}.map { certificateAdapter.fromHtml(it) }.flatMap { )))
api.sendADFSForm(it.action, mapOf(
"wa" to it.wa, return certificateAdapter.fromHtml(api.sendADFSForm(form.action, mapOf(
"wresult" to it.wresult, "wa" to form.wa,
"wctx" to it.wctx "wresult" to form.wresult,
)) "wctx" to form.wctx
}.map { certificateAdapter.fromHtml(it) } )))
} }
private fun sendADFSCards(email: String, password: String): Single<CertificateResponse> { private suspend fun sendADFSCards(email: String, password: String): CertificateResponse {
return api.getForm(getADFSUrl(ADFSCards)).flatMap { val form = api.getForm(getADFSUrl(ADFSCards))
api.sendADFSFormStandardChoice("$schema://adfs.$host/${it.formAction.removePrefix("/")}", mapOf(
"__db" to it.db, val form2 = api.sendADFSFormStandardChoice("$schema://adfs.$host/${form.formAction.removePrefix("/")}", mapOf(
"__VIEWSTATE" to it.viewstate, "__db" to form.db,
"__VIEWSTATEGENERATOR" to it.viewStateGenerator, "__VIEWSTATE" to form.viewstate,
"__EVENTVALIDATION" to it.eventValidation, "__VIEWSTATEGENERATOR" to form.viewStateGenerator,
"PassiveSignInButton.x" to "0", "__EVENTVALIDATION" to form.eventValidation,
"PassiveSignInButton.y" to "0" "PassiveSignInButton.x" to "0",
)) "PassiveSignInButton.y" to "0"
}.flatMap { ))
api.sendADFSForm("$schema://adfs.$host/${it.formAction.removePrefix("/")}", mapOf(
"__db" to it.db, val form3 = certificateAdapter.fromHtml(api.sendADFSForm("$schema://adfs.$host/${form2.formAction.removePrefix("/")}", mapOf(
"__VIEWSTATE" to it.viewstate, "__db" to form2.db,
"__VIEWSTATEGENERATOR" to it.viewStateGenerator, "__VIEWSTATE" to form2.viewstate,
"__EVENTVALIDATION" to it.eventValidation, "__VIEWSTATEGENERATOR" to form2.viewStateGenerator,
"SubmitButton.x" to "0", "__EVENTVALIDATION" to form2.eventValidation,
"SubmitButton.y" to "0", "SubmitButton.x" to "0",
"UsernameTextBox" to email, "SubmitButton.y" to "0",
"PasswordTextBox" to password "UsernameTextBox" to email,
)) "PasswordTextBox" to password
}.map { certificateAdapter.fromHtml(it) }.flatMap { )))
api.sendADFSForm(it.action, mapOf(
"wa" to it.wa, return certificateAdapter.fromHtml(api.sendADFSForm(form3.action, mapOf(
"wresult" to it.wresult, "wa" to form3.wa,
"wctx" to it.wctx "wresult" to form3.wresult,
)) "wctx" to form3.wctx
}.map { certificateAdapter.fromHtml(it) } )))
} }
private fun getADFSUrl(type: Scrapper.LoginType): String { private fun getADFSUrl(type: Scrapper.LoginType): String {

View file

@ -15,7 +15,6 @@ import io.github.wulkanowy.sdk.scrapper.exception.NoAccountFoundException
import io.github.wulkanowy.sdk.scrapper.exception.PasswordResetErrorException import io.github.wulkanowy.sdk.scrapper.exception.PasswordResetErrorException
import io.github.wulkanowy.sdk.scrapper.service.AccountService import io.github.wulkanowy.sdk.scrapper.service.AccountService
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.reactivex.Single
import java.net.URL import java.net.URL
class AccountRepository(private val account: AccountService) { class AccountRepository(private val account: AccountService) {
@ -27,45 +26,45 @@ class AccountRepository(private val account: AccountService) {
const val SELECTOR_ADFS_CARDS = "#PassiveSignInButton" const val SELECTOR_ADFS_CARDS = "#PassiveSignInButton"
} }
fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Single<Pair<String, String>> { suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Pair<String, String> {
return getPasswordResetUrl(registerBaseUrl, symbol.trim()).flatMap { (_, resetUrl) -> val (_, resetUrl) = getPasswordResetUrl(registerBaseUrl, symbol.trim())
account.getPasswordResetPageWithCaptcha(resetUrl) val res = account.getPasswordResetPageWithCaptcha(resetUrl)
.map { res -> resetUrl to res.recaptchaSiteKey } return resetUrl to res.recaptchaSiteKey
}
} }
fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): Single<String> { suspend fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): String {
return getPasswordResetUrl(registerBaseUrl, symbol.trim()).flatMap { (type, url) -> val (type, url) = getPasswordResetUrl(registerBaseUrl, symbol.trim())
when (type) {
STANDARD -> account.sendPasswordResetRequest(url, email, captchaCode)
ADFSLight, ADFSLightScoped, ADFSLightCufs -> account.sendPasswordResetRequestADFSLight(url, email, captchaCode)
ADFS, ADFSCards -> account.getPasswordResetPageADFS(url).flatMap {
account.sendPasswordResetRequestADFS(url, email, captchaCode, (it.html.select("[type=hidden]").map { input ->
input.attr("name") to input.attr("value")
}).toMap().plus("btSend.x" to "5").plus("btSend.y" to "6"))
}
else -> Single.error(ScrapperException("Never happen"))
}
}.map { res ->
with(res.html) {
select(".ErrorMessage")?.text()?.let { // STANDARD
if (it.contains("Niepoprawny adres email")) throw InvalidEmailException(it)
}
select(".ErrorMessage, #ErrorTextLabel, #lblStatus")?.text()?.let { // STANDARD, ADFSLight, ADFSCards
if (it.contains("nie zostało odnalezione lub zostało zablokowane")) throw NoAccountFoundException(it)
if (it.contains("nie ma w systemie zarejestrowanych")) throw NoAccountFoundException(it) // 😀
if (it.contains("żądanie nie zostało poprawnie autoryzowane")) throw InvalidCaptchaException(it)
}
}
if (!res.message.startsWith("Wysłano wiadomość")) throw PasswordResetErrorException("Unexpected message: ${res.message}")
res.message val res = when (type) {
STANDARD -> account.sendPasswordResetRequest(url, email, captchaCode)
ADFSLight, ADFSLightScoped, ADFSLightCufs -> account.sendPasswordResetRequestADFSLight(url, email, captchaCode)
ADFS, ADFSCards -> {
val page = account.getPasswordResetPageADFS(url)
account.sendPasswordResetRequestADFS(url, email, captchaCode, (page.html.select("[type=hidden]").map { input ->
input.attr("name") to input.attr("value")
}).toMap().plus("btSend.x" to "5").plus("btSend.y" to "6"))
}
else -> throw ScrapperException("Never happen")
} }
with(res.html) {
select(".ErrorMessage")?.text()?.let { // STANDARD
if (it.contains("Niepoprawny adres email")) throw InvalidEmailException(it)
}
select(".ErrorMessage, #ErrorTextLabel, #lblStatus")?.text()?.let { // STANDARD, ADFSLight, ADFSCards
if (it.contains("nie zostało odnalezione lub zostało zablokowane")) throw NoAccountFoundException(it)
if (it.contains("nie ma w systemie zarejestrowanych")) throw NoAccountFoundException(it) // 😀
if (it.contains("żądanie nie zostało poprawnie autoryzowane")) throw InvalidCaptchaException(it)
}
}
if (!res.message.startsWith("Wysłano wiadomość")) throw PasswordResetErrorException("Unexpected message: ${res.message}")
return res.message
} }
private fun getPasswordResetUrl(registerBaseUrl: String, symbol: String): Single<Pair<Scrapper.LoginType, String>> { private suspend fun getPasswordResetUrl(registerBaseUrl: String, symbol: String): Pair<Scrapper.LoginType, String> {
val url = URL(registerBaseUrl) val url = URL(registerBaseUrl)
return Single.just(when (url.host) { val unlockUrl = when (url.host) {
"fakelog.cf" -> STANDARD to "https://cufs.fakelog.cf/Default/AccountManage/UnlockAccount" "fakelog.cf" -> STANDARD to "https://cufs.fakelog.cf/Default/AccountManage/UnlockAccount"
"fakelog.tk" -> STANDARD to "https://cufs.fakelog.tk/Default/AccountManage/UnlockAccount" "fakelog.tk" -> STANDARD to "https://cufs.fakelog.tk/Default/AccountManage/UnlockAccount"
"eszkola.opolskie.pl" -> ADFSCards to "https://konta.eszkola.opolskie.pl/maintenance/unlock.aspx" "eszkola.opolskie.pl" -> ADFSCards to "https://konta.eszkola.opolskie.pl/maintenance/unlock.aspx"
@ -75,35 +74,36 @@ class AccountRepository(private val account: AccountService) {
"umt.tarnow.pl" -> ADFS to "https://konta.umt.tarnow.pl/maintenance/unlock.aspx" "umt.tarnow.pl" -> ADFS to "https://konta.umt.tarnow.pl/maintenance/unlock.aspx"
"vulcan.net.pl" -> AUTO to "" // stream hack - bellow "vulcan.net.pl" -> AUTO to "" // stream hack - bellow
else -> throw ScrapperException("Nieznany dziennik $url") else -> throw ScrapperException("Nieznany dziennik $url")
}).flatMap {
if (it.first == AUTO) getLoginType(ServiceManager.UrlGenerator(url, symbol, "")).map { loginType ->
loginType to when (loginType) {
STANDARD -> "https://cufs.vulcan.net.pl/$symbol/AccountManage/UnlockAccount"
ADFSLightScoped -> "https://adfslight.vulcan.net.pl/$symbol/AccountManage/UnlockAccountRequest"
else -> throw ScrapperException("Nieznany dziennik $registerBaseUrl, $loginType")
}
} else Single.just(it)
} }
return if (unlockUrl.first == AUTO) {
val loginType = getLoginType(ServiceManager.UrlGenerator(url, symbol, ""))
loginType to when (loginType) {
STANDARD -> "https://cufs.vulcan.net.pl/$symbol/AccountManage/UnlockAccount"
ADFSLightScoped -> "https://adfslight.vulcan.net.pl/$symbol/AccountManage/UnlockAccountRequest"
else -> throw ScrapperException("Nieznany dziennik $registerBaseUrl, $loginType")
}
} else unlockUrl
} }
private fun getLoginType(urlGenerator: ServiceManager.UrlGenerator): Single<Scrapper.LoginType> { private suspend fun getLoginType(urlGenerator: ServiceManager.UrlGenerator): Scrapper.LoginType {
return account.getFormType(urlGenerator.generate(ServiceManager.UrlGenerator.Site.LOGIN) + "Account/LogOn").map { it.page }.map { val page = account.getFormType(urlGenerator.generate(ServiceManager.UrlGenerator.Site.LOGIN) + "Account/LogOn").page
when {
it.select(SELECTOR_STANDARD).isNotEmpty() -> STANDARD return when {
it.select(SELECTOR_ADFS).isNotEmpty() -> ADFS page.select(SELECTOR_STANDARD).isNotEmpty() -> STANDARD
it.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> { page.select(SELECTOR_ADFS).isNotEmpty() -> ADFS
it.selectFirst("form").attr("action").run { page.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> {
when { page.selectFirst("form").attr("action").run {
contains("cufs.edu.lublin.eu") -> ADFSLightCufs when {
startsWith("/LoginPage.aspx") -> ADFSLight contains("cufs.edu.lublin.eu") -> ADFSLightCufs
startsWith("/${urlGenerator.symbol}/LoginPage.aspx") -> ADFSLightScoped startsWith("/LoginPage.aspx") -> ADFSLight
else -> throw ScrapperException("Nieznany typ dziennika ADFS") startsWith("/${urlGenerator.symbol}/LoginPage.aspx") -> ADFSLightScoped
} else -> throw ScrapperException("Nieznany typ dziennika ADFS")
} }
} }
it.select(SELECTOR_ADFS_CARDS).isNotEmpty() -> ADFSCards
else -> throw ScrapperException("Nieznany typ dziennika '${it.select("title")}")
} }
page.select(SELECTOR_ADFS_CARDS).isNotEmpty() -> ADFSCards
else -> throw ScrapperException("Nieznany typ dziennika '${page.select("title")}")
} }
} }
} }

View file

@ -3,97 +3,71 @@ package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.getScriptParam import io.github.wulkanowy.sdk.scrapper.getScriptParam
import io.github.wulkanowy.sdk.scrapper.home.GovernmentUnit import io.github.wulkanowy.sdk.scrapper.home.GovernmentUnit
import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorHandlerTransformer import io.github.wulkanowy.sdk.scrapper.interceptor.handleErrors
import io.github.wulkanowy.sdk.scrapper.service.HomepageService import io.github.wulkanowy.sdk.scrapper.service.HomepageService
import io.reactivex.Single
class HomepageRepository(private val api: HomepageService) { class HomepageRepository(private val api: HomepageService) {
private lateinit var token: String private lateinit var token: String
private fun getToken(): Single<String> { private suspend fun getToken(): String {
if (::token.isInitialized) return Single.just(token) if (::token.isInitialized) return token
return api.getStart().map { val page = api.getStart()
getScriptParam("permissions", it) val permissions = getScriptParam("permissions", page)
}.map { it.apply { token = this } } token = permissions
return permissions
} }
fun getSelfGovernments(): Single<List<GovernmentUnit>> { suspend fun getSelfGovernments(): List<GovernmentUnit> {
return getToken().flatMap { api.getSelfGovernments(it) } val res = api.getSelfGovernments(getToken()).handleErrors().data
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } return requireNotNull(res)
} }
fun getStudentThreats(): Single<List<String>> { suspend fun getStudentThreats(): List<String> {
return getToken().flatMap { api.getStudentThreats(it) } return api.getStudentThreats(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getStudentsTrips(): Single<List<String>> { suspend fun getStudentsTrips(): List<String> {
return getToken().flatMap { api.getStudentsTrips(it) } return api.getStudentsTrips(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getLastGrades(): Single<List<String>> { suspend fun getLastGrades(): List<String> {
return getToken().flatMap { api.getLastGrades(it) } return api.getLastGrades(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getFreeDays(): Single<List<String>> { suspend fun getFreeDays(): List<String> {
return getToken().flatMap { api.getFreeDays(it) } return api.getFreeDays(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getKidsLuckyNumbers(): Single<List<LuckyNumber>> { suspend fun getKidsLuckyNumbers(): List<LuckyNumber> {
return getToken().flatMap { api.getKidsLuckyNumbers(it) } val res = api.getKidsLuckyNumbers(getToken()).handleErrors().data
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() } return requireNotNull(res).map { unit ->
.map { res -> unit.content.map { school ->
res.map { unit -> school.content.map { number ->
unit.content.map { school -> LuckyNumber(
school.content.map { number -> unitName = unit.name,
LuckyNumber( school = school.name,
unitName = unit.name, number = number.name.substringAfterLast(": ").toInt()
school = school.name, )
number = number.name.substringAfterLast(": ").toInt() }
) }.flatten()
} }.flatten()
}.flatten()
}.flatten()
}
} }
fun getKidsLessonPlan(): Single<List<String>> { suspend fun getKidsLessonPlan(): List<String> {
return getToken().flatMap { api.getKidsLessonPlan(it) } return api.getKidsLessonPlan(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }
.map { res -> res.map { it.name } }
} }
fun getLastHomework(): Single<List<String>> { suspend fun getLastHomework(): List<String> {
return getToken().flatMap { api.getLastHomework(it) } return api.getLastHomework(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getLastTests(): Single<List<String>> { suspend fun getLastTests(): List<String> {
return getToken().flatMap { api.getLastTests(it) } return api.getLastTests(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
fun getLastStudentLessons(): Single<List<String>> { suspend fun getLastStudentLessons(): List<String> {
return getToken().flatMap { api.getLastStudentLessons(it) } return api.getLastStudentLessons(getToken()).handleErrors().data.orEmpty()[0].content.map { it.name }
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }.map { it[0].content }.map { res ->
res.map { it.name }
}
} }
} }

View file

@ -4,8 +4,8 @@ import com.google.gson.Gson
import io.github.wulkanowy.sdk.scrapper.ApiResponse import io.github.wulkanowy.sdk.scrapper.ApiResponse
import io.github.wulkanowy.sdk.scrapper.ScrapperException import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.getScriptParam import io.github.wulkanowy.sdk.scrapper.getScriptParam
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorHandlerTransformer
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.interceptor.handleErrors
import io.github.wulkanowy.sdk.scrapper.messages.Attachment import io.github.wulkanowy.sdk.scrapper.messages.Attachment
import io.github.wulkanowy.sdk.scrapper.messages.DeleteMessageRequest import io.github.wulkanowy.sdk.scrapper.messages.DeleteMessageRequest
import io.github.wulkanowy.sdk.scrapper.messages.Message import io.github.wulkanowy.sdk.scrapper.messages.Message
@ -14,125 +14,101 @@ import io.github.wulkanowy.sdk.scrapper.messages.ReportingUnit
import io.github.wulkanowy.sdk.scrapper.messages.SendMessageRequest import io.github.wulkanowy.sdk.scrapper.messages.SendMessageRequest
import io.github.wulkanowy.sdk.scrapper.messages.SentMessage import io.github.wulkanowy.sdk.scrapper.messages.SentMessage
import io.github.wulkanowy.sdk.scrapper.service.MessagesService import io.github.wulkanowy.sdk.scrapper.service.MessagesService
import io.reactivex.Single
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime
import org.threeten.bp.format.DateTimeFormatter import org.threeten.bp.format.DateTimeFormatter
class MessagesRepository(private val api: MessagesService) { class MessagesRepository(private val api: MessagesService) {
fun getReportingUnits(): Single<List<ReportingUnit>> { suspend fun getReportingUnits(): List<ReportingUnit> {
return api.getUserReportingUnits().map { it.data.orEmpty() } return api.getUserReportingUnits().data.orEmpty()
} }
fun getRecipients(unitId: Int, role: Int = 2): Single<List<Recipient>> { suspend fun getRecipients(unitId: Int, role: Int = 2): List<Recipient> {
return api.getRecipients(unitId, role) return api.getRecipients(unitId, role).handleErrors().data.orEmpty().map {
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() } it.copy(shortName = it.name.normalizeRecipient())
.map { res -> }
res.map { it.copy(shortName = it.name.normalizeRecipient()) } }
suspend fun getReceivedMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): List<Message> {
return api.getReceived(getDate(startDate), getDate(endDate)).handleErrors().data.orEmpty()
.map { it.copy(folderId = 1) }
.sortedBy { it.date }
.toList()
}
suspend fun getSentMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): List<Message> {
return api.getSent(getDate(startDate), getDate(endDate)).handleErrors().data.orEmpty()
.map { message ->
message.copy(
messageId = message.id,
folderId = 2,
recipient = message.recipient?.split(";")?.joinToString("; ") { it.normalizeRecipient() }
)
} }
.sortedBy { it.date }
.toList()
} }
fun getReceivedMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): Single<List<Message>> { suspend fun getDeletedMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): List<Message> {
return api.getReceived(getDate(startDate), getDate(endDate)) return api.getDeleted(getDate(startDate), getDate(endDate)).handleErrors().data.orEmpty()
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() } .map { it.apply { removed = true } }
.map { res -> .sortedBy { it.date }
res.asSequence() .toList()
.map { it.copy(folderId = 1) }
.sortedBy { it.date }
.toList()
}
} }
fun getSentMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): Single<List<Message>> { suspend fun getMessageRecipients(messageId: Int, loginId: Int): List<Recipient> {
return api.getSent(getDate(startDate), getDate(endDate)) return (if (0 == loginId) api.getMessageRecipients(messageId).handleErrors()
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() } else api.getMessageSender(loginId, messageId)).handleErrors().data.orEmpty().map { recipient ->
.map { res -> recipient.copy(shortName = recipient.name.normalizeRecipient())
res.asSequence() }
.map { message ->
message.copy(
messageId = message.id,
folderId = 2,
recipient = message.recipient?.split(";")?.joinToString("; ") { it.normalizeRecipient() }
)
}
.sortedBy { it.date }
.toList()
}
} }
fun getDeletedMessages(startDate: LocalDateTime?, endDate: LocalDateTime?): Single<List<Message>> { suspend fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean, id: Int?): Message {
return api.getDeleted(getDate(startDate), getDate(endDate)) return api.getMessage(messageId, folderId, read, id).handleErrors().data!!
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map { res ->
res.asSequence()
.map { it.apply { removed = true } }
.sortedBy { it.date }
.toList()
}
} }
fun getMessageRecipients(messageId: Int, loginId: Int): Single<List<Recipient>> { suspend fun getMessage(messageId: Int, folderId: Int, read: Boolean, id: Int?): String {
return (if (0 == loginId) api.getMessageRecipients(messageId) return api.getMessage(messageId, folderId, read, id).handleErrors().data?.content.orEmpty()
else api.getMessageSender(loginId, messageId))
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map {
it.map { recipient ->
recipient.copy(shortName = recipient.name.normalizeRecipient())
}
}
} }
fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean, id: Int?): Single<Message> { suspend fun getMessageAttachments(messageId: Int, folderId: Int): List<Attachment> {
return api.getMessage(messageId, folderId, read, id) return api.getMessage(messageId, folderId, false, null).handleErrors().data?.attachments.orEmpty()
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
} }
fun getMessage(messageId: Int, folderId: Int, read: Boolean, id: Int?): Single<String> { suspend fun sendMessage(subject: String, content: String, recipients: List<Recipient>): SentMessage {
return api.getMessage(messageId, folderId, read, id) val res = api.getStart()
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } return api.sendMessage(
.map { it.content.orEmpty() } SendMessageRequest(
SendMessageRequest.Incoming(
recipients = recipients,
subject = subject,
content = content
)
),
getScriptParam("antiForgeryToken", res).ifBlank { throw ScrapperException("Can't find antiForgeryToken property!") },
getScriptParam("appGuid", res),
getScriptParam("version", res)
).handleErrors().data!!
} }
fun getMessageAttachments(messageId: Int, folderId: Int): Single<List<Attachment>> { suspend fun deleteMessages(messages: List<Pair<Int, Int>>): Boolean {
return api.getMessage(messageId, folderId, false, null) val startPage = api.getStart()
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } val res = api.deleteMessage(
.map { it.attachments.orEmpty() } messages.map { (messageId, folderId) ->
} DeleteMessageRequest(
messageId = messageId,
folderId = folderId
)
},
getScriptParam("antiForgeryToken", startPage),
getScriptParam("appGuid", startPage),
getScriptParam("version", startPage)
)
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> { val apiResponse = if (res.isBlank()) throw VulcanException("Unexpected empty response. Message(s) may already be deleted")
return api.getStart().flatMap { res -> else Gson().fromJson(res, ApiResponse::class.java)
api.sendMessage(
SendMessageRequest(
SendMessageRequest.Incoming(
recipients = recipients,
subject = subject,
content = content
)
),
getScriptParam("antiForgeryToken", res).ifBlank { throw ScrapperException("Can't find antiForgeryToken property!") },
getScriptParam("appGuid", res),
getScriptParam("version", res)
)
}.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
}
fun deleteMessages(messages: List<Pair<Int, Int>>): Single<Boolean> { return apiResponse.success
return api.getStart().flatMap { res ->
api.deleteMessage(
messages.map { (messageId, folderId) ->
DeleteMessageRequest(
messageId = messageId,
folderId = folderId
)
},
getScriptParam("antiForgeryToken", res),
getScriptParam("appGuid", res),
getScriptParam("version", res)
)
}.flatMap {
if (it.isBlank()) Single.error(VulcanException("Unexpected empty response. Message(s) may already be deleted"))
else Single.just(Gson().fromJson(it, ApiResponse::class.java))
}.compose(ErrorHandlerTransformer()).map { it.success }
} }
private fun String.normalizeRecipient(): String { private fun String.normalizeRecipient(): String {

View file

@ -5,7 +5,7 @@ import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.exception.TemporarilyDisabledException import io.github.wulkanowy.sdk.scrapper.exception.TemporarilyDisabledException
import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.sdk.scrapper.getScriptParam import io.github.wulkanowy.sdk.scrapper.getScriptParam
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorHandlerTransformer import io.github.wulkanowy.sdk.scrapper.interceptor.handleErrors
import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException
import io.github.wulkanowy.sdk.scrapper.login.CertificateResponse import io.github.wulkanowy.sdk.scrapper.login.CertificateResponse
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
@ -20,8 +20,6 @@ import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import io.reactivex.Observable
import io.reactivex.Single
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.parser.Parser import org.jsoup.parser.Parser
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -44,128 +42,118 @@ class RegisterRepository(
private val logger = LoggerFactory.getLogger(this::class.java) private val logger = LoggerFactory.getLogger(this::class.java)
} }
fun getStudents(): Single<List<Student>> { suspend fun getStudents(): List<Student> {
return getSymbols().flatMapObservable { Observable.fromIterable(it) }.flatMap { (symbol, certificate) -> return getSymbols().map { (symbol, certificate) ->
loginHelper.sendCertificate(certificate, email, certificate.action.replace(startSymbol.getNormalizedSymbol(), symbol)) val cert = try {
.onErrorResumeNext { t -> loginHelper.sendCertificate(certificate, email, certificate.action.replace(startSymbol.getNormalizedSymbol(), symbol))
if (t is AccountPermissionException) Single.just(SendCertificateResponse()) } catch (e: AccountPermissionException) {
else Single.error(t) SendCertificateResponse()
}
.flatMapObservable { Observable.fromIterable(if (useNewStudent) it.studentSchools else it.oldStudentSchools) }
.flatMapSingle { moduleUrl ->
getLoginType(symbol).flatMap { loginType ->
getStudents(symbol, moduleUrl.attr("href")).map { students ->
students.map { student ->
Student(
email = email,
symbol = symbol,
studentId = student.id,
studentName = student.name,
schoolSymbol = getExtractedSchoolSymbolFromUrl(moduleUrl.attr("href")),
schoolShortName = moduleUrl.text().takeIf { "Uczeń" !in it }.orEmpty(),
schoolName = student.description,
className = student.className,
classId = student.classId,
baseUrl = url.generate(ServiceManager.UrlGenerator.Site.BASE),
loginType = loginType,
isParent = student.isParent
)
}
}
}
}
}.toList().map {
it.flatten().distinctBy { pupil ->
listOf(pupil.studentId, pupil.classId, pupil.schoolSymbol)
} }
} (if (useNewStudent) cert.studentSchools else cert.oldStudentSchools).map { moduleUrl ->
val loginType = getLoginType(symbol)
getStudents(symbol, moduleUrl.attr("href")).map { student ->
Student(
email = email,
symbol = symbol,
studentId = student.id,
studentName = student.name,
schoolSymbol = getExtractedSchoolSymbolFromUrl(moduleUrl.attr("href")),
schoolShortName = moduleUrl.text().takeIf { "Uczeń" !in it }.orEmpty(),
schoolName = student.description,
className = student.className,
classId = student.classId,
baseUrl = url.generate(ServiceManager.UrlGenerator.Site.BASE),
loginType = loginType,
isParent = student.isParent
)
}
}.flatten()
}.flatten().distinctBy { pupil -> listOf(pupil.studentId, pupil.classId, pupil.schoolSymbol) }
} }
private fun getSymbols(): Single<List<Pair<String, CertificateResponse>>> { private suspend fun getSymbols(): List<Pair<String, CertificateResponse>> {
return getLoginType(startSymbol.getNormalizedSymbol()).map { val symbolLoginType = getLoginType(startSymbol.getNormalizedSymbol())
loginHelper.apply { loginType = it } val cert = loginHelper.apply { loginType = symbolLoginType }.sendCredentials(email, password)
}.flatMap { login ->
login.sendCredentials(email, password).flatMap { Single.just(it) }.flatMap { cert -> return Jsoup.parse(cert.wresult.replace(":", ""), "", Parser.xmlParser())
Single.just(Jsoup.parse(cert.wresult.replace(":", ""), "", Parser.xmlParser()) .select("[AttributeName$=\"Instance\"] samlAttributeValue")
.select("[AttributeName$=\"Instance\"] samlAttributeValue") .map { it.text().trim() }
.map { it.text().trim() } .apply { logger.debug("$this") }
.apply { logger.debug("$this") } .filter { it.matches("[a-zA-Z0-9]*".toRegex()) } // early filter invalid symbols
.filter { it.matches("[a-zA-Z0-9]*".toRegex()) } // early filter invalid symbols .map { Pair(it, cert) }
.map { Pair(it, cert) }
)
}
}
} }
private fun getLoginType(symbol: String): Single<Scrapper.LoginType> { private suspend fun getLoginType(symbol: String): Scrapper.LoginType {
return getLoginType(url.also { it.symbol = symbol }) return getLoginType(url.also { it.symbol = symbol })
} }
private fun getLoginType(urlGenerator: ServiceManager.UrlGenerator): Single<Scrapper.LoginType> { private suspend fun getLoginType(urlGenerator: ServiceManager.UrlGenerator): Scrapper.LoginType {
return register.getFormType(urlGenerator.generate(ServiceManager.UrlGenerator.Site.LOGIN) + "Account/LogOn").map { it.page }.map { val page = register.getFormType(urlGenerator.generate(ServiceManager.UrlGenerator.Site.LOGIN) + "Account/LogOn").page
when { return when {
it.select(SELECTOR_STANDARD).isNotEmpty() -> Scrapper.LoginType.STANDARD page.select(SELECTOR_STANDARD).isNotEmpty() -> Scrapper.LoginType.STANDARD
it.select(SELECTOR_ADFS).isNotEmpty() -> Scrapper.LoginType.ADFS page.select(SELECTOR_ADFS).isNotEmpty() -> Scrapper.LoginType.ADFS
it.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> { page.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> {
it.selectFirst("form").attr("action").run { page.selectFirst("form").attr("action").run {
when { when {
contains("cufs.edu.lublin.eu") -> Scrapper.LoginType.ADFSLightCufs contains("cufs.edu.lublin.eu") -> Scrapper.LoginType.ADFSLightCufs
startsWith("/LoginPage.aspx") -> Scrapper.LoginType.ADFSLight startsWith("/LoginPage.aspx") -> Scrapper.LoginType.ADFSLight
startsWith("/${urlGenerator.symbol}/LoginPage.aspx") -> Scrapper.LoginType.ADFSLightScoped startsWith("/${urlGenerator.symbol}/LoginPage.aspx") -> Scrapper.LoginType.ADFSLightScoped
else -> throw ScrapperException("Nieznany typ dziennika ADFS") else -> throw ScrapperException("Nieznany typ dziennika ADFS")
}
} }
} }
it.select(SELECTOR_ADFS_CARDS).isNotEmpty() -> Scrapper.LoginType.ADFSCards
else -> throw ScrapperException("Nieznany typ dziennika")
} }
page.select(SELECTOR_ADFS_CARDS).isNotEmpty() -> Scrapper.LoginType.ADFSCards
else -> throw ScrapperException("Nieznany typ dziennika")
} }
} }
private fun getStudents(symbol: String, schoolUrl: String): Single<List<StudentAndParentResponse.Student>> { private suspend fun getStudents(symbol: String, schoolUrl: String): List<StudentAndParentResponse.Student> {
url.schoolId = getExtractedSchoolSymbolFromUrl(schoolUrl) url.schoolId = getExtractedSchoolSymbolFromUrl(schoolUrl)
url.symbol = symbol url.symbol = symbol
return if (!useNewStudent) snp.getSchoolInfo(schoolUrl).map { res -> return if (!useNewStudent) {
val res = snp.getSchoolInfo(schoolUrl)
res.students.map { student -> res.students.map { student ->
student.apply { student.apply {
description = res.schoolName description = res.schoolName
className = res.diaries[0].name className = res.diaries[0].name
} }
} }
} else student.getStart(url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "Start").onErrorResumeNext { } else {
if (it is TemporarilyDisabledException) Single.just("") val startPage = try {
else Single.error(it) student.getStart(url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "Start")
}.flatMap { startPage -> } catch (e: TemporarilyDisabledException) {
if (startPage.isBlank()) return@flatMap Single.just<List<StudentAndParentResponse.Student>>(listOf()) return listOf()
student.getUserCache( }
val cache = student.getUserCache(
url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "UczenCache.mvc/Get", url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "UczenCache.mvc/Get",
getScriptParam("antiForgeryToken", startPage), getScriptParam("antiForgeryToken", startPage),
getScriptParam("appGuid", startPage), getScriptParam("appGuid", startPage),
getScriptParam("version", startPage) getScriptParam("version", startPage)
).flatMap { cache -> )
student.getSchoolInfo(url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "UczenDziennik.mvc/Get")
.compose(ErrorHandlerTransformer()) val diaries = student
.map { diaries -> .getSchoolInfo(url.generate(ServiceManager.UrlGenerator.Site.STUDENT) + "UczenDziennik.mvc/Get")
diaries.data.orEmpty() .handleErrors()
.filter { diary -> diary.semesters?.isNotEmpty() ?: false } .data.orEmpty()
.sortedByDescending { diary -> diary.level }
.distinctBy { diary -> listOf(diary.studentId, diary.semesters!![0].classId) } diaries.filter { diary -> diary.semesters?.isNotEmpty() ?: false }
.map { .sortedByDescending { diary -> diary.level }
StudentAndParentResponse.Student().apply { .distinctBy { diary -> listOf(diary.studentId, diary.semesters!![0].classId) }
id = it.studentId .map {
name = "${it.studentName} ${it.studentSurname}" StudentAndParentResponse.Student().apply {
description = getScriptParam("organizationName", startPage, it.symbol + " " + (it.year - it.level + 1)) id = it.studentId
className = it.level.toString() + it.symbol name = "${it.studentName} ${it.studentSurname}"
classId = it.semesters!![0].classId description = getScriptParam("organizationName", startPage, it.symbol + " " + (it.year - it.level + 1))
isParent = cache.data?.isParent ?: false className = it.level.toString() + it.symbol
} classId = it.semesters!![0].classId
} isParent = cache.data?.isParent ?: false
.ifEmpty {
logger.debug("No supported student found: $diaries")
emptyList()
}
} }
} }
.ifEmpty {
logger.debug("No supported student found: $diaries")
emptyList()
}
} }
} }

View file

@ -25,7 +25,6 @@ import io.github.wulkanowy.sdk.scrapper.timetable.TimetableParser
import io.github.wulkanowy.sdk.scrapper.toDate import io.github.wulkanowy.sdk.scrapper.toDate
import io.github.wulkanowy.sdk.scrapper.toFormat import io.github.wulkanowy.sdk.scrapper.toFormat
import io.github.wulkanowy.sdk.scrapper.toLocalDate import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.Month import org.threeten.bp.Month
import java.util.Calendar import java.util.Calendar
@ -34,207 +33,189 @@ import java.util.TimeZone
class StudentAndParentRepository(private val api: StudentAndParentService) { class StudentAndParentRepository(private val api: StudentAndParentService) {
fun getAttendance(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Attendance>> { suspend fun getAttendance(startDate: LocalDate, endDate: LocalDate? = null): List<Attendance> {
val end = endDate ?: startDate.plusDays(4) val end = endDate ?: startDate.plusDays(4)
return api.getAttendance(startDate.getLastMonday().toTick()).map { res -> val res = api.getAttendance(startDate.getLastMonday().toTick())
res.rows.flatMap { row -> return res.rows.flatMap { row ->
row.lessons.mapIndexedNotNull { i, it -> row.lessons.mapIndexedNotNull { i, it ->
if ("null" == it.subject) return@mapIndexedNotNull null // fix empty months if ("null" == it.subject) return@mapIndexedNotNull null // fix empty months
it.apply {
date = res.days[i]
number = row.number
presence = it.type == Types.PRESENCE || it.type == Types.ABSENCE_FOR_SCHOOL_REASONS
absence = it.type == Types.ABSENCE_UNEXCUSED || it.type == Types.ABSENCE_EXCUSED
lateness = it.type == Types.EXCUSED_LATENESS || it.type == Types.UNEXCUSED_LATENESS
excused = it.type == Types.ABSENCE_EXCUSED || it.type == Types.EXCUSED_LATENESS
exemption = it.type == Types.EXEMPTION
excusable = res.excuseActiveSnp.isNotEmpty() && (absence || lateness) && !excused
}
}
}.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end
}.sortedWith(compareBy({ it.date }, { it.number })).toList()
}
}
fun getAttendanceSummary(subjectId: Int?): Single<List<AttendanceSummary>> {
return api.getAttendanceSummary(subjectId).map { res ->
res.months.mapIndexedNotNull { i, month ->
if (res.summaryRows.all { it.value[i].isBlank() }) return@mapIndexedNotNull null
AttendanceSummary(romanToMonthEnum(month),
res.summaryRows[0].value[i].toIntOrNull() ?: 0,
res.summaryRows[1].value[i].toIntOrNull() ?: 0,
res.summaryRows[2].value[i].toIntOrNull() ?: 0,
res.summaryRows[3].value[i].toIntOrNull() ?: 0,
res.summaryRows[4].value[i].toIntOrNull() ?: 0,
res.summaryRows[5].value[i].toIntOrNull() ?: 0,
res.summaryRows[6].value[i].toIntOrNull() ?: 0
)
}
}
}
fun getSubjects(): Single<List<Subject>> {
return api.getAttendanceSummary(-1).map { it.subjects }
}
fun getExams(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Exam>> {
val end = endDate ?: startDate.plusDays(4)
return api.getExams(startDate.getLastMonday().toTick()).map { res ->
res.days.flatMap { day ->
day.exams.map { exam ->
exam.apply {
if (group.contains(" ")) group = ""
date = day.date
}
}
}.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end
}.sortedBy { it.date }.toList()
}
}
fun getGrades(semesterId: Int?): Single<Pair<List<Grade>, List<GradeSummary>>> {
return getGradesDetails(semesterId).flatMap { details ->
getGradesSummary(semesterId).map { summary ->
details to summary
}
}
}
fun getGradesDetails(semesterId: Int?): Single<List<Grade>> {
return api.getGrades(semesterId).map { res ->
res.grades.asSequence().map { grade ->
grade.apply {
comment = if (entry.length > 4) "$entry ($comment)".replace(" ($comment)", "") else comment
entry = entry.run { if (length > 4) "..." else this }
if (entry == comment) comment = ""
if (description == symbol) description = ""
}
}.toList().sortedByDescending { it.date }
}
}
fun getGradesSummary(semesterId: Int?): Single<List<GradeSummary>> {
return api.getGradesSummary(semesterId).map { res ->
res.subjects.asSequence().map { summary ->
summary.apply {
predicted = if (predicted != "-") getGradeShortValue(predicted) else ""
final = if (final != "-") getGradeShortValue(final) else ""
}
}.sortedBy { it.name }.toList()
}
}
fun getGradesStatistics(semesterId: Int, annual: Boolean): Single<List<GradeStatistics>> {
return api.getGradesStatistics(if (!annual) 1 else 2, semesterId).map { res ->
res.items.map {
it.apply { it.apply {
grade = getGradeShortValue(grade) date = res.days[i]
gradeValue = getGradeShortValue(grade).toIntOrNull() ?: 0 number = row.number
this.semesterId = res.semesterId presence = it.type == Types.PRESENCE || it.type == Types.ABSENCE_FOR_SCHOOL_REASONS
absence = it.type == Types.ABSENCE_UNEXCUSED || it.type == Types.ABSENCE_EXCUSED
lateness = it.type == Types.EXCUSED_LATENESS || it.type == Types.UNEXCUSED_LATENESS
excused = it.type == Types.ABSENCE_EXCUSED || it.type == Types.EXCUSED_LATENESS
exemption = it.type == Types.EXEMPTION
excusable = res.excuseActiveSnp.isNotEmpty() && (absence || lateness) && !excused
} }
} }
}.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end
}.sortedWith(compareBy({ it.date }, { it.number })).toList()
}
suspend fun getAttendanceSummary(subjectId: Int?): List<AttendanceSummary> {
val res = api.getAttendanceSummary(subjectId)
return res.months.mapIndexedNotNull { i, month ->
if (res.summaryRows.all { it.value[i].isBlank() }) return@mapIndexedNotNull null
AttendanceSummary(romanToMonthEnum(month),
res.summaryRows[0].value[i].toIntOrNull() ?: 0,
res.summaryRows[1].value[i].toIntOrNull() ?: 0,
res.summaryRows[2].value[i].toIntOrNull() ?: 0,
res.summaryRows[3].value[i].toIntOrNull() ?: 0,
res.summaryRows[4].value[i].toIntOrNull() ?: 0,
res.summaryRows[5].value[i].toIntOrNull() ?: 0,
res.summaryRows[6].value[i].toIntOrNull() ?: 0
)
}
}
suspend fun getSubjects(): List<Subject> {
return api.getAttendanceSummary(-1).subjects
}
suspend fun getExams(startDate: LocalDate, endDate: LocalDate? = null): List<Exam> {
val end = endDate ?: startDate.plusDays(4)
val res = api.getExams(startDate.getLastMonday().toTick())
return res.days.flatMap { day ->
day.exams.map { exam ->
exam.apply {
if (group.contains(" ")) group = ""
date = day.date
}
}
}.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end
}.sortedBy { it.date }.toList()
}
suspend fun getGrades(semesterId: Int?): Pair<List<Grade>, List<GradeSummary>> {
return getGradesDetails(semesterId) to getGradesSummary(semesterId)
}
suspend fun getGradesDetails(semesterId: Int?): List<Grade> {
val res = api.getGrades(semesterId)
return res.grades.asSequence().map { grade ->
grade.apply {
comment = if (entry.length > 4) "$entry ($comment)".replace(" ($comment)", "") else comment
entry = entry.run { if (length > 4) "..." else this }
if (entry == comment) comment = ""
if (description == symbol) description = ""
}
}.toList().sortedByDescending { it.date }
}
suspend fun getGradesSummary(semesterId: Int?): List<GradeSummary> {
val res = api.getGradesSummary(semesterId)
return res.subjects.asSequence().map { summary ->
summary.apply {
predicted = if (predicted != "-") getGradeShortValue(predicted) else ""
final = if (final != "-") getGradeShortValue(final) else ""
}
}.sortedBy { it.name }.toList()
}
suspend fun getGradesStatistics(semesterId: Int, annual: Boolean): List<GradeStatistics> {
val res = api.getGradesStatistics(if (!annual) 1 else 2, semesterId)
return res.items.map {
it.apply {
grade = getGradeShortValue(grade)
gradeValue = getGradeShortValue(grade).toIntOrNull() ?: 0
this.semesterId = res.semesterId
}
} }
} }
fun getHomework(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Homework>> { suspend fun getHomework(startDate: LocalDate, endDate: LocalDate? = null): List<Homework> {
val end = endDate ?: startDate.plusDays(4) val end = endDate ?: startDate.plusDays(4)
return api.getHomework(startDate.toTick()).map { res -> val res = api.getHomework(startDate.toTick())
res.items.asSequence().map { return res.items.asSequence().map {
it.apply { it.apply {
date = res.date date = res.date
} }
}.filter { }.filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= end
}.sortedWith(compareBy({ it.date }, { it.subject })).toList() }.sortedWith(compareBy({ it.date }, { it.subject })).toList()
}
} }
fun getNotes(): Single<List<Note>> { suspend fun getNotes(): List<Note> {
return api.getNotes().map { res -> val res = api.getNotes()
res.notes.asSequence().mapIndexed { i, note -> return res.notes.asSequence().mapIndexed { i, note ->
note.apply { note.apply {
if (teacher == teacherSymbol) teacherSymbol = "" if (teacher == teacherSymbol) teacherSymbol = ""
date = res.dates[i] date = res.dates[i]
} }
}.sortedWith(compareBy({ it.date }, { it.category })).toList() }.sortedWith(compareBy({ it.date }, { it.category })).toList()
}
} }
fun getRegisteredDevices(): Single<List<Device>> { suspend fun getRegisteredDevices(): List<Device> {
return api.getRegisteredDevices().map { it.devices } return api.getRegisteredDevices().devices
} }
fun getToken(): Single<TokenResponse> { suspend fun getToken(): TokenResponse {
return api.getToken() return api.getToken()
} }
fun unregisterDevice(id: Int): Single<Boolean> { suspend fun unregisterDevice(id: Int): Boolean {
return api.unregisterDevice(id).map { !it.devices.any { device -> device.id == id } } return api.unregisterDevice(id).devices.any { device -> device.id == id }
} }
fun getTeachers(): Single<List<Teacher>> { suspend fun getTeachers(): List<Teacher> {
return api.getSchoolAndTeachers().map { res -> val res = api.getSchoolAndTeachers()
res.subjects.flatMap { subject -> return res.subjects.flatMap { subject ->
subject.teachers.split(", ").map { teacher -> subject.teachers.split(", ").map { teacher ->
teacher.split(" [").run { teacher.split(" [").run {
Teacher(first().getEmptyIfDash(), last().removeSuffix("]").getEmptyIfDash(), subject.name.let { Teacher(first().getEmptyIfDash(), last().removeSuffix("]").getEmptyIfDash(), subject.name.let {
if (it.isBlank()) "" if (it.isBlank()) ""
else it else it
}) })
}
} }
}.sortedWith(compareBy({ it.subject }, { it.name }))
}
}
fun getSchool(): Single<School> {
return api.getSchoolAndTeachers().map {
School(it.name, it.address, it.contact, it.headmaster, it.pedagogue)
}
}
fun getStudentInfo(): Single<StudentInfo> {
return api.getStudentInfo().map {
it.apply {
student.polishCitizenship = if ("Tak" == student.polishCitizenship) "1" else "0"
} }
}.sortedWith(compareBy({ it.subject }, { it.name }))
}
suspend fun getSchool(): School {
val res = api.getSchoolAndTeachers()
return School(res.name, res.address, res.contact, res.headmaster, res.pedagogue)
}
suspend fun getStudentInfo(): StudentInfo {
return api.getStudentInfo().apply {
student.polishCitizenship = if ("Tak" == student.polishCitizenship) "1" else "0"
} }
} }
fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Timetable>> { suspend fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null): List<Timetable> {
return api.getTimetable(startDate.getLastMonday().toTick()).map { res -> val res = api.getTimetable(startDate.getLastMonday().toTick())
res.rows.flatMap { row -> return res.rows.flatMap { row ->
row.lessons.asSequence().mapIndexed { i, it -> row.lessons.asSequence().mapIndexed { i, it ->
it.apply { it.apply {
date = res.days[i] date = res.days[i]
start = "${date.toLocalDate().toFormat("yyy-MM-dd")} ${row.startTime}".toDate("yyyy-MM-dd HH:mm") start = "${date.toLocalDate().toFormat("yyy-MM-dd")} ${row.startTime}".toDate("yyyy-MM-dd HH:mm")
end = "${date.toLocalDate().toFormat("yyy-MM-dd")} ${row.endTime}".toDate("yyyy-MM-dd HH:mm") end = "${date.toLocalDate().toFormat("yyy-MM-dd")} ${row.endTime}".toDate("yyyy-MM-dd HH:mm")
number = row.number number = row.number
} }
}.mapNotNull { TimetableParser().getTimetable(it) }.toList() }.mapNotNull { TimetableParser().getTimetable(it) }.toList()
}.asSequence().filter { }.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= endDate ?: startDate.plusDays(4) it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= endDate ?: startDate.plusDays(4)
}.sortedWith(compareBy({ it.date }, { it.number })).toList() }.sortedWith(compareBy({ it.date }, { it.number })).toList()
}
} }
fun getCompletedLessons(start: LocalDate, endDate: LocalDate?, subjectId: Int): Single<List<CompletedLesson>> { suspend fun getCompletedLessons(start: LocalDate, endDate: LocalDate?, subjectId: Int): List<CompletedLesson> {
val end = endDate ?: start.plusMonths(1) val end = endDate ?: start.plusMonths(1)
return api.getCompletedLessons(start.toTick(), end.toTick(), subjectId).map { res -> val res = api.getCompletedLessons(start.toTick(), end.toTick(), subjectId)
return res.items.mapNotNull {
lateinit var lastDate: Date lateinit var lastDate: Date
res.items.asSequence().mapNotNull { if (it.subject.isBlank()) {
if (it.subject.isBlank()) { lastDate = it.date
lastDate = it.date return@mapNotNull null
return@mapNotNull null
}
it.apply { date = lastDate }
}.sortedWith(compareBy({ it.date }, { it.number })).toList().filter {
it.date.toLocalDate() >= start && it.date.toLocalDate() <= end
} }
it.apply { date = lastDate }
}.sortedWith(compareBy({ it.date }, { it.number })).filter {
it.date.toLocalDate() >= start && it.date.toLocalDate() <= end
} }
} }

View file

@ -3,8 +3,6 @@ package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.register.Semester import io.github.wulkanowy.sdk.scrapper.register.Semester
import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService
import io.reactivex.Observable
import io.reactivex.Single
class StudentAndParentStartRepository( class StudentAndParentStartRepository(
private val symbol: String, private val symbol: String,
@ -13,23 +11,21 @@ class StudentAndParentStartRepository(
private val api: StudentAndParentService private val api: StudentAndParentService
) { ) {
fun getSemesters(): Single<List<Semester>> { suspend fun getSemesters(): List<Semester> {
return api.getUserInfo(studentId).map { val userInfo = api.getUserInfo(studentId)
it.apply { if (!userInfo.title.startsWith("Witryna ucznia i rodzica")) throw VulcanException("Unknow page with title: ${userInfo.title}")
if (!it.title.startsWith("Witryna ucznia i rodzica")) throw VulcanException("Unknow page with title: ${it.title}")
return userInfo.diaries.reversed().map { diary ->
val res = api.getDiaryInfo(diary.id, "/$symbol/$schoolSymbol/Oceny.mvc/Wszystkie")
if (!res.title.endsWith("Oceny")) throw VulcanException("Unknow page with title: ${res.title}")
res.semesters.map {
Semester(diary.id,
diary.name,
diary.name.substringAfter(" ").toInt(),
it.semesterId,
it.semesterNumber,
"selected" == it.current && "selected" == diary.current)
} }
}.flatMapObservable { Observable.fromIterable(it.diaries.reversed()) }.flatMapSingle { diary -> }.flatten()
api.getDiaryInfo(diary.id, "/$symbol/$schoolSymbol/Oceny.mvc/Wszystkie").map { res ->
if (!res.title.endsWith("Oceny")) throw VulcanException("Unknow page with title: ${res.title}")
res.semesters.map {
Semester(diary.id,
diary.name,
diary.name.substringAfter(" ").toInt(),
it.semesterId,
it.semesterNumber,
"selected" == it.current && "selected" == diary.current)
}
}
}.toList().map { it.flatten() }
} }
} }

View file

@ -32,8 +32,8 @@ import io.github.wulkanowy.sdk.scrapper.homework.Homework
import io.github.wulkanowy.sdk.scrapper.homework.HomeworkRequest import io.github.wulkanowy.sdk.scrapper.homework.HomeworkRequest
import io.github.wulkanowy.sdk.scrapper.homework.mapHomework import io.github.wulkanowy.sdk.scrapper.homework.mapHomework
import io.github.wulkanowy.sdk.scrapper.homework.mapHomeworkList import io.github.wulkanowy.sdk.scrapper.homework.mapHomeworkList
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorHandlerTransformer
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.scrapper.interceptor.handleErrors
import io.github.wulkanowy.sdk.scrapper.mobile.Device import io.github.wulkanowy.sdk.scrapper.mobile.Device
import io.github.wulkanowy.sdk.scrapper.mobile.TokenResponse import io.github.wulkanowy.sdk.scrapper.mobile.TokenResponse
import io.github.wulkanowy.sdk.scrapper.mobile.UnregisterDeviceRequest import io.github.wulkanowy.sdk.scrapper.mobile.UnregisterDeviceRequest
@ -51,7 +51,6 @@ import io.github.wulkanowy.sdk.scrapper.timetable.mapCompletedLessonsList
import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableList import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableList
import io.github.wulkanowy.sdk.scrapper.toDate import io.github.wulkanowy.sdk.scrapper.toDate
import io.github.wulkanowy.sdk.scrapper.toFormat import io.github.wulkanowy.sdk.scrapper.toFormat
import io.reactivex.Single
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
@ -65,184 +64,172 @@ class StudentRepository(private val api: StudentService) {
private fun LocalDate.toISOFormat(): String = toFormat("yyyy-MM-dd'T00:00:00'") private fun LocalDate.toISOFormat(): String = toFormat("yyyy-MM-dd'T00:00:00'")
private fun getCache(): Single<CacheResponse> { private suspend fun getCache(): CacheResponse {
if (::cache.isInitialized) return Single.just(cache) if (::cache.isInitialized) return cache
return api.getStart("Start").flatMap { val it = api.getStart("Start")
api.getUserCache(
getScriptParam("antiForgeryToken", it), val res = api.getUserCache(
getScriptParam("appGuid", it), getScriptParam("antiForgeryToken", it),
getScriptParam("version", it) getScriptParam("appGuid", it),
) getScriptParam("version", it)
}.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } ).handleErrors()
.map { it.apply { cache = this } }
val data = requireNotNull(res.data)
cache = data
return data
} }
private fun getTimes(): Single<List<CacheResponse.Time>> { private suspend fun getTimes(): List<CacheResponse.Time> {
if (::times.isInitialized) return Single.just(times) if (::times.isInitialized) return times
return getCache().map { res -> res.times }.map { list -> val res = getCache()
list.apply { times = this } times = res.times
return res.times
}
suspend fun getAttendance(startDate: LocalDate, endDate: LocalDate?): List<Attendance> {
return api.getAttendance(AttendanceRequest(startDate.toDate()))
.handleErrors()
.data?.mapAttendanceList(startDate, endDate, getTimes())!!
}
suspend fun getAttendanceSummary(subjectId: Int?): List<AttendanceSummary> {
return api.getAttendanceStatistics(AttendanceSummaryRequest(subjectId))
.handleErrors()
.data?.mapAttendanceSummaryList(gson)!!
}
suspend fun excuseForAbsence(absents: List<Absent>, content: String?): Boolean {
val it = api.getStart("Start")
return api.excuseForAbsence(
getScriptParam("antiForgeryToken", it),
getScriptParam("appGuid", it),
getScriptParam("version", it),
AttendanceExcuseRequest(
AttendanceExcuseRequest.Excuse(
absents = absents.map { absence ->
AttendanceExcuseRequest.Excuse.Absent(
date = absence.date.toFormat("yyyy-MM-dd'T'HH:mm:ss"),
timeId = absence.timeId
)
},
content = content
)
)
).handleErrors().success
}
suspend fun getSubjects(): List<Subject> {
return api.getAttendanceSubjects().handleErrors().data.orEmpty()
}
suspend fun getExams(startDate: LocalDate, endDate: LocalDate? = null): List<Exam> {
return api.getExams(ExamRequest(startDate.toDate(), startDate.getSchoolYear()))
.handleErrors()
.data.orEmpty().mapExamsList(startDate, endDate)
}
suspend fun getGrades(semesterId: Int?): Pair<List<Grade>, List<GradeSummary>> {
val data = api.getGrades(GradeRequest(semesterId))
.handleErrors()
.data
return requireNotNull(data).mapGradesList() to data.mapGradesSummary()
}
suspend fun getGradesDetails(semesterId: Int?): List<Grade> {
return api.getGrades(GradeRequest(semesterId))
.handleErrors()
.data?.mapGradesList()!!
}
suspend fun getGradesSummary(semesterId: Int?): List<GradeSummary> {
return api.getGrades(GradeRequest(semesterId))
.handleErrors()
.data?.mapGradesSummary()!!
}
suspend fun getGradesPartialStatistics(semesterId: Int): List<GradeStatistics> {
return api.getGradesPartialStatistics(GradesStatisticsRequest(semesterId))
.handleErrors()
.data.orEmpty().mapGradesStatisticsPartial(semesterId)
}
suspend fun getGradesPointsStatistics(semesterId: Int): List<GradePointsSummary> {
return api.getGradesPointsStatistics(GradesStatisticsRequest(semesterId))
.handleErrors()
.data.orEmpty().mapGradesStatisticsPoints(semesterId)
}
suspend fun getGradesAnnualStatistics(semesterId: Int): List<GradeStatistics> {
return api.getGradesAnnualStatistics(GradesStatisticsRequest(semesterId))
.handleErrors()
.data.orEmpty().mapGradesStatisticsAnnual(semesterId)
}
suspend fun getHomework(startDate: LocalDate, endDate: LocalDate? = null): List<Homework> {
return try {
api.getHomework(HomeworkRequest(startDate.toDate(), startDate.getSchoolYear(), -1))
.handleErrors()
.data.orEmpty().mapHomework(startDate, endDate)
} catch (e: InvalidPathException) {
api.getZadaniaDomowe(ExamRequest(startDate.toDate(), startDate.getSchoolYear()))
.handleErrors()
.data.orEmpty().mapHomeworkList(startDate, endDate)
} }
} }
fun getAttendance(startDate: LocalDate, endDate: LocalDate?): Single<List<Attendance>> { suspend fun getNotes(): List<Note> {
return api.getAttendance(AttendanceRequest(startDate.toDate())) return api.getNotes().handleErrors().data?.notes.orEmpty().map {
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } it.apply {
.mapAttendanceList(startDate, endDate, ::getTimes) teacherSymbol = teacher.split(" [").last().removeSuffix("]")
} teacher = teacher.split(" [").first()
fun getAttendanceSummary(subjectId: Int?): Single<List<AttendanceSummary>> {
return api.getAttendanceStatistics(AttendanceSummaryRequest(subjectId))
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapAttendanceSummaryList(gson) }
}
fun excuseForAbsence(absents: List<Absent>, content: String?): Single<Boolean> {
return api.getStart("Start").flatMap {
api.excuseForAbsence(
getScriptParam("antiForgeryToken", it),
getScriptParam("appGuid", it),
getScriptParam("version", it),
AttendanceExcuseRequest(
AttendanceExcuseRequest.Excuse(
absents = absents.map { absence ->
AttendanceExcuseRequest.Excuse.Absent(
date = absence.date.toFormat("yyyy-MM-dd'T'HH:mm:ss"),
timeId = absence.timeId
)
},
content = content
)
)
)
}.compose(ErrorHandlerTransformer()).map { it.success }
}
fun getSubjects(): Single<List<Subject>> {
return api.getAttendanceSubjects()
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
}
fun getExams(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Exam>> {
return api.getExams(ExamRequest(startDate.toDate(), startDate.getSchoolYear()))
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map { it.mapExamsList(startDate, endDate) }
}
fun getGrades(semesterId: Int?): Single<Pair<List<Grade>, List<GradeSummary>>> {
return api.getGrades(GradeRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapGradesList() to it.mapGradesSummary() }
}
fun getGradesDetails(semesterId: Int?): Single<List<Grade>> {
return api.getGrades(GradeRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapGradesList() }
}
fun getGradesSummary(semesterId: Int?): Single<List<GradeSummary>> {
return api.getGrades(GradeRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapGradesSummary() }
}
fun getGradesPartialStatistics(semesterId: Int): Single<List<GradeStatistics>> {
return api.getGradesPartialStatistics(GradesStatisticsRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map { it.mapGradesStatisticsPartial(semesterId) }
}
fun getGradesPointsStatistics(semesterId: Int): Single<List<GradePointsSummary>> {
return api.getGradesPointsStatistics(GradesStatisticsRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map { it.mapGradesStatisticsPoints(semesterId) }
}
fun getGradesAnnualStatistics(semesterId: Int): Single<List<GradeStatistics>> {
return api.getGradesAnnualStatistics(GradesStatisticsRequest(semesterId))
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
.map { it.mapGradesStatisticsAnnual(semesterId) }
}
fun getHomework(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Homework>> {
return api.getHomework(HomeworkRequest(startDate.toDate(), startDate.getSchoolYear(), -1))
.compose(ErrorHandlerTransformer())
.map { it.data.orEmpty().mapHomework(startDate, endDate) }
.onErrorResumeNext { t ->
if (t is InvalidPathException) api.getZadaniaDomowe(ExamRequest(startDate.toDate(), startDate.getSchoolYear()))
.compose(ErrorHandlerTransformer())
.map { it.data.orEmpty().mapHomeworkList(startDate, endDate) }
else Single.error(t)
} }
}.sortedWith(compareBy({ it.date }, { it.category }))
} }
fun getNotes(): Single<List<Note>> { suspend fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null): List<Timetable> {
return api.getNotes() return api.getTimetable(TimetableRequest(startDate.toISOFormat())).handleErrors().data
.compose(ErrorHandlerTransformer()).map { it.data?.notes.orEmpty() } ?.mapTimetableList(startDate, endDate)!!
.map { res ->
res.map {
it.apply {
teacherSymbol = teacher.split(" [").last().removeSuffix("]")
teacher = teacher.split(" [").first()
}
}.sortedWith(compareBy({ it.date }, { it.category }))
}
} }
fun getTimetable(startDate: LocalDate, endDate: LocalDate? = null): Single<List<Timetable>> { suspend fun getCompletedLessons(start: LocalDate, endDate: LocalDate?, subjectId: Int): List<CompletedLesson> {
return api.getTimetable(TimetableRequest(startDate.toISOFormat()))
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapTimetableList(startDate, endDate) }
}
fun getCompletedLessons(start: LocalDate, endDate: LocalDate?, subjectId: Int): Single<List<CompletedLesson>> {
val end = endDate ?: start.plusMonths(1) val end = endDate ?: start.plusMonths(1)
return getCache().map { cache -> val cache = getCache()
if (!cache.showCompletedLessons) throw FeatureDisabledException("Widok lekcji zrealizowanych został wyłączony przez Administratora szkoły") if (!cache.showCompletedLessons) throw FeatureDisabledException("Widok lekcji zrealizowanych został wyłączony przez Administratora szkoły")
}.flatMap {
api.getCompletedLessons(CompletedLessonsRequest(start.toISOFormat(), end.toISOFormat(), subjectId)) val res = api.getCompletedLessons(CompletedLessonsRequest(start.toISOFormat(), end.toISOFormat(), subjectId))
}.map { return gson.create().fromJson(res, ApiResponse::class.java).handleErrors().mapCompletedLessonsList(start, endDate, gson)
gson.create().fromJson(it, ApiResponse::class.java)
}.compose<ApiResponse<*>>(ErrorHandlerTransformer()).map { it.mapCompletedLessonsList(start, endDate, gson) }
} }
fun getTeachers(): Single<List<Teacher>> { suspend fun getTeachers(): List<Teacher> {
return api.getSchoolAndTeachers() return api.getSchoolAndTeachers().handleErrors().data?.mapToTeachers()!!
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.mapToTeachers() }
} }
fun getSchool(): Single<School> { suspend fun getSchool(): School {
return api.getSchoolAndTeachers() return api.getSchoolAndTeachers().handleErrors().data?.school!!
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) }
.map { it.school }
} }
fun getRegisteredDevices(): Single<List<Device>> { suspend fun getRegisteredDevices(): List<Device> {
return api.getRegisteredDevices() return api.getRegisteredDevices().handleErrors().data.orEmpty()
.compose(ErrorHandlerTransformer()).map { it.data.orEmpty() }
} }
fun getToken(): Single<TokenResponse> { suspend fun getToken(): TokenResponse {
return api.getToken() val data = api.getToken().handleErrors().data
.compose(ErrorHandlerTransformer()).map { requireNotNull(it.data) } requireNotNull(data).qrCodeImage = Jsoup.parse(data.qrCodeImage)
.map { res -> .select("img")
res.apply { .attr("src")
qrCodeImage = Jsoup.parse(qrCodeImage).select("img").attr("src").split("data:image/png;base64,")[1] .split("data:image/png;base64,")[1]
} return data
}
} }
fun unregisterDevice(id: Int): Single<Boolean> { suspend fun unregisterDevice(id: Int): Boolean {
return api.getStart("Start").flatMap { val it = api.getStart("Start")
api.unregisterDevice( return api.unregisterDevice(
getScriptParam("antiForgeryToken", it), getScriptParam("antiForgeryToken", it),
getScriptParam("appGuid", it), getScriptParam("appGuid", it),
getScriptParam("version", it), getScriptParam("version", it),
UnregisterDeviceRequest(id) UnregisterDeviceRequest(id)
) ).handleErrors().success
}.compose(ErrorHandlerTransformer()).map { it.success }
} }
} }

View file

@ -1,10 +1,9 @@
package io.github.wulkanowy.sdk.scrapper.repository package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorHandlerTransformer import io.github.wulkanowy.sdk.scrapper.interceptor.handleErrors
import io.github.wulkanowy.sdk.scrapper.register.Semester import io.github.wulkanowy.sdk.scrapper.register.Semester
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import io.github.wulkanowy.sdk.scrapper.toLocalDate import io.github.wulkanowy.sdk.scrapper.toLocalDate
import io.reactivex.Single
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.threeten.bp.LocalDate.now import org.threeten.bp.LocalDate.now
@ -18,40 +17,36 @@ class StudentStartRepository(
@JvmStatic private val logger = LoggerFactory.getLogger(this::class.java) @JvmStatic private val logger = LoggerFactory.getLogger(this::class.java)
} }
fun getSemesters(): Single<List<Semester>> { suspend fun getSemesters(): List<Semester> {
return api.getDiaries() val diaries = api.getDiaries().handleErrors().data
.compose(ErrorHandlerTransformer()) return diaries.orEmpty()
.map { diaries -> .asSequence()
diaries.data.orEmpty().asSequence() .filter { it.semesters?.isNotEmpty() ?: false }
.filter { diary -> diary.semesters?.isNotEmpty() ?: false } .filter { it.studentId == studentId }
.filter { diary -> diary.studentId == studentId } .filter { it.semesters!![0].classId == classId }
.filter { diary -> diary.semesters!![0].classId == classId } .map { diary ->
.map { diary -> diary.semesters!!.map {
diary.semesters!!.map { Semester(
Semester( diaryId = diary.diaryId,
diaryId = diary.diaryId, diaryName = "${diary.level}${diary.symbol}",
diaryName = "${diary.level}${diary.symbol}", schoolYear = diary.year,
schoolYear = diary.year, semesterId = it.id,
semesterId = it.id, semesterNumber = it.number,
semesterNumber = it.number, start = it.start.toLocalDate(),
start = it.start.toLocalDate(), end = it.end.toLocalDate(),
end = it.end.toLocalDate(), current = it.start.toLocalDate() <= now() && it.end.toLocalDate() >= now(),
current = it.start.toLocalDate() <= now() && it.end.toLocalDate() >= now(), classId = it.classId,
classId = it.classId, unitId = it.unitId
unitId = it.unitId )
) }
} }
} .flatten()
.flatten() .sortedByDescending { it.semesterId }
.sortedByDescending { it.semesterId } .toList()
.toList() .ifEmpty {
.ifEmpty { logger.debug("Student $studentId, class $classId not found in diaries: $diaries")
logger.debug("Student $studentId, class $classId not found in diaries: $diaries") emptyList()
emptyList() }.apply {
} if (isNotEmpty() && singleOrNull { semester -> semester.current } == null) first().current = true }
}.map {
if (it.isNotEmpty() && it.singleOrNull { semester -> semester.current } == null) it.apply { first().current = true }
else it
} }
}
} }

View file

@ -3,7 +3,6 @@ package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.register.LoginForm import io.github.wulkanowy.sdk.scrapper.register.LoginForm
import io.github.wulkanowy.sdk.scrapper.register.SentUnlockAccountResponse import io.github.wulkanowy.sdk.scrapper.register.SentUnlockAccountResponse
import io.github.wulkanowy.sdk.scrapper.register.UnlockAccountResponse import io.github.wulkanowy.sdk.scrapper.register.UnlockAccountResponse
import io.reactivex.Single
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FieldMap import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
@ -14,36 +13,36 @@ import retrofit2.http.Url
interface AccountService { interface AccountService {
@GET @GET
fun getFormType(@Url url: String): Single<LoginForm> suspend fun getFormType(@Url url: String): LoginForm
@GET @GET
fun getPasswordResetPageWithCaptcha(@Url url: String): Single<UnlockAccountResponse> suspend fun getPasswordResetPageWithCaptcha(@Url url: String): UnlockAccountResponse
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendPasswordResetRequest( suspend fun sendPasswordResetRequest(
@Url url: String, @Url url: String,
@Field("Email") email: String, @Field("Email") email: String,
@Field("g-recaptcha-response") captchaCode: String @Field("g-recaptcha-response") captchaCode: String
): Single<SentUnlockAccountResponse> ): SentUnlockAccountResponse
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendPasswordResetRequestADFSLight( suspend fun sendPasswordResetRequestADFSLight(
@Url url: String, @Url url: String,
@Field("UserId") username: String, @Field("UserId") username: String,
@Field("g-recaptcha-response") captchaCode: String @Field("g-recaptcha-response") captchaCode: String
): Single<SentUnlockAccountResponse> ): SentUnlockAccountResponse
@GET @GET
fun getPasswordResetPageADFS(@Url url: String): Single<SentUnlockAccountResponse> suspend fun getPasswordResetPageADFS(@Url url: String): SentUnlockAccountResponse
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendPasswordResetRequestADFS( suspend fun sendPasswordResetRequestADFS(
@Url url: String, @Url url: String,
@Field("txtUserID") username: String, @Field("txtUserID") username: String,
@Field("g-recaptcha-response") captchaCode: String, @Field("g-recaptcha-response") captchaCode: String,
@FieldMap viewStateParams: Map<String, String> @FieldMap viewStateParams: Map<String, String>
): Single<SentUnlockAccountResponse> ): SentUnlockAccountResponse
} }

View file

@ -3,7 +3,6 @@ package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.ApiResponse import io.github.wulkanowy.sdk.scrapper.ApiResponse
import io.github.wulkanowy.sdk.scrapper.home.GovernmentUnit import io.github.wulkanowy.sdk.scrapper.home.GovernmentUnit
import io.github.wulkanowy.sdk.scrapper.home.HomepageTileResponse import io.github.wulkanowy.sdk.scrapper.home.HomepageTileResponse
import io.reactivex.Single
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
@ -12,45 +11,45 @@ import retrofit2.http.POST
interface HomepageService { interface HomepageService {
@GET("Start.mvc/Index") @GET("Start.mvc/Index")
fun getStart(): Single<String> suspend fun getStart(): String
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetSelfGovernments") @POST("Start.mvc/GetSelfGovernments")
fun getSelfGovernments(@Field("permissions") token: String): Single<ApiResponse<List<GovernmentUnit>>> suspend fun getSelfGovernments(@Field("permissions") token: String): ApiResponse<List<GovernmentUnit>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetStudentTrips") @POST("Start.mvc/GetStudentTrips")
fun getStudentsTrips(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getStudentsTrips(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetStudentThreats") @POST("Start.mvc/GetStudentThreats")
fun getStudentThreats(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getStudentThreats(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetLastNotes") @POST("Start.mvc/GetLastNotes")
fun getLastGrades(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getLastGrades(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetFreeDays") @POST("Start.mvc/GetFreeDays")
fun getFreeDays(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getFreeDays(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetKidsLuckyNumbers") @POST("Start.mvc/GetKidsLuckyNumbers")
fun getKidsLuckyNumbers(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getKidsLuckyNumbers(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetKidsLessonPlan") @POST("Start.mvc/GetKidsLessonPlan")
fun getKidsLessonPlan(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getKidsLessonPlan(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetLastHomeworks") @POST("Start.mvc/GetLastHomeworks")
fun getLastHomework(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getLastHomework(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetLastTests") @POST("Start.mvc/GetLastTests")
fun getLastTests(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getLastTests(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
@FormUrlEncoded @FormUrlEncoded
@POST("Start.mvc/GetLastStudentLessons") @POST("Start.mvc/GetLastStudentLessons")
fun getLastStudentLessons(@Field("permissions") token: String): Single<ApiResponse<List<HomepageTileResponse>>> suspend fun getLastStudentLessons(@Field("permissions") token: String): ApiResponse<List<HomepageTileResponse>>
} }

View file

@ -2,7 +2,6 @@ package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.login.ADFSFormResponse import io.github.wulkanowy.sdk.scrapper.login.ADFSFormResponse
import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse
import io.reactivex.Single
import retrofit2.http.FieldMap import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
@ -14,25 +13,25 @@ interface LoginService {
@POST("Account/LogOn") @POST("Account/LogOn")
@FormUrlEncoded @FormUrlEncoded
fun sendCredentials(@Query("ReturnUrl") returnUrl: String, @FieldMap credentials: Map<String, String>): Single<String> suspend fun sendCredentials(@Query("ReturnUrl") returnUrl: String, @FieldMap credentials: Map<String, String>): String
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendCertificate(@Url url: String, @FieldMap certificate: Map<String, String>): Single<SendCertificateResponse> suspend fun sendCertificate(@Url url: String, @FieldMap certificate: Map<String, String>): SendCertificateResponse
@GET @GET
fun switchLogin(@Url url: String): Single<SendCertificateResponse> suspend fun switchLogin(@Url url: String): SendCertificateResponse
// ADFS // ADFS
@GET @GET
fun getForm(@Url url: String): Single<ADFSFormResponse> suspend fun getForm(@Url url: String): ADFSFormResponse
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendADFSFormStandardChoice(@Url url: String, @FieldMap formState: Map<String, String>): Single<ADFSFormResponse> suspend fun sendADFSFormStandardChoice(@Url url: String, @FieldMap formState: Map<String, String>): ADFSFormResponse
@POST @POST
@FormUrlEncoded @FormUrlEncoded
fun sendADFSForm(@Url url: String, @FieldMap values: Map<String, String>): Single<String> suspend fun sendADFSForm(@Url url: String, @FieldMap values: Map<String, String>): String
} }

View file

@ -7,7 +7,6 @@ import io.github.wulkanowy.sdk.scrapper.messages.Recipient
import io.github.wulkanowy.sdk.scrapper.messages.ReportingUnit import io.github.wulkanowy.sdk.scrapper.messages.ReportingUnit
import io.github.wulkanowy.sdk.scrapper.messages.SendMessageRequest import io.github.wulkanowy.sdk.scrapper.messages.SendMessageRequest
import io.github.wulkanowy.sdk.scrapper.messages.SentMessage import io.github.wulkanowy.sdk.scrapper.messages.SentMessage
import io.reactivex.Single
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
@ -19,51 +18,51 @@ import retrofit2.http.Query
interface MessagesService { interface MessagesService {
@GET(".") @GET(".")
fun getStart(): Single<String> suspend fun getStart(): String
@GET("NowaWiadomosc.mvc/GetJednostkiUzytkownika") @GET("NowaWiadomosc.mvc/GetJednostkiUzytkownika")
fun getUserReportingUnits(): Single<ApiResponse<List<ReportingUnit>>> suspend fun getUserReportingUnits(): ApiResponse<List<ReportingUnit>>
@GET("Adresaci.mvc/GetAdresaci") @GET("Adresaci.mvc/GetAdresaci")
fun getRecipients(@Query("IdJednostkaSprawozdawcza") reportingUnitId: Int, @Query("Rola") role: Int): Single<ApiResponse<List<Recipient>>> suspend fun getRecipients(@Query("IdJednostkaSprawozdawcza") reportingUnitId: Int, @Query("Rola") role: Int): ApiResponse<List<Recipient>>
@GET("Wiadomosc.mvc/GetWiadomosciOdebrane") @GET("Wiadomosc.mvc/GetWiadomosciOdebrane")
fun getReceived(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): Single<ApiResponse<List<Message>>> suspend fun getReceived(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): ApiResponse<List<Message>>
@GET("Wiadomosc.mvc/GetWiadomosciWyslane") @GET("Wiadomosc.mvc/GetWiadomosciWyslane")
fun getSent(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): Single<ApiResponse<List<Message>>> suspend fun getSent(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): ApiResponse<List<Message>>
@GET("Wiadomosc.mvc/GetWiadomosciUsuniete") @GET("Wiadomosc.mvc/GetWiadomosciUsuniete")
fun getDeleted(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): Single<ApiResponse<List<Message>>> suspend fun getDeleted(@Query("dataOd") dateStart: String, @Query("dataDo") dateEnd: String): ApiResponse<List<Message>>
@GET("Wiadomosc.mvc/GetAdresaciWiadomosci") @GET("Wiadomosc.mvc/GetAdresaciWiadomosci")
fun getMessageRecipients(@Query("idWiadomosci") messageId: Int): Single<ApiResponse<List<Recipient>>> suspend fun getMessageRecipients(@Query("idWiadomosci") messageId: Int): ApiResponse<List<Recipient>>
@GET("Wiadomosc.mvc/GetRoleUzytkownika") @GET("Wiadomosc.mvc/GetRoleUzytkownika")
fun getMessageSender(@Query("idLogin") loginId: Int, @Query("idWiadomosci") messageId: Int): Single<ApiResponse<List<Recipient>>> suspend fun getMessageSender(@Query("idLogin") loginId: Int, @Query("idWiadomosci") messageId: Int): ApiResponse<List<Recipient>>
@POST("Wiadomosc.mvc/GetTrescWiadomosci") @POST("Wiadomosc.mvc/GetTrescWiadomosci")
@FormUrlEncoded @FormUrlEncoded
fun getMessage( suspend fun getMessage(
@Field("idWiadomosc") messageId: Int, @Field("idWiadomosc") messageId: Int,
@Field("Folder") folderId: Int, @Field("Folder") folderId: Int,
@Field("Nieprzeczytana") read: Boolean, @Field("Nieprzeczytana") read: Boolean,
@Field("idWiadomoscAdresat") id: Int? @Field("idWiadomoscAdresat") id: Int?
): Single<ApiResponse<Message>> ): ApiResponse<Message>
@POST("NowaWiadomosc.mvc/InsertWiadomosc") @POST("NowaWiadomosc.mvc/InsertWiadomosc")
fun sendMessage( suspend fun sendMessage(
@Body sendMessageRequest: SendMessageRequest, @Body sendMessageRequest: SendMessageRequest,
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String @Header("X-V-AppVersion") appVersion: String
): Single<ApiResponse<SentMessage>> ): ApiResponse<SentMessage>
@POST("Wiadomosc.mvc/UsunWiadomosc") @POST("Wiadomosc.mvc/UsunWiadomosc")
fun deleteMessage( suspend fun deleteMessage(
@Body deleteMessageRequests: List<DeleteMessageRequest>, @Body deleteMessageRequests: List<DeleteMessageRequest>,
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String @Header("X-V-AppVersion") appVersion: String
): Single<String> ): String
} }

View file

@ -1,12 +1,11 @@
package io.github.wulkanowy.sdk.scrapper.service package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.register.LoginForm import io.github.wulkanowy.sdk.scrapper.register.LoginForm
import io.reactivex.Single
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Url import retrofit2.http.Url
interface RegisterService { interface RegisterService {
@GET @GET
fun getFormType(@Url url: String): Single<LoginForm> suspend fun getFormType(@Url url: String): LoginForm
} }

View file

@ -1,6 +1,5 @@
package io.github.wulkanowy.sdk.scrapper.service package io.github.wulkanowy.sdk.scrapper.service
import RxJava2ReauthCallAdapterFactory
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
@ -14,9 +13,6 @@ import io.github.wulkanowy.sdk.scrapper.interceptor.NotLoggedInErrorInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.StudentAndParentInterceptor import io.github.wulkanowy.sdk.scrapper.interceptor.StudentAndParentInterceptor
import io.github.wulkanowy.sdk.scrapper.interceptor.UserAgentInterceptor import io.github.wulkanowy.sdk.scrapper.interceptor.UserAgentInterceptor
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException
import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse
import io.reactivex.Flowable
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.JavaNetCookieJar import okhttp3.JavaNetCookieJar
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -24,7 +20,6 @@ import okhttp3.logging.HttpLoggingInterceptor
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import pl.droidsonroids.retrofit2.JspoonConverterFactory import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.create import retrofit2.create
@ -160,12 +155,7 @@ class ServiceManager(
.serializeNulls() .serializeNulls()
.registerTypeAdapter(GradeDate::class.java, DateDeserializer(GradeDate::class.java)) .registerTypeAdapter(GradeDate::class.java, DateDeserializer(GradeDate::class.java))
.create()) else JspoonConverterFactory.create()) .create()) else JspoonConverterFactory.create())
.addCallAdapterFactory(if (!login) RxJava2CallAdapterFactory.create() else .build()
RxJava2ReauthCallAdapterFactory.create(
getLoginHelper(),
{ it is NotLoggedInException }
)
).build()
} }
private fun getClientBuilder( private fun getClientBuilder(
@ -196,12 +186,11 @@ class ServiceManager(
} }
} }
private fun getLoginHelper(): Flowable<SendCertificateResponse> { // private suspend fun getLoginHelper(): Flowable<SendCertificateResponse> {
return loginHelper // return loginHelper
.login(email, password) // .login(email, password)
.toFlowable() // .share()
.share() // }
}
class UrlGenerator(private val schema: String, private val host: String, var symbol: String, var schoolId: String) { class UrlGenerator(private val schema: String, private val host: String, var symbol: String, var schoolId: String) {

View file

@ -14,7 +14,6 @@ import io.github.wulkanowy.sdk.scrapper.school.SchoolAndTeachersResponse
import io.github.wulkanowy.sdk.scrapper.student.StudentInfo import io.github.wulkanowy.sdk.scrapper.student.StudentInfo
import io.github.wulkanowy.sdk.scrapper.timetable.RealizedResponse import io.github.wulkanowy.sdk.scrapper.timetable.RealizedResponse
import io.github.wulkanowy.sdk.scrapper.timetable.TimetableResponse import io.github.wulkanowy.sdk.scrapper.timetable.TimetableResponse
import io.reactivex.Single
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
@ -26,57 +25,57 @@ import retrofit2.http.Url
interface StudentAndParentService { interface StudentAndParentService {
@GET @GET
fun getSchoolInfo(@Url url: String): Single<StudentAndParentResponse> suspend fun getSchoolInfo(@Url url: String): StudentAndParentResponse
@GET("Uczen/UczenOnChange") @GET("Uczen/UczenOnChange")
fun getUserInfo(@Query("id") userId: Int): Single<StudentAndParentResponse> suspend fun getUserInfo(@Query("id") userId: Int): StudentAndParentResponse
@GET("Dziennik/DziennikOnChange") @GET("Dziennik/DziennikOnChange")
fun getDiaryInfo(@Query("id") diaryId: Int, @Header("Referer") referer: String): Single<StudentAndParentResponse> suspend fun getDiaryInfo(@Query("id") diaryId: Int, @Header("Referer") referer: String): StudentAndParentResponse
@GET("Frekwencja.mvc") @GET("Frekwencja.mvc")
fun getAttendance(@Query("data") date: String): Single<AttendanceResponse> suspend fun getAttendance(@Query("data") date: String): AttendanceResponse
@GET("Frekwencja.mvc") @GET("Frekwencja.mvc")
fun getAttendanceSummary(@Query("idPrzedmiot") subjectId: Int?): Single<AttendanceResponse> suspend fun getAttendanceSummary(@Query("idPrzedmiot") subjectId: Int?): AttendanceResponse
@GET("Sprawdziany.mvc/Terminarz?rodzajWidoku=2") @GET("Sprawdziany.mvc/Terminarz?rodzajWidoku=2")
fun getExams(@Query("data") date: String): Single<ExamResponse> suspend fun getExams(@Query("data") date: String): ExamResponse
@GET("Oceny/Wszystkie?details=2") @GET("Oceny/Wszystkie?details=2")
fun getGrades(@Query("okres") semester: Int?): Single<GradesResponse> suspend fun getGrades(@Query("okres") semester: Int?): GradesResponse
@GET("Oceny/Wszystkie?details=1") @GET("Oceny/Wszystkie?details=1")
fun getGradesSummary(@Query("okres") semester: Int?): Single<GradesSummaryResponse> suspend fun getGradesSummary(@Query("okres") semester: Int?): GradesSummaryResponse
@GET("Statystyki.mvc/Uczen") @GET("Statystyki.mvc/Uczen")
fun getGradesStatistics(@Query("rodzajWidoku") type: Int?, @Query("semestr") semesterId: Int): Single<GradesStatisticsResponse> suspend fun getGradesStatistics(@Query("rodzajWidoku") type: Int?, @Query("semestr") semesterId: Int): GradesStatisticsResponse
@GET("ZadaniaDomowe.mvc?rodzajWidoku=Dzien") @GET("ZadaniaDomowe.mvc?rodzajWidoku=Dzien")
fun getHomework(@Query("data") date: String): Single<HomeworkResponse> suspend fun getHomework(@Query("data") date: String): HomeworkResponse
@GET("UwagiOsiagniecia.mvc/Wszystkie") @GET("UwagiOsiagniecia.mvc/Wszystkie")
fun getNotes(): Single<NotesResponse> suspend fun getNotes(): NotesResponse
@GET("DostepMobilny.mvc") @GET("DostepMobilny.mvc")
fun getRegisteredDevices(): Single<RegisteredDevicesResponse> suspend fun getRegisteredDevices(): RegisteredDevicesResponse
@GET("DostepMobilny.mvc/Rejestruj") @GET("DostepMobilny.mvc/Rejestruj")
fun getToken(): Single<TokenResponse> suspend fun getToken(): TokenResponse
@POST("DostepMobilny.mvc/PotwierdzWyrejestrowanie") @POST("DostepMobilny.mvc/PotwierdzWyrejestrowanie")
@FormUrlEncoded @FormUrlEncoded
fun unregisterDevice(@Field("Id") id: Int): Single<RegisteredDevicesResponse> suspend fun unregisterDevice(@Field("Id") id: Int): RegisteredDevicesResponse
@GET("Szkola.mvc/Nauczyciele") @GET("Szkola.mvc/Nauczyciele")
fun getSchoolAndTeachers(): Single<SchoolAndTeachersResponse> suspend fun getSchoolAndTeachers(): SchoolAndTeachersResponse
@GET("Lekcja.mvc/PlanZajec") @GET("Lekcja.mvc/PlanZajec")
fun getTimetable(@Query("data") date: String): Single<TimetableResponse> suspend fun getTimetable(@Query("data") date: String): TimetableResponse
@GET("Lekcja.mvc/Zrealizowane") @GET("Lekcja.mvc/Zrealizowane")
fun getCompletedLessons(@Query("start") start: String, @Query("end") end: String?, @Query("idPrzedmiot") subjectId: Int?): Single<RealizedResponse> suspend fun getCompletedLessons(@Query("start") start: String, @Query("end") end: String?, @Query("idPrzedmiot") subjectId: Int?): RealizedResponse
@GET("Uczen.mvc/DanePodstawowe") @GET("Uczen.mvc/DanePodstawowe")
fun getStudentInfo(): Single<StudentInfo> suspend fun getStudentInfo(): StudentInfo
} }

View file

@ -27,7 +27,6 @@ import io.github.wulkanowy.sdk.scrapper.timetable.CacheResponse
import io.github.wulkanowy.sdk.scrapper.timetable.CompletedLessonsRequest import io.github.wulkanowy.sdk.scrapper.timetable.CompletedLessonsRequest
import io.github.wulkanowy.sdk.scrapper.timetable.TimetableRequest import io.github.wulkanowy.sdk.scrapper.timetable.TimetableRequest
import io.github.wulkanowy.sdk.scrapper.timetable.TimetableResponse import io.github.wulkanowy.sdk.scrapper.timetable.TimetableResponse
import io.reactivex.Single
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header import retrofit2.http.Header
@ -37,101 +36,101 @@ import retrofit2.http.Url
interface StudentService { interface StudentService {
@GET @GET
fun getStart(@Url url: String): Single<String> suspend fun getStart(@Url url: String): String
@POST @POST
fun getUserCache( suspend fun getUserCache(
@Url url: String, @Url url: String,
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String, @Header("X-V-AppVersion") appVersion: String,
@Body body: Any = Object() @Body body: Any = Object()
): Single<ApiResponse<CacheResponse>> ): ApiResponse<CacheResponse>
@POST("UczenCache.mvc/Get") @POST("UczenCache.mvc/Get")
fun getUserCache( suspend fun getUserCache(
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String, @Header("X-V-AppVersion") appVersion: String,
@Body body: Any = Object() @Body body: Any = Object()
): Single<ApiResponse<CacheResponse>> ): ApiResponse<CacheResponse>
@POST @POST
fun getSchoolInfo(@Url url: String, @Body body: Any = Object()): Single<ApiResponse<List<Diary>>> suspend fun getSchoolInfo(@Url url: String, @Body body: Any = Object()): ApiResponse<List<Diary>>
@POST("UczenDziennik.mvc/Get") @POST("UczenDziennik.mvc/Get")
fun getDiaries(@Body body: Any = Object()): Single<ApiResponse<List<Diary>>> suspend fun getDiaries(@Body body: Any = Object()): ApiResponse<List<Diary>>
@POST("Oceny.mvc/Get") @POST("Oceny.mvc/Get")
fun getGrades(@Body gradeRequest: GradeRequest): Single<ApiResponse<GradesResponse>> suspend fun getGrades(@Body gradeRequest: GradeRequest): ApiResponse<GradesResponse>
@POST("Statystyki.mvc/GetOcenyCzastkowe") @POST("Statystyki.mvc/GetOcenyCzastkowe")
fun getGradesPartialStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): Single<ApiResponse<List<GradesStatisticsResponse.Partial>>> suspend fun getGradesPartialStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): ApiResponse<List<GradesStatisticsResponse.Partial>>
@POST("Statystyki.mvc/GetPunkty") @POST("Statystyki.mvc/GetPunkty")
fun getGradesPointsStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): Single<ApiResponse<List<GradePointsSummary>>> suspend fun getGradesPointsStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): ApiResponse<List<GradePointsSummary>>
@POST("Statystyki.mvc/GetOcenyRoczne") @POST("Statystyki.mvc/GetOcenyRoczne")
fun getGradesAnnualStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): Single<ApiResponse<List<GradesStatisticsResponse.Annual>>> suspend fun getGradesAnnualStatistics(@Body gradesStatisticsRequest: GradesStatisticsRequest): ApiResponse<List<GradesStatisticsResponse.Annual>>
@POST("Frekwencja.mvc/Get") @POST("Frekwencja.mvc/Get")
fun getAttendance(@Body attendanceRequest: AttendanceRequest): Single<ApiResponse<AttendanceResponse>> suspend fun getAttendance(@Body attendanceRequest: AttendanceRequest): ApiResponse<AttendanceResponse>
@POST("FrekwencjaStatystyki.mvc/Get") @POST("FrekwencjaStatystyki.mvc/Get")
fun getAttendanceStatistics(@Body attendanceSummaryRequest: AttendanceSummaryRequest): Single<ApiResponse<AttendanceSummaryResponse>> suspend fun getAttendanceStatistics(@Body attendanceSummaryRequest: AttendanceSummaryRequest): ApiResponse<AttendanceSummaryResponse>
@POST("FrekwencjaStatystykiPrzedmioty.mvc/Get") @POST("FrekwencjaStatystykiPrzedmioty.mvc/Get")
fun getAttendanceSubjects(@Body body: Any = Object()): Single<ApiResponse<List<Subject>>> suspend fun getAttendanceSubjects(@Body body: Any = Object()): ApiResponse<List<Subject>>
@POST("Usprawiedliwienia.mvc/Post") @POST("Usprawiedliwienia.mvc/Post")
fun excuseForAbsence( suspend fun excuseForAbsence(
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String, @Header("X-V-AppVersion") appVersion: String,
@Body attendanceExcuseRequest: AttendanceExcuseRequest @Body attendanceExcuseRequest: AttendanceExcuseRequest
): Single<ApiResponse<Nothing>> ): ApiResponse<Nothing>
@POST("EgzaminyZewnetrzne.mvc/Get") @POST("EgzaminyZewnetrzne.mvc/Get")
fun getExternalExaminations() suspend fun getExternalExaminations()
@POST("Sprawdziany.mvc/Get") @POST("Sprawdziany.mvc/Get")
fun getExams(@Body examRequest: ExamRequest): Single<ApiResponse<List<ExamResponse>>> suspend fun getExams(@Body examRequest: ExamRequest): ApiResponse<List<ExamResponse>>
@POST("ZadaniaDomowe.mvc/Get") @POST("ZadaniaDomowe.mvc/Get")
fun getZadaniaDomowe(@Body homeworkRequest: ExamRequest): Single<ApiResponse<List<HomeworkResponse>>> suspend fun getZadaniaDomowe(@Body homeworkRequest: ExamRequest): ApiResponse<List<HomeworkResponse>>
@POST("Homework.mvc/Get") @POST("Homework.mvc/Get")
fun getHomework(@Body homeworkRequest: HomeworkRequest): Single<ApiResponse<List<HomeworkDay>>> suspend fun getHomework(@Body homeworkRequest: HomeworkRequest): ApiResponse<List<HomeworkDay>>
@POST("PlanZajec.mvc/Get") @POST("PlanZajec.mvc/Get")
fun getTimetable(@Body timetableRequest: TimetableRequest): Single<ApiResponse<TimetableResponse>> suspend fun getTimetable(@Body timetableRequest: TimetableRequest): ApiResponse<TimetableResponse>
@POST("LekcjeZrealizowane.mvc/GetPrzedmioty") @POST("LekcjeZrealizowane.mvc/GetPrzedmioty")
fun getRealizedSubjects(@Body body: Any = Object()) suspend fun getRealizedSubjects(@Body body: Any = Object())
@POST("LekcjeZrealizowane.mvc/GetZrealizowane") @POST("LekcjeZrealizowane.mvc/GetZrealizowane")
fun getCompletedLessons(@Body completedLessonsRequest: CompletedLessonsRequest): Single<String> suspend fun getCompletedLessons(@Body completedLessonsRequest: CompletedLessonsRequest): String
@POST("UwagiIOsiagniecia.mvc/Get") @POST("UwagiIOsiagniecia.mvc/Get")
fun getNotes(@Body body: Any = Object()): Single<ApiResponse<NotesResponse>> suspend fun getNotes(@Body body: Any = Object()): ApiResponse<NotesResponse>
@POST("ZarejestrowaneUrzadzenia.mvc/Get") @POST("ZarejestrowaneUrzadzenia.mvc/Get")
fun getRegisteredDevices(@Body body: Any = Object()): Single<ApiResponse<List<Device>>> suspend fun getRegisteredDevices(@Body body: Any = Object()): ApiResponse<List<Device>>
@POST("RejestracjaUrzadzeniaToken.mvc/Get") @POST("RejestracjaUrzadzeniaToken.mvc/Get")
fun getToken(@Body body: Any = Object()): Single<ApiResponse<TokenResponse>> suspend fun getToken(@Body body: Any = Object()): ApiResponse<TokenResponse>
@POST("ZarejestrowaneUrzadzenia.mvc/Delete") @POST("ZarejestrowaneUrzadzenia.mvc/Delete")
fun unregisterDevice( suspend fun unregisterDevice(
@Header("X-V-RequestVerificationToken") token: String, @Header("X-V-RequestVerificationToken") token: String,
@Header("X-V-AppGuid") appGuid: String, @Header("X-V-AppGuid") appGuid: String,
@Header("X-V-AppVersion") appVersion: String, @Header("X-V-AppVersion") appVersion: String,
@Body unregisterDeviceRequest: UnregisterDeviceRequest @Body unregisterDeviceRequest: UnregisterDeviceRequest
): Single<ApiResponse<Nothing>> ): ApiResponse<Nothing>
@POST("SzkolaINauczyciele.mvc/Get") @POST("SzkolaINauczyciele.mvc/Get")
fun getSchoolAndTeachers(@Body body: Any = Object()): Single<ApiResponse<SchoolAndTeachersResponse>> suspend fun getSchoolAndTeachers(@Body body: Any = Object()): ApiResponse<SchoolAndTeachersResponse>
@POST("Uczen.mvc/Get") @POST("Uczen.mvc/Get")
fun getStudentInfo() suspend fun getStudentInfo()
} }

View file

@ -17,7 +17,6 @@ import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import pl.droidsonroids.retrofit2.JspoonConverterFactory import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
@ -68,7 +67,6 @@ abstract class BaseLocalTest : BaseTest() {
.serializeNulls() .serializeNulls()
.registerTypeAdapter(GradeDate::class.java, DateDeserializer(GradeDate::class.java)) .registerTypeAdapter(GradeDate::class.java, DateDeserializer(GradeDate::class.java))
.create()) else JspoonConverterFactory.create()) .create()) else JspoonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(url) .baseUrl(url)
.build() .build()
.create(service) .create(service)

View file

@ -1,30 +1,8 @@
package io.github.wulkanowy.sdk.scrapper package io.github.wulkanowy.sdk.scrapper
import io.github.wulkanowy.sdk.scrapper.attendance.Attendance
import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceSummary
import io.github.wulkanowy.sdk.scrapper.attendance.Subject
import io.github.wulkanowy.sdk.scrapper.exams.Exam
import io.github.wulkanowy.sdk.scrapper.grades.Grade
import io.github.wulkanowy.sdk.scrapper.grades.GradeStatistics
import io.github.wulkanowy.sdk.scrapper.grades.GradeSummary
import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber
import io.github.wulkanowy.sdk.scrapper.homework.Homework
import io.github.wulkanowy.sdk.scrapper.messages.Folder import io.github.wulkanowy.sdk.scrapper.messages.Folder
import io.github.wulkanowy.sdk.scrapper.messages.Message
import io.github.wulkanowy.sdk.scrapper.messages.Recipient import io.github.wulkanowy.sdk.scrapper.messages.Recipient
import io.github.wulkanowy.sdk.scrapper.messages.ReportingUnit import kotlinx.coroutines.runBlocking
import io.github.wulkanowy.sdk.scrapper.messages.SentMessage
import io.github.wulkanowy.sdk.scrapper.mobile.Device
import io.github.wulkanowy.sdk.scrapper.mobile.TokenResponse
import io.github.wulkanowy.sdk.scrapper.notes.Note
import io.github.wulkanowy.sdk.scrapper.register.Semester
import io.github.wulkanowy.sdk.scrapper.register.Student
import io.github.wulkanowy.sdk.scrapper.school.School
import io.github.wulkanowy.sdk.scrapper.school.Teacher
import io.github.wulkanowy.sdk.scrapper.student.StudentInfo
import io.github.wulkanowy.sdk.scrapper.timetable.CompletedLesson
import io.github.wulkanowy.sdk.scrapper.timetable.Timetable
import io.reactivex.observers.TestObserver
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -66,35 +44,29 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun getPasswordResetCaptchaCode() { fun getPasswordResetCaptchaCode() {
val code = api.getPasswordResetCaptcha("https://fakelog.cf", "Default") val code = runBlocking { api.getPasswordResetCaptcha("https://fakelog.cf", "Default") }
val codeObserver = TestObserver<Pair<String, String>>()
code.subscribe(codeObserver)
codeObserver.assertComplete()
assertEquals("https://cufs.fakelog.cf/Default/AccountManage/UnlockAccount", codeObserver.values()[0].first) assertEquals("https://cufs.fakelog.cf/Default/AccountManage/UnlockAccount", code.first)
assertEquals("6LeAGMYUAAAAAMszd5VWZTEb5WQHqsNT1F4GCqUd", codeObserver.values()[0].second) assertEquals("6LeAGMYUAAAAAMszd5VWZTEb5WQHqsNT1F4GCqUd", code.second)
} }
@Test @Test
fun sendPasswordResetRequest() { fun sendPasswordResetRequest() {
val res = api.sendPasswordResetRequest("https://fakelog.cf", "Default", "jan@fakelog.cf", "03AOLTBLQRPyr0pWvWLRAgD4hRLfxktoqD2IVweeMuXwbkpR_8S9YQtcS3cAXqUOyEw3NxfvwzV0lTjgFWyl8j3UXGQpsc2nvQcqIofj1N8DYfxvtZO-h24W_S0Z9-fDnfXErd7vERS-Ny4d5IU1FupBAEKvT8rrf3OA3GYYbMM7TwB8b_o9Tt192TqYnSxkyIYE4UdaZnLBA0KIXxlBAoqM6QGlPEsSPK9gmCGx-0hn68w-UBQkv_ghRruf4kpv2Shw5emcP-qHBlv3YjAagsb_358K0v8uGJeyLrx4dXN9Ky02TXFMKYWNHz29fjhfunxT73u_PrsLj56f-MjOXrqO894NkUlJ7RkTTclwIsqXtJ794LEBH--mtsqZBND0miR5-odmZszqiNB3V5UsS5ObsqF_fWMl2TCWyNTTvF4elOGwOEeKiumVpjB6e740COxvxN3vbkNWxP9eeghpd5nPN5l2wUV3VL2R5s44TbqHqkrkNpUOd3h7efs3cQtCfGc-tCXoqLC26LxT7aztvKpjXMuqGEf-7wbQ") val res = runBlocking {
val resObserver = TestObserver<String>() api.sendPasswordResetRequest("https://fakelog.cf",
res.subscribe(resObserver) "Default",
resObserver.assertComplete() "jan@fakelog.cf",
"03AOLTBLQRPyr0pWvWLRAgD4hRLfxktoqD2IVweeMuXwbkpR_8S9YQtcS3cAXqUOyEw3NxfvwzV0lTjgFWyl8j3UXGQpsc2nvQcqIofj1N8DYfxvtZO-h24W_S0Z9-fDnfXErd7vERS-Ny4d5IU1FupBAEKvT8rrf3OA3GYYbMM7TwB8b_o9Tt192TqYnSxkyIYE4UdaZnLBA0KIXxlBAoqM6QGlPEsSPK9gmCGx-0hn68w-UBQkv_ghRruf4kpv2Shw5emcP-qHBlv3YjAagsb_358K0v8uGJeyLrx4dXN9Ky02TXFMKYWNHz29fjhfunxT73u_PrsLj56f-MjOXrqO894NkUlJ7RkTTclwIsqXtJ794LEBH--mtsqZBND0miR5-odmZszqiNB3V5UsS5ObsqF_fWMl2TCWyNTTvF4elOGwOEeKiumVpjB6e740COxvxN3vbkNWxP9eeghpd5nPN5l2wUV3VL2R5s44TbqHqkrkNpUOd3h7efs3cQtCfGc-tCXoqLC26LxT7aztvKpjXMuqGEf-7wbQ")
}
assertTrue(resObserver.values()[0].startsWith("Wysłano wiadomość na zapisany w systemie adres e-mail")) assertTrue(res.startsWith("Wysłano wiadomość na zapisany w systemie adres e-mail"))
} }
@Test @Test
fun studentsTest() { fun studentsTest() {
val students = api.getStudents() val students = runBlocking { api.getStudents() }
val studentObserver = TestObserver<List<Student>>()
students.subscribe(studentObserver)
studentObserver.assertComplete()
val values = studentObserver.values()[0] students[0].run {
values[0].run {
assertEquals("powiatwulkanowy", symbol) assertEquals("powiatwulkanowy", symbol)
assertEquals("jan@fakelog.cf", email) assertEquals("jan@fakelog.cf", email)
assertEquals("Jan Kowalski", studentName) assertEquals("Jan Kowalski", studentName)
@ -108,26 +80,21 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun semestersTest() { fun semestersTest() {
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val values = semestersObserver.values()[0] semesters[0].run {
values[0].run {
assertEquals(15, diaryId) assertEquals(15, diaryId)
assertEquals("4A", diaryName) assertEquals("4A", diaryName)
// assertEquals(true, current) // assertEquals(true, current)
} }
values[3].run { semesters[3].run {
assertEquals(13, diaryId) assertEquals(13, diaryId)
assertEquals("3A", diaryName) assertEquals("3A", diaryName)
assertEquals(2017, schoolYear) assertEquals(2017, schoolYear)
} }
values[5].run { semesters[5].run {
assertEquals(11, diaryId) assertEquals(11, diaryId)
assertEquals("2A", diaryName) assertEquals("2A", diaryName)
assertEquals(2016, schoolYear) assertEquals(2016, schoolYear)
@ -135,7 +102,7 @@ class ScrapperRemoteTest : BaseTest() {
// assertEquals(1, semesterNumber) // assertEquals(1, semesterNumber)
} }
values[6].run { semesters[6].run {
// assertEquals(12, semesterId) // assertEquals(12, semesterId)
// assertEquals(2, semesterNumber) // assertEquals(2, semesterNumber)
} }
@ -143,14 +110,9 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun attendanceTest() { fun attendanceTest() {
val attendance = api.getAttendance(getLocalDate(2018, 10, 1)) val attendance = runBlocking { api.getAttendance(getLocalDate(2018, 10, 1)) }
val attendanceObserver = TestObserver<List<Attendance>>()
attendance.subscribe(attendanceObserver)
attendanceObserver.assertComplete()
val values = attendanceObserver.values()[0] attendance[0].run {
values[0].run {
assertEquals(1, number) assertEquals(1, number)
assertEquals("Zajęcia z wychowawcą", subject) assertEquals("Zajęcia z wychowawcą", subject)
assertEquals(getDate(2018, 10, 1), date) assertEquals(getDate(2018, 10, 1), date)
@ -159,31 +121,26 @@ class ScrapperRemoteTest : BaseTest() {
assertTrue(presence) assertTrue(presence)
} }
values[1].run { attendance[1].run {
assertEquals("Nieobecność nieusprawiedliwiona", name) assertEquals("Nieobecność nieusprawiedliwiona", name)
assertTrue(absence) assertTrue(absence)
assertFalse(excused) assertFalse(excused)
} }
assertEquals("Nieobecność nieusprawiedliwiona", values[3].name) assertEquals("Nieobecność nieusprawiedliwiona", attendance[3].name)
assertEquals("Nieobecność nieusprawiedliwiona", values[4].name) assertEquals("Nieobecność nieusprawiedliwiona", attendance[4].name)
assertEquals("Nieobecność usprawiedliwiona", values[5].name) assertEquals("Nieobecność usprawiedliwiona", attendance[5].name)
assertEquals("Spóźnienie nieusprawiedliwione", values[6].name) assertEquals("Spóźnienie nieusprawiedliwione", attendance[6].name)
assertEquals("Obecność", values[9].name) assertEquals("Obecność", attendance[9].name)
} }
@Test @Test
fun getSubjects() { fun getSubjects() {
val subjects = api.getSubjects() val subjects = runBlocking { api.getSubjects() }
val subjectsObserver = TestObserver<List<Subject>>()
subjects.subscribe(subjectsObserver)
subjectsObserver.assertComplete()
val values = subjectsObserver.values()[0] assertEquals(17, subjects.size)
assertEquals(17, values.size) subjects[0].run {
values[0].run {
assertEquals(-1, value) assertEquals(-1, value)
assertEquals("Wszystkie", name) assertEquals("Wszystkie", name)
} }
@ -191,16 +148,11 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun attendanceSummaryTest() { fun attendanceSummaryTest() {
val attendance = api.getAttendanceSummary() val attendance = runBlocking { api.getAttendanceSummary() }
val attendanceObserver = TestObserver<List<AttendanceSummary>>()
attendance.subscribe(attendanceObserver)
attendanceObserver.assertComplete()
val values = attendanceObserver.values()[0] assertEquals(10, attendance.size)
assertEquals(10, values.size) attendance[0].run {
values[0].run {
assertEquals(Month.SEPTEMBER, month) assertEquals(Month.SEPTEMBER, month)
assertEquals(32, presence) assertEquals(32, presence)
assertEquals(1, absence) assertEquals(1, absence)
@ -211,19 +163,14 @@ class ScrapperRemoteTest : BaseTest() {
assertEquals(6, exemption) assertEquals(6, exemption)
} }
assertEquals(64, values[1].presence) assertEquals(64, attendance[1].presence)
} }
@Test @Test
fun examsTest() { fun examsTest() {
val exams = api.getExams(getLocalDate(2018, 5, 7)) val exams = runBlocking { api.getExams(getLocalDate(2018, 5, 7)) }
val examsObserver = TestObserver<List<Exam>>()
exams.subscribe(examsObserver)
examsObserver.assertComplete()
val values = examsObserver.values()[0] exams[0].run {
values[0].run {
assertEquals(getDate(2018, 5, 7), date) assertEquals(getDate(2018, 5, 7), date)
assertEquals(getDate(1970, 1, 1), entryDate) assertEquals(getDate(1970, 1, 1), entryDate)
assertEquals("Matematyka", subject) assertEquals("Matematyka", subject)
@ -237,14 +184,9 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun homeworkTest() { fun homeworkTest() {
val homework = api.getHomework(getLocalDate(2018, 9, 11)) val homework = runBlocking { api.getHomework(getLocalDate(2018, 9, 11)) }
val homeworkObserver = TestObserver<List<Homework>>()
homework.subscribe(homeworkObserver)
homeworkObserver.assertComplete()
val values = homeworkObserver.values()[0] homework[1].run {
values[1].run {
assertEquals(getDate(2018, 9, 11), date) assertEquals(getDate(2018, 9, 11), date)
assertEquals(getDate(2017, 10, 26), entryDate) assertEquals(getDate(2017, 10, 26), entryDate)
assertEquals("Etyka", subject) assertEquals("Etyka", subject)
@ -256,14 +198,9 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun notesTest() { fun notesTest() {
val notes = api.getNotes() val notes = runBlocking { api.getNotes() }
val notesObserver = TestObserver<List<Note>>()
notes.subscribe(notesObserver)
notesObserver.assertComplete()
val values = notesObserver.values()[0] notes[0].run {
values[0].run {
assertEquals(getDate(2018, 1, 16), date) assertEquals(getDate(2018, 1, 16), date)
assertEquals("Stanisław Krupa", teacher) assertEquals("Stanisław Krupa", teacher)
assertEquals("BS", teacherSymbol) assertEquals("BS", teacherSymbol)
@ -274,14 +211,9 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun gradesTest() { fun gradesTest() {
val grades = api.getGradesDetails(865) val grades = runBlocking { api.getGradesDetails(865) }
val gradesObserver = TestObserver<List<Grade>>()
grades.subscribe(gradesObserver)
gradesObserver.assertComplete()
val values = gradesObserver.values()[0] grades[5].run {
values[5].run {
assertEquals("Religia", subject) assertEquals("Religia", subject)
assertEquals("1", entry) assertEquals("1", entry)
assertEquals("6ECD07", color) assertEquals("6ECD07", color)
@ -293,7 +225,7 @@ class ScrapperRemoteTest : BaseTest() {
assertEquals("Michał Mazur", teacher) assertEquals("Michał Mazur", teacher)
} }
values[0].run { grades[0].run {
assertEquals("Bież", symbol) assertEquals("Bież", symbol)
assertEquals("", description) assertEquals("", description)
} }
@ -301,26 +233,21 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun gradesSummaryTest() { fun gradesSummaryTest() {
val summary = api.getGradesSummary(865) val summary = runBlocking { api.getGradesSummary(865) }
val summaryObserver = TestObserver<List<GradeSummary>>()
summary.subscribe(summaryObserver)
summaryObserver.assertComplete()
val values = summaryObserver.values()[0] summary[2].run {
values[2].run {
assertEquals("Etyka", name) assertEquals("Etyka", name)
assertEquals("4", predicted) assertEquals("4", predicted)
assertEquals("4", final) assertEquals("4", final)
} }
values[5].run { summary[5].run {
assertEquals("Historia", name) assertEquals("Historia", name)
assertEquals("4", predicted) assertEquals("4", predicted)
assertEquals("4", final) assertEquals("4", final)
} }
values[8].run { summary[8].run {
assertEquals("Język niemiecki", name) assertEquals("Język niemiecki", name)
assertEquals("", predicted) assertEquals("", predicted)
assertEquals("", final) assertEquals("", final)
@ -329,59 +256,37 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun gradesStatisticsTest() { fun gradesStatisticsTest() {
val stats = api.getGradesPartialStatistics(321) val stats = runBlocking { api.getGradesPartialStatistics(321) }
val statsObserver = TestObserver<List<GradeStatistics>>()
stats.subscribe(statsObserver)
statsObserver.assertComplete()
val values = statsObserver.values()[0] assertEquals("Język polski", stats[0].subject)
assertEquals("Matematyka", stats[7].subject)
assertEquals("Język polski", values[0].subject) val annual = runBlocking { api.getGradesAnnualStatistics(123) }
assertEquals("Matematyka", values[7].subject)
val annual = api.getGradesAnnualStatistics(123) assertEquals("Język angielski", annual[0].subject)
val annualObserver = TestObserver<List<GradeStatistics>>()
annual.subscribe(annualObserver)
val values2 = annualObserver.values()[0]
assertEquals("Język angielski", values2[0].subject)
} }
@Test @Test
fun teachersTest() { fun teachersTest() {
val teachers = api.getTeachers() val teachers = runBlocking { api.getTeachers() }
val teachersObserver = TestObserver<List<Teacher>>()
teachers.subscribe(teachersObserver)
teachersObserver.assertComplete()
val values = teachersObserver.values()[0] assertEquals("Historia", teachers[1].subject)
assertEquals("Aleksandra Krajewska", teachers[1].name)
assertEquals("Historia", values[1].subject) assertEquals("AK", teachers[1].short)
assertEquals("Aleksandra Krajewska", values[1].name)
assertEquals("AK", values[1].short)
} }
@Test @Test
fun schoolTest() { fun schoolTest() {
val school = api.getSchool() val school = runBlocking { api.getSchool() }
val schoolObserver = TestObserver<School>()
school.subscribe(schoolObserver)
schoolObserver.assertComplete()
val values = schoolObserver.values()[0] assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", school.name)
assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", values.name)
} }
@Test @Test
fun studentInfoTest() { fun studentInfoTest() {
val info = api.getStudentInfo() val info = runBlocking { api.getStudentInfo() }
val studentObserver = TestObserver<StudentInfo>()
info.subscribe(studentObserver)
studentObserver.assertComplete()
studentObserver.values()[0].run { info.run {
assertEquals("Jan Marek Kowalski", student.fullName) assertEquals("Jan Marek Kowalski", student.fullName)
assertEquals("Jan", student.firstName) assertEquals("Jan", student.firstName)
assertEquals("Marek", student.secondName) assertEquals("Marek", student.secondName)
@ -413,85 +318,52 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun messagesTest() { fun messagesTest() {
val units = api.getReportingUnits() val units = runBlocking { api.getReportingUnits() }
val unitsObserver = TestObserver<List<ReportingUnit>>() assertEquals(1, units.size)
units.subscribe(unitsObserver)
unitsObserver.assertComplete()
val recipients = api.getRecipients(6) val recipients = runBlocking { api.getRecipients(6) }
val recipientsObserver = TestObserver<List<Recipient>>() assertEquals(10, recipients.size)
recipients.subscribe(recipientsObserver)
recipientsObserver.assertComplete()
val messages = api.getMessages(Folder.RECEIVED) val messages = runBlocking { api.getMessages(Folder.RECEIVED) }
val messagesObserver = TestObserver<List<Message>>() assertEquals(2, messages.size)
messages.subscribe(messagesObserver)
messagesObserver.assertComplete()
val inbox = api.getReceivedMessages(getLocalDateTime(2015, 10, 5)) val inbox = runBlocking { api.getReceivedMessages(getLocalDateTime(2015, 10, 5)) }
val inboxObserver = TestObserver<List<Message>>() assertEquals(2, inbox.size)
inbox.subscribe(inboxObserver)
inboxObserver.assertComplete()
assertEquals(2, inboxObserver.values()[0].size) val sent = runBlocking { api.getSentMessages() }
assertEquals(1, sent.size)
val sent = api.getSentMessages() val trash = runBlocking { api.getDeletedMessages() }
val outObserver = TestObserver<List<Message>>() assertEquals(1, trash.size)
sent.subscribe(outObserver)
outObserver.assertComplete()
assertEquals(1, outObserver.values()[0].size) val mRecipients = runBlocking { api.getMessageRecipients(trash[0].messageId ?: 0) }
assertEquals(2, mRecipients.size)
val trash = api.getDeletedMessages() val details = runBlocking { api.getMessageDetails(trash[0].messageId ?: 0, trash[0].folderId) }
val trashObserver = TestObserver<List<Message>>() assertEquals(27214, details.id)
trash.subscribe(trashObserver)
trashObserver.assertComplete()
val del = trashObserver.values()[0]
assertEquals(1, del.size)
val mRecipients = api.getMessageRecipients(del[0].messageId ?: 0)
val mRecipientsObserver = TestObserver<List<Recipient>>()
mRecipients.subscribe(mRecipientsObserver)
mRecipientsObserver.assertComplete()
val m = api.getMessageDetails(del[0].messageId ?: 0, del[0].folderId)
val mObserver = TestObserver<Message>()
m.subscribe(mObserver)
mObserver.assertComplete()
} }
@Test @Test
fun sendMessage() { fun sendMessage() {
val send = api.sendMessage("Temat wiadomości", "Treść", runBlocking {
listOf(Recipient("0", "Kowalski Jan", 0, 0, 2, "hash")) api.sendMessage("Temat wiadomości", "Treść",
) listOf(Recipient("0", "Kowalski Jan", 0, 0, 2, "hash"))
val sendObserver = TestObserver<SentMessage>() )
send.subscribe(sendObserver) }
sendObserver.assertComplete()
} }
@Test @Test
fun devicesTest() { fun devicesTest() {
val devices = api.getRegisteredDevices() val devices = runBlocking { api.getRegisteredDevices() }
val devicesObserver = TestObserver<List<Device>>()
devices.subscribe(devicesObserver)
devicesObserver.assertComplete()
val values = devicesObserver.values()[0] assertEquals(2, devices.size)
assertEquals(2, values.size)
} }
@Test @Test
fun tokenTest() { fun tokenTest() {
val tokenizer = api.getToken() val tokenizer = runBlocking { api.getToken() }
val tokenObserver = TestObserver<TokenResponse>()
tokenizer.subscribe(tokenObserver)
tokenObserver.assertComplete()
tokenObserver.values()[0].run { tokenizer.run {
assertEquals("FK100000", token) assertEquals("FK100000", token)
assertEquals("powiatwulkanowy", symbol) assertEquals("powiatwulkanowy", symbol)
assertEquals("999999", pin) assertEquals("999999", pin)
@ -500,24 +372,16 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun unregisterTest() { fun unregisterTest() {
val unregister = api.unregisterDevice(1234) val unregister = runBlocking { api.unregisterDevice(1234) }
val unregisterObserver = TestObserver<Boolean>()
unregister.subscribe(unregisterObserver)
unregisterObserver.assertComplete()
assertEquals(true, unregisterObserver.values()[0]) assertEquals(true, unregister)
} }
@Test @Test
fun timetableTest() { fun timetableTest() {
val timetable = api.getTimetable(getLocalDate(2018, 9, 17)) val timetable = runBlocking { api.getTimetable(getLocalDate(2018, 9, 17)) }
val timetableObserver = TestObserver<List<Timetable>>()
timetable.subscribe(timetableObserver)
timetableObserver.assertComplete()
val values = timetableObserver.values()[0] timetable[0].run {
values[0].run {
assertEquals(1, number) assertEquals(1, number)
assertEquals("Fizyka", subject) assertEquals("Fizyka", subject)
assertEquals("Karolina Kowalska", teacher) assertEquals("Karolina Kowalska", teacher)
@ -531,12 +395,9 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun realizedTest() { fun realizedTest() {
val realized = api.getCompletedLessons(getLocalDate(2018, 9, 17)) val realized = runBlocking { api.getCompletedLessons(getLocalDate(2018, 9, 17)) }
val realizedObserver = TestObserver<List<CompletedLesson>>()
realized.subscribe(realizedObserver)
realizedObserver.assertComplete()
realizedObserver.values()[0][0].run { realized[0].run {
assertEquals(getDate(2018, 9, 17), date) assertEquals(getDate(2018, 9, 17), date)
assertEquals(1, number) assertEquals(1, number)
assertEquals("Historia i społeczeństwo", subject) assertEquals("Historia i społeczeństwo", subject)
@ -549,17 +410,14 @@ class ScrapperRemoteTest : BaseTest() {
@Test @Test
fun luckyNumberTest() { fun luckyNumberTest() {
val luckyNumber = api.getKidsLuckyNumbers() val luckyNumber = runBlocking { api.getKidsLuckyNumbers() }
val luckyNumberObserver = TestObserver<List<LuckyNumber>>()
luckyNumber.subscribe(luckyNumberObserver)
luckyNumberObserver.assertComplete()
assertEquals(37, luckyNumberObserver.values()[0][0].number) assertEquals(37, luckyNumber[0].number)
} }
@Test @Test
fun freeDays() { fun freeDays() {
val freeDays = api.getFreeDays().blockingGet() val freeDays = runBlocking { api.getFreeDays() }
assertEquals(2, freeDays.size) assertEquals(2, freeDays.size)
} }
} }

View file

@ -1,8 +1,7 @@
package io.github.wulkanowy.sdk.scrapper package io.github.wulkanowy.sdk.scrapper
import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceSummaryTest import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceSummaryTest
import io.github.wulkanowy.sdk.scrapper.attendance.Subject import kotlinx.coroutines.runBlocking
import io.reactivex.observers.TestObserver
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Test import org.junit.Test
@ -25,18 +24,20 @@ class ScrapperTest : BaseLocalTest() {
diaryId = 101 diaryId = 101
} }
val subjects = api.getSubjects() try {
val subjectsObserver = TestObserver<List<Subject>>() runBlocking { api.getSubjects() }
subjects.subscribe(subjectsObserver) } catch (e: Throwable) {
subjectsObserver.assertNotComplete() // assert(true) //
}
api.apply { api.apply {
host = "fakelog.localhost:3000" // host = "fakelog.localhost:3000" //
} }
val subjects2 = api.getSubjects() try {
val subjectsObserver2 = TestObserver<List<Subject>>() runBlocking { api.getSubjects() }
subjects2.subscribe(subjectsObserver2) } catch (e: Throwable) {
subjectsObserver2.assertComplete() // assert(false) //
}
} }
} }

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.attendance package io.github.wulkanowy.sdk.scrapper.attendance
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.threeten.bp.Month.SEPTEMBER import org.threeten.bp.Month.SEPTEMBER
@ -10,19 +11,19 @@ import org.threeten.bp.Month.JUNE
class AttendanceSummaryTest : BaseLocalTest() { class AttendanceSummaryTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(AttendanceSummaryTest::class.java, "Frekwencja.html").getAttendanceSummary(-1).blockingGet() runBlocking { getSnpRepo(AttendanceSummaryTest::class.java, "Frekwencja.html").getAttendanceSummary(-1) }
} }
private val snpSubjects by lazy { private val snpSubjects by lazy {
getSnpRepo(AttendanceSummaryTest::class.java, "Frekwencja.html").getSubjects().blockingGet() runBlocking { getSnpRepo(AttendanceSummaryTest::class.java, "Frekwencja.html").getSubjects() }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(AttendanceSummaryTest::class.java, "StatystykiFrekwencji.json").getAttendanceSummary(-1).blockingGet() runBlocking { getStudentRepo(AttendanceSummaryTest::class.java, "StatystykiFrekwencji.json").getAttendanceSummary(-1) }
} }
private val studentSubjects by lazy { private val studentSubjects by lazy {
getStudentRepo(AttendanceSummaryTest::class.java, "Przedmioty.json").getSubjects().blockingGet() runBlocking { getStudentRepo(AttendanceSummaryTest::class.java, "Przedmioty.json").getSubjects() }
} }
@Test @Test

View file

@ -5,6 +5,7 @@ import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.runBlocking
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
@ -16,7 +17,7 @@ import org.threeten.bp.LocalDateTime
class AttendanceTest : BaseLocalTest() { class AttendanceTest : BaseLocalTest() {
private val student by lazy { private val student by lazy {
getStudentRepo(AttendanceTest::class.java, "Frekwencja.json").getAttendance(getLocalDate(2018, 10, 1), null).blockingGet() runBlocking { getStudentRepo(AttendanceTest::class.java, "Frekwencja.json").getAttendance(getLocalDate(2018, 10, 1), null) }
} }
override fun getStudentRepo(testClass: Class<*>, fixture: String, loginType: Scrapper.LoginType): StudentRepository { override fun getStudentRepo(testClass: Class<*>, fixture: String, loginType: Scrapper.LoginType): StudentRepository {
@ -202,27 +203,32 @@ class AttendanceTest : BaseLocalTest() {
@Test @Test
fun excuseForAbsence() { fun excuseForAbsence() {
server.enqueue(MockResponse().setBody(RegisterTest::class.java.getResource("WitrynaUcznia.html").readText())) server.enqueue(MockResponse().setBody(RegisterTest::class.java.getResource("WitrynaUcznia.html").readText()))
getStudentRepo(AttendanceTest::class.java, "Usprawiedliwione.json").excuseForAbsence(
absents = listOf( val absents = listOf(
Absent( Absent(
date = LocalDateTime.of(2019, 2, 11, 15, 53, 9), date = LocalDateTime.of(2019, 2, 11, 15, 53, 9),
timeId = 1 timeId = 1
),
Absent(
date = LocalDateTime.of(2019, 2, 11, 15, 53, 9),
timeId = 2
),
Absent(
date = LocalDateTime.of(2019, 2, 11, 15, 53, 9),
timeId = 3
),
Absent(
date = LocalDateTime.of(2019, 2, 12, 15, 53, 9),
timeId = null
)
), ),
content = "Test" Absent(
).blockingGet() date = LocalDateTime.of(2019, 2, 11, 15, 53, 9),
timeId = 2
),
Absent(
date = LocalDateTime.of(2019, 2, 11, 15, 53, 9),
timeId = 3
),
Absent(
date = LocalDateTime.of(2019, 2, 12, 15, 53, 9),
timeId = null
)
)
runBlocking {
getStudentRepo(AttendanceTest::class.java, "Usprawiedliwione.json").excuseForAbsence(
absents = absents,
content = "Test"
)
}
server.takeRequest() server.takeRequest()

View file

@ -1,21 +1,22 @@
package io.github.wulkanowy.sdk.scrapper.exams package io.github.wulkanowy.sdk.scrapper.exams
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class ExamsTest : BaseLocalTest() { class ExamsTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(ExamsTest::class.java, "Sprawdziany-one-per-day.html").getExams(getLocalDate(2018, 10, 1)).blockingGet() runBlocking { getSnpRepo(ExamsTest::class.java, "Sprawdziany-one-per-day.html").getExams(getLocalDate(2018, 10, 1)) }
} }
private val snpEmpty by lazy { private val snpEmpty by lazy {
getSnpRepo(ExamsTest::class.java, "Sprawdziany-empty.html").getExams(getLocalDate(2018, 10, 1)).blockingGet() runBlocking { getSnpRepo(ExamsTest::class.java, "Sprawdziany-empty.html").getExams(getLocalDate(2018, 10, 1)) }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(ExamsTest::class.java, "Sprawdziany.json").getExams(getLocalDate(2018, 10, 1)).blockingGet() runBlocking { getStudentRepo(ExamsTest::class.java, "Sprawdziany.json").getExams(getLocalDate(2018, 10, 1)) }
} }
@Test @Test

View file

@ -1,25 +1,26 @@
package io.github.wulkanowy.sdk.scrapper.grades package io.github.wulkanowy.sdk.scrapper.grades
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class GradesGradeSummaryTest : BaseLocalTest() { class GradesGradeSummaryTest : BaseLocalTest() {
private val std by lazy { private val std by lazy {
getSnpRepo(GradesTest::class.java, "OcenyWszystkie-subjects.html").getGradesSummary(0).blockingGet() runBlocking { getSnpRepo(GradesTest::class.java, "OcenyWszystkie-subjects.html").getGradesSummary(0) }
} }
private val snp by lazy { private val snp by lazy {
getSnpRepo(GradesTest::class.java, "OcenyWszystkie-subjects-average.html").getGradesSummary(0).blockingGet() runBlocking { getSnpRepo(GradesTest::class.java, "OcenyWszystkie-subjects-average.html").getGradesSummary(0) }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(GradesTest::class.java, "Oceny.json").getGradesSummary(0).blockingGet() runBlocking { getStudentRepo(GradesTest::class.java, "Oceny.json").getGradesSummary(0) }
} }
private val studentPoints by lazy { private val studentPoints by lazy {
getStudentRepo(GradesTest::class.java, "Oceny-points.json").getGradesSummary(0).blockingGet() runBlocking { getStudentRepo(GradesTest::class.java, "Oceny-points.json").getGradesSummary(0) }
} }
@Test @Test

View file

@ -1,29 +1,30 @@
package io.github.wulkanowy.sdk.scrapper.grades package io.github.wulkanowy.sdk.scrapper.grades
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class GradesStatisticsTest : BaseLocalTest() { class GradesStatisticsTest : BaseLocalTest() {
private val snpPartial by lazy { private val snpPartial by lazy {
getSnpRepo(GradesStatisticsTest::class.java, "Statystyki-czastkowe.html").getGradesStatistics(123, false).blockingGet() runBlocking { getSnpRepo(GradesStatisticsTest::class.java, "Statystyki-czastkowe.html").getGradesStatistics(123, false) }
} }
private val snpAnnual by lazy { private val snpAnnual by lazy {
getSnpRepo(GradesStatisticsTest::class.java, "Statystyki-roczne.html").getGradesStatistics(321, true).blockingGet() runBlocking { getSnpRepo(GradesStatisticsTest::class.java, "Statystyki-roczne.html").getGradesStatistics(321, true) }
} }
private val studentPartial by lazy { private val studentPartial by lazy {
getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-czastkowe.json").getGradesPartialStatistics(123).blockingGet() runBlocking { getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-czastkowe.json").getGradesPartialStatistics(123) }
} }
private val studentAnnual by lazy { private val studentAnnual by lazy {
getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-roczne.json").getGradesAnnualStatistics(321).blockingGet() runBlocking { getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-roczne.json").getGradesAnnualStatistics(321) }
} }
private val points by lazy { private val points by lazy {
getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-punkty.json").getGradesPointsStatistics(420).blockingGet() runBlocking { getStudentRepo(GradesStatisticsTest::class.java, "Statystyki-punkty.json").getGradesPointsStatistics(420) }
} }
@Test @Test

View file

@ -1,21 +1,22 @@
package io.github.wulkanowy.sdk.scrapper.grades package io.github.wulkanowy.sdk.scrapper.grades
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class GradesTest : BaseLocalTest() { class GradesTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(GradesTest::class.java, "OcenyWszystkie-details.html").getGradesDetails(0).blockingGet() runBlocking { getSnpRepo(GradesTest::class.java, "OcenyWszystkie-details.html").getGradesDetails(0) }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(GradesTest::class.java, "Oceny.json").getGradesDetails(0).blockingGet() runBlocking { getStudentRepo(GradesTest::class.java, "Oceny.json").getGradesDetails(0) }
} }
private val studentPoints by lazy { private val studentPoints by lazy {
getStudentRepo(GradesTest::class.java, "Oceny-points.json").getGradesDetails(0).blockingGet() runBlocking { getStudentRepo(GradesTest::class.java, "Oceny-points.json").getGradesDetails(0) }
} }
@Test @Test

View file

@ -4,6 +4,7 @@ import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber
import io.github.wulkanowy.sdk.scrapper.repository.HomepageRepository import io.github.wulkanowy.sdk.scrapper.repository.HomepageRepository
import io.github.wulkanowy.sdk.scrapper.service.HomepageService import io.github.wulkanowy.sdk.scrapper.service.HomepageService
import kotlinx.coroutines.runBlocking
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -21,7 +22,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue("GetSelfGovernments.json") server.enqueue("GetSelfGovernments.json")
server.start(3000) server.start(3000)
val units = repo.getSelfGovernments().blockingGet() val units = runBlocking { repo.getSelfGovernments() }
assertEquals(1, units.size) assertEquals(1, units.size)
assertEquals("ZST-I", units[0].unitName) assertEquals("ZST-I", units[0].unitName)
@ -45,7 +46,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue("GetStudentThreats.json") server.enqueue("GetStudentThreats.json")
server.start(3000) server.start(3000)
val threats = repo.getStudentThreats().blockingGet() val threats = runBlocking { repo.getStudentThreats() }
assertEquals(1, threats.size) assertEquals(1, threats.size)
assertEquals("Jan Kowalski matematyka", threats[0]) assertEquals("Jan Kowalski matematyka", threats[0])
} }
@ -56,7 +57,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetLastNotes.json").readText())) server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetLastNotes.json").readText()))
server.start(3000) server.start(3000)
val res = repo.getLastGrades().blockingGet() val res = runBlocking { repo.getLastGrades() }
assertEquals( assertEquals(
listOf( listOf(
"j. angielski: 1, 6", "j. angielski: 1, 6",
@ -72,7 +73,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetFreeDays.json").readText())) server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetFreeDays.json").readText()))
server.start(3000) server.start(3000)
val res = repo.getFreeDays().blockingGet() val res = runBlocking { repo.getFreeDays() }
assertEquals( assertEquals(
listOf( listOf(
"Czwartek (20.06.2019) - Sobota (31.08.2019) - Ferie letnie", "Czwartek (20.06.2019) - Sobota (31.08.2019) - Ferie letnie",
@ -107,7 +108,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetKidsLuckyNumbers.json").readText())) server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetKidsLuckyNumbers.json").readText()))
server.start(3000) server.start(3000)
val number = repo.getKidsLuckyNumbers().blockingGet() val number = runBlocking { repo.getKidsLuckyNumbers() }
assertEquals(listOf(LuckyNumber("", "SPL", 18)), number) assertEquals(listOf(LuckyNumber("", "SPL", 18)), number)
server.takeRequest() server.takeRequest()
@ -123,7 +124,7 @@ class HomepageTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetKidsLuckyNumbers-multi-institution.json").readText())) server.enqueue(MockResponse().setBody(HomepageTest::class.java.getResource("GetKidsLuckyNumbers-multi-institution.json").readText()))
server.start(3000) server.start(3000)
val numbers = repo.getKidsLuckyNumbers().blockingGet() val numbers = runBlocking { repo.getKidsLuckyNumbers() }
assertEquals(listOf( assertEquals(listOf(
LuckyNumber("002547", "T", 37), LuckyNumber("002547", "T", 37),
LuckyNumber("010472", "ZSP Warcie", 12) LuckyNumber("010472", "ZSP Warcie", 12)

View file

@ -4,13 +4,14 @@ import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository import io.github.wulkanowy.sdk.scrapper.repository.StudentRepository
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class HomeworkTest : BaseLocalTest() { class HomeworkTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(HomeworkTest::class.java, "ZadaniaDomowe.html").getHomework(getLocalDate(2018, 10, 1)).blockingGet() runBlocking { getSnpRepo(HomeworkTest::class.java, "ZadaniaDomowe.html").getHomework(getLocalDate(2018, 10, 1)) }
} }
private val studentRaw by lazy { private val studentRaw by lazy {
@ -18,7 +19,7 @@ class HomeworkTest : BaseLocalTest() {
} }
private val student by lazy { private val student by lazy {
getStudentRepo(HomeworkTest::class.java, "Homework.json").getHomework(getLocalDate(2018, 10, 1)).blockingGet() runBlocking { getStudentRepo(HomeworkTest::class.java, "Homework.json").getHomework(getLocalDate(2018, 10, 1)) }
} }
@Test @Test
@ -66,7 +67,7 @@ class HomeworkTest : BaseLocalTest() {
server.enqueue("ZadaniaDomowe.json") server.enqueue("ZadaniaDomowe.json")
server.start(3030) server.start(3030)
val homework = studentRaw.getHomework(getLocalDate(2018, 10, 1)).blockingGet() val homework = runBlocking { studentRaw.getHomework(getLocalDate(2018, 10, 1)) }
assertEquals(2, homework.size) assertEquals(2, homework.size)
} }
} }

View file

@ -7,74 +7,82 @@ import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
import io.github.wulkanowy.sdk.scrapper.notes.Note import kotlinx.coroutines.runBlocking
import io.reactivex.observers.TestObserver import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
class ErrorInterceptorTest : BaseLocalTest() { class ErrorInterceptorTest : BaseLocalTest() {
@Test @Test
fun notLoggedIn_standard() { fun notLoggedIn_standard() {
val notes = getSnpRepo(LoginTest::class.java, "Logowanie-standard.html", Scrapper.LoginType.STANDARD).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "Logowanie-standard.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(NotLoggedInException::class.java) assertTrue(e is NotLoggedInException)
}
} }
@Test @Test
fun notLoggedIn_standard2() { fun notLoggedIn_standard2() {
val notes = getSnpRepo(LoginTest::class.java, "LoginPage-standard.html", Scrapper.LoginType.STANDARD).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "LoginPage-standard.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(NotLoggedInException::class.java) assertTrue(e is NotLoggedInException)
}
} }
@Test @Test
fun notLoggedIn_adfs() { fun notLoggedIn_adfs() {
val notes = getSnpRepo(LoginTest::class.java, "ADFS-form-2.html", Scrapper.LoginType.ADFS).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "ADFS-form-2.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(NotLoggedInException::class.java) assertTrue(e is NotLoggedInException)
}
} }
@Test @Test
fun notLoggedIn_adfsCards() { fun notLoggedIn_adfsCards() {
val notes = getSnpRepo(LoginTest::class.java, "ADFS-form-1.html", Scrapper.LoginType.ADFSCards).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "ADFS-form-1.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(NotLoggedInException::class.java) assertTrue(e is NotLoggedInException)
}
} }
@Test @Test
fun notLoggedInt_adfsLight() { fun notLoggedInt_adfsLight() {
val notes = getSnpRepo(LoginTest::class.java, "ADFSLight-form-1.html", Scrapper.LoginType.ADFSLight).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "ADFSLight-form-1.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(NotLoggedInException::class.java) assertTrue(e is NotLoggedInException)
}
} }
@Test @Test
fun offline_databaseUpdate() { fun offline_databaseUpdate() {
val notes = getSnpRepo(ErrorInterceptorTest::class.java, "AktualizacjaBazyDanych.html", Scrapper.LoginType.STANDARD).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(ErrorInterceptorTest::class.java, "AktualizacjaBazyDanych.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(ServiceUnavailableException::class.java) assertTrue(e is ServiceUnavailableException)
}
} }
@Test @Test
fun passwordChangeRequired() { fun passwordChangeRequired() {
val notes = getSnpRepo(LoginTest::class.java, "PrzywracanieDostepu.html", Scrapper.LoginType.ADFSLight).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(LoginTest::class.java, "PrzywracanieDostepu.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(PasswordChangeRequiredException::class.java) assertTrue(e is PasswordChangeRequiredException)
}
} }
@Test @Test
fun error_unknown() { fun error_unknown() {
val notes = getSnpRepo(ErrorInterceptorTest::class.java, "Błąd-adfs.html", Scrapper.LoginType.ADFSLight).getNotes() try {
val observer = TestObserver<List<Note>>() runBlocking { getSnpRepo(ErrorInterceptorTest::class.java, "Błąd-adfs.html", Scrapper.LoginType.STANDARD).getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertError(VulcanException::class.java) assertTrue(e is VulcanException)
observer.assertError { it.message?.startsWith("Błąd") == true } assertTrue(e.message?.startsWith("Błąd") == true)
}
} }
} }

View file

@ -1,13 +1,12 @@
package io.github.wulkanowy.sdk.scrapper.login package io.github.wulkanowy.sdk.scrapper.login
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.homework.HomeworkTest import io.github.wulkanowy.sdk.scrapper.homework.HomeworkTest
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.register.SendCertificateResponse
import io.github.wulkanowy.sdk.scrapper.service.LoginService import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.reactivex.observers.TestObserver import kotlinx.coroutines.runBlocking
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
@ -36,7 +35,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText()))
server.start(3000) server.start(3000)
val res = adfs.login("jan@fakelog.cf", "jan123").blockingGet() val res = runBlocking { adfs.login("jan@fakelog.cf", "jan123") }
assertTrue(res.oldStudentSchools.isNotEmpty()) assertTrue(res.oldStudentSchools.isNotEmpty())
} }
@ -47,7 +46,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan123").blockingGet() val res = runBlocking { normal.login("jan@fakelog.cf", "jan123") }
assertTrue(res.oldStudentSchools.isNotEmpty()) assertTrue(res.oldStudentSchools.isNotEmpty())
} }
@ -58,7 +57,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText()))
server.start(3000) server.start(3000)
normal.login("jan@fakelog.cf", "jan123").blockingGet() runBlocking { normal.login("jan@fakelog.cf", "jan123") }
assertEquals("[text=LoginName=jan%40fakelog.cf&Password=jan123]", server.takeRequest().body.toString()) assertEquals("[text=LoginName=jan%40fakelog.cf&Password=jan123]", server.takeRequest().body.toString())
} }
@ -70,7 +69,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success-account-switch.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success-account-switch.html").readText()))
server.start(3000) server.start(3000)
normal.login("jan||jan@fakelog.cf", "jan123").blockingGet() runBlocking { normal.login("jan||jan@fakelog.cf", "jan123") }
assertEquals("[text=LoginName=jan&Password=jan123]", server.takeRequest().body.toString()) assertEquals("[text=LoginName=jan&Password=jan123]", server.takeRequest().body.toString())
} }
@ -81,7 +80,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success-old.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success-old.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan123").blockingGet() val res = runBlocking { normal.login("jan@fakelog.cf", "jan123") }
assertTrue(res.oldStudentSchools.isNotEmpty()) assertTrue(res.oldStudentSchools.isNotEmpty())
} }
@ -92,7 +91,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Login-success.html").readText()))
server.start(3000) server.start(3000)
normal.login("jan@fakelog.cf", "jan123").blockingGet() runBlocking { normal.login("jan@fakelog.cf", "jan123") }
server.takeRequest() server.takeRequest()
assertFalse(server.takeRequest().body.readUtf8().contains("ValueType%3D%26t%3Bhttp")) // ValueType=&t;http assertFalse(server.takeRequest().body.readUtf8().contains("ValueType%3D%26t%3Bhttp")) // ValueType=&t;http
@ -105,11 +104,11 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-adfs-zle-haslo.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-adfs-zle-haslo.html").readText()))
server.start(3000) server.start(3000)
val res = adfs.login("jan@fakelog.cf", "jan1234") try {
val observer = TestObserver<SendCertificateResponse>() runBlocking { adfs.login("jan@fakelog.cf", "jan1234") }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is BadCredentialsException)
observer.assertError(BadCredentialsException::class.java) }
} }
@Test @Test
@ -118,11 +117,11 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-normal-zle-haslo.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-normal-zle-haslo.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan1234") try {
val observer = TestObserver<SendCertificateResponse>() runBlocking { adfs.login("jan@fakelog.cf", "jan1234") }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is BadCredentialsException)
observer.assertError(BadCredentialsException::class.java) }
} }
@Test @Test
@ -131,13 +130,11 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan123") try {
val observer = TestObserver<SendCertificateResponse>() runBlocking { adfs.login("jan@fakelog.cf", "jan1234") }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is AccountPermissionException)
observer.assertError(AccountPermissionException::class.java) assertEquals("Adres nie został zarejestrowany w dzienniku uczniowskim jako adres rodzica, bądź ucznia.", e.message)
observer.assertError {
it.localizedMessage == "Adres nie został zarejestrowany w dzienniku uczniowskim jako adres rodzica, bądź ucznia."
} }
} }
@ -146,10 +143,7 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(HomeworkTest::class.java.getResource("ZadaniaDomowe.html").readText())) server.enqueue(MockResponse().setBody(HomeworkTest::class.java.getResource("ZadaniaDomowe.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan123") runBlocking { normal.login("jan@fakelog.cf", "jan123") }
val observer = TestObserver<SendCertificateResponse>()
res.subscribe(observer)
observer.assertComplete()
} }
@Test @Test
@ -157,10 +151,10 @@ class LoginTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(ErrorInterceptorTest::class.java.getResource("Offline.html").readText())) server.enqueue(MockResponse().setBody(ErrorInterceptorTest::class.java.getResource("Offline.html").readText()))
server.start(3000) server.start(3000)
val res = normal.login("jan@fakelog.cf", "jan123") try {
val observer = TestObserver<SendCertificateResponse>() runBlocking { adfs.login("jan@fakelog.cf", "jan1234") }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
observer.assertError(VulcanException::class.java) }
} }
} }

View file

@ -6,9 +6,10 @@ import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
import io.github.wulkanowy.sdk.scrapper.repository.MessagesRepository import io.github.wulkanowy.sdk.scrapper.repository.MessagesRepository
import io.github.wulkanowy.sdk.scrapper.service.MessagesService import io.github.wulkanowy.sdk.scrapper.service.MessagesService
import io.reactivex.observers.TestObserver import kotlinx.coroutines.runBlocking
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
class MessagesTest : BaseLocalTest() { class MessagesTest : BaseLocalTest() {
@ -22,7 +23,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText()))
server.start(3000) server.start(3000)
val recipients = api.getRecipients(6).blockingGet() val recipients = runBlocking { api.getRecipients(6) }
assertEquals(4, recipients.size) assertEquals(4, recipients.size)
@ -52,7 +53,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciOdebrane.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciOdebrane.json").readText()))
server.start(3000) server.start(3000)
val messages = api.getReceivedMessages(null, null).blockingGet() val messages = runBlocking { api.getReceivedMessages(null, null) }
assertEquals(2, messages.size) assertEquals(2, messages.size)
with(messages[0]) { with(messages[0]) {
@ -73,7 +74,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciUsuniete.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciUsuniete.json").readText()))
server.start(3000) server.start(3000)
assertEquals(1, api.getDeletedMessages(null, null).blockingGet().size) assertEquals(1, runBlocking { api.getDeletedMessages(null, null) }.size)
} }
@Test @Test
@ -81,7 +82,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText()))
server.start(3000) server.start(3000)
val messages = api.getSentMessages(null, null).blockingGet() val messages = runBlocking { api.getSentMessages(null, null) }
assertEquals(6, messages.size) assertEquals(6, messages.size)
@ -100,7 +101,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText()))
server.start(3000) server.start(3000)
api.getSentMessages(null, null).blockingGet()[1].run { runBlocking { api.getSentMessages(null, null) }[1].run {
assertEquals("Czerwieńska - Kowalska Joanna", recipient) assertEquals("Czerwieńska - Kowalska Joanna", recipient)
} }
} }
@ -110,7 +111,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText()))
server.start(3000) server.start(3000)
api.getSentMessages(null, null).blockingGet()[3].run { runBlocking { api.getSentMessages(null, null) }[3].run {
assertEquals("Czerwieńska - Kowalska Joanna; Tracz Janusz", recipient) assertEquals("Czerwieńska - Kowalska Joanna; Tracz Janusz", recipient)
} }
} }
@ -120,7 +121,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WiadomosciWyslane.json").readText()))
server.start(3000) server.start(3000)
api.getSentMessages(null, null).blockingGet()[5].run { runBlocking { api.getSentMessages(null, null) }[5].run {
assertEquals("Tracz Antoni; Kowalska Joanna", recipient) assertEquals("Tracz Antoni; Kowalska Joanna", recipient)
} }
} }
@ -130,7 +131,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText()))
server.start(3000) server.start(3000)
api.getMessageRecipients(421, 0).blockingGet()[0].run { runBlocking { api.getMessageRecipients(421, 0) }[0].run {
assertEquals("18rPracownik", id) assertEquals("18rPracownik", id)
assertEquals("Tracz Janusz [TJ] - pracownik (Fake123456)", name) assertEquals("Tracz Janusz [TJ] - pracownik (Fake123456)", name)
assertEquals(18, loginId) assertEquals(18, loginId)
@ -146,7 +147,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Adresaci.json").readText()))
server.start(3000) server.start(3000)
api.getMessageRecipients(421, 94).blockingGet()[1].run { runBlocking { api.getMessageRecipients(421, 94) }[1].run {
assertEquals("94rPracownik", id) assertEquals("94rPracownik", id)
assertEquals(94, loginId) assertEquals(94, loginId)
} }
@ -157,7 +158,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Wiadomosc.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Wiadomosc.json").readText()))
server.start(3000) server.start(3000)
assertEquals(90, api.getMessage(1, 1, false, 0).blockingGet().length) assertEquals(90, runBlocking { api.getMessage(1, 1, false, 0) }.length)
} }
@Test @Test
@ -165,7 +166,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Wiadomosc.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("Wiadomosc.json").readText()))
server.start(3000) server.start(3000)
val attachments = api.getMessageAttachments(1, 1).blockingGet() val attachments = runBlocking { api.getMessageAttachments(1, 1) }
assertEquals(1, attachments.size) assertEquals(1, attachments.size)
with(attachments[0]) { with(attachments[0]) {
@ -183,10 +184,12 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WyslanaWiadomosc.json").readText())) server.enqueue(MockResponse().setBody(MessagesTest::class.java.getResource("WyslanaWiadomosc.json").readText()))
server.start(3000) server.start(3000)
api.sendMessage( runBlocking {
"Temat wiadomości", "Tak wygląda zawartość wiadomości.\nZazwyczaj ma wiele linijek.\n\nZ poważaniem,\nNazwisko Imię", api.sendMessage(
listOf(Recipient("0", "Kowalski Jan", 0, 0, 2, "hash")) "Temat wiadomości", "Tak wygląda zawartość wiadomości.\nZazwyczaj ma wiele linijek.\n\nZ poważaniem,\nNazwisko Imię",
).blockingGet() listOf(Recipient("0", "Kowalski Jan", 0, 0, 2, "hash"))
)
}
server.takeRequest() server.takeRequest()
@ -209,12 +212,12 @@ class MessagesTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val api = MessagesRepository(getService(MessagesService::class.java, "http://fakelog.localhost:3000/", false, loginType = Scrapper.LoginType.ADFSLight)) val api = MessagesRepository(getService(MessagesService::class.java, "http://fakelog.localhost:3000/", false, loginType = Scrapper.LoginType.ADFSLight))
val sent = api.sendMessage("Temat", "Treść", listOf()) try {
val observer = TestObserver<SentMessage>() runBlocking { api.sendMessage("Temat", "Treść", listOf()) }
sent.subscribe(observer) } catch (e: Throwable) {
observer.assertNotComplete() assertTrue(e is ScrapperException)
observer.assertError(ScrapperException::class.java) assertEquals("User not logged in", e.message)
observer.assertErrorMessage("User not logged in") }
} }
@Test @Test
@ -223,7 +226,7 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody("{\"success\": true}")) server.enqueue(MockResponse().setBody("{\"success\": true}"))
server.start(3000) server.start(3000)
assertEquals(api.deleteMessages(listOf(Pair(74, 1), Pair(69, 2))).blockingGet(), true) assertEquals(runBlocking { api.deleteMessages(listOf(Pair(74, 1), Pair(69, 2))) }, true)
server.takeRequest() server.takeRequest()
@ -246,9 +249,10 @@ class MessagesTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody("")) server.enqueue(MockResponse().setBody(""))
server.start(3000) server.start(3000)
val deleted = api.deleteMessages(listOf(Pair(74, 1), Pair(69, 2))) try {
val observer = TestObserver<Boolean>() runBlocking { api.deleteMessages(listOf(Pair(74, 1), Pair(69, 2))) }
deleted.subscribe(observer) } catch (e: Throwable) {
observer.assertErrorMessage("Unexpected empty response. Message(s) may already be deleted") assertEquals("Unexpected empty response. Message(s) may already be deleted", e.message)
}
} }
} }

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.mobile package io.github.wulkanowy.sdk.scrapper.mobile
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
@ -8,19 +9,19 @@ import org.junit.Test
class MobileTest : BaseLocalTest() { class MobileTest : BaseLocalTest() {
private val devicesSnp by lazy { private val devicesSnp by lazy {
getSnpRepo(MobileTest::class.java, "DostepMobilny-filled.html").getRegisteredDevices().blockingGet() runBlocking { getSnpRepo(MobileTest::class.java, "DostepMobilny-filled.html").getRegisteredDevices() }
} }
private val tokenSnp by lazy { private val tokenSnp by lazy {
getSnpRepo(MobileTest::class.java, "Rejestruj.html").getToken().blockingGet() runBlocking { getSnpRepo(MobileTest::class.java, "Rejestruj.html").getToken() }
} }
private val devicesStudent by lazy { private val devicesStudent by lazy {
getStudentRepo(MobileTest::class.java, "ZarejestrowaneUrzadzenia.json").getRegisteredDevices().blockingGet() runBlocking { getStudentRepo(MobileTest::class.java, "ZarejestrowaneUrzadzenia.json").getRegisteredDevices() }
} }
private val tokenStudent by lazy { private val tokenStudent by lazy {
getStudentRepo(MobileTest::class.java, "RejestracjaUrzadzeniaToken.json").getToken().blockingGet() runBlocking { getStudentRepo(MobileTest::class.java, "RejestracjaUrzadzeniaToken.json").getToken() }
} }
@Test @Test

View file

@ -1,17 +1,18 @@
package io.github.wulkanowy.sdk.scrapper.notes package io.github.wulkanowy.sdk.scrapper.notes
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class NotesTest : BaseLocalTest() { class NotesTest : BaseLocalTest() {
private val student by lazy { private val student by lazy {
getStudentRepo(NotesTest::class.java, "UwagiIOsiagniecia.json").getNotes().blockingGet() runBlocking { getStudentRepo(NotesTest::class.java, "UwagiIOsiagniecia.json").getNotes() }
} }
private val studentPoints by lazy { private val studentPoints by lazy {
getStudentRepo(NotesTest::class.java, "UwagiIOsiagniecia-points.json").getNotes().blockingGet() runBlocking { getStudentRepo(NotesTest::class.java, "UwagiIOsiagniecia-points.json").getNotes() }
} }
@Test @Test

View file

@ -1,7 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.register package io.github.wulkanowy.sdk.scrapper.register
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.grades.GradesTest import io.github.wulkanowy.sdk.scrapper.grades.GradesTest
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
@ -12,6 +12,7 @@ import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.runBlocking
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
@ -21,7 +22,7 @@ class RegisterTest : BaseLocalTest() {
private val login by lazy { private val login by lazy {
LoginHelper(Scrapper.LoginType.STANDARD, "http", "fakelog.localhost:3000", "default", CookieManager(), LoginHelper(Scrapper.LoginType.STANDARD, "http", "fakelog.localhost:3000", "default", CookieManager(),
getService(LoginService::class.java, "http://fakelog.localhost:3000/", true, true, false, Scrapper.LoginType.STANDARD)) getService(LoginService::class.java, "http://fakelog.localhost:3000/", true, true, false, Scrapper.LoginType.STANDARD))
} }
private val registerSnp by lazy { private val registerSnp by lazy {
@ -44,7 +45,7 @@ class RegisterTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
StudentAndParentStartRepository("default", "0012345", 123, StudentAndParentStartRepository("default", "0012345", 123,
getService(StudentAndParentService::class.java, "http://fakelog.localhost:3000/")) getService(StudentAndParentService::class.java, "http://fakelog.localhost:3000/"))
} }
@Test @Test
@ -62,7 +63,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(1, res.size) assertEquals(1, res.size)
assertEquals("Jan Kowal", res[0].studentName) assertEquals("Jan Kowal", res[0].studentName)
@ -83,7 +84,7 @@ class RegisterTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = registerStudent.getStudents().blockingGet() val res = runBlocking { registerStudent.getStudents() }
assertEquals(2, res.size) assertEquals(2, res.size)
@ -119,7 +120,7 @@ class RegisterTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = registerStudent.getStudents().blockingGet() val res = runBlocking { registerStudent.getStudents() }
assertEquals(1, res.size) assertEquals(1, res.size)
@ -147,7 +148,7 @@ class RegisterTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = registerStudent.getStudents().blockingGet() val res = runBlocking { registerStudent.getStudents() }
assertEquals(1, res.size) assertEquals(1, res.size)
@ -175,7 +176,7 @@ class RegisterTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = registerStudent.getStudents().blockingGet() val res = runBlocking { registerStudent.getStudents() }
assertEquals(2, res.size) assertEquals(2, res.size)
@ -205,7 +206,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(GradesTest::class.java.getResource("OcenyWszystkie-details.html").readText().replace("1234568", "1234572"))) server.enqueue(MockResponse().setBody(GradesTest::class.java.getResource("OcenyWszystkie-details.html").readText().replace("1234568", "1234572")))
server.start(3000) server.start(3000)
val res = snp.getSemesters().blockingGet() val res = runBlocking { snp.getSemesters() }
assertEquals(6, res.size) assertEquals(6, res.size)
assertEquals(1234567, res[0].semesterId) assertEquals(1234567, res[0].semesterId)
@ -231,7 +232,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.STANDARD, res[0].loginType) assertEquals(Scrapper.LoginType.STANDARD, res[0].loginType)
} }
@ -252,7 +253,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.ADFS, res[0].loginType) assertEquals(Scrapper.LoginType.ADFS, res[0].loginType)
} }
@ -274,7 +275,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.ADFSCards, res[0].loginType) assertEquals(Scrapper.LoginType.ADFSCards, res[0].loginType)
} }
@ -294,7 +295,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.ADFSLight, res[0].loginType) assertEquals(Scrapper.LoginType.ADFSLight, res[0].loginType)
} }
@ -314,7 +315,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.ADFSLight, res[0].loginType) assertEquals(Scrapper.LoginType.ADFSLight, res[0].loginType)
} }
@ -334,7 +335,7 @@ class RegisterTest : BaseLocalTest() {
server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText())) server.enqueue(MockResponse().setBody(LoginTest::class.java.getResource("Logowanie-brak-dostepu.html").readText()))
server.start(3000) server.start(3000)
val res = registerSnp.getStudents().blockingGet() val res = runBlocking { registerSnp.getStudents() }
assertEquals(Scrapper.LoginType.ADFSLightScoped, res[0].loginType) assertEquals(Scrapper.LoginType.ADFSLightScoped, res[0].loginType)
} }
} }

View file

@ -1,19 +1,19 @@
package io.github.wulkanowy.sdk.scrapper.repository package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.ScrapperException import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.github.wulkanowy.sdk.scrapper.register.Student
import io.github.wulkanowy.sdk.scrapper.service.LoginService import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.github.wulkanowy.sdk.scrapper.service.RegisterService import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.ServiceManager import io.github.wulkanowy.sdk.scrapper.service.ServiceManager
import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService import io.github.wulkanowy.sdk.scrapper.service.StudentAndParentService
import io.github.wulkanowy.sdk.scrapper.service.StudentService import io.github.wulkanowy.sdk.scrapper.service.StudentService
import io.reactivex.observers.TestObserver import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
@ -50,11 +50,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
} }
server.start(3000) server.start(3000)
val res = getRegisterRepository("Default", true).getStudents() val students = runBlocking { getRegisterRepository("Default", true).getStudents() }
val observer = TestObserver<List<Student>>()
res.subscribe(observer)
observer.assertComplete()
val students = observer.values()[0]
assertEquals(1, students.size) assertEquals(1, students.size)
with(students[0]) { with(students[0]) {
@ -81,11 +77,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
} }
server.start(3000) server.start(3000)
val res = getRegisterRepository("Default", true).getStudents() val students = runBlocking { getRegisterRepository("Default", true).getStudents() }
val observer = TestObserver<List<Student>>()
res.subscribe(observer)
observer.assertComplete()
val students = observer.values()[0]
assertEquals(3, students.size) assertEquals(3, students.size)
with(students[0]) { with(students[0]) {
@ -125,11 +117,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
} }
server.start(3000) server.start(3000)
val res = getRegisterRepository("Default", true).getStudents() val students = runBlocking { getRegisterRepository("Default", true).getStudents() }
val observer = TestObserver<List<Student>>()
res.subscribe(observer)
observer.assertComplete()
val students = observer.values()[0]
assertEquals(2, students.size) assertEquals(2, students.size)
} }
@ -141,11 +129,11 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.enqueue("Offline.html", ErrorInterceptorTest::class.java) server.enqueue("Offline.html", ErrorInterceptorTest::class.java)
server.start(3000) server.start(3000)
val res = normal.getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { normal.getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is ScrapperException)
observer.assertError(ScrapperException::class.java) }
} }
@Test @Test
@ -161,10 +149,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = normal.getStudents() runBlocking { normal.getStudents() }
val observer = TestObserver<List<Student>>()
res.subscribe(observer)
observer.assertComplete()
} }
@Test @Test
@ -176,10 +161,12 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = getRegisterRepository("Default").getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { getRegisterRepository("Default").getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
assertEquals("Wystąpił nieoczekiwany błąd. Wystąpił błąd aplikacji. Prosimy zalogować się ponownie. Jeśli problem będzie się powtarzał, prosimy o kontakt z serwisem.", e.message)
}
assertEquals("/Default/Account/LogOn", server.takeRequest().path) assertEquals("/Default/Account/LogOn", server.takeRequest().path)
} }
@ -193,10 +180,12 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = getRegisterRepository(" Rzeszów + ").getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { getRegisterRepository(" Rzeszów + ").getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
assertEquals("Wystąpił nieoczekiwany błąd. Wystąpił błąd aplikacji. Prosimy zalogować się ponownie. Jeśli problem będzie się powtarzał, prosimy o kontakt z serwisem.", e.message)
}
assertEquals("/rzeszow/Account/LogOn", server.takeRequest().path) assertEquals("/rzeszow/Account/LogOn", server.takeRequest().path)
} }
@ -210,10 +199,12 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = getRegisterRepository(" Niepoprawny symbol no ale + ").getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { getRegisterRepository(" Niepoprawny symbol no ale + ").getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
assertEquals("Wystąpił nieoczekiwany błąd. Wystąpił błąd aplikacji. Prosimy zalogować się ponownie. Jeśli problem będzie się powtarzał, prosimy o kontakt z serwisem.", e.message)
}
assertEquals("/niepoprawnysymbolnoale/Account/LogOn", server.takeRequest().path) assertEquals("/niepoprawnysymbolnoale/Account/LogOn", server.takeRequest().path)
} }
@ -227,10 +218,12 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = getRegisterRepository(" + ").getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { getRegisterRepository(" + ").getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
assertEquals("Wystąpił nieoczekiwany błąd. Wystąpił błąd aplikacji. Prosimy zalogować się ponownie. Jeśli problem będzie się powtarzał, prosimy o kontakt z serwisem.", e.message)
}
assertEquals("/Default/Account/LogOn", server.takeRequest().path) assertEquals("/Default/Account/LogOn", server.takeRequest().path)
} }
@ -244,10 +237,12 @@ class RegisterRepositoryTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val res = getRegisterRepository("Default").getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { getRegisterRepository("Default").getStudents() }
res.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is VulcanException)
assertEquals("Wystąpił nieoczekiwany błąd. Wystąpił błąd aplikacji. Prosimy zalogować się ponownie. Jeśli problem będzie się powtarzał, prosimy o kontakt z serwisem.", e.message)
}
assertEquals("/Default/Account/LogOn", server.takeRequest().path) assertEquals("/Default/Account/LogOn", server.takeRequest().path)
assertTrue(server.takeRequest().path.startsWith("/Account/LogOn?ReturnUrl=%2FDefault")) assertTrue(server.takeRequest().path.startsWith("/Account/LogOn?ReturnUrl=%2FDefault"))

View file

@ -5,8 +5,7 @@ import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.grades.GradesTest import io.github.wulkanowy.sdk.scrapper.grades.GradesTest
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.github.wulkanowy.sdk.scrapper.register.Semester import kotlinx.coroutines.runBlocking
import io.reactivex.observers.TestObserver
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
@ -34,11 +33,11 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.STANDARD api.loginType = Scrapper.LoginType.STANDARD
val semesters = api.getSemesters() try {
val semestersObserver = TestObserver<List<Semester>>() runBlocking { api.getSemesters() }
semesters.subscribe(semestersObserver) } catch (e: Throwable) {
semestersObserver.assertTerminated() assertEquals("Unknow page with title: Uonet+", e.message)
semestersObserver.assertErrorMessage("Unknow page with title: Uonet+") }
} }
@Test @Test
@ -54,11 +53,11 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.STANDARD api.loginType = Scrapper.LoginType.STANDARD
val semesters = api.getSemesters() try {
val semestersObserver = TestObserver<List<Semester>>() runBlocking { api.getSemesters() }
semesters.subscribe(semestersObserver) } catch (e: Throwable) {
semestersObserver.assertTerminated() assertEquals("Unknow page with title: Witryna ucznia i rodzica Strona główna", e.message)
semestersObserver.assertErrorMessage("Unknow page with title: Witryna ucznia i rodzica Strona główna") }
} }
@Test @Test
@ -71,17 +70,12 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.STANDARD api.loginType = Scrapper.LoginType.STANDARD
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234567, semesters[0].semesterId)
assertEquals(1234568, semesters[1].semesterId)
assertEquals(1234567, items[0].semesterId)
assertEquals(1234568, items[1].semesterId)
} }
@Test @Test
@ -99,17 +93,12 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.STANDARD api.loginType = Scrapper.LoginType.STANDARD
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234567, semesters[0].semesterId)
assertEquals(1234568, semesters[1].semesterId)
assertEquals(1234567, items[0].semesterId)
assertEquals(1234568, items[1].semesterId)
} }
@Test @Test
@ -129,17 +118,12 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.ADFS api.loginType = Scrapper.LoginType.ADFS
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234567, semesters[0].semesterId)
assertEquals(1234568, semesters[1].semesterId)
assertEquals(1234567, items[0].semesterId)
assertEquals(1234568, items[1].semesterId)
} }
@Test @Test
@ -158,17 +142,12 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.ADFSLight api.loginType = Scrapper.LoginType.ADFSLight
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234567, semesters[0].semesterId)
assertEquals(1234568, semesters[1].semesterId)
assertEquals(1234567, items[0].semesterId)
assertEquals(1234568, items[1].semesterId)
} }
@Test @Test
@ -189,18 +168,13 @@ class StudentAndParentStartRepositoryTest : BaseLocalTest() {
api.loginType = Scrapper.LoginType.ADFSCards api.loginType = Scrapper.LoginType.ADFSCards
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234567, semesters[0].semesterId)
assertEquals(1234568, semesters[1].semesterId)
assertEquals(1234567, items[0].semesterId) assertEquals(2015, semesters[0].schoolYear)
assertEquals(1234568, items[1].semesterId) assertEquals(2015, semesters[1].schoolYear)
assertEquals(2015, items[0].schoolYear)
assertEquals(2015, items[1].schoolYear)
} }
} }

View file

@ -3,8 +3,7 @@ package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.github.wulkanowy.sdk.scrapper.register.Semester import kotlinx.coroutines.runBlocking
import io.reactivex.observers.TestObserver
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -34,24 +33,19 @@ class StudentStartRepositoryTest : BaseLocalTest() {
api.studentId = 1 api.studentId = 1
api.classId = 1 api.classId = 1
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234568, semesters[0].semesterId)
assertEquals(1234567, semesters[1].semesterId)
assertEquals(2018, semesters[0].schoolYear)
assertEquals(2018, semesters[1].schoolYear)
assertEquals(1234568, items[0].semesterId) assertEquals(1234566, semesters[2].semesterId)
assertEquals(1234567, items[1].semesterId) assertEquals(2017, semesters[2].schoolYear)
assertEquals(2018, items[0].schoolYear) assertEquals(2017, semesters[3].schoolYear)
assertEquals(2018, items[1].schoolYear) assertTrue(semesters.single { it.current }.current)
assertEquals(1234566, items[2].semesterId)
assertEquals(2017, items[2].schoolYear)
assertEquals(2017, items[3].schoolYear)
assertTrue(items.single { it.current }.current)
} }
@Test @Test
@ -62,14 +56,9 @@ class StudentStartRepositoryTest : BaseLocalTest() {
api.studentId = 1 api.studentId = 1
api.classId = 2 // api.classId = 2 //
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(0, semesters.size)
assertEquals(0, items.size)
} }
@Test @Test
@ -80,18 +69,13 @@ class StudentStartRepositoryTest : BaseLocalTest() {
api.studentId = 3881 api.studentId = 3881
api.classId = 121 api.classId = 121
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(2, semesters.size)
assertEquals(2, items.size) assertEquals(714, semesters[0].semesterId)
assertEquals(713, semesters[1].semesterId)
assertEquals(714, items[0].semesterId) assertTrue(semesters.single { it.current }.current)
assertEquals(713, items[1].semesterId)
assertTrue(items.single { it.current }.current)
} }
@Test @Test
@ -102,19 +86,14 @@ class StudentStartRepositoryTest : BaseLocalTest() {
api.studentId = 2 api.studentId = 2
api.classId = 2 api.classId = 2
val semesters = api.getSemesters() val semesters = runBlocking { api.getSemesters() }
val semestersObserver = TestObserver<List<Semester>>()
semesters.subscribe(semestersObserver)
semestersObserver.assertComplete()
val items = semestersObserver.values()[0] assertEquals(6, semesters.size)
assertEquals(6, items.size) assertEquals(1234568, semesters[0].semesterId)
assertEquals(1234568, semesters.single { it.current }.semesterId)
assertEquals(1234568, items[0].semesterId) assertEquals(1234567, semesters[1].semesterId)
assertEquals(1234568, items.single { it.current }.semesterId) assertTrue(semesters.single { it.current }.current)
assertEquals(1234567, items[1].semesterId) assertTrue(semesters[0].current)
assertTrue(items.single { it.current }.current)
assertTrue(items[0].current)
} }
} }

View file

@ -1,17 +1,18 @@
package io.github.wulkanowy.sdk.scrapper.school package io.github.wulkanowy.sdk.scrapper.school
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class TeachersTest : BaseLocalTest() { class TeachersTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(TeachersTest::class.java, "Szkola.html").getTeachers().blockingGet() runBlocking { getSnpRepo(TeachersTest::class.java, "Szkola.html").getTeachers() }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(TeachersTest::class.java, "Szkola.json").getTeachers().blockingGet() runBlocking { getStudentRepo(TeachersTest::class.java, "Szkola.json").getTeachers() }
} }
@Test @Test

View file

@ -1,22 +1,20 @@
package io.github.wulkanowy.sdk.scrapper.service package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.ApiResponse
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.BaseTest import io.github.wulkanowy.sdk.scrapper.BaseTest
import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.ScrapperException
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
import io.github.wulkanowy.sdk.scrapper.notes.NotesResponse
import io.github.wulkanowy.sdk.scrapper.notes.NotesTest import io.github.wulkanowy.sdk.scrapper.notes.NotesTest
import io.github.wulkanowy.sdk.scrapper.register.Student import kotlinx.coroutines.runBlocking
import io.reactivex.observers.TestObserver
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.net.URL import java.net.URL
@ -45,12 +43,11 @@ class ServiceManagerTest : BaseTest() {
throw ScrapperException("Test") throw ScrapperException("Test")
}) })
val notes = manager.getSnpService().getNotes() try {
val observer = TestObserver<NotesResponse>() runBlocking { manager.getSnpService().getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is ScrapperException)
observer.assertNotComplete() }
observer.assertError(ScrapperException::class.java)
} }
@Test @Test
@ -69,12 +66,11 @@ class ServiceManagerTest : BaseTest() {
throw ScrapperException("Test") throw ScrapperException("Test")
}, false) }, false)
val notes = manager.getStudentService().getNotes() try {
val observer = TestObserver<ApiResponse<NotesResponse>>() runBlocking { manager.getStudentService().getNotes() }
notes.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is ScrapperException)
observer.assertNotComplete() }
observer.assertError(ScrapperException::class.java)
} }
@Test @Test
@ -98,11 +94,11 @@ class ServiceManagerTest : BaseTest() {
symbol = "" symbol = ""
} }
val pupils = api.getStudents() try {
val observer = TestObserver<List<Student>>() runBlocking { api.getStudents() }
pupils.subscribe(observer) } catch (e: Throwable) {
observer.assertTerminated() assertTrue(e is ScrapperException)
observer.assertError(ScrapperException::class.java) }
server.takeRequest() server.takeRequest()
// /Default/Account/LogOn < default symbol set // /Default/Account/LogOn < default symbol set

View file

@ -1,13 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.student package io.github.wulkanowy.sdk.scrapper.student
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class StudentInfoTest : BaseLocalTest() { class StudentInfoTest : BaseLocalTest() {
private val info by lazy { private val info by lazy {
getSnpRepo(StudentInfoTest::class.java, "UczenDanePodstawowe.html").getStudentInfo().blockingGet() runBlocking { getSnpRepo(StudentInfoTest::class.java, "UczenDanePodstawowe.html").getStudentInfo() }
} }
@Test @Test

View file

@ -4,8 +4,9 @@ import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.register.RegisterTest import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.reactivex.observers.TestObserver import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@ -20,11 +21,13 @@ class CompletedLessonsTest : BaseLocalTest() {
// } // }
private val student by lazy { private val student by lazy {
getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane.json").getCompletedLessons( runBlocking {
getLocalDate(2018, 9, 17), getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane.json").getCompletedLessons(
getLocalDate(2018, 9, 18), getLocalDate(2018, 9, 17),
-1 getLocalDate(2018, 9, 18),
).blockingGet() -1
)
}
} }
@Before @Before
@ -41,28 +44,34 @@ class CompletedLessonsTest : BaseLocalTest() {
@Test @Test
fun getRealized_disabled() { fun getRealized_disabled() {
val lessons = getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane-disabled.json").getCompletedLessons( try {
getLocalDate(2018, 9, 17), runBlocking {
getLocalDate(2018, 9, 18), getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane-disabled.json").getCompletedLessons(
-1 getLocalDate(2018, 9, 17),
) getLocalDate(2018, 9, 18),
val lessonsObserver = TestObserver<List<CompletedLesson>>() -1
lessons.subscribe(lessonsObserver) )
lessonsObserver.assertError(FeatureDisabledException::class.java) }
lessonsObserver.assertErrorMessage("Widok lekcji zrealizowanych został wyłączony przez Administratora szkoły.") } catch (e: Throwable) {
assertTrue(e is FeatureDisabledException)
assertEquals("Widok lekcji zrealizowanych został wyłączony przez Administratora szkoły.", e.message)
}
} }
@Test @Test
fun getRealized_errored() { fun getRealized_errored() {
val lessons = getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane-errored.json").getCompletedLessons( try {
getLocalDate(2018, 9, 17), runBlocking {
getLocalDate(2018, 9, 18), getStudentRepo(CompletedLessonsTest::class.java, "Zrealizowane-errored.json").getCompletedLessons(
-1 getLocalDate(2018, 9, 17),
) getLocalDate(2018, 9, 18),
val lessonsObserver = TestObserver<List<CompletedLesson>>() -1
lessons.subscribe(lessonsObserver) )
lessonsObserver.assertError(VulcanException::class.java) }
lessonsObserver.assertErrorMessage("DB_ERROR") } catch (e: Throwable) {
assertTrue(e is VulcanException)
assertEquals("DB_ERROR", e.message)
}
} }
@Test @Test

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.timetable package io.github.wulkanowy.sdk.scrapper.timetable
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
@ -8,15 +9,15 @@ import org.junit.Test
class TimetableTest : BaseLocalTest() { class TimetableTest : BaseLocalTest() {
private val snp by lazy { private val snp by lazy {
getSnpRepo(TimetableTest::class.java, "PlanLekcji.html").getTimetable(getLocalDate(2018, 9, 24)).blockingGet() runBlocking { getSnpRepo(TimetableTest::class.java, "PlanLekcji.html").getTimetable(getLocalDate(2018, 9, 24)) }
} }
private val student by lazy { private val student by lazy {
getStudentRepo(TimetableTest::class.java, "PlanLekcji.json").getTimetable(getLocalDate(2018, 9, 24)).blockingGet() runBlocking { getStudentRepo(TimetableTest::class.java, "PlanLekcji.json").getTimetable(getLocalDate(2018, 9, 24)) }
} }
private val studentBefore1911 by lazy { private val studentBefore1911 by lazy {
getStudentRepo(TimetableTest::class.java, "PlanLekcji-before-19.11.json").getTimetable(getLocalDate(2018, 9, 24)).blockingGet() runBlocking { getStudentRepo(TimetableTest::class.java, "PlanLekcji-before-19.11.json").getTimetable(getLocalDate(2018, 9, 24)) }
} }
@Test @Test

View file

@ -10,6 +10,7 @@ import io.reactivex.Completable
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.Single import io.reactivex.Single
import kotlinx.coroutines.rx2.rxSingle
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
@ -173,10 +174,10 @@ class Sdk {
} }
} }
fun getPasswordResetCaptchaCode(registerBaseUrl: String, symbol: String) = scrapper.getPasswordResetCaptcha(registerBaseUrl, symbol) fun getPasswordResetCaptchaCode(registerBaseUrl: String, symbol: String) = rxSingle { scrapper.getPasswordResetCaptcha(registerBaseUrl, symbol) }
fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): Single<String> { fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): Single<String> {
return scrapper.sendPasswordResetRequest(registerBaseUrl, symbol, email, captchaCode) return rxSingle { scrapper.sendPasswordResetRequest(registerBaseUrl, symbol, email, captchaCode) }
} }
fun getStudentsFromMobileApi(token: String, pin: String, symbol: String, firebaseToken: String, apiKey: String = ""): Single<List<Student>> { fun getStudentsFromMobileApi(token: String, pin: String, symbol: String, firebaseToken: String, apiKey: String = ""): Single<List<Student>> {
@ -191,7 +192,7 @@ class Sdk {
it.email = email it.email = email
it.password = password it.password = password
it.symbol = symbol it.symbol = symbol
it.getStudents().compose(ScrapperExceptionTransformer()).map { students -> students.mapStudents() } rxSingle { it.getStudents() }.compose(ScrapperExceptionTransformer()).map { students -> students.mapStudents() }
} }
} }
@ -209,7 +210,7 @@ class Sdk {
it.classId = scrapperStudent.classId it.classId = scrapperStudent.classId
it.loginType = Scrapper.LoginType.valueOf(scrapperStudent.loginType.name) it.loginType = Scrapper.LoginType.valueOf(scrapperStudent.loginType.name)
} }
scrapper.getToken().compose(ScrapperExceptionTransformer()) rxSingle { scrapper.getToken() }.compose(ScrapperExceptionTransformer())
.flatMap { getStudentsFromMobileApi(it.token, it.pin, it.symbol, firebaseToken, apiKey) } .flatMap { getStudentsFromMobileApi(it.token, it.pin, it.symbol, firebaseToken, apiKey) }
.map { apiStudents -> .map { apiStudents ->
apiStudents.map { student -> apiStudents.map { student ->
@ -225,14 +226,14 @@ class Sdk {
fun getSemesters(now: LocalDate = LocalDate.now()): Single<List<Semester>> { fun getSemesters(now: LocalDate = LocalDate.now()): Single<List<Semester>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getSemesters().compose(ScrapperExceptionTransformer()).map { it.mapSemesters() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getSemesters() }.compose(ScrapperExceptionTransformer()).map { it.mapSemesters() }
Mode.API -> mobile.getStudents().map { it.mapSemesters(studentId, now) } Mode.API -> mobile.getStudents().map { it.mapSemesters(studentId, now) }
} }
} }
fun getAttendance(startDate: LocalDate, endDate: LocalDate, semesterId: Int): Single<List<Attendance>> { fun getAttendance(startDate: LocalDate, endDate: LocalDate, semesterId: Int): Single<List<Attendance>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getAttendance(startDate, endDate).compose(ScrapperExceptionTransformer()).map { it.mapAttendance() } Mode.SCRAPPER -> rxSingle { scrapper.getAttendance(startDate, endDate) }.compose(ScrapperExceptionTransformer()).map { it.mapAttendance() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getAttendance(startDate, endDate, semesterId).map { it.mapAttendance(dict) } mobile.getAttendance(startDate, endDate, semesterId).map { it.mapAttendance(dict) }
} }
@ -241,28 +242,28 @@ class Sdk {
fun getAttendanceSummary(subjectId: Int? = -1): Single<List<AttendanceSummary>> { fun getAttendanceSummary(subjectId: Int? = -1): Single<List<AttendanceSummary>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getAttendanceSummary(subjectId).compose(ScrapperExceptionTransformer()).map { it.mapAttendanceSummary() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getAttendanceSummary(subjectId) }.compose(ScrapperExceptionTransformer()).map { it.mapAttendanceSummary() }
Mode.API -> throw FeatureNotAvailableException("Attendance summary is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Attendance summary is not available in API mode")
} }
} }
fun excuseForAbsence(absents: List<Absent>, content: String? = null): Single<Boolean> { fun excuseForAbsence(absents: List<Absent>, content: String? = null): Single<Boolean> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.excuseForAbsence(absents.mapToScrapperAbsent(), content).compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.excuseForAbsence(absents.mapToScrapperAbsent(), content) }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Absence excusing is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Absence excusing is not available in API mode")
} }
} }
fun getSubjects(): Single<List<Subject>> { fun getSubjects(): Single<List<Subject>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getSubjects().compose(ScrapperExceptionTransformer()).map { it.mapSubjects() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getSubjects() }.compose(ScrapperExceptionTransformer()).map { it.mapSubjects() }
Mode.API -> mobile.getDictionaries().map { it.subjects }.map { it.mapSubjects() } Mode.API -> mobile.getDictionaries().map { it.subjects }.map { it.mapSubjects() }
} }
} }
fun getExams(start: LocalDate, end: LocalDate, semesterId: Int): Single<List<Exam>> { fun getExams(start: LocalDate, end: LocalDate, semesterId: Int): Single<List<Exam>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getExams(start, end).compose(ScrapperExceptionTransformer()).map { it.mapExams() } Mode.SCRAPPER -> rxSingle { scrapper.getExams(start, end) }.compose(ScrapperExceptionTransformer()).map { it.mapExams() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getExams(start, end, semesterId).map { it.mapExams(dict) } mobile.getExams(start, end, semesterId).map { it.mapExams(dict) }
} }
@ -271,7 +272,7 @@ class Sdk {
fun getGrades(semesterId: Int): Single<Pair<List<Grade>, List<GradeSummary>>> { fun getGrades(semesterId: Int): Single<Pair<List<Grade>, List<GradeSummary>>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getGrades(semesterId).compose(ScrapperExceptionTransformer()).map { grades -> grades.mapGrades() } Mode.SCRAPPER -> rxSingle { scrapper.getGrades(semesterId) }.compose(ScrapperExceptionTransformer()).map { grades -> grades.mapGrades() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getGrades(semesterId).map { grades -> grades.mapGrades(dict) } mobile.getGrades(semesterId).map { grades -> grades.mapGrades(dict) }
} }
@ -280,7 +281,7 @@ class Sdk {
fun getGradesDetails(semesterId: Int): Single<List<Grade>> { fun getGradesDetails(semesterId: Int): Single<List<Grade>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getGradesDetails(semesterId).compose(ScrapperExceptionTransformer()).map { grades -> grades.mapGradesDetails() } Mode.SCRAPPER -> rxSingle { scrapper.getGradesDetails(semesterId) }.compose(ScrapperExceptionTransformer()).map { grades -> grades.mapGradesDetails() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getGradesDetails(semesterId).map { it.mapGradesDetails(dict) } mobile.getGradesDetails(semesterId).map { it.mapGradesDetails(dict) }
} }
@ -289,7 +290,7 @@ class Sdk {
fun getGradesSummary(semesterId: Int): Single<List<GradeSummary>> { fun getGradesSummary(semesterId: Int): Single<List<GradeSummary>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getGradesSummary(semesterId).compose(ScrapperExceptionTransformer()).map { it.mapGradesSummary() } Mode.SCRAPPER -> rxSingle { scrapper.getGradesSummary(semesterId) }.compose(ScrapperExceptionTransformer()).map { it.mapGradesSummary() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getGradesSummary(semesterId).map { it.mapGradesSummary(dict) } mobile.getGradesSummary(semesterId).map { it.mapGradesSummary(dict) }
} }
@ -298,28 +299,28 @@ class Sdk {
fun getGradesAnnualStatistics(semesterId: Int): Single<List<GradeStatistics>> { fun getGradesAnnualStatistics(semesterId: Int): Single<List<GradeStatistics>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getGradesAnnualStatistics(semesterId).compose(ScrapperExceptionTransformer()).map { it.mapGradeStatistics() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getGradesAnnualStatistics(semesterId) }.compose(ScrapperExceptionTransformer()).map { it.mapGradeStatistics() }
Mode.API -> throw FeatureNotAvailableException("Class grades annual statistics is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Class grades annual statistics is not available in API mode")
} }
} }
fun getGradesPartialStatistics(semesterId: Int): Single<List<GradeStatistics>> { fun getGradesPartialStatistics(semesterId: Int): Single<List<GradeStatistics>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getGradesPartialStatistics(semesterId).compose(ScrapperExceptionTransformer()).map { it.mapGradeStatistics() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getGradesPartialStatistics(semesterId) }.compose(ScrapperExceptionTransformer()).map { it.mapGradeStatistics() }
Mode.API -> throw FeatureNotAvailableException("Class grades partial statistics is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Class grades partial statistics is not available in API mode")
} }
} }
fun getGradesPointsStatistics(semesterId: Int): Single<List<GradePointsStatistics>> { fun getGradesPointsStatistics(semesterId: Int): Single<List<GradePointsStatistics>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getGradesPointsStatistics(semesterId).compose(ScrapperExceptionTransformer()).map { it.mapGradePointsStatistics() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getGradesPointsStatistics(semesterId) }.compose(ScrapperExceptionTransformer()).map { it.mapGradePointsStatistics() }
Mode.API -> throw FeatureNotAvailableException("Class grades points statistics is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Class grades points statistics is not available in API mode")
} }
} }
fun getHomework(start: LocalDate, end: LocalDate, semesterId: Int = 0): Single<List<Homework>> { fun getHomework(start: LocalDate, end: LocalDate, semesterId: Int = 0): Single<List<Homework>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getHomework(start, end).compose(ScrapperExceptionTransformer()).map { it.mapHomework() } Mode.SCRAPPER -> rxSingle { scrapper.getHomework(start, end) }.compose(ScrapperExceptionTransformer()).map { it.mapHomework() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getHomework(start, end, semesterId).map { it.mapHomework(dict) } mobile.getHomework(start, end, semesterId).map { it.mapHomework(dict) }
} }
@ -328,7 +329,7 @@ class Sdk {
fun getNotes(semesterId: Int): Single<List<Note>> { fun getNotes(semesterId: Int): Single<List<Note>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getNotes().compose(ScrapperExceptionTransformer()).map { it.mapNotes() } Mode.SCRAPPER -> rxSingle { scrapper.getNotes() }.compose(ScrapperExceptionTransformer()).map { it.mapNotes() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getNotes(semesterId).map { it.mapNotes(dict) } mobile.getNotes(semesterId).map { it.mapNotes(dict) }
} }
@ -337,28 +338,28 @@ class Sdk {
fun getRegisteredDevices(): Single<List<Device>> { fun getRegisteredDevices(): Single<List<Device>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getRegisteredDevices().compose(ScrapperExceptionTransformer()).map { it.mapDevices() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getRegisteredDevices() }.compose(ScrapperExceptionTransformer()).map { it.mapDevices() }
Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode")
} }
} }
fun getToken(): Single<Token> { fun getToken(): Single<Token> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getToken().compose(ScrapperExceptionTransformer()).map { it.mapToken() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getToken() }.compose(ScrapperExceptionTransformer()).map { it.mapToken() }
Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode")
} }
} }
fun unregisterDevice(id: Int): Single<Boolean> { fun unregisterDevice(id: Int): Single<Boolean> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.unregisterDevice(id).compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.unregisterDevice(id) }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Devices management is not available in API mode")
} }
} }
fun getTeachers(semesterId: Int): Single<List<Teacher>> { fun getTeachers(semesterId: Int): Single<List<Teacher>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getTeachers().compose(ScrapperExceptionTransformer()).map { it.mapTeachers() } Mode.SCRAPPER -> rxSingle { scrapper.getTeachers() }.compose(ScrapperExceptionTransformer()).map { it.mapTeachers() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getTeachers(studentId, semesterId).map { it.mapTeachers(dict) } mobile.getTeachers(studentId, semesterId).map { it.mapTeachers(dict) }
} }
@ -367,28 +368,28 @@ class Sdk {
fun getSchool(): Single<School> { fun getSchool(): Single<School> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getSchool().compose(ScrapperExceptionTransformer()).map { it.mapSchool() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getSchool() }.compose(ScrapperExceptionTransformer()).map { it.mapSchool() }
Mode.API -> throw FeatureNotAvailableException("School info is not available in API mode") Mode.API -> throw FeatureNotAvailableException("School info is not available in API mode")
} }
} }
fun getStudentInfo(): Single<StudentInfo> { fun getStudentInfo(): Single<StudentInfo> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getStudentInfo().compose(ScrapperExceptionTransformer()).map { it.mapStudent() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getStudentInfo() }.compose(ScrapperExceptionTransformer()).map { it.mapStudent() }
Mode.API -> throw FeatureNotAvailableException("Student info is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Student info is not available in API mode")
} }
} }
fun getReportingUnits(): Single<List<ReportingUnit>> { fun getReportingUnits(): Single<List<ReportingUnit>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getReportingUnits().compose(ScrapperExceptionTransformer()).map { it.mapReportingUnits() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getReportingUnits() }.compose(ScrapperExceptionTransformer()).map { it.mapReportingUnits() }
Mode.API -> mobile.getStudents().map { it.mapReportingUnits(studentId) } Mode.API -> mobile.getStudents().map { it.mapReportingUnits(studentId) }
} }
} }
fun getRecipients(unitId: Int, role: Int = 2): Single<List<Recipient>> { fun getRecipients(unitId: Int, role: Int = 2): Single<List<Recipient>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getRecipients(unitId, role).compose(ScrapperExceptionTransformer()).map { it.mapRecipients() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getRecipients(unitId, role) }.compose(ScrapperExceptionTransformer()).map { it.mapRecipients() }
Mode.API -> mobile.getDictionaries().map { it.teachers }.map { it.mapRecipients(unitId) } Mode.API -> mobile.getDictionaries().map { it.teachers }.map { it.mapRecipients(unitId) }
} }
} }
@ -403,7 +404,7 @@ class Sdk {
fun getReceivedMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> { fun getReceivedMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getReceivedMessages().compose(ScrapperExceptionTransformer()).map { it.mapMessages() } // TODO Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getReceivedMessages() }.compose(ScrapperExceptionTransformer()).map { it.mapMessages() } // TODO
Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getMessages(start, end).map { it.mapMessages(dict) } mobile.getMessages(start, end).map { it.mapMessages(dict) }
} }
@ -412,7 +413,7 @@ class Sdk {
fun getSentMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> { fun getSentMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getSentMessages().compose(ScrapperExceptionTransformer()).map { it.mapMessages() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getSentMessages() }.compose(ScrapperExceptionTransformer()).map { it.mapMessages() }
Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getMessagesSent(start, end).map { it.mapMessages(dict) } mobile.getMessagesSent(start, end).map { it.mapMessages(dict) }
} }
@ -421,7 +422,7 @@ class Sdk {
fun getDeletedMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> { fun getDeletedMessages(start: LocalDateTime, end: LocalDateTime): Single<List<Message>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getDeletedMessages().compose(ScrapperExceptionTransformer()).map { it.mapMessages() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getDeletedMessages() }.compose(ScrapperExceptionTransformer()).map { it.mapMessages() }
Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getMessagesDeleted(start, end).map { it.mapMessages(dict) } mobile.getMessagesDeleted(start, end).map { it.mapMessages(dict) }
} }
@ -430,14 +431,14 @@ class Sdk {
fun getMessageRecipients(messageId: Int, senderId: Int): Single<List<Recipient>> { fun getMessageRecipients(messageId: Int, senderId: Int): Single<List<Recipient>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getMessageRecipients(messageId, senderId).compose(ScrapperExceptionTransformer()).map { it.mapRecipients() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getMessageRecipients(messageId, senderId) }.compose(ScrapperExceptionTransformer()).map { it.mapRecipients() }
Mode.API -> TODO() Mode.API -> TODO()
} }
} }
fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null): Single<MessageDetails> { fun getMessageDetails(messageId: Int, folderId: Int, read: Boolean = false, id: Int? = null): Single<MessageDetails> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getMessageDetails(messageId, folderId, read, id).compose(ScrapperExceptionTransformer()).map { it.mapScrapperMessage() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getMessageDetails(messageId, folderId, read, id) }.compose(ScrapperExceptionTransformer()).map { it.mapScrapperMessage() }
Mode.API -> mobile.changeMessageStatus(messageId, when (folderId) { Mode.API -> mobile.changeMessageStatus(messageId, when (folderId) {
1 -> "Odebrane" 1 -> "Odebrane"
2 -> "Wysłane" 2 -> "Wysłane"
@ -448,7 +449,7 @@ class Sdk {
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> { fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.sendMessage(subject, content, recipients.mapFromRecipientsToScraper()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.sendMessage(subject, content, recipients.mapFromRecipientsToScraper()) }
.compose(ScrapperExceptionTransformer()) .compose(ScrapperExceptionTransformer())
.map { it.mapSentMessage() } .map { it.mapSentMessage() }
Mode.API -> mobile.sendMessage(subject, content, recipients.mapFromRecipientsToMobile()).map { it.mapSentMessage(loginId) } Mode.API -> mobile.sendMessage(subject, content, recipients.mapFromRecipientsToMobile()).map { it.mapSentMessage(loginId) }
@ -457,7 +458,7 @@ class Sdk {
fun deleteMessages(messages: List<Pair<Int, Int>>): Single<Boolean> { fun deleteMessages(messages: List<Pair<Int, Int>>): Single<Boolean> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.deleteMessages(messages).compose(ScrapperExceptionTransformer()) Mode.SCRAPPER -> rxSingle { scrapper.deleteMessages(messages) }.compose(ScrapperExceptionTransformer())
Mode.HYBRID, Mode.API -> Completable.mergeDelayError(messages.map { (messageId, folderId) -> Mode.HYBRID, Mode.API -> Completable.mergeDelayError(messages.map { (messageId, folderId) ->
mobile.changeMessageStatus(messageId, when (folderId) { mobile.changeMessageStatus(messageId, when (folderId) {
1 -> "Odebrane" 1 -> "Odebrane"
@ -470,7 +471,7 @@ class Sdk {
fun getTimetable(start: LocalDate, end: LocalDate): Single<List<Timetable>> { fun getTimetable(start: LocalDate, end: LocalDate): Single<List<Timetable>> {
return when (mode) { return when (mode) {
Mode.SCRAPPER -> scrapper.getTimetable(start, end).compose(ScrapperExceptionTransformer()).map { it.mapTimetable() } Mode.SCRAPPER -> rxSingle { scrapper.getTimetable(start, end) }.compose(ScrapperExceptionTransformer()).map { it.mapTimetable() }
Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict -> Mode.HYBRID, Mode.API -> mobile.getDictionaries().flatMap { dict ->
mobile.getTimetable(start, end, 0).map { it.mapTimetable(dict) } mobile.getTimetable(start, end, 0).map { it.mapTimetable(dict) }
} }
@ -479,7 +480,7 @@ class Sdk {
fun getCompletedLessons(start: LocalDate, end: LocalDate? = null, subjectId: Int = -1): Single<List<CompletedLesson>> { fun getCompletedLessons(start: LocalDate, end: LocalDate? = null, subjectId: Int = -1): Single<List<CompletedLesson>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getCompletedLessons(start, end, subjectId).compose(ScrapperExceptionTransformer()).map { it.mapCompletedLessons() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getCompletedLessons(start, end, subjectId) }.compose(ScrapperExceptionTransformer()).map { it.mapCompletedLessons() }
Mode.API -> throw FeatureNotAvailableException("Completed lessons are not available in API mode") Mode.API -> throw FeatureNotAvailableException("Completed lessons are not available in API mode")
} }
} }
@ -508,70 +509,70 @@ class Sdk {
fun getSelfGovernments(): Single<List<GovernmentUnit>> { fun getSelfGovernments(): Single<List<GovernmentUnit>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getSelfGovernments().compose(ScrapperExceptionTransformer()).map { it.mapToUnits() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getSelfGovernments() }.compose(ScrapperExceptionTransformer()).map { it.mapToUnits() }
Mode.API -> throw FeatureNotAvailableException("Self governments is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Self governments is not available in API mode")
} }
} }
fun getStudentThreats(): Single<List<String>> { fun getStudentThreats(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getStudentThreats().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getStudentThreats() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Student threats are not available in API mode") Mode.API -> throw FeatureNotAvailableException("Student threats are not available in API mode")
} }
} }
fun getStudentsTrips(): Single<List<String>> { fun getStudentsTrips(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getStudentsTrips().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getStudentsTrips() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Students trips is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Students trips is not available in API mode")
} }
} }
fun getLastGrades(): Single<List<String>> { fun getLastGrades(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getLastGrades().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getLastGrades() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Last grades is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Last grades is not available in API mode")
} }
} }
fun getFreeDays(): Single<List<String>> { fun getFreeDays(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getFreeDays().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getFreeDays() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Free days is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Free days is not available in API mode")
} }
} }
fun getKidsLuckyNumbers(): Single<List<LuckyNumber>> { fun getKidsLuckyNumbers(): Single<List<LuckyNumber>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getKidsLuckyNumbers().compose(ScrapperExceptionTransformer()).map { it.mapLuckyNumbers() } Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getKidsLuckyNumbers() }.compose(ScrapperExceptionTransformer()).map { it.mapLuckyNumbers() }
Mode.API -> throw FeatureNotAvailableException("Kids Lucky number is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Kids Lucky number is not available in API mode")
} }
} }
fun getKidsTimetable(): Single<List<String>> { fun getKidsTimetable(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getKidsLessonPlan().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getKidsLessonPlan() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Kids timetable is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Kids timetable is not available in API mode")
} }
} }
fun getLastHomework(): Single<List<String>> { fun getLastHomework(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getLastHomework().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getLastHomework() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Last homework is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Last homework is not available in API mode")
} }
} }
fun getLastExams(): Single<List<String>> { fun getLastExams(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getLastTests().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getLastTests() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Last exams is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Last exams is not available in API mode")
} }
} }
fun getLastStudentLessons(): Single<List<String>> { fun getLastStudentLessons(): Single<List<String>> {
return when (mode) { return when (mode) {
Mode.HYBRID, Mode.SCRAPPER -> scrapper.getLastStudentLessons().compose(ScrapperExceptionTransformer()) Mode.HYBRID, Mode.SCRAPPER -> rxSingle { scrapper.getLastStudentLessons() }.compose(ScrapperExceptionTransformer())
Mode.API -> throw FeatureNotAvailableException("Last student lesson is not available in API mode") Mode.API -> throw FeatureNotAvailableException("Last student lesson is not available in API mode")
} }
} }