Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Hide Tag" option to settings #45

Merged
merged 11 commits into from
Jul 12, 2024
35 changes: 30 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,39 @@ on:
branches:
- master
- develop
- testing

jobs:
build:
unit_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
- name: Run Unit Tests
run: ./gradlew testDebugUnitTest

android_tests:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
- name: Start Emulator and Run Instrumented Tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
script: ./gradlew connectedDebugAndroidTest

build_and_release:
runs-on: ubuntu-latest
needs: [unit_tests, android_tests]
steps:
- uses: actions/checkout@v3

Expand All @@ -26,9 +54,6 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Run Unit Tests
run: ./gradlew test

- name: Build app
run: ./gradlew assembleRelease
env:
Expand All @@ -42,7 +67,7 @@ jobs:

- name: Create Release on GitHub
uses: softprops/action-gh-release@v1
if: github.ref == 'refs/heads/master' # Solo crea releases para commits en master
if: github.ref == 'refs/heads/master'
env:
GITHUB_TOKEN: ${{ secrets.SHIORI_TOKEN }}
with:
Expand Down
1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ buildscript {
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.3.1' apply false
id 'com.android.library' version '8.3.1' apply false
id 'com.android.application' version '8.5.0' apply false
id 'com.android.library' version '8.5.0' apply false
id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
id 'org.jetbrains.kotlin.plugin.compose' version '2.0.0' apply false
}
9 changes: 7 additions & 2 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ android {
kotlinOptions {
jvmTarget = "17"
}
// JUnit 5 will bundle in files with identical paths, exclude them
packagingOptions {
exclude("META-INF/LICENSE*")
jniLibs {
excludes += setOf("META-INF/LICENSE*")
}
resources {
excludes += setOf("META-INF/LICENSE*")
}
}
// JUnit 5 will bundle in files with identical paths, exclude them
}

