Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions JokeApp/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ android {
targetSdk 30
versionCode 1
versionName "1.0"

multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
manifestPlaceholders = [auth0Domain: "dev-18w6525q.us.auth0.com", auth0Scheme: "demo"]
}

buildTypes {
Expand Down Expand Up @@ -50,15 +51,20 @@ android {


dependencies {

implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.test.ext:junit-ktx:1.1.3'
implementation 'androidx.room:room-common:2.3.0'
implementation 'androidx.room:room-ktx:2.3.0'
implementation 'com.auth0.android:auth0:2.+'
implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha02'
testImplementation 'junit:junit:4.+'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation "androidx.room:room-testing:2.2.6"
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
testImplementation "org.robolectric:robolectric:4.5.1"
Expand All @@ -67,6 +73,7 @@ dependencies {
implementation "android.arch.navigation:navigation-ui-ktx:$version_navigation"
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
kapt "androidx.room:room-compiler:2.3.0"

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.example.jokeapp

import android.util.Log
import androidx.room.Room
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry

import com.example.jokeapp.database.jokes.Joke
import com.example.jokeapp.database.jokes.JokeDatabase
import com.example.jokeapp.database.jokes.JokeDatabaseDao
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException

/**
* This is not meant to be a full set of tests. For simplicity, most of your samples do not
* include tests. However, when building the Room, it is helpful to make sure it works before
* adding the UI.
*/

@RunWith(AndroidJUnit4::class)
class JokeDatabaseTest {

private lateinit var jokeDao: JokeDatabaseDao
private lateinit var db: JokeDatabase

@Before
fun createDb() {
Log.i("before", "running before")
val context = InstrumentationRegistry.getInstrumentation().targetContext
// Using an in-memory database because the information stored here disappears when the
// process is killed.
db = Room.inMemoryDatabaseBuilder(context, JokeDatabase::class.java)
// Allowing main thread queries, just for testing.
.allowMainThreadQueries()
.build()
jokeDao = db.jokeDatabaseDao
}

@After
@Throws(IOException::class)
fun closeDb() {
db.close()
}

@Test
@Throws(Exception::class)
fun insertAndGetJoke() = runBlocking {
val joke = Joke()
jokeDao.insert(joke)
val lastJoke = jokeDao.getLastJoke()
assertEquals(lastJoke?.punchline, "")
}
}
2 changes: 2 additions & 0 deletions JokeApp/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.jokeapp">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".JokeApplication"
android:allowBackup="true"
Expand Down
2 changes: 2 additions & 0 deletions JokeApp/app/src/main/java/com/example/jokeapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI

import com.google.android.material.navigation.NavigationView
import timber.log.Timber

Expand All @@ -15,6 +16,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var appBarConfiguration: AppBarConfiguration


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//setContentView(R.layout.activity_main)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.jokeapp.database.jokes

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "custom_joke_table")
data class Joke(
@PrimaryKey(autoGenerate = true)
var jokeId: Long = 0L,

@ColumnInfo(name = "joke_setup")
var jokeSetup: String = "",

@ColumnInfo(name = "joke_type")
var jokeType: String = "",

@ColumnInfo(name = "joke_punchline")
var punchline: String = "",

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.jokeapp.database.jokes

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(entities = [Joke::class], version = 1, exportSchema = false)
abstract class JokeDatabase : RoomDatabase() {

abstract val jokeDatabaseDao: JokeDatabaseDao

companion object {

@Volatile
private var INSTANCE: JokeDatabase? = null

fun getInstance(context: Context): JokeDatabase {
synchronized(this) {
var instance = INSTANCE

if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
JokeDatabase::class.java,
"custom_joke_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.jokeapp.database.jokes


import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update

/**
* Defines methods for using the SleepNight class with Room.
*/
@Dao
interface JokeDatabaseDao {

@Insert
suspend fun insert(joke: Joke)

@Update
suspend fun update(joke: Joke)

@Query("SELECT * from custom_joke_table WHERE jokeId = :key")
suspend fun get(key: Long): Joke?

@Query("DELETE FROM custom_joke_table")
suspend fun clear()

@Query("SELECT * FROM custom_joke_table ORDER BY jokeId DESC")
suspend fun getAllJokes(): List<Joke>

//get the joke with the highest ID (last joke added)
@Query("SELECT * FROM custom_joke_table ORDER BY jokeId DESC LIMIT 1")
suspend fun getLastJoke(): Joke?

//get the number of jokes present
@Query("SELECT COUNT(*) FROM custom_joke_table")
suspend fun numberOfJokes(): Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.example.jokeapp.login

import android.content.Context
import com.auth0.android.result.Credentials
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys


object CredentialsManager {
private val ACCESS_TOKEN = "access_token"

private lateinit var editor: SharedPreferences.Editor

fun saveCredentials(context: Context, credentials: Credentials) {

val masterKeyAlias: String = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

val sp: SharedPreferences = EncryptedSharedPreferences.create(
"secret_shared_prefs",
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

editor = sp.edit()
editor.putString(ACCESS_TOKEN, credentials.accessToken)
.apply()
}

fun getAccessToken(context: Context): String? {
val masterKeyAlias: String = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

val sp: SharedPreferences = EncryptedSharedPreferences.create(
"secret_shared_prefs",
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

return sp.getString(ACCESS_TOKEN, null)
}
}
Loading