Repository: zulip/zulip

Issue:
Clean up code for hacky OpenAPI curl test
After testing `deactivate_own_account` endpoint, we need to reactivate the client so that other tests are not affected by the deactivated client. In `test_curl_examples`, this has been hackily implemented and should be replaced by cleaner code. More details at https://github.com/zulip/zulip/pull/17014#discussion_r601173277


Discussion:
Hello @zulip/server-testing members, this issue was labeled with the "area: testing-infrastructure" label, so you may want to check it out!

<!-- areaLabelAddition -->
@MSurfer20 Hey, are you working on this issue?
@100RABHpy I had planned to take this up after completing work on some other PRs. Feel free to claim this;I'd be happy to review your work :)
Thanks @MSurfer20,
Can you explain a bit on (like what error you get when tried to delete any other user):
>it's awkward to test the "deactivate myself" endpoint with how this system tries to use the same account for all tests without some special logic for that endpoint
>
I was thinking to create a new administrator user and delete this in `deactivate_own_user` function. 
@zulipbot claim
 If you deactivate a user, then that user can't call any other endpoints(since it's deactivated), which leads to all remaining tests failing. 
>I was thinking to create a new administrator user and delete this in deactivate_own_user function.  

This seems to be good!
Oh, Okay, that can be handle. 
Also, If I'm getting it right only reason of adding owner_client is for reactivation. Right?
Yes, it was just added for reactivating the client after the deactivation.

Resolving patch:
diff --git a/zerver/openapi/curl_param_value_generators.py b/zerver/openapi/curl_param_value_generators.py
--- a/zerver/openapi/curl_param_value_generators.py
+++ b/zerver/openapi/curl_param_value_generators.py
@@ -20,11 +20,15 @@
 from zerver.lib.events import do_events_register
 from zerver.lib.initial_password import initial_password
 from zerver.lib.test_classes import ZulipTestCase
-from zerver.models import Client, Message, UserGroup, UserPresence, get_realm
+from zerver.lib.users import get_api_key
+from zerver.models import Client, Message, UserGroup, UserPresence, get_realm, get_user
 
 GENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}
 REGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()
 CALLED_GENERATOR_FUNCTIONS: Set[str] = set()
+# This is a List rather than just a string in order to make it easier
+# to write to it from another module.
+AUTHENTICATION_LINE: List[str] = [""]
 
 helpers = ZulipTestCase()
 
@@ -310,3 +314,22 @@ def deactivate_user() -> Dict[str, object]:
         acting_user=None,
     )
     return {"user_id": user_profile.id}
+
+
+@openapi_param_value_generator(["/users/me:delete"])
+def deactivate_own_user() -> Dict[str, object]:
+    test_user_email = "delete-test@zulip.com"
+    deactivate_test_user = do_create_user(
+        test_user_email,
+        "secret",
+        get_realm("zulip"),
+        "Mr. Delete",
+        role=200,
+        acting_user=None,
+    )
+    realm = get_realm("zulip")
+    test_user = get_user(test_user_email, realm)
+    test_user_api_key = get_api_key(test_user)
+    # change authentication line to allow test_client to delete itself.
+    AUTHENTICATION_LINE[0] = f"{deactivate_test_user.email}:{test_user_api_key}"
+    return {}


Test patch:
diff --git a/zerver/openapi/test_curl_examples.py b/zerver/openapi/test_curl_examples.py
--- a/zerver/openapi/test_curl_examples.py
+++ b/zerver/openapi/test_curl_examples.py
@@ -16,11 +16,14 @@
 
 from zerver.models import get_realm
 from zerver.openapi import markdown_extension
-from zerver.openapi.curl_param_value_generators import assert_all_helper_functions_called
+from zerver.openapi.curl_param_value_generators import (
+    AUTHENTICATION_LINE,
+    assert_all_helper_functions_called,
+)
 
 
-def test_generated_curl_examples_for_success(client: Client, owner_client: Client) -> None:
-    authentication_line = f"{client.email}:{client.api_key}"
+def test_generated_curl_examples_for_success(client: Client) -> None:
+    default_authentication_line = f"{client.email}:{client.api_key}"
     # A limited Markdown engine that just processes the code example syntax.
     realm = get_realm("zulip")
     md_engine = markdown.Markdown(
@@ -35,6 +38,10 @@ def test_generated_curl_examples_for_success(client: Client, owner_client: Clien
     for file_name in sorted(glob.glob("templates/zerver/api/*.md")):
         with open(file_name) as f:
             for line in f:
+                # Set AUTHENTICATION_LINE to default_authentication_line.
+                # Set this every iteration, because deactivate_own_user
+                # will override this for its test.
+                AUTHENTICATION_LINE[0] = default_authentication_line
                 # A typical example from the Markdown source looks like this:
                 #     {generate_code_example(curl, ...}
                 if not line.startswith("{generate_code_example(curl"):
@@ -47,21 +54,9 @@ def test_generated_curl_examples_for_success(client: Client, owner_client: Clien
                 unescaped_html = html.unescape(curl_command_html)
                 curl_command_text = unescaped_html[len("<p><code>curl\n") : -len("</code></p>")]
                 curl_command_text = curl_command_text.replace(
-                    "BOT_EMAIL_ADDRESS:BOT_API_KEY", authentication_line
+                    "BOT_EMAIL_ADDRESS:BOT_API_KEY", AUTHENTICATION_LINE[0]
                 )
 
-                # TODO: This needs_reactivation block is a hack.
-                # However, it's awkward to test the "deactivate
-                # myself" endpoint with how this system tries to use
-                # the same account for all tests without some special
-                # logic for that endpoint; and the hack is better than
-                # just not documenting the endpoint.
-                needs_reactivation = False
-                user_id = 0
-                if file_name == "templates/zerver/api/deactivate-own-user.md":
-                    needs_reactivation = True
-                    user_id = client.get_profile()["user_id"]
-
                 print("Testing {} ...".format(curl_command_text.split("\n")[0]))
 
                 # Turn the text into an arguments list.
@@ -77,8 +72,6 @@ def test_generated_curl_examples_for_success(client: Client, owner_client: Clien
                     )
                     response = json.loads(response_json)
                     assert response["result"] == "success"
-                    if needs_reactivation:
-                        owner_client.reactivate_user_by_id(user_id)
                 except (AssertionError, Exception):
                     error_template = """
 Error verifying the success of the API documentation curl example.