mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Fixes #17795 In PR #17014, we added support for deactivate-own-user. And while doing so, we first deactivated the client and then reactivated it. But this implementation is a bit hacky. So, to fix this, we're now deactivating a test_user so that we don't have to reactivate it. We did so by changing the value of authentication_line. As we want to keep endpoint code out of the “test_curl_examples”, we changed the value of authentication_line in `curl_param_value_generators.py`. To work this out, we create a new global variable named AUTHENTICATION_LINE in “curl_param_value_generators.py” and change its value in function “deactivate_own_user” and to use this change in “test_curl_examples,” we import AUTHENTICATION_LINE. AUTHENTICATION_LINE is of list data type because we want a pointer to original mutable object so that changes made during run time show across the module. Another way to do this is to change the way we import variable, but that will be inconsistent to the way we had in all other files. To remove confusion between AUTHENTICATION_LINE and authentication_line we renamed authentication_line to default_authentication_line.
		
			
				
	
	
		
			111 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Zulip's OpenAPI-based API documentation system is documented at
 | 
						|
#   https://zulip.readthedocs.io/en/latest/documentation/api.html
 | 
						|
#
 | 
						|
# This file contains the top-level logic for testing the cURL examples
 | 
						|
# in Zulip's API documentation; the details are in
 | 
						|
# zerver.openapi.curl_param_value_generators.
 | 
						|
 | 
						|
import glob
 | 
						|
import html
 | 
						|
import json
 | 
						|
import shlex
 | 
						|
import subprocess
 | 
						|
 | 
						|
import markdown
 | 
						|
from zulip import Client
 | 
						|
 | 
						|
from zerver.models import get_realm
 | 
						|
from zerver.openapi import markdown_extension
 | 
						|
from zerver.openapi.curl_param_value_generators import (
 | 
						|
    AUTHENTICATION_LINE,
 | 
						|
    assert_all_helper_functions_called,
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
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(
 | 
						|
        extensions=[markdown_extension.makeExtension(api_url=realm.uri + "/api")]
 | 
						|
    )
 | 
						|
 | 
						|
    # We run our curl tests in alphabetical order (except that we
 | 
						|
    # delay the deactivate-user test to the very end), since we depend
 | 
						|
    # on "add" tests coming before "remove" tests in some cases.  We
 | 
						|
    # should try to either avoid ordering dependencies or make them
 | 
						|
    # very explicit.
 | 
						|
    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"):
 | 
						|
                    continue
 | 
						|
                # To do an end-to-end test on the documentation examples
 | 
						|
                # that will be actually shown to users, we use the
 | 
						|
                # Markdown rendering pipeline to compute the user-facing
 | 
						|
                # example, and then run that to test it.
 | 
						|
                curl_command_html = md_engine.convert(line.strip())
 | 
						|
                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[0]
 | 
						|
                )
 | 
						|
 | 
						|
                print("Testing {} ...".format(curl_command_text.split("\n")[0]))
 | 
						|
 | 
						|
                # Turn the text into an arguments list.
 | 
						|
                generated_curl_command = [x for x in shlex.split(curl_command_text) if x != "\n"]
 | 
						|
 | 
						|
                response_json = None
 | 
						|
                response = None
 | 
						|
                try:
 | 
						|
                    # We split this across two lines so if curl fails and
 | 
						|
                    # returns non-JSON output, we'll still print it.
 | 
						|
                    response_json = subprocess.check_output(
 | 
						|
                        generated_curl_command, universal_newlines=True
 | 
						|
                    )
 | 
						|
                    response = json.loads(response_json)
 | 
						|
                    assert response["result"] == "success"
 | 
						|
                except (AssertionError, Exception):
 | 
						|
                    error_template = """
 | 
						|
Error verifying the success of the API documentation curl example.
 | 
						|
 | 
						|
File: {file_name}
 | 
						|
Line: {line}
 | 
						|
Curl command:
 | 
						|
{curl_command}
 | 
						|
Response:
 | 
						|
{response}
 | 
						|
 | 
						|
This test is designed to check each generate_code_example(curl) instance in the
 | 
						|
API documentation for success. If this fails then it means that the curl example
 | 
						|
that was generated was faulty and when tried, it resulted in an unsuccessful
 | 
						|
response.
 | 
						|
 | 
						|
Common reasons for why this could occur:
 | 
						|
    1. One or more example values in zerver/openapi/zulip.yaml for this endpoint
 | 
						|
       do not line up with the values in the test database.
 | 
						|
    2. One or more mandatory parameters were included in the "exclude" list.
 | 
						|
 | 
						|
To learn more about the test itself, see zerver/openapi/test_curl_examples.py.
 | 
						|
"""
 | 
						|
                    print(
 | 
						|
                        error_template.format(
 | 
						|
                            file_name=file_name,
 | 
						|
                            line=line,
 | 
						|
                            curl_command=generated_curl_command,
 | 
						|
                            response=response_json
 | 
						|
                            if response is None
 | 
						|
                            else json.dumps(response, indent=4),
 | 
						|
                        )
 | 
						|
                    )
 | 
						|
                    raise
 | 
						|
 | 
						|
    assert_all_helper_functions_called()
 |