Example #1
0
    def test_get_fixture_http_headers_for_error_handling(
            self, import_module_mock: MagicMock) -> None:
        fake_module = SimpleNamespace()
        import_module_mock.return_value = fake_module

        with self.assertRaises(AttributeError):
            get_fixture_http_headers("some_integration", "simple_fixture")
def send_all_webhook_fixture_messages(
    request: HttpRequest, url: str = REQ(), integration_name: str = REQ()
) -> HttpResponse:
    fixtures_dir = os.path.join(
        ZULIP_PATH, "zerver/webhooks/{integration_name}/fixtures".format(
            integration_name=integration_name))
    if not os.path.exists(fixtures_dir):
        msg = ("The integration \"{integration_name}\" does not have fixtures."
               ).format(integration_name=integration_name)
        return json_error(msg, status=404)

    responses = []
    for fixture in os.listdir(fixtures_dir):
        fixture_path = os.path.join(fixtures_dir, fixture)
        with open(fixture_path, 'r') as f:
            content = f.read()
        x = fixture.split(".")
        fixture_name, fixture_format = "".join(_ for _ in x[:-1]), x[-1]
        headers = get_fixture_http_headers(integration_name, fixture_name)
        if fixture_format == "json":
            is_json = True
        else:
            is_json = False
        response = send_webhook_fixture_message(url, content, is_json, headers)
        responses.append({
            "status_code": response.status_code,
            "fixture_name": fixture,
            "message": response.content
        })
    return json_success({"responses": responses})
Example #3
0
    def send_and_test_private_message(
        self,
        fixture_name: str,
        expected_topic: Optional[str] = None,
        expected_message: Optional[str] = None,
        content_type: Optional[str] = "application/json",
        **kwargs: Any,
    ) -> Message:
        payload = self.get_body(fixture_name)
        if content_type is not None:
            kwargs['content_type'] = content_type
        if self.FIXTURE_DIR_NAME is not None:
            headers = get_fixture_http_headers(self.FIXTURE_DIR_NAME,
                                               fixture_name)
            headers = standardize_headers(headers)
            kwargs.update(headers)
        # The sender profile shouldn't be passed any further in kwargs, so we pop it.
        sender = kwargs.pop('sender', self.test_user)
        msg = self.send_json_payload(sender,
                                     self.url,
                                     payload,
                                     stream_name=None,
                                     **kwargs)
        self.do_test_message(msg, expected_message)

        return msg
Example #4
0
    def send_and_test_private_message(
        self,
        fixture_name: str,
        expected_message: str,
        content_type: str = "application/json",
        **kwargs: Any,
    ) -> Message:
        """
        For the rare cases that you are testing a webhook that sends
        private messages, use this function.

        Most webhooks send to streams, and you will want to look at
        check_webhook.
        """
        payload = self.get_payload(fixture_name)
        kwargs['content_type'] = content_type

        if self.FIXTURE_DIR_NAME is not None:
            headers = get_fixture_http_headers(self.FIXTURE_DIR_NAME, fixture_name)
            headers = standardize_headers(headers)
            kwargs.update(headers)
        # The sender profile shouldn't be passed any further in kwargs, so we pop it.
        sender = kwargs.pop('sender', self.test_user)

        msg = self.send_webhook_payload(
            sender,
            self.url,
            payload,
            **kwargs,
        )
        self.assertEqual(msg.content, expected_message)

        return msg
