From 8f83f56c7aaf3a93b11d3d2859d482ee73fa61fe Mon Sep 17 00:00:00 2001
From: Felipe D'Abrantes <felidabrantes@gmail>
Date: Sat, 8 Apr 2023 00:52:13 +0100
Subject: [PATCH] Add endpoint and functionality to unlike a Daily

---
 .../app/controllers/DailyController.scala     | 18 ++++++++++++
 .../feed-service/app/models/Daily.scala       | 29 +++++++++++++++++++
 backend-services/feed-service/conf/routes     |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/backend-services/feed-service/app/controllers/DailyController.scala b/backend-services/feed-service/app/controllers/DailyController.scala
index 3dc422bd..8e5d1b2b 100644
--- a/backend-services/feed-service/app/controllers/DailyController.scala
+++ b/backend-services/feed-service/app/controllers/DailyController.scala
@@ -98,4 +98,22 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents)
         case _: Throwable => BadRequest("Exception raised")
     }
   }
+
+   /**
+   * Create an Action to unlike a Daily.
+   */
+  def unlike() = Action {
+    println("DailyController:unlike")
+
+    try {
+        // Dummy data
+        Daily.unlikeAsync(new ObjectId("642314b4b9748f6794e9895b"), new ObjectId("641128f7e80bcd1ba39d04ae"))
+        Ok("Updated")
+    } catch {
+        case _: TimeoutException => BadRequest("Request timed out")
+        case ex: ConflictException => BadRequest(ex.getMessage())
+        case ex: NotFoundException => BadRequest(ex.getMessage())
+        case _: Throwable => BadRequest("Exception raised")
+    }
+  }
 }
diff --git a/backend-services/feed-service/app/models/Daily.scala b/backend-services/feed-service/app/models/Daily.scala
index ab1b1f15..033168a5 100644
--- a/backend-services/feed-service/app/models/Daily.scala
+++ b/backend-services/feed-service/app/models/Daily.scala
@@ -93,6 +93,35 @@ object Daily {
         Await.result[Unit](result, timeout.seconds)
     }
 
+    def unlikeAsync(dailyId: ObjectId, likerId: ObjectId, timeout: Int = 4): Unit = {
+        val result: Future[Unit] = for {
+            // Fetch Daily from given ID
+            daily: Daily  <- {
+                dailyRepo.getById(dailyId).map((oDaily: Option[Daily]) => {
+                    if (oDaily.isEmpty) 
+                        throw new NotFoundException("No daily with given ID.") 
+                    else 
+                        oDaily.get
+                })
+            }
+
+            // Check user with given ID exists
+            _ <- User.userExists(likerId).map((exists: Boolean) => if (!exists) throw new NotFoundException("No user with given ID."))
+
+            // Check user has liked the Daily
+            _ = if (!daily.usersLiked.contains(likerId)) throw new ConflictException("User has not liked this Daily.")
+
+            unlike: Unit <- {
+                val updatedUsersLiked: Seq[ObjectId] = daily.usersLiked.filterNot(_ == likerId)
+                val update: Bson = Updates.set("usersLiked", updatedUsersLiked)
+
+                dailyRepo.updateOne(dailyId, Seq(update))
+            }
+        } yield unlike
+
+        Await.result[Unit](result, timeout.seconds)
+    }
+
     // Convert from Daily object to JSON (serializing to JSON)
     def toJson(daily: Daily): JsValue = {
         val usersLikedAsJsStrings: Seq[JsString] = daily.usersLiked.map[JsString](id => JsString(id.toString()))
diff --git a/backend-services/feed-service/conf/routes b/backend-services/feed-service/conf/routes
index f580a634..90c87567 100644
--- a/backend-services/feed-service/conf/routes
+++ b/backend-services/feed-service/conf/routes
@@ -18,3 +18,5 @@ GET     /feed              controllers.DailyController.getUserFeed()
 POST     /daily/create      controllers.DailyController.create()
 
 PUT     /daily/like      controllers.DailyController.like()
+
+PUT     /daily/unlike      controllers.DailyController.unlike()
-- 
GitLab