Repository: openfun/marsha

Issue:
Add a new live state
## Feature Request

**Is your feature request related to a problem or unsupported use case? Please describe.**

Once a live is configured there is a few seconds between the switch from `configuring` to `idle` state in medialive channel. During this time if the use click on `start live`, aws will return a 400 response. 

**Describe the solution you'd like**

Add `configuring` to `live_state` list and switch from `configuring` to `idle` when the lambda call the update live state endpoint.



Discussion:

Resolving patch:
diff --git a/src/backend/marsha/core/api.py b/src/backend/marsha/core/api.py
--- a/src/backend/marsha/core/api.py
+++ b/src/backend/marsha/core/api.py
@@ -356,7 +356,7 @@ def initiate_live(
         Video.objects.filter(pk=pk).update(
             live_info=live_info,
             upload_state=defaults.PENDING,
-            live_state=defaults.IDLE,
+            live_state=defaults.CREATING,
             uploaded_on=None,
         )
 
diff --git a/src/backend/marsha/core/defaults.py b/src/backend/marsha/core/defaults.py
--- a/src/backend/marsha/core/defaults.py
+++ b/src/backend/marsha/core/defaults.py
@@ -15,6 +15,7 @@
     STOPPING,
     RUNNING,
     DELETED,
+    CREATING,
 ) = (
     "pending",
     "processing",
@@ -28,6 +29,7 @@
     "stopping",
     "running",
     "deleted",
+    "creating",
 )
 STATE_CHOICES = (
     (PENDING, _("pending")),
@@ -40,6 +42,7 @@
 )
 
 LIVE_CHOICES = (
+    (CREATING, _("creating")),
     (IDLE, _("idle")),
     (STARTING, _("starting")),
     (RUNNING, _("running")),
diff --git a/src/backend/marsha/core/serializers.py b/src/backend/marsha/core/serializers.py
--- a/src/backend/marsha/core/serializers.py
+++ b/src/backend/marsha/core/serializers.py
@@ -17,6 +17,7 @@
 from .defaults import (
     ERROR,
     HARVESTED,
+    IDLE,
     LIVE_CHOICES,
     PROCESSING,
     READY,
@@ -663,7 +664,7 @@ class UpdateLiveStateSerializer(serializers.Serializer):
     """A serializer to validate data submitted on the UpdateLiveState API endpoint."""
 
     state = serializers.ChoiceField(
-        tuple(c for c in LIVE_CHOICES if c[0] in (RUNNING, STOPPED))
+        tuple(c for c in LIVE_CHOICES if c[0] in (IDLE, RUNNING, STOPPED))
     )
     logGroupName = serializers.CharField()
 


Test patch:
diff --git a/src/backend/marsha/core/tests/test_api_video.py b/src/backend/marsha/core/tests/test_api_video.py
--- a/src/backend/marsha/core/tests/test_api_video.py
+++ b/src/backend/marsha/core/tests/test_api_video.py
@@ -13,6 +13,7 @@
 from .. import api, factories, models
 from ..api import timezone
 from ..defaults import (
+    CREATING,
     HARVESTING,
     IDLE,
     LIVE_CHOICES,
@@ -1911,7 +1912,7 @@ def test_api_video_instructor_initiate_live(self):
                     "title": "foo bar",
                     "lti_id": "course-v1:ufr+mathematics+00001",
                 },
-                "live_state": "idle",
+                "live_state": "creating",
                 "live_info": {
                     "medialive": {
                         "input": {
@@ -2365,6 +2366,41 @@ def test_api_video_update_live_state_stopped(self):
             },
         )
 
+    @override_settings(UPDATE_STATE_SHARED_SECRETS=["shared secret"])
+    def test_api_video_update_live_state_idle(self):
+        """Updating state to idle."""
+        video = factories.VideoFactory(
+            id="a1a21411-bf2f-4926-b97f-3c48a124d528",
+            upload_state=PENDING,
+            live_state=CREATING,
+            live_info={},
+        )
+        data = {
+            "logGroupName": "/aws/lambda/dev-test-marsha-medialive",
+            "state": "idle",
+        }
+
+        response = self.client.patch(
+            "/api/videos/{!s}/update-live-state/".format(video.id),
+            data,
+            content_type="application/json",
+            HTTP_X_MARSHA_SIGNATURE=(
+                "7fca3f22cc16b5c0f3b9c83dd1aef6d7dba70cc72195c685734ba499901826da"
+            ),
+        )
+
+        video.refresh_from_db()
+
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(json.loads(response.content), {"success": True})
+        self.assertEqual(video.live_state, IDLE)
+        self.assertEqual(
+            video.live_info,
+            {
+                "cloudwatch": {"logGroupName": "/aws/lambda/dev-test-marsha-medialive"},
+            },
+        )
+
     @override_settings(UPDATE_STATE_SHARED_SECRETS=["shared secret"])
     def test_api_video_update_live_state_invalid_signature(self):
         """Live state update with an invalid signature should fails."""