Example #5
0
def get_fixtures(request: HttpResponse,
                 integration_name: str=REQ()) -> HttpResponse:
    integrations = get_webhook_integrations()
    if integration_name not in integrations:
        return json_error("\"{integration_name}\" is not a valid webhook integration.".format(
            integration_name=integration_name), status=404)

    fixtures = {}
    fixtures_dir = os.path.join(ZULIP_PATH, "zerver/webhooks/{integration_name}/fixtures".format(
        integration_name=integration_name))
    if not os.path.exists(fixtures_dir):
        msg = ("The integration \"{integration_name}\" does not have fixtures.").format(
            integration_name=integration_name)
        return json_error(msg, status=404)

    for fixture in os.listdir(fixtures_dir):
        fixture_path = os.path.join(fixtures_dir, fixture)
        body = open(fixture_path).read()
        try:
            body = ujson.loads(body)
        except ValueError:
            pass  # The file extension will be used to determine the type.

        headers_raw = get_fixture_http_headers(integration_name,
                                               "".join(fixture.split(".")[:-1]))
        headers = {}
        for header in headers_raw:
            if header.startswith("HTTP_"):  # HTTP_ is a prefix intended for Django.
                headers[header.lstrip("HTTP_")] = headers_raw[header]
            else:
                headers[header] = headers_raw[header]

        fixtures[fixture] = {"body": body, "headers": headers}

    return json_success({"fixtures": fixtures})
