EPForumL/androidApp

View on GitHub
app/src/main/java/com/github/ybecker/epforuml/database/MockDatabase.kt

Summary

Maintainability
F
5 days
Test Coverage
A
98%
package com.github.ybecker.epforuml.database

import android.util.Log
import com.github.ybecker.epforuml.database.Model.*
import com.google.android.gms.maps.model.LatLng
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.messaging.FirebaseMessaging
import java.time.LocalDateTime
import java.util.concurrent.CompletableFuture

/**
 * This class is a database that should only be used for tests
 */
class MockDatabase : Database() {

    private val questions = hashMapOf<String, Question>()
    private val answers = hashMapOf<String, Answer>()
    private val users = hashMapOf<String, User>()
    private val courses = hashMapOf<String, Course>()
    private val chats = hashMapOf<String, Chat>()

    init {
        val course1 = Course("course0","Sweng", mutableListOf(), emptyList())
        courses[course1.courseId] = course1
        val course2 = Course("course1","SDP", mutableListOf(), emptyList())
        courses[course2.courseId] = course2
        val course3 = Course("course2","AnalyseI", mutableListOf(), emptyList())
        courses[course3.courseId] = course3
        val course4 = Course("course3","AnalyseII", mutableListOf(), emptyList())
        courses[course4.courseId] = course4
        val course5 = Course("course4","AnalyseIII", mutableListOf(), emptyList())
        courses[course5.courseId] = course5
        val course6 = Course("course5","AnalyseIV", mutableListOf(), emptyList())
        courses[course6.courseId] = course6
        val course7 = Course("course6","Algo", mutableListOf(), emptyList())
        courses[course7.courseId] = course7
        val course8 = Course("course7","TOC", mutableListOf(), emptyList())
        courses[course8.courseId] = course8
        val course9 = Course("course8","POO", mutableListOf(), emptyList())
        courses[course9.courseId] = course9
        val course10 = Course("course9","POS", mutableListOf(), emptyList())
        courses[course10.courseId] = course10
        val course11 = Course("course10","OS", mutableListOf(), emptyList())
        courses[course11.courseId] = course11
        val course12 = Course("course11","Database", mutableListOf(), emptyList())
        courses[course12.courseId] = course12

        val user1 = User("user1", "TestUser", "", emptyList(), emptyList(), emptyList())
        users[user1.userId] = user1
        val userWithCredentials = User("userX", "Jean Dupont", "jdupont@epfl.ch")
        users[userWithCredentials.userId] = userWithCredentials

        val question1 = Question("question1", "course1", "user1", false,"About ci",
                                "How do I fix the CI ?",
            "",
            mutableListOf(), emptyList(),"")
        questions[question1.questionId] = question1
        val question2 = Question("question2", "course0", "user1", false,"About Scrum master",
                                "What is a Scrum Master ?", "" , mutableListOf(), emptyList(),"")


        questions[question2.questionId] = question2
        val question3 = Question("question3", "course0", "user1", false,"Very long question",
            "Extremely long long long long long long long long long long long long long " +
                    "long long long long long long long long long long long long long long long" +
                    "long long long long long long long long long long long long long long long" +
                    "long long long long long long long long long long long long long long long " +
                    "question" ,"", mutableListOf(), emptyList(),"")

        questions[question3.questionId] = question3

        val question4 = Question("question4", "course1", "user1", false,"AUDIO",
            "How do I fix the CI ?",
            "",
            mutableListOf(), emptyList(),"https://firebasestorage.googleapis.com/v0/b/epforuml-38150.appspot.com/o/random-acoustic-electronic-guitar-136427.mp3?alt=media&token=3ba7228f-a76f-4137-81fe-8126a30a0173")
        questions[question4.questionId] = question4

        val answer1 = Answer("answer1", "question1", "user1", "première réponse", emptyList(), "")
        addAnswer(answer1.userId, answer1.questionId, answer1.answerText)

        val answer2 = Answer("answer2", "question1", "user1", "Nan mais je suis pas d'accord", emptyList(), "")
        addAnswer(answer2.userId, answer2.questionId, answer2.answerText)

        val answer3 = Answer("answer3", "question1", "user1", "Ok alors si tu veux faire ça, " +
                "il faut installer la VM et faire tout depuis chez toi avec le VPN", emptyList(), ""
        )
        addAnswer(answer3.userId, answer3.questionId, answer3.answerText)

        val answer4 = Answer("answer4", "question1", "user1", "Nan mais je suis pas d'accord", emptyList(), "")
        addAnswer(answer4.userId, answer4.questionId, answer4.answerText)

        val answer5 = Answer("answer5", "question1", "user1", "Nan mais je suis pas d'accord non plus", emptyList(), "")
        addAnswer(answer5.userId, answer5.questionId, answer5.answerText)

        val answer6 = Answer("answer6", "question3", "user1", "Nan mais je suis pas d'accord non plus", emptyList(), "")
        addAnswer(answer6.userId, answer6.questionId, answer6.answerText)

        val chat1 = Chat("chat0",LocalDateTime.now().toString(), user1.userId, user1.userId, "Hey me!")
        addChat(chat1.senderId, chat1.receiverId, chat1.text)
        this.addSubscription(user1.userId, course1.courseId)
        this.addSubscription(user1.userId, course2.courseId)

    }
    override fun getChat(userId1: String, userId2:String): CompletableFuture<List<Chat>> {
        return CompletableFuture.completedFuture(chats.filterValues {
            (it.senderId == userId1 && it.receiverId == userId2)
                ||(it.senderId == userId2 && it.receiverId == userId1)
        }.values.toList().reversed())
    }

