content: import time
  from copy import deepcopy
  from multiprocessing.dummy import Pool as ThreadPool
  
  import orjson
  import pytest
  import shortuuid
  
  from django_unicorn.components import UnicornView
  from django_unicorn.utils import generate_checksum
  
  
  class FakeSlowComponent(UnicornView):
      template_name = "templates/test_component.html"
  
      counter = 0
      another_thing = 0
  
      def slow_action(self):
          time.sleep(0.3)
          self.counter += 1
  
          return self.counter
  
  
  def _set_serial(
      settings,
      enabled,
      timeout,
      cache_backend="django.core.cache.backends.locmem.LocMemCache",
  ):
      settings.UNICORN["SERIAL"]["ENABLED"] = enabled
      settings.UNICORN["SERIAL"]["TIMEOUT"] = timeout
      settings.UNICORN["CACHE_ALIAS"] = "default"
      settings.CACHES["default"]["BACKEND"] = cache_backend
  
  
  def _message_runner(args):
      client = args[0]
      sleep_time = args[1]
      message = args[2]
      time.sleep(sleep_time)
      message["epoch"] = time.time()
  
      response = client.post(
          "/message/tests.views.message.test_call_method_multiple.FakeSlowComponent",
          message,
          content_type="application/json",
      )
      return response
  
  
  @pytest.mark.slow
  def test_message_single(client, settings):
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
          "epoch": time.time(),
      }
  
      response = client.post(
          "/message/tests.views.message.test_call_method_multiple.FakeSlowComponent",
          message,
          content_type="application/json",
      )
  
      body = orjson.loads(response.content)
      assert body["data"].get("counter") == 1
  
  
  @pytest.mark.slow
  def test_message_two(client, settings):
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.1, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 2
  
          second_result = results[1]
          second_body = orjson.loads(second_result.content)
          assert second_body["queued"] is True
  
  
  @pytest.mark.slow
  def test_message_multiple(client, settings):
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.1, message), (client, 0.2, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == len(results)
  
          for result in results[1:]:
              body = orjson.loads(result.content)
              assert body.get("queued") is True
  
  
  @pytest.mark.slow
  def test_message_multiple_return_is_correct(client, settings):
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.1, message), (client, 0.2, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == len(results)
          assert first_body["return"].get("value") == len(results)
  
          for result in results[1:]:
              body = orjson.loads(result.content)
              assert body.get("queued") is True
  
  
  @pytest.mark.slow
  def test_message_multiple_with_updated_data(client, settings):
      """
      Not sure how likely this is to happen, but if the data got changed in a new queued request
      it gets disregarded because no sane way to merge it together. Not ideal, but not sure how to
      handle it.
      """
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.1, message), (client, 0.2, message)]
  
      # This new message with different data won't get used because not
      # sure how to reconcile this with resulting data from queued messages
      message_with_new_data = deepcopy(message)
      message_with_new_data["data"] = {"counter": 7}
      message_with_new_data["checksum"] = generate_checksum(str(message_with_new_data["data"]))
      messages.append((client, 0.4, message_with_new_data))
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 4
  
          for result in results[1:]:
              body = orjson.loads(result.content)
              assert body.get("queued") is True
  
  
  @pytest.mark.slow
  def test_message_second_request_not_queued_because_after_first(client, settings):
      _set_serial(settings, True, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.4, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 1
  
          second_result = results[1]
          second_body = orjson.loads(second_result.content)
          assert second_body["data"].get("counter") == 1
  
  
  @pytest.mark.slow
  def test_message_second_request_not_queued_because_serial_timeout(client, settings):
      _set_serial(settings, True, 0.1)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.2, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 1
  
          second_result = results[1]
          second_body = orjson.loads(second_result.content)
          assert second_body["data"].get("counter") == 1
  
  
  @pytest.mark.slow
  def test_message_second_request_not_queued_because_serial_disabled(client, settings):
      _set_serial(settings, False, 5)
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.2, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 1
  
          second_result = results[1]
          second_body = orjson.loads(second_result.content)
          assert second_body["data"].get("counter") == 1
  
  
  @pytest.mark.slow
  @pytest.mark.skip
  def test_message_second_request_not_queued_because_dummy_cache(client, settings):
      _set_serial(settings, True, 5, cache_backend="django.core.cache.backends.dummy.DummyCache")
  
      data = {"counter": 0}
      component_id = shortuuid.uuid()[:8]
      message = {
          "actionQueue": [
              {
                  "payload": {"name": "slow_action"},
                  "type": "callMethod",
              }
          ],
          "data": data,
          "checksum": generate_checksum(str(data)),
          "id": component_id,
      }
      messages = [(client, 0, message), (client, 0.2, message)]
  
      with ThreadPool(len(messages)) as pool:
          results = pool.map(_message_runner, messages)
          assert len(results) == len(messages)
  
          first_result = results[0]
          first_body = orjson.loads(first_result.content)
          assert first_body["data"].get("counter") == 1
  
          second_result = results[1]
          second_body = orjson.loads(second_result.content)
          assert second_body["data"].get("counter") == 1
  