java {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.desarrollodroide.data.local.room

import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import com.desarrollodroide.data.local.room.dao.BookmarkHtmlDao
import com.desarrollodroide.data.local.room.database.BookmarksDatabase
import com.desarrollodroide.data.local.room.entity.BookmarkHtmlEntity
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
class BookmarkHtmlDaoTest {

private lateinit var database: BookmarksDatabase
private lateinit var bookmarkHtmlDao: BookmarkHtmlDao

private val bookmarkHtml = BookmarkHtmlEntity(
id = 1,
url = "http://example.com",
readableContentHtml = "<html>Test Content</html>"
)

@Before
fun setup() {
database = Room.inMemoryDatabaseBuilder(
ApplicationProvider.getApplicationContext(),
BookmarksDatabase::class.java
)
.allowMainThreadQueries()
.build()

bookmarkHtmlDao = database.bookmarkHtmlDao()
}

@After
fun tearDown() {
database.close()
}

@Test
fun testInsertAndFetchBookmarkHtml(): Unit = runBlocking {
bookmarkHtmlDao.insertOrUpdate(bookmarkHtml)
val retrievedHtml = bookmarkHtmlDao.getHtmlContent(bookmarkHtml.id)
Assert.assertEquals(bookmarkHtml.readableContentHtml, retrievedHtml)
bookmarkHtmlDao.getBookmarkHtml(bookmarkHtml.id)?.let {
Assert.assertEquals(bookmarkHtml, it)
}
}

@Test
fun testUpdateBookmarkHtml() = runBlocking {
bookmarkHtmlDao.insertOrUpdate(bookmarkHtml)
val updatedBookmarkHtml = bookmarkHtml.copy(readableContentHtml = "<html>Updated Content</html>")
bookmarkHtmlDao.insertOrUpdate(updatedBookmarkHtml)
val retrievedHtml = bookmarkHtmlDao.getHtmlContent(bookmarkHtml.id)
Assert.assertEquals(updatedBookmarkHtml.readableContentHtml, retrievedHtml)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.desarrollodroide.data.local.room

import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import com.desarrollodroide.data.local.room.dao.TagDao
import com.desarrollodroide.data.local.room.database.BookmarksDatabase
import com.desarrollodroide.data.local.room.entity.TagEntity
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test

class TagDaoTest {

private lateinit var database: BookmarksDatabase
private lateinit var tagDao: TagDao

private val tag = TagEntity(
id = 1,
name = "Test Tag",
nBookmarks = 5
)

@Before
fun setup() {
database = Room.inMemoryDatabaseBuilder(
ApplicationProvider.getApplicationContext(),
BookmarksDatabase::class.java
)
.allowMainThreadQueries()
.build()

tagDao = database.tagDao()
}

@After
fun tearDown() {
database.close()
}

@Test
fun testInsertAndFetchTags() = runBlocking {
tagDao.insertTag(tag)
val retrievedTags = tagDao.getAllTags().first()
assertTrue(retrievedTags.contains(tag))
tagDao.deleteAllTags()
assertTrue(tagDao.getAllTags().first().isEmpty())
}

@Test
fun testDeleteTag() = runBlocking {
tagDao.insertTag(tag)
tagDao.deleteTag(tag)
val retrievedTags = tagDao.getAllTags().first()
assertFalse(retrievedTags.contains(tag))
}

@Test
fun testInsertAndFetchMultipleTags() = runBlocking {
val tags = listOf(
TagEntity(1, "Tag1", 2),
TagEntity(2, "Tag2", 3)
)
tagDao.insertAllTags(tags)
val retrievedTags = tagDao.getAllTags().first()
assertTrue(retrievedTags.containsAll(tags))
}
}
15 changes: 12 additions & 3 deletions data/src/main/java/com/desarrollodroide/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.desarrollodroide.common.result.ErrorHandler
import com.desarrollodroide.data.local.datastore.HideTagSerializer
import com.desarrollodroide.data.local.datastore.RememberUserPreferencesSerializer
import com.desarrollodroide.data.local.datastore.UserPreferencesSerializer
import com.desarrollodroide.data.local.preferences.SettingsPreferenceDataSource
Expand Down Expand Up @@ -33,6 +34,7 @@ fun dataModule() = module {
val preferencesDataStoreQualifier = named("preferencesDataStore")
val protoDataStoreQualifier = named("protoDataStore")
val protoRememberUserDataStoreQualifier = named("protoRememberUserDataStore")
val protoHideTagDataStoreQualifier = named("protoHideTagDataStore")

single(preferencesDataStoreQualifier) {
PreferenceDataStoreFactory.create(
Expand All @@ -59,10 +61,19 @@ fun dataModule() = module {
)
}

single(protoHideTagDataStoreQualifier) {
DataStoreFactory.create(
serializer = HideTagSerializer,
produceFile = { androidContext().preferencesDataStoreFile("hide_tag_data")},
corruptionHandler = null,
)
}

single { SettingsPreferencesDataSourceImpl(
dataStore = get(preferencesDataStoreQualifier),
protoDataStore = get(protoDataStoreQualifier),
rememberUserProtoDataStore = get(protoRememberUserDataStoreQualifier)
rememberUserProtoDataStore = get(protoRememberUserDataStoreQualifier),
hideTagDataStore = get(protoHideTagDataStoreQualifier)
) as SettingsPreferenceDataSource }

single { AuthRepositoryImpl(
Expand Down Expand Up @@ -102,8 +113,6 @@ fun dataModule() = module {
) as TagsRepository
}



single { FileRemoteDataSource() }
single { ErrorHandlerImpl() as ErrorHandler }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.desarrollodroide.data.local.datastore

import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import com.desarrollodroide.data.HideTag
import com.google.protobuf.InvalidProtocolBufferException
import java.io.InputStream
import java.io.OutputStream

/**
* Serializer for the [HideTag] object defined in your .proto file.
*/
object HideTagSerializer : Serializer<HideTag> {
override val defaultValue: HideTag = HideTag.getDefaultInstance()

override suspend fun readFrom(input: InputStream): HideTag {
try {
return HideTag.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}

override suspend fun writeTo(t: HideTag, output: OutputStream) = t.writeTo(output)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.desarrollodroide.data.local.preferences
import com.desarrollodroide.data.UserPreferences
import com.desarrollodroide.data.helpers.ThemeMode
import com.desarrollodroide.model.Account
import com.desarrollodroide.model.Tag
import com.desarrollodroide.model.User
import kotlinx.coroutines.flow.Flow

Expand Down Expand Up @@ -46,4 +47,6 @@ interface SettingsPreferenceDataSource {

fun getUseDynamicColors(): Boolean
fun setUseDynamicColors(newValue: Boolean)
suspend fun getHideTag(): Tag?
suspend fun setHideTag(tag: Tag?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import com.desarrollodroide.data.HideTag
import com.desarrollodroide.data.RememberUserPreferences
import com.desarrollodroide.data.helpers.ThemeMode
import com.desarrollodroide.model.Tag
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.runBlocking

class SettingsPreferencesDataSourceImpl(
private val dataStore: DataStore<Preferences>,
private val protoDataStore: DataStore<UserPreferences>,
private val rememberUserProtoDataStore: DataStore<RememberUserPreferences>
private val rememberUserProtoDataStore: DataStore<RememberUserPreferences>,
private val hideTagDataStore: DataStore<HideTag>,

) : SettingsPreferenceDataSource {
) : SettingsPreferenceDataSource {

val THEME_MODE_KEY = stringPreferencesKey("theme_mode")
val COMPACT_VIEW = booleanPreferencesKey("compact_view")
Expand Down Expand Up @@ -249,4 +252,23 @@ class SettingsPreferencesDataSourceImpl(
}
}

override suspend fun setHideTag(tag: Tag?) {
hideTagDataStore.updateData { currentHideTag ->
when (tag) {
null -> HideTag.getDefaultInstance()
else -> currentHideTag.toBuilder()
.setId(tag.id)
.setName(tag.name)
.build()
}
}
}

override suspend fun getHideTag(): Tag? {
return hideTagDataStore.data.first().let { hideTag ->
if (hideTag == HideTag.getDefaultInstance()) null
else Tag(id = hideTag.id, name = hideTag.name, selected = false, nBookmarks = 0)
}
}

}
8 changes: 8 additions & 0 deletions data/src/main/proto/prefs.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,11 @@ message RememberUserPreferences {
bool createArchive = 7;

}


message HideTag {

int32 id = 1;
string name = 2;

}
Loading
Loading