Merge branch 'release/1.7.2'

This commit is contained in:
Mikołaj Pich 2022-08-30 13:34:20 +02:00
commit 4b795d6ef5
8 changed files with 155 additions and 25 deletions
app
build.gradle
src
main
java/io/github/wulkanowy/data
play/release-notes/pl-PL
res/values
test/java/io/github/wulkanowy/data/repositories

@ -23,8 +23,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 32
versionCode 110
versionName "1.7.1"
versionCode 111
versionName "1.7.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@ -161,7 +161,7 @@ play {
defaultToAppBundles = false
track = 'production'
releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
userFraction = 0.95d
userFraction = 0.05d
updatePriority = 5
enabled.set(false)
}
@ -181,16 +181,16 @@ ext {
android_hilt = "1.0.0"
room = "2.4.3"
chucker = "3.5.2"
mockk = "1.12.5"
mockk = "1.12.7"
coroutines = "1.6.4"
}
dependencies {
implementation "io.github.wulkanowy:sdk:1.7.0"
implementation "io.github.wulkanowy:sdk:1.7.2"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
implementation "androidx.core:core-ktx:1.8.0"
@ -263,7 +263,7 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.8.1'
testImplementation 'org.robolectric:robolectric:4.8.2'
testImplementation "androidx.test:runner:1.4.0"
testImplementation "androidx.test.ext:junit:1.1.3"
testImplementation "androidx.test:core:1.4.0"

@ -2,11 +2,12 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Update
interface BaseDao<T> {
@Insert
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(items: List<T>): List<Long>
@Update

@ -11,7 +11,4 @@ interface MailboxDao : BaseDao<Mailbox> {
@Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId ")
suspend fun loadAll(userLoginId: Int): List<Mailbox>
@Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId AND studentName = :studentName ")
suspend fun load(userLoginId: Int, studentName: String): Mailbox?
}

@ -32,17 +32,22 @@ class MailboxRepository @Inject constructor(
suspend fun getMailbox(student: Student): Mailbox {
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
val mailbox = mailboxDao.load(student.userLoginId, student.studentName)
val mailboxes = mailboxDao.loadAll(student.userLoginId)
val mailbox = mailboxes.filterByStudent(student)
return if (isExpired || mailbox == null) {
refreshMailboxes(student)
val newMailbox = mailboxDao.load(student.userLoginId, student.studentName)
val newMailbox = mailboxDao.loadAll(student.userLoginId).filterByStudent(student)
requireNotNull(newMailbox) {
"Mailbox for ${student.userName} - ${student.studentName} not found!"
"Mailbox for ${student.userName} - ${student.studentName} not found! Saved mailboxes: $mailboxes"
}
newMailbox
} else mailbox
}
private fun List<Mailbox>.filterByStudent(student: Student): Mailbox? = find {
it.studentName.trim() == student.studentName.trim()
}
}

@ -167,10 +167,10 @@ class MessageRepository @Inject constructor(
}
var draftMessage: MessageDraft?
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_draft))
?.let { json.decodeFromString(it) }
set(value) = sharedPrefProvider.putString(
context.getString(R.string.pref_key_message_send_draft),
context.getString(R.string.pref_key_message_draft),
value?.let { json.encodeToString(it) }
)
}

@ -1,9 +1,5 @@
Wersja 1.7.1
Wersja 1.7.2
- naprawiliśmy logowanie do aplikacji
- dodaliśmy wsparcie nowego modułu Wiadomości Plus
- dodaliśmy nową możliwość wsparcia naszego projektu przez opcjonalne reklamy
- dodaliśmy sortowanie po średniej
- naprawiliśmy też kilka usterek wpływających na komfort używania aplikacji
- naprawiliśmy kilka błędów w obsłudze nowego modułu wiadomości
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