    override fun getQuestionFollowers(questionId: String): CompletableFuture<List<String>> {
        return CompletableFuture.completedFuture(questions[questionId]?.followers)
    }

    override fun getAnswerLike(answerId: String): CompletableFuture<List<String>> {
        return CompletableFuture.completedFuture(answers[answerId]?.like)
    }

    override fun addChat(senderId: String, receiverId: String, text: String?): Chat {
        val chatId = "chats${chats.size + 1}"
        val chat = Chat(chatId, LocalDateTime.now().toString(),receiverId,senderId,text)
        chats[chatId] = chat

        return chat
    }

    override fun addChatsWith(senderId: String, receiverId: String): String {

        if(!users[senderId]?.chatsWith?.contains(receiverId)!!){
            users[senderId]?.chatsWith = users[senderId]?.chatsWith?.plus(receiverId) ?: listOf(receiverId)
        }
        if(!users[receiverId]?.chatsWith?.contains(senderId)!!){
            users[receiverId]?.chatsWith = users[receiverId]?.chatsWith?.plus(senderId) ?: listOf(senderId)
        }
        return ""
    }

    override fun getUserId(userName: String): CompletableFuture<String> {
        return CompletableFuture.completedFuture(users.filterValues { it.username== userName}.values.toList().reversed()[0].userId)
    }

    override fun getChatsWith(userID: String): CompletableFuture<List<String>> {
        return CompletableFuture.completedFuture(users[userID]!!.chatsWith)
    }

    override fun getCourseQuestions(courseId: String): CompletableFuture<List<Question>> {
        return CompletableFuture.completedFuture(questions.filterValues { it.courseId == courseId }.values.toList().reversed())
    }

    override fun getQuestionAnswers(questionId: String): CompletableFuture<List<Answer>> {
        return CompletableFuture.completedFuture(answers.filterValues { it.questionId == questionId }.values.toList().reversed())
    }

    override fun addCourse(courseName: String): Course {
        val courseId = "question${questions.size + 1}"

        var course = courses[courseId]
        if(course != null) {
            return course
        }

        course = Course(courseId, courseName, emptyList(), emptyList())
        courses[courseId] = course

        return course
    }

    override fun addQuestion(userId: String, courseId: String, isAnonymous:Boolean, questionTitle: String, questionText: String?, image_uri: String, audioPath : String): CompletableFuture<Question> {
        val questionId = "question${questions.size + 1}"
        val question = Question(questionId, courseId, userId, isAnonymous, questionTitle,questionText ?: "", image_uri, emptyList(), emptyList(),"")

        questions[questionId] = question
        courses[courseId]?.questions = courses[courseId]?.questions?.plus(question.questionId) ?: listOf(question.questionId)
        users[userId]?.let {
            val updatedQuestions = it.questions + question.questionId
            users[userId] = it.copy(questions = updatedQuestions)
        }
        val question_future = CompletableFuture<Question>()
        question_future.complete(question)
        return question_future
    }

    override fun addAnswer(userId: String, questionId: String, answerText: String?): Answer {
        val answerId = "answer${answers.size + 1}"
        val answer = Answer(answerId, questionId, userId, answerText ?: "", emptyList(), "")
        answers[answerId] = answer
        questions[questionId]?.answers = questions[questionId]?.answers?.plus(answer.answerId) ?: mutableListOf(answer.answerId)

        users[userId]?.let {
            val updatedAnswers = it.answers + answer.answerId
            users[userId] = it.copy(answers = updatedAnswers)
        }
        return answer
    }

