Entities unification (#248)

* Remove default entieties params

* Change var to vals

* Fix indent in data classes

* Change message unread to val

* Make all fields in Message non-nullable

* Add destructive db migrations #246

* Fix password decrypting

* Fix tests

* Fix student logout

* Use orEmpty() on nullable strings

* Use var in Student password and Message unread
This commit is contained in:
Mikołaj Pich 2019-02-16 21:20:23 +01:00 committed by Kacper Ziubryniewicz
parent c56cfec564
commit 11b6c00e4a
31 changed files with 216 additions and 179 deletions

View File

@ -35,13 +35,13 @@ class AttendanceLocalTest {
@Test
fun saveAndReadTest() {
attendanceLocal.saveAttendance(listOf(
Attendance(1, 2, LocalDate.of(2018, 9, 10), 0, "", ""),
Attendance(1, 2, LocalDate.of(2018, 9, 14), 0, "", ""),
Attendance(1, 2, LocalDate.of(2018, 9, 17), 0, "", "")
Attendance(1, 2, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false),
Attendance(1, 2, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false),
Attendance(1, 2, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false)
))
val attendance = attendanceLocal
.getAttendance(Semester(1, 1, 2, "", 3, 1),
.getAttendance(Semester(1, 2, "", 1, 3, true),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)

View File

@ -42,7 +42,7 @@ class CompletedLessonsLocalTest {
))
val completed = completedLessonsLocal
.getCompletedLessons(Semester(1, 1, 2, "", 3, 1),
.getCompletedLessons(Semester(1, 2, "", 1, 3, true),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)

View File

@ -41,7 +41,7 @@ class ExamLocalTest {
))
val exams = examLocal
.getExams(Semester(1, 1, 2, "", 3, 1),
.getExams(Semester(1, 2, "", 1, 3, true),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)

View File

@ -37,7 +37,7 @@ class LuckyNumberLocalTest {
fun saveAndReadTest() {
luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, 2, "", 3, 1),
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, true),
LocalDate.of(2019, 1, 20)
).blockingGet()

View File

@ -39,7 +39,7 @@ class StudentLocalTest {
@Test
fun saveAndReadTest() {
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true))
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, symbol = ""))
.blockingGet()
val student = studentLocal.getCurrentStudent(true).blockingGet()

View File

@ -37,15 +37,15 @@ class TimetableLocalTest {
fun saveAndReadTest() {
timetableDb.saveTimetable(listOf(
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(),
LocalDate.of(2018, 9, 10), "", "", "", "", ""),
LocalDate.of(2018, 9, 10), "", "", "", "", "", false, false),
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(),
LocalDate.of(2018, 9, 14), "", "", "", "", ""),
LocalDate.of(2018, 9, 14), "", "", "", "", "", false, false),
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(),
LocalDate.of(2018, 9, 17), "", "", "", "", "")
LocalDate.of(2018, 9, 17), "", "", "", "", "", false, false)
))
val exams = timetableDb.getTimetable(
Semester(0, 1, 2, "3", 1, 1),
Semester(1, 2, "", 1, 1, true),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
).blockingGet()

View File

@ -22,6 +22,12 @@ class ApiHelper @Inject constructor(private val api: Api) {
}
fun initApi(email: String, password: String, symbol: String, endpoint: String) {
initApi(Student(email = email, password = password, symbol = symbol, endpoint = endpoint, loginType = "AUTO"))
api.apply {
this.email = email
this.password = password
this.symbol = symbol
host = URL(endpoint).run { host + ":$port".removeSuffix(":-1") }
ssl = endpoint.startsWith("https")
}
}
}

View File

@ -36,6 +36,7 @@ import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
import javax.inject.Singleton
@Singleton
@ -56,7 +57,7 @@ import javax.inject.Singleton
LuckyNumber::class,
CompletedLesson::class
],
version = 3,
version = 4,
exportSchema = false
)
@TypeConverters(Converters::class)
@ -66,9 +67,12 @@ abstract class AppDatabase : RoomDatabase() {
fun newInstance(context: Context): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(5)
.fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(
Migration2(),
Migration3()
Migration3(),
Migration4()
)
.build()
}

View File

