Skip to content
This repository has been archived by the owner on Jan 31, 2024. It is now read-only.

Kamila/add_user_search #181

Merged
merged 29 commits into from
Apr 17, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ce29c0b
SearchUsers: add activity to search for users
kamilababayeva Apr 15, 2022
d67cf79
remove previously wrong added files
kamilababayeva Apr 16, 2022
8e2cf4d
AndroidManifest.xml: add new activity to search users
kamilababayeva Apr 16, 2022
9f526dd
WelcomeActivity: add new button to search users
kamilababayeva Apr 16, 2022
b54d615
WelcomeActivity: remove unnecessary lines
kamilababayeva Apr 16, 2022
b7d18da
activity_search_user.xml: with editText and recycler view
kamilababayeva Apr 16, 2022
3b2ea07
user_search_item_layout: add user view
kamilababayeva Apr 16, 2022
59ab298
UserAdapter: adapter that hold UserProfiles based on search
kamilababayeva Apr 16, 2022
f4d3469
SearchUserActivity: activity to search the user
kamilababayeva Apr 16, 2022
832ede4
WelcomActivityTest: add test for new button
kamilababayeva Apr 16, 2022
8b874a5
UserProfileAdapterTest: add tests to check the adapter, similar to Pl…
kamilababayeva Apr 16, 2022
55ee0e8
UserProfileAdapter: rename and move file
kamilababayeva Apr 16, 2022
f6e69ed
SarchActivity: fix the names and types
kamilababayeva Apr 16, 2022
25a500e
SearchUserActivityTest: add tests
kamilababayeva Apr 16, 2022
d7a26f3
UserProfileAdapterTest: remove unnecessary files
kamilababayeva Apr 16, 2022
71e9649
SearchUserActivity: add function to display all the users
kamilababayeva Apr 16, 2022
5144feb
rename the edittext id
kamilababayeva Apr 16, 2022
e925180
SearchUserActivity: remove unnecessary function
kamilababayeva Apr 16, 2022
d0a715c
SearchUserActivityTest: add extra test
kamilababayeva Apr 16, 2022
4d5983c
SearchUserActivityTest: remove redundant code
kamilababayeva Apr 16, 2022
f451da7
UserProfileAdapterTest: remove redundant tests
kamilababayeva Apr 16, 2022
634e497
SearchUserActivity: fix variables names and spaces
kamilababayeva Apr 16, 2022
b9b3647
UserProfileAdapter: remove addUsers function
kamilababayeva Apr 16, 2022
241cf0d
UserProfileAdapter: fix comments
kamilababayeva Apr 16, 2022
431b30c
SearchUserActivity: put log on database errror
kamilababayeva Apr 16, 2022
44387f6
rerun tests
kamilababayeva Apr 16, 2022
e0a3b91
Merge branch 'main' into kamila/refactor_sharedPreferences
kamilababayeva Apr 17, 2022
a883b46
SearchUserActivity: add comment, change var to val
kamilababayeva Apr 17, 2022
354458c
Add strings, change hint text
kamilababayeva Apr 17, 2022
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ch.sdp.vibester.activity

import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import ch.sdp.vibester.R
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class SearchUserActivityTest {

@Rule
@JvmField
val activityRule = ActivityScenarioRule(SearchUserActivity::class.java)

@Before
fun setUp() {
Intents.init()
}

@After
fun clean() {
Intents.release()
}

@Test
fun recycleViewToViewTest() {
onView(ViewMatchers.withId(R.id.searchList))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
}

@Test
fun recycleViewClickTest() {
onView((ViewMatchers.withId(R.id.searchList)))
.perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(
2,
ViewActions.click()
)
)
}