    override fun addUser(userId:String, username: String, email: String): CompletableFuture<User> {
        return addUser(User(userId, username, email))
    }

    override fun addUser(user: User): CompletableFuture<User> {
        val dbUser = users[user.userId]
        if(dbUser != null){
            return CompletableFuture.completedFuture(dbUser)
        }
        users[user.userId] = user
        return CompletableFuture.completedFuture(user)
    }

    override fun addQuestionFollower(userId: String, questionId: String) {
        val question = questions[questionId]
        if(question != null) {
            val updatedEndorsement = question.followers + userId
            questions[questionId] = question.copy(followers = updatedEndorsement)
        }
    }

    override fun addAnswerLike(userId: String, answerId: String) {
        val answers = answers[answerId]
        if(answers != null) {
            val updatedEndorsement = answers.like + userId
            this.answers[answerId] = answers.copy(like = updatedEndorsement)
        }
    }

    override fun removeUser(userId: String) {
        users.remove(userId)
    }

    override fun updateUser(user: User) {
        if (user.userId == DatabaseManager.user?.userId) {
            users[user.userId] = user
        }
    }

    override fun addSubscription(userId: String, courseId: String): CompletableFuture<User?> {
        if (users[userId] == null) {
            return CompletableFuture.completedFuture(null)
        } else {
            users[userId]?.let {
                val subscriptions = it.subscriptions.toMutableList()
                if (!subscriptions.contains(courseId)) {
                    subscriptions.add(courseId)
                }
                val updatedSubscription = subscriptions.toList()
                users[userId] = it.copy(subscriptions = updatedSubscription)
            }
            return CompletableFuture.completedFuture(users[userId])
        }
    }

    override fun removeSubscription(userId: String, courseId: String) {
        val user = users[userId]
        if(user != null) {
            val updatedSubscription = user.subscriptions.filter { it != courseId }
            users[userId] = user.copy(subscriptions = updatedSubscription)
        }
    }

    override fun addNotification(userId: String, courseId: String) {
        val course = courses[courseId]
        val user = users[userId]
        if(course != null && user != null) {
            val updatedCourseNotification = course.notifications + userId
            courses[courseId] = course.copy(notifications = updatedCourseNotification)

            val updatedUserNotification = user.notifications + courseId
            users[userId] = user.copy(notifications = updatedUserNotification)
        }
    }

    override fun removeNotification(userId: String, courseId: String) {
        val course = courses[courseId]
        val user = users[userId]
        if(course != null && user != null) {
            val updatedCourseNotification = course.notifications.filter { it != userId }
            courses[courseId] = course.copy(notifications = updatedCourseNotification)

            val updatedUserNotification = user.notifications.filter { it != courseId }
            users[userId] = user.copy(notifications = updatedUserNotification)
        }
    }

    override fun removeQuestionFollower(userId: String, questionId: String) {
        val course = questions[questionId]
        if(course != null) {
            val updatedNotification = course.followers.filter { it != userId }
            questions[questionId] = course.copy(followers = updatedNotification)
        }
    }

    override fun removeAnswerLike(userId: String, answerId: String) {
        val answer = answers[answerId]
        if(answer != null) {
            val updatedNotification = answer.like.filter { it != userId }
            answers[answerId] = answer.copy(like = updatedNotification)
        }
    }


    override fun availableCourses(): CompletableFuture<List<Course>> {
        return CompletableFuture.completedFuture(courses.values.toList())
    }

    override fun getAllAnswers(): CompletableFuture<List<Answer>> {
        return CompletableFuture.completedFuture(answers.values.toList())
    }

    override fun registeredUsers(): CompletableFuture<List<String>> {
        return CompletableFuture.completedFuture(users.values.toList().map { u -> u.username })
    }

    override fun getQuestions(): CompletableFuture<List<Question>> {
        return CompletableFuture.completedFuture(questions.values.toList().reversed())
    }

    override fun getAllUsers(): CompletableFuture<List<User>> {
        return CompletableFuture.completedFuture(users.values.toList())
    }

    override fun getQuestionById(id: String): CompletableFuture<Question?> {
        return CompletableFuture.completedFuture(questions.get(id))
    }

    override fun getAnswerById(id: String): CompletableFuture<Answer?> {
        return CompletableFuture.completedFuture(answers.get(id))
    }