@ -31,8 +31,7 @@
<string name="pref_key_homework_fullscreen">homework_fullscreen</string>
<string name="pref_key_subjects_without_grades">subjects_without_grades</string>
<string name="pref_key_optional_arithmetic_average">optional_arithmetic_average</string>
<string name="pref_key_message_send_is_draft">message_send_is_draft</string>
<string name="pref_key_message_send_draft">message_send_recipients</string>
<string name="pref_key_message_draft">message_draft</string>
<string name="pref_key_last_sync_date">last_sync_date</string>
<string name="pref_key_notifications_piggyback">notifications_piggyback</string>
<string name="pref_key_notifications_piggyback_cancel_original">notifications_piggyback_cancel_original</string>

@ -0,0 +1,132 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.dao.MailboxDao
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.MailboxType
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AutoRefreshHelper
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK
import io.mockk.just
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import java.time.Instant
@OptIn(ExperimentalCoroutinesApi::class)
class MailboxRepositoryTest {
@SpyK
private var sdk = Sdk()
@MockK
private lateinit var mailboxDao: MailboxDao
@MockK
private lateinit var refreshHelper: AutoRefreshHelper
private lateinit var systemUnderTest: MailboxRepository
@Before
fun setUp() {
MockKAnnotations.init(this)
coEvery { refreshHelper.shouldBeRefreshed(any()) } returns false
coEvery { refreshHelper.updateLastRefreshTimestamp(any()) } just Runs
coEvery { mailboxDao.deleteAll(any()) } just Runs
coEvery { mailboxDao.insertAll(any()) } returns emptyList()
coEvery { mailboxDao.loadAll(any()) } returns emptyList()
coEvery { sdk.getMailboxes() } returns emptyList()
systemUnderTest = MailboxRepository(
mailboxDao = mailboxDao,
sdk = sdk,
refreshHelper = refreshHelper,
)
}
@Test(expected = IllegalArgumentException::class)
fun `get mailbox that doesn't exist`() = runTest {
val student = getStudentEntity(
userName = "Stanisław Kowalski",
studentName = "Jan Kowalski",
)
coEvery { sdk.getMailboxes() } returns emptyList()
systemUnderTest.getMailbox(student)
}
@Test
fun `get mailbox for user with additional spaces`() = runTest {
val student = getStudentEntity(
userName = " Stanisław Kowalski ",
studentName = " Jan Kowalski ",
)
val expectedMailbox = getMailboxEntity("Jan Kowalski ")
coEvery { mailboxDao.loadAll(any()) } returns listOf(
expectedMailbox,
)
val selectedMailbox = systemUnderTest.getMailbox(student)
assertEquals(expectedMailbox, selectedMailbox)
}
@Test(expected = IllegalArgumentException::class)
fun `get mailbox for student with strange name`() = runTest {
val student = getStudentEntity(
userName = "Stanisław Kowalski",
studentName = "J**** K*****",
)
val expectedMailbox = getMailboxEntity("Jan Kowalski")
coEvery { mailboxDao.loadAll(any()) } returns listOf(
expectedMailbox,
)
systemUnderTest.getMailbox(student)
}
private fun getMailboxEntity(
studentName: String,
) = Mailbox(
globalKey = "",
fullName = "",
userName = "",
userLoginId = 123,
studentName = studentName,
schoolNameShort = "",
type = MailboxType.STUDENT,
)
private fun getStudentEntity(
studentName: String,
userName: String,
) = Student(
scrapperBaseUrl = "http://fakelog.cf",
email = "jan@fakelog.cf",
certificateKey = "",
classId = 0,
className = "",
isCurrent = false,
isParent = false,
loginMode = Sdk.Mode.API.name,
loginType = Sdk.ScrapperLoginType.STANDARD.name,
mobileBaseUrl = "",
password = "",
privateKey = "",
registrationDate = Instant.now(),
schoolName = "",
schoolShortName = "test",
schoolSymbol = "",
studentId = 1,
studentName = studentName,
symbol = "",
userLoginId = 1,
userName = userName,
)
}