@Test
fun recycleViewScrollDownTest() {
val recyclerView = RecyclerView(ApplicationProvider.getApplicationContext())
val itemCount = recyclerView.adapter?.itemCount
if (itemCount != null) {
onView(ViewMatchers.withId(R.id.searchList)).perform(
RecyclerViewActions.scrollToPosition<RecyclerView.ViewHolder>(
itemCount.minus(1)
)
)
}
}
@Test
fun recycleViewCheckEmpty() {
val inputTxt= "TESTESTESTEST"
onView(ViewMatchers.withId(R.id.searchUserET)).perform(ViewActions.typeText(inputTxt),
ViewActions.closeSoftKeyboard())
val recyclerView = RecyclerView(ApplicationProvider.getApplicationContext())
val itemCount = recyclerView.adapter?.itemCount
assertEquals(itemCount, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,10 @@ class WelcomeActivityTest {
onView(withId(R.id.welcome_download)).perform(click())
intended(hasComponent(DownloadActivity::class.java.name))
}

@Test
fun checkIntentOnSearch() {
onView(withId(R.id.welcome_search)).perform(click())
intended(hasComponent(SearchUserActivity::class.java.name))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ch.sdp.vibester.profile

import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
import org.junit.Test

class UserProfileAdapterTest {

@Test
fun recyclerViewShowsCorrectCount() {
val user1 = UserProfile("test1", "Brownie", "https://images.app.goo.gl/yiPpy7JDRFaZRiAg9", "[email protected]")
val user2 = UserProfile("test2", "Cookie", "https://images.app.goo.gl/yiPpy7JDRFaZRiAg9", "[email protected]")
val users: MutableList<UserProfile> = arrayListOf()
users.addAll(listOf(user1, user2))
val userProfileViewHolder: RecyclerView.Adapter<UserProfileAdapter.UserProfileViewHolder> = UserProfileAdapter(users)
MatcherAssert.assertThat(userProfileViewHolder.itemCount, CoreMatchers.equalTo(2))
}

@Test
fun itemTypeIsCorrect() {
val user1 = UserProfile("test1", "Brownie", "https://images.app.goo.gl/yiPpy7JDRFaZRiAg9", "[email protected]")
val user2 = UserProfile("test2", "Cookie", "https://images.app.goo.gl/yiPpy7JDRFaZRiAg9", "[email protected]")
val users: MutableList<UserProfile> = arrayListOf()
users.addAll(listOf(user1, user2))
val userProfileViewHolder: RecyclerView.Adapter<UserProfileAdapter.UserProfileViewHolder> = UserProfileAdapter(users)
val defaultType = 0
MatcherAssert.assertThat(
userProfileViewHolder.getItemViewType(0),
CoreMatchers.equalTo(defaultType)
)
}
}
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
android:usesCleartextTraffic="true">
<activity
android:name=".activity.SearchUserActivity"
android:exported="false" />
<activity
android:name=".activity.DownloadActivity"
android:exported="false" />
Expand Down
86 changes: 86 additions & 0 deletions app/src/main/java/ch/sdp/vibester/activity/SearchUserActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package ch.sdp.vibester.activity

import android.content.ContentValues
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.Window
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import ch.sdp.vibester.R
import ch.sdp.vibester.database.Database
import ch.sdp.vibester.profile.UserProfile
import ch.sdp.vibester.profile.UserProfileAdapter
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener

/**
* Search for users based on their usernames.
*/
class SearchUserActivity : AppCompatActivity() {
private var userProfileAdapter: UserProfileAdapter? = null
private var users: MutableList<UserProfile>? = null
private var recyclerView: RecyclerView? = null
private var searchEditText: EditText? = null
private var dbRef: DatabaseReference = Database.get().getReference("users")
laurislopata marked this conversation as resolved.
Show resolved Hide resolved

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
supportActionBar?.hide()
setContentView(R.layout.activity_search_user)

recyclerView = findViewById(R.id.searchList)
recyclerView!!.setHasFixedSize(true)
recyclerView!!.layoutManager = LinearLayoutManager(this)

users = ArrayList()

searchEditText = findViewById(R.id.searchUserET)
searchForUsers("")

searchEditText!!.addTextChangedListener(object:TextWatcher{
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
searchForUsers(p0.toString())
}
override fun afterTextChanged(p0: Editable?) {
}
})
}

/**
* Search for users by usernames in Firebase Realtime Database
* @param inputUsername search text inputed by user
*/
private fun searchForUsers(inputUsername:String){
val queryUsers = dbRef
.orderByChild("username")
.startAt(inputUsername)
.endAt(inputUsername+"\uf8ff")
laurislopata marked this conversation as resolved.
Show resolved Hide resolved

queryUsers.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
(users as ArrayList<UserProfile>).clear()
for (snapshot in dataSnapshot.children) {
val userProfile:UserProfile? = snapshot.getValue(UserProfile::class.java)
if (userProfile != null) {
(users as ArrayList<UserProfile>).add(userProfile)
}
}
userProfileAdapter = UserProfileAdapter(users!!)
recyclerView!!.adapter = userProfileAdapter
}
override fun onCancelled(error: DatabaseError) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

Log.w(ContentValues.TAG, "searchForUsers:onCancelled", error.toException())
}
})
}
}