    override fun getUserById(id: String): CompletableFuture<User?> {
        return CompletableFuture.completedFuture(users.get(id))
    }

    override fun getCourseById(id: String): CompletableFuture<Course?> {
        return CompletableFuture.completedFuture(courses.get(id))
    }

    override fun getUserQuestions(userId: String): CompletableFuture<List<Question>> {
        return CompletableFuture.completedFuture(questions.filterValues { it.userId == userId }.values.toList().reversed())
    }

    override fun getUserAnswers(userId: String): CompletableFuture<List<Answer>> {
        return CompletableFuture.completedFuture(answers.filterValues { it.userId == userId }.values.toList().reversed())
    }

    override fun getUserSubscriptions(userId: String): CompletableFuture<List<Course>> {
        val list = (users[userId]?.subscriptions ?: listOf()).map { courseId ->
            getCourseById(courseId).thenApply { course ->
                course?.let { it }
            }
        }
        val allFutures = CompletableFuture.allOf(*list.toTypedArray())
        return allFutures.thenApply {
            list.map { it.join() }
        }
    }


    override fun getCourseNotificationUserIds(courseId: String): CompletableFuture<List<String>> {
        val list = courses[courseId]?.notifications
        if(list == null || list.isEmpty()){
            return CompletableFuture.completedFuture(listOf())
        }
        return CompletableFuture.completedFuture(list)
    }

    override fun getUserNotificationIds(userId: String): CompletableFuture<List<String>> {
        val list = users[userId]?.notifications
        if(list == null || list.isEmpty()){
            return CompletableFuture.completedFuture(listOf())
        }
        return CompletableFuture.completedFuture(list)
    }

    override fun setUserPresence(userId: String) {
        users[userId]?.connections?.add(true)
    }

    override fun removeUserConnection(userId: String) {
        val co = users[userId]?.connections
        if (co != null && co.size > 0) {
            co.removeAt(0)
        }
    }

    override fun addStatus(userId: String, courseId: String, statut: UserStatus) {
        val user = users[userId]
        if(user != null){
            val statutString = user.status.filter {it.split("/").get(0) != courseId}
            val updatedUser = user.copy(status = statutString + ("$courseId/${statut.name}"))
            users[userId] = updatedUser
        }
    }

    override fun removeStatus(userId: String, courseId: String) {
        val user = users[userId]
        if(user != null){
            val updatedUser = user.copy(status = user.status.filter { it.split("/").get(0) != courseId})
            users[userId] = updatedUser
        }
    }

    override fun getUserStatus(userId: String, courseId: String): CompletableFuture<UserStatus?> {
        val future = CompletableFuture<UserStatus?>()
        val user = users[userId]
        if(user != null){
            val statusString = user.status.filter {it.split("/")[0] == courseId}

            if(statusString.isEmpty()) return CompletableFuture.completedFuture(null)

             future.complete(UserStatus.valueOf(statusString[0].split("/")[1]))
        } else {
            future.complete(null)
        }

        return future
    }

    override fun getAnswerEndorsement(answerId: String): CompletableFuture<String?> {
        val answer = answers[answerId]
        if(answer!=null && answer.endorsed != ""){
            return CompletableFuture.completedFuture(answer.endorsed)
        }
        return CompletableFuture.completedFuture(null)
    }

    override fun addAnswerEndorsement(answerId: String, username: String) {
        val answer = answers[answerId]
        if(answer!=null){
            val updatedAnswer = answer.copy(endorsed = username)
            answers[answerId] = updatedAnswer
        }
    }

    override fun removeAnswerEndorsement(answerId: String) {
        val answer = answers[answerId]
        if(answer!=null){
            val updatedAnswer = answer.copy(endorsed = "")
            answers[answerId] = updatedAnswer
        }
    }

    override fun getOtherUsers(userId: String): CompletableFuture<List<User>> {
        return CompletableFuture.completedFuture(users.values.toList().filter { it.userId != userId })
    }

    override fun removeChat(chatId: String): Boolean {
        return try {
            chats.remove(chatId)
            true
        } catch (e: Exception) {
            false
        }
    }

    override fun updateLocalization(userId: String, position: LatLng, sharesLocation: Boolean) {
        users[userId]?.longitude = position.longitude
        users[userId]?.latitude = position.latitude
        users[userId]?.sharesLocation = sharesLocation
    }

    override fun getDbInstance(): FirebaseDatabase? {
        return null
    }
}