diff --git a/app/src/main/java/com/android/unio/model/Association.kt b/app/src/main/java/com/android/unio/model/Association.kt new file mode 100644 index 000000000..e957f6d9e --- /dev/null +++ b/app/src/main/java/com/android/unio/model/Association.kt @@ -0,0 +1,9 @@ +package com.android.unio.model + +data class Association( + val uid: String, + val acronym: String, + val fullName: String, + val description: String, + val members: List +) diff --git a/app/src/main/java/com/android/unio/model/AssociationRepository.kt b/app/src/main/java/com/android/unio/model/AssociationRepository.kt new file mode 100644 index 000000000..b711a0c75 --- /dev/null +++ b/app/src/main/java/com/android/unio/model/AssociationRepository.kt @@ -0,0 +1,5 @@ +package com.android.unio.model + +interface AssociationRepository { + fun getAssociations(onSuccess: (List) -> Unit, onFailure: (Exception) -> Unit) +} diff --git a/app/src/main/java/com/android/unio/model/AssociationRepositoryFirestore.kt b/app/src/main/java/com/android/unio/model/AssociationRepositoryFirestore.kt new file mode 100644 index 000000000..516b3f82f --- /dev/null +++ b/app/src/main/java/com/android/unio/model/AssociationRepositoryFirestore.kt @@ -0,0 +1,39 @@ +package com.android.unio.model + +import com.google.firebase.firestore.DocumentSnapshot +import com.google.firebase.firestore.FirebaseFirestore + +class AssociationRepositoryFirestore(private val db: FirebaseFirestore) : AssociationRepository { + + override fun getAssociations( + onSuccess: (List) -> Unit, + onFailure: (Exception) -> Unit + ) { + db.collection(ASSOCIATION_PATH) + .get() + .addOnSuccessListener { result -> + val associations = mutableListOf() + for (document in result) { + val association = hydrate(document) + + associations.add(association) + } + onSuccess(associations) + } + .addOnFailureListener { exception -> onFailure(exception) } + } + + fun hydrate(doc: DocumentSnapshot): Association { + return Association( + uid = doc.id, + acronym = doc.getString("acronym") ?: "", + fullName = doc.getString("fullName") ?: "", + description = doc.getString("description") ?: "", + members = doc.get("members") as? List ?: emptyList()) + } + + companion object { + private const val ASSOCIATION_PATH = "associations" + private const val USER_PATH = "users" + } +} diff --git a/app/src/main/java/com/android/unio/model/User.kt b/app/src/main/java/com/android/unio/model/User.kt new file mode 100644 index 000000000..7e6b121e6 --- /dev/null +++ b/app/src/main/java/com/android/unio/model/User.kt @@ -0,0 +1,8 @@ +package com.android.unio.model + +data class User( + val id: String, + val name: String, + val email: String, + val followingAssociations: List +) diff --git a/app/src/test/java/com/android/unio/model/AssociationRepositoryFirestoreTest.kt b/app/src/test/java/com/android/unio/model/AssociationRepositoryFirestoreTest.kt new file mode 100644 index 000000000..cd41ecb88 --- /dev/null +++ b/app/src/test/java/com/android/unio/model/AssociationRepositoryFirestoreTest.kt @@ -0,0 +1,111 @@ +package com.android.unio.model + +import com.google.android.gms.tasks.OnSuccessListener +import com.google.android.gms.tasks.Task +import com.google.firebase.firestore.CollectionReference +import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.QueryDocumentSnapshot +import com.google.firebase.firestore.QuerySnapshot +import junit.framework.TestCase.assertEquals +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.eq + +class AssociationRepositoryFirestoreTest { + @Mock private lateinit var db: FirebaseFirestore + @Mock private lateinit var collectionReference: CollectionReference + @Mock private lateinit var querySnapshot: QuerySnapshot + @Mock private lateinit var queryDocumentSnapshot1: QueryDocumentSnapshot + @Mock private lateinit var queryDocumentSnapshot2: QueryDocumentSnapshot + @Mock private lateinit var task: Task + + private lateinit var repository: AssociationRepositoryFirestore + + private val association1 = + Association( + uid = "1", + acronym = "ACM", + fullName = "Association for Computing Machinery", + description = "ACM is the world's largest educational and scientific computing society.", + members = mutableListOf("1", "2")) + + private val association2 = + Association( + uid = "2", + acronym = "IEEE", + fullName = "Institute of Electrical and Electronics Engineers", + description = + "IEEE is the world's largest technical professional organization dedicated to advancing technology for the benefit of humanity.", + members = mutableListOf("3", "4")) + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + + // When getting the collection, return the task + `when`(db.collection(eq("associations"))).thenReturn(collectionReference) + `when`(collectionReference.get()).thenReturn(task) + + // When the task is successful, return the query snapshot + `when`(task.addOnSuccessListener(any())).thenAnswer { invocation -> + val callback = invocation.arguments[0] as OnSuccessListener + callback.onSuccess(querySnapshot) + task + } + + // When the query snapshot is iterated, return the two query document snapshots + `when`(querySnapshot.iterator()) + .thenReturn(mutableListOf(queryDocumentSnapshot1, queryDocumentSnapshot2).iterator()) + + // When the query document snapshots are queried for specific fields, return the fields + `when`(queryDocumentSnapshot1.id).thenReturn(association1.uid) + `when`(queryDocumentSnapshot1.getString("acronym")).thenReturn(association1.acronym) + `when`(queryDocumentSnapshot1.getString("fullName")).thenReturn(association1.fullName) + `when`(queryDocumentSnapshot1.getString("description")).thenReturn(association1.description) + `when`(queryDocumentSnapshot1.get("members")).thenReturn(association1.members) + + repository = AssociationRepositoryFirestore(db) + } + + @Test + fun testGetAssociations() { + `when`(queryDocumentSnapshot2.id).thenReturn(association2.uid) + `when`(queryDocumentSnapshot2.getString("acronym")).thenReturn(association2.acronym) + `when`(queryDocumentSnapshot2.getString("fullName")).thenReturn(association2.fullName) + `when`(queryDocumentSnapshot2.getString("description")).thenReturn(association2.description) + `when`(queryDocumentSnapshot2.get("members")).thenReturn(association2.members) + + repository.getAssociations( + onSuccess = { associations -> + assertEquals(2, associations.size) + assertEquals(association1, associations[0]) + assertEquals(association2, associations[1]) + }, + onFailure = { exception -> assert(false) }) + } + + @Test + fun testGetAssociationsWithMissingFields() { + // Only set the ID for the second association, leaving the other fields as null + `when`(queryDocumentSnapshot2.id).thenReturn(association2.uid) + + repository.getAssociations( + onSuccess = { associations -> + assertEquals(2, associations.size) + assertEquals(association1, associations[0]) + assertEquals( + Association( + uid = association2.uid, + acronym = "", + fullName = "", + description = "", + members = emptyList()), + associations[1]) + }, + onFailure = { exception -> assert(false) }) + } +} diff --git a/app/src/test/java/com/android/unio/model/UserTest.kt b/app/src/test/java/com/android/unio/model/UserTest.kt new file mode 100644 index 000000000..d00edc527 --- /dev/null +++ b/app/src/test/java/com/android/unio/model/UserTest.kt @@ -0,0 +1,15 @@ +package com.android.unio.model + +import junit.framework.TestCase.assertEquals +import org.junit.Test + +class UserTest { + @Test + fun testUser() { + val user = User("1", "John", "john@example.com", emptyList()) + assertEquals("1", user.id) + assertEquals("John", user.name) + assertEquals("john@example.com", user.email) + assertEquals(emptyList(), user.followingAssociations) + } +}