13 changes: 3 additions & 10 deletions app/src/main/java/ch/sdp/vibester/activity/WelcomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package ch.sdp.vibester.activity
//import ch.sdp.vibester.profile.ProfileDataProvider
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window.FEATURE_NO_TITLE
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import ch.sdp.vibester.R
import ch.sdp.vibester.model.Song
import ch.sdp.vibester.model.UserSharedPref

class WelcomeActivity : AppCompatActivity() {
Expand Down Expand Up @@ -57,12 +55,7 @@ class WelcomeActivity : AppCompatActivity() {
sendDirectIntent(DownloadActivity::class.java)
}

/*
* Belongs to a previously implemented button, taken out for UI purposes.
* Might bring it back, thus leaving the code for now.
*/

/*fun switchToLogin(view: View) { //FILLER INTENT
sendDirectIntent(GameSetupScreen::class.java)
}*/
fun switchToSearch(view: View) {
sendDirectIntent(SearchUserActivity::class.java)
}
}
51 changes: 51 additions & 0 deletions app/src/main/java/ch/sdp/vibester/profile/UserProfileAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package ch.sdp.vibester.profile

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import ch.sdp.vibester.R

/**
* UserAdapter to set userProfile views with username and image in RecycleView. It is used to search for users.
*/
class UserProfileAdapter(val users: MutableList<UserProfile>):
RecyclerView.Adapter<UserProfileAdapter.UserProfileViewHolder>() {

/**
* Create a RecycleView layout with the userProfile view as an item
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserProfileViewHolder {
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.user_search_item_layout, parent, false)
return UserProfileViewHolder(view)
}

override fun onBindViewHolder(holder: UserProfileViewHolder, position: Int) {
holder.bind(users[position])
}

/**
* Get amount of users displayed
*/
override fun getItemCount(): Int {
return users.size
}

/**
* Customer ViewHolder class for UserProfile. Each item contains username and image.
*/
inner class UserProfileViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
/**
* @param userProfile with all the parameters
*/
fun bind(user: UserProfile) {
itemView.findViewById<TextView>(R.id.search_user_username).text = user.username
// TODO fix the image upload
// itemView.findViewById<ImageView>(R.id.iv_photo).loadImg(player.photo)
}
}


}
26 changes: 26 additions & 0 deletions app/src/main/res/layout/activity_search_user.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/floral_white"
tools:context=".activity.SearchUserActivity">

<EditText
android:id="@+id/searchUserET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:autofillHints="">
</EditText>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchList"
android:layout_below="@+id/searchUserET"
android:layout_width="match_parent"
android:layout_height="match_parent">

</androidx.recyclerview.widget.RecyclerView>

</RelativeLayout>
13 changes: 13 additions & 0 deletions app/src/main/res/layout/activity_welcome_screen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@
android:translationZ="10dp"
app:icon="@android:drawable/stat_sys_download" />

<Button
android:id="@+id/welcome_search"
android:layout_width="200dp"
android:layout_height="48dp"
android:layout_marginTop="10dp"
android:backgroundTint="@color/cg_blue"
android:elevation="10dp"
android:onClick="switchToSearch"
android:stateListAnimator="@null"
android:text="SEARCH USERS"
kamilababayeva marked this conversation as resolved.
Show resolved Hide resolved
android:translationZ="10dp"/>


<Space
android:layout_width="match_parent"
android:layout_height="42dp" />
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/res/layout/user_search_item_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/floral_white"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/profile_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/logo">
</ImageView>

<TextView
android:id="@+id/search_user_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/profile_image"
android:layout_centerInParent="true"
android:layout_marginStart="12dp"
android:text="user name"
kamilababayeva marked this conversation as resolved.
Show resolved Hide resolved
android:textSize="19sp">
</TextView>

</RelativeLayout>