Example #6
0
def get_fixtures(request: HttpResponse,
                 integration_name: str=REQ()) -> HttpResponse:
    valid_integration_name = get_valid_integration_name(integration_name)
    if not valid_integration_name:
        return json_error(f"\"{integration_name}\" is not a valid webhook integration.", status=404)

    fixtures = {}
    fixtures_dir = os.path.join(ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
    if not os.path.exists(fixtures_dir):
        msg = ("The integration \"{valid_integration_name}\" does not have fixtures.").format(
            valid_integration_name=valid_integration_name)
        return json_error(msg, status=404)

    for fixture in os.listdir(fixtures_dir):
        fixture_path = os.path.join(fixtures_dir, fixture)
        with open(fixture_path) as f:
            body = f.read()
        try:
            body = orjson.loads(body)
        except orjson.JSONDecodeError:
            pass  # The file extension will be used to determine the type.

        headers_raw = get_fixture_http_headers(valid_integration_name,
                                               "".join(fixture.split(".")[:-1]))

        def fix_name(header: str) -> str:
            if header.startswith("HTTP_"):  # HTTP_ is a prefix intended for Django.
                return header[len("HTTP_"):]
            return header

        headers = {fix_name(k): v for k, v in headers_raw.items()}
        fixtures[fixture] = {"body": body, "headers": headers}

    return json_success({"fixtures": fixtures})
Example #7
0
    def test_get_fixture_http_headers_with_no_fixtures_to_headers_function(
            self, import_module_mock: MagicMock) -> None:

        fake_module = SimpleNamespace()
        import_module_mock.return_value = fake_module

        self.assertEqual(
            get_fixture_http_headers("some_integration", "simple_fixture"), {})
Example #8
0
    def test_get_fixture_http_headers_for_success(self, import_module_mock: MagicMock) -> None:
        def fixture_to_headers(fixture_name: str) -> Dict[str, str]:
            # A sample function which would normally perform some
            # extra operations before returning a dictionary
            # corresponding to the fixture name passed. For this test,
            # we just return a fixed dictionary.
            return {"key": "value"}

        fake_module = SimpleNamespace(fixture_to_headers=fixture_to_headers)
        import_module_mock.return_value = fake_module

        headers = get_fixture_http_headers("some_integration", "complex_fixture")
        self.assertEqual(headers, {"key": "value"})
Example #9
0
    def check_webhook(
        self,
        fixture_name: str,
        expected_topic: str,
        expected_message: str,
        content_type: Optional[str] = "application/json",
        **kwargs: Any,
    ) -> None:
        """
        check_webhook is the main way to test "normal" webhooks that
        work by receiving a payload from a third party and then writing
        some message to a Zulip stream.

        We use `fixture_name` to find the payload data in of our test
        fixtures.  Then we verify that a message gets sent to a stream:

            self.STREAM_NAME: stream name
            expected_topic: topic
            expected_message: content

        We simulate the delivery of the payload with `content_type`,
        and you can pass other headers via `kwargs`.

        For the rare cases of webhooks actually sending private messages,
        see send_and_test_private_message.
        """
        assert self.STREAM_NAME is not None
        self.subscribe(self.test_user, self.STREAM_NAME)

        payload = self.get_payload(fixture_name)
        if content_type is not None:
            kwargs['content_type'] = content_type
        if self.FIXTURE_DIR_NAME is not None:
            headers = get_fixture_http_headers(self.FIXTURE_DIR_NAME,
                                               fixture_name)
            headers = standardize_headers(headers)
            kwargs.update(headers)

        msg = self.send_webhook_payload(
            self.test_user,
            self.url,
            payload,
            **kwargs,
        )

        self.assert_stream_message(
            message=msg,
            stream_name=self.STREAM_NAME,
            topic_name=expected_topic,
            content=expected_message,
        )
Example #10
0
    def send_and_test_stream_message(self, fixture_name: str, expected_topic: Optional[str]=None,
                                     expected_message: Optional[str]=None,
                                     content_type: Optional[str]="application/json", **kwargs: Any) -> Message:
        payload = self.get_body(fixture_name)
        if content_type is not None:
            kwargs['content_type'] = content_type
        headers = get_fixture_http_headers(self.FIXTURE_DIR_NAME, fixture_name)
        headers = standardize_headers(headers)
        kwargs.update(headers)
        msg = self.send_json_payload(self.test_user, self.url, payload,
                                     self.STREAM_NAME, **kwargs)
        self.do_test_topic(msg, expected_topic)
        self.do_test_message(msg, expected_message)

        return msg
Example #11
0
    def send_and_test_private_message(self,
                                      fixture_name: str,
                                      expected_topic: str = None,
                                      expected_message: str = None,
                                      content_type: str = "application/json",
                                      **kwargs: Any) -> Message:
        payload = self.get_body(fixture_name)
        if content_type is not None:
            kwargs['content_type'] = content_type
        headers = get_fixture_http_headers(self.FIXTURE_DIR_NAME, fixture_name)
        headers = parse_headers_dict(headers)
        kwargs.update(headers)
        sender = kwargs.get('sender', self.test_user)
        msg = self.send_json_payload(sender,
                                     self.url,
                                     payload,
                                     stream_name=None,
                                     **kwargs)
        self.do_test_message(msg, expected_message)

        return msg
Example #12
0
def send_all_webhook_fixture_messages(
    request: HttpRequest, url: str = REQ(), integration_name: str = REQ()
) -> HttpResponse:
    valid_integration_name = get_valid_integration_name(integration_name)
    if not valid_integration_name:
        raise ResourceNotFoundError(
            f'"{integration_name}" is not a valid webhook integration.')

    fixtures_dir = os.path.join(
        ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
    if not os.path.exists(fixtures_dir):
        msg = (
            'The integration "{valid_integration_name}" does not have fixtures.'
        ).format(valid_integration_name=valid_integration_name)
        raise ResourceNotFoundError(msg)

    responses = []
    for fixture in os.listdir(fixtures_dir):
        fixture_path = os.path.join(fixtures_dir, fixture)
        with open(fixture_path) as f:
            content = f.read()
        x = fixture.split(".")
        fixture_name, fixture_format = "".join(_ for _ in x[:-1]), x[-1]
        headers = get_fixture_http_headers(valid_integration_name,
                                           fixture_name)
        if fixture_format == "json":
            is_json = True
        else:
            is_json = False
        response = send_webhook_fixture_message(url, content, is_json, headers)
        responses.append({
            "status_code": response.status_code,
            "fixture_name": fixture,
            "message": response.content.decode(),
        })
    return json_success({"responses": responses})
Example #13
0
 def test_get_fixture_http_headers_for_non_existent_integration(
         self) -> None:
     headers = get_fixture_http_headers(
         "some_random_nonexistent_integration", "fixture_name")
     self.assertEqual(headers, {})