@ -10,30 +10,30 @@ import java.io.Serializable
data class Attendance(
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
val diaryId: Int,
var date: LocalDate,
val date: LocalDate,
var number: Int,
val number: Int,
var subject: String,
val subject: String,
var name: String,
val name: String,
var presence: Boolean = false,
val presence: Boolean,
var absence: Boolean = false,
val absence: Boolean,
var exemption: Boolean = false,
val exemption: Boolean,
var lateness: Boolean = false,
val lateness: Boolean,
var excused: Boolean = false,
val excused: Boolean,
var deleted: Boolean = false
val deleted: Boolean
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -10,13 +10,13 @@ import java.io.Serializable
data class AttendanceSummary(
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
val diaryId: Int,
@ColumnInfo(name = "subject_id")
var subjectId: Int = 0,
val subjectId: Int,
val month: Month,

View File

@ -10,29 +10,29 @@ import java.io.Serializable
data class CompletedLesson(
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
val diaryId: Int,
var date: LocalDate,
val date: LocalDate,
var number: Int,
val number: Int,
var subject: String,
val subject: String,
var topic: String,
val topic: String,
var teacher: String,
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
var teacherSymbol: String,
val teacherSymbol: String,
var substitution: String,
val substitution: String,
var absence: String,
val absence: String,
var resources: String
val resources: String
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -9,29 +9,29 @@ import java.io.Serializable
@Entity(tableName = "Exams")
data class Exam(
@ColumnInfo(name = "student_id")
var studentId: Int,
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
var date: LocalDate,
val date: LocalDate,
@ColumnInfo(name = "entry_date")
var entryDate: LocalDate = LocalDate.now(),
@ColumnInfo(name = "entry_date")
val entryDate: LocalDate,
var subject: String,
val subject: String,
var group: String,
val group: String,
var type: String,
val type: String,
var description: String,
val description: String,
var teacher: String,
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
var teacherSymbol: String
@ColumnInfo(name = "teacher_symbol")
val teacherSymbol: String
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -10,35 +10,35 @@ import java.io.Serializable
data class Grade(
@ColumnInfo(name = "semester_id")
var semesterId: Int,
val semesterId: Int,
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
var subject: String,
val subject: String,
var entry: String,
val entry: String,
var value: Int,
val value: Int,
var modifier: Double,
val modifier: Double,
var comment: String,
val comment: String,
var color: String,
val color: String,
@ColumnInfo(name = "grade_symbol")
var gradeSymbol: String,
val gradeSymbol: String,
var description: String,
val description: String,
var weight: String,
val weight: String,
var weightValue: Int,
val weightValue: Int,
var date: LocalDate,
val date: LocalDate,
var teacher: String
val teacher: String
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -7,19 +7,18 @@ import androidx.room.PrimaryKey
@Entity(tableName = "Grades_Summary")
data class GradeSummary(
@ColumnInfo(name = "semester_id")
var semesterId: Int,
@ColumnInfo(name = "semester_id")
val semesterId: Int,
@ColumnInfo(name = "student_id")
var studentId: Int,
@ColumnInfo(name = "student_id")
val studentId: Int,
var subject: String,
val subject: String,
var predictedGrade: String,
val predictedGrade: String,
var finalGrade: String
val finalGrade: String
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -10,24 +10,24 @@ import java.io.Serializable
data class Homework(
@ColumnInfo(name = "semester_id")
var semesterId: Int,
val semesterId: Int,
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
var date: LocalDate,
val date: LocalDate,
@ColumnInfo(name = "entry_date")
var entryDate: LocalDate,
val entryDate: LocalDate,
var subject: String,
val subject: String,
var content: String,
val content: String,
var teacher: String,
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
var teacherSymbol: String
val teacherSymbol: String
) : Serializable {

View File

@ -10,12 +10,12 @@ import java.io.Serializable
data class LuckyNumber (
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
var date: LocalDate,
val date: LocalDate,
@ColumnInfo(name = "lucky_number")
var luckyNumber: Int
val luckyNumber: Int
) : Serializable {
@ -24,5 +24,4 @@ data class LuckyNumber (
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View File

@ -10,40 +10,40 @@ import java.io.Serializable
data class Message(
@ColumnInfo(name = "student_id")
var studentId: Int? = null,
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: Int? = null,
val realId: Int,
@ColumnInfo(name = "message_id")
val messageId: Int? = null,
val messageId: Int,
@ColumnInfo(name = "sender_name")
val sender: String? = null,
val sender: String,
@ColumnInfo(name = "sender_id")
val senderId: Int? = null,
val senderId: Int,
@ColumnInfo(name = "recipient_id")
val recipientId: Int? = null,
val recipientId: Int,
@ColumnInfo(name = "recipient_name")
val recipient: String? = "",
val recipient: String,
val subject: String = "",
val subject: String,
val date: LocalDateTime? = null,
val date: LocalDateTime,
@ColumnInfo(name = "folder_id")
val folderId: Int = 0,
val folderId: Int,
var unread: Boolean? = false,
var unread: Boolean,
val unreadBy: Int? = 0,
val unreadBy: Int,
val readBy: Int? = 0,
val readBy: Int,
val removed: Boolean = false
val removed: Boolean
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -10,18 +10,18 @@ import java.io.Serializable
data class Note(
@ColumnInfo(name = "semester_id")
var semesterId: Int,
val semesterId: Int,
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
var date: LocalDate,
val date: LocalDate,
var teacher: String,
val teacher: String,
var category: String,
val category: String,
var content: String
val content: String
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -8,24 +8,25 @@ import androidx.room.PrimaryKey
@Entity(tableName = "Semesters", indices = [Index(value = ["student_id", "diary_id", "semester_id"], unique = true)])
data class Semester(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
val diaryId: Int,
@ColumnInfo(name = "diary_name")
var diaryName: String,
val diaryName: String,
@ColumnInfo(name = "semester_id")
var semesterId: Int,
val semesterId: Int,
@ColumnInfo(name = "semester_name")
var semesterName: Int,
val semesterName: Int,
@ColumnInfo(name = "is_current")
var isCurrent: Boolean = false
)
val isCurrent: Boolean
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -9,31 +9,32 @@ import java.io.Serializable
@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id"], unique = true)])
data class Student(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
val endpoint: String,
var endpoint: String,
val loginType: String,
var loginType: String,
var email: String,
val email: String,
var password: String,
var symbol: String = "",
val symbol: String,
@ColumnInfo(name = "student_id")
var studentId: Int = 0,
val studentId: Int,
@ColumnInfo(name = "student_name")
var studentName: String = "",
val studentName: String,
@ColumnInfo(name = "school_id")
var schoolSymbol: String = "",
val schoolSymbol: String,
@ColumnInfo(name = "school_name")
var schoolName: String = "",
val schoolName: String,
@ColumnInfo(name = "is_current")
var isCurrent: Boolean = false
) : Serializable
val isCurrent: Boolean
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -9,15 +9,15 @@ import java.io.Serializable
data class Subject(
@ColumnInfo(name = "student_id")
var studentId: Int,
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
val diaryId: Int,
@ColumnInfo(name = "real_id")
var realId: Int,
val realId: Int,
var name: String
val name: String
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -10,33 +10,33 @@ import java.io.Serializable
@Entity(tableName = "Timetable")
data class Timetable(
@ColumnInfo(name = "student_id")
var studentId: Int,
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
var diaryId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val number: Int = 0,
val number: Int,
val start: LocalDateTime = LocalDateTime.now(),
val start: LocalDateTime,
val end: LocalDateTime = LocalDateTime.now(),
val end: LocalDateTime,
val date: LocalDate,
val date: LocalDate,
val subject: String,
val subject: String,
val group: String,
val group: String,
val room: String,
val room: String,
val teacher: String,
val teacher: String,
val info: String,
val info: String,
val changes: Boolean = false,
val changes: Boolean,
val canceled: Boolean = false
val canceled: Boolean
) : Serializable {
@PrimaryKey(autoGenerate = true)

View File

@ -0,0 +1,29 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration4 : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS `Messages`")
database.execSQL("CREATE TABLE IF NOT EXISTS `Messages` (" +
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
"`is_notified` INTEGER NOT NULL," +
"`content` TEXT," +
"`student_id` INTEGER NOT NULL," +
"`real_id` INTEGER NOT NULL," +
"`message_id` INTEGER NOT NULL," +
"`sender_name` TEXT NOT NULL," +
"`sender_id` INTEGER NOT NULL," +
"`recipient_id` INTEGER NOT NULL," +
"`recipient_name` TEXT NOT NULL," +
"`subject` TEXT NOT NULL," +
"`date` INTEGER NOT NULL," +
"`folder_id` INTEGER NOT NULL," +
"`unread` INTEGER NOT NULL," +
"`unreadBy` INTEGER NOT NULL," +
"`readBy` INTEGER NOT NULL," +
"`removed` INTEGER NOT NULL)")
}
}

View File

@ -5,6 +5,7 @@ import io.github.wulkanowy.api.messages.Folder
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.utils.toLocalDateTime
import io.reactivex.Single
import org.threeten.bp.LocalDateTime.now
import javax.inject.Inject
import javax.inject.Singleton
import io.github.wulkanowy.api.messages.Message as ApiMessage
@ -17,18 +18,18 @@ class MessageRemote @Inject constructor(private val api: Api) {
messages.map {
Message(
studentId = studentId,
realId = it.id,
messageId = it.messageId,
sender = it.sender,
senderId = it.senderId,
recipient = it.recipient,
realId = it.id ?: 0,
messageId = it.messageId ?: 0,
sender = it.sender.orEmpty(),
senderId = it.senderId ?: 0,
recipient = it.recipient.orEmpty(),
recipientId = it.recipientId,
subject = it.subject.trim(),
date = it.date?.toLocalDateTime(),
date = it.date?.toLocalDateTime() ?: now(),
folderId = it.folderId,
unread = it.unread,
unreadBy = it.unreadBy,
readBy = it.readBy,
unread = it.unread ?: false,
unreadBy = it.unreadBy ?: 0,
readBy = it.readBy ?: 0,
removed = it.removed
)
}
@ -36,6 +37,6 @@ class MessageRemote @Inject constructor(private val api: Api) {
}
fun getMessagesContent(message: Message, markAsRead: Boolean = false): Single<String> {
return api.getMessageContent(message.messageId ?: 0, message.folderId, markAsRead, message.realId ?: 0)
return api.getMessageContent(message.messageId, message.folderId, markAsRead, message.realId)
}
}

View File

@ -21,7 +21,8 @@ class StudentRemote @Inject constructor(private val api: Api) {
schoolSymbol = student.schoolSymbol,
schoolName = student.schoolName,
endpoint = endpoint,
loginType = student.loginType.name
loginType = student.loginType.name,
isCurrent = false
)
}
}

View File

@ -27,10 +27,10 @@ class MessageItem(val message: Message, private val noSubjectString: String) :
position: Int, payloads: MutableList<Any>?
) {
holder.apply {
val style = if (message.unread == true) BOLD else NORMAL
val style = if (message.unread) BOLD else NORMAL
messageItemAuthor.run {
text = if (message.recipient?.isNotBlank() == true) message.recipient else message.sender
text = if (message.recipient.isNotBlank()) message.recipient else message.sender
setTypeface(null, style)
}
messageItemSubject.run {
@ -38,7 +38,7 @@ class MessageItem(val message: Message, private val noSubjectString: String) :
setTypeface(null, style)
}
messageItemDate.run {
text = message.date?.toFormattedString()
text = message.date.toFormattedString()
setTypeface(null, style)
}
}

View File

@ -41,14 +41,14 @@ class MessagePreviewPresenter @Inject constructor(
view?.run {
message.let {
setSubject(if (it.subject.isNotBlank()) it.subject else noSubjectString)
setDate(it.date?.toFormattedString("yyyy-MM-dd HH:mm:ss"))
setDate(it.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
setContent(it.content)
if (it.recipient?.isNotBlank() == true) setRecipient(it.recipient)
if (it.recipient.isNotBlank()) setRecipient(it.recipient)
else setSender(it.sender)
}
}
analytics.logEvent("load_message_preview", START_DATE to message.date?.toFormattedString("yyyy.MM.dd"), "lenght" to message.content?.length)
analytics.logEvent("load_message_preview", START_DATE to message.date.toFormattedString("yyyy.MM.dd"), "length" to message.content?.length)
}) {
Timber.i("Loading message $id preview result: An exception occurred ")
view?.showMessageError()

View File

@ -70,7 +70,7 @@ class MessageTabPresenter @Inject constructor(
Timber.i("Select message ${item.message.realId} item")
view?.run {
openMessage(item.message.realId)
if (item.message.unread == true) {
if (item.message.unread) {
item.message.unread = false
updateItem(item)
updateMessage(item.message)

View File

@ -48,13 +48,9 @@ inline val Grade.colorStringId: Int
}
fun Grade.changeModifier(plusModifier: Double, minusModifier: Double): Grade {
if (modifier != 0.0) {
if (plusModifier != 0.0 && modifier > 0) {
modifier = plusModifier
}
if (minusModifier != .0 && modifier < 0) {
modifier = -minusModifier
}
return when {
modifier != .0 && plusModifier != .0 && modifier > 0 -> copy(modifier = plusModifier)
modifier != .0 && minusModifier != .0 && modifier < 0 -> copy(modifier = -minusModifier)
else -> this
}
return this
}

View File

@ -75,7 +75,7 @@ class LoginFormPresenterTest {
@Test
fun loginTest() {
val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO")
val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO", studentName = "", schoolSymbol = "", schoolName = "", studentId = 0, isCurrent = false, symbol = "")
doReturn(Single.just(listOf(studentTest)))
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
presenter.attemptLogin("@", "123456", "https://fakelog.cf")

View File

@ -36,7 +36,7 @@ class LoginStudentSelectPresenterTest {
private lateinit var presenter: LoginStudentSelectPresenter
private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO") }
private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO", symbol = "", isCurrent = false, studentId = 0, schoolName = "", schoolSymbol = "", studentName = "") }
private val testException by lazy { RuntimeException("Problem") }