コード例 #1
0
    def _parse_response(self, response_json):
        """Parse a raw JSON response into a response dict.

        :rtype: Dict[str, JobResult]
        """
        response = {}
        for identifier, result in response_json['results'].items():
            job = self.jobs[identifier]

            error = None
            if result['error']:
                error = HypernovaError(
                    name=result['error']['name'],
                    message=result['error']['message'],
                    stack=result['error']['stack'],
                )
                self.plugin_controller.on_error(error, {identifier: job},
                                                self.pyramid_request)

            html = result['html']
            if not html:
                html = render_blank_markup(identifier, job, True,
                                           self.json_encoder)

            response[identifier] = JobResult(error=error, html=html, job=job)
        return response
コード例 #2
0
    def test_batch_request_with_application_error(self, spy_plugin_controller, batch_request):
        job = Job(name='MyComponent.js', data={'foo': 'bar'})
        token = batch_request.render('MyComponent.js', {'foo': 'bar'})

        fake_response_json = {
            'error': {
                'name': 'SomeError',
                'message': 'yikes',
                'stack': ['line 1', 'line 2']
            }
        }

        with mock.patch('fido.fetch') as mock_fetch:
            mock_fetch.return_value.wait.return_value.json.return_value = fake_response_json
            response = batch_request.submit()

        if batch_request.max_batch_size is None:
            assert mock_fetch.call_count == 1
        else:
            # Division (rounded-up) up to get total number of calls
            jobs_count = len(batch_request.jobs)
            max_batch_size = batch_request.max_batch_size
            assert mock_fetch.call_count == (jobs_count + (max_batch_size - 1)) // max_batch_size

        assert response == {
            token.identifier: JobResult(
                error=HypernovaError(
                    name='SomeError',
                    message='yikes',
                    stack=['line 1', 'line 2'],
                ),
                html=render_blank_markup(token.identifier, job, True),
                job=job,
            ),
        }
コード例 #3
0
    def test_batch_request_with_unhealthy_service(self, spy_plugin_controller, test_data, batch_request):
        data = test_data[0]
        job = Job(name='MyComponent.js', data=data[0])
        token = batch_request.render('MyComponent.js', data[0])

        with mock.patch('fido.fetch') as mock_fetch:
            mock_fetch.return_value.wait.return_value.json.side_effect = NetworkError('oh no')
            response = batch_request.submit()

        if batch_request.max_batch_size is None:
            assert mock_fetch.call_count == 1
        else:
            # Division (rounded-up) up to get total number of calls
            jobs_count = len(batch_request.jobs)
            max_batch_size = batch_request.max_batch_size
            assert mock_fetch.call_count == (jobs_count + (max_batch_size - 1)) // max_batch_size

        assert response == {
            token.identifier: JobResult(
                error=HypernovaError(
                    name="<class 'fido.exceptions.NetworkError'>",
                    message='oh no',
                    stack=mock.ANY,
                ),
                html=render_blank_markup(token.identifier, job, True, batch_request.json_encoder),
                job=job,
            ),
        }
コード例 #4
0
def test_render_blank_markup_with_error():
    job = Job('MyCoolComponent.js', data={'title': 'sup'}, context={})
    markup = render_blank_markup('my-unique-token', job, True, JSONEncoder())

    assert markup == dedent('''
        <div data-hypernova-key="MyCoolComponentjs" data-hypernova-id="my-unique-token"></div>
        <script
          type="application/json"
          data-hypernova-key="MyCoolComponentjs"
          data-hypernova-id="my-unique-token"
        ><!--{"title": "sup"}--></script>

        <script type="text/javascript">
            (function () {
                function ServerSideRenderingError(component) {
                    this.name = 'ServerSideRenderingError';
                    this.component = component;
                }

                ServerSideRenderingError.prototype = Object.create(ServerSideRenderingError.prototype);
                ServerSideRenderingError.prototype.constructor = ServerSideRenderingError;

                throw new ServerSideRenderingError('MyCoolComponentjs failed to render server-side, and fell back to client-side rendering.');
            }());
        </script>
    ''')  # noqa: ignore=E501
コード例 #5
0
def create_fallback_response(jobs, throw_client_error, error=None):
    return {
        identifier: JobResult(
            error=error,
            html=render_blank_markup(identifier, job, throw_client_error),
            job=job,
        )
        for identifier, job in jobs.items()
    }
コード例 #6
0
def test_create_fallback_response(jobs, throw_client_error, json_encoder):
    expected_response = {
        identifier: JobResult(
            error=None,
            html=render_blank_markup(identifier, job, throw_client_error, json_encoder),
            job=job,
        )
        for identifier, job in jobs.items()
    }

    assert create_fallback_response(jobs, throw_client_error, json_encoder) == expected_response
コード例 #7
0
def test_render_blank_markup():
    job = Job('MyCoolComponent.js', data={'title': 'sup'}, context={})
    markup = render_blank_markup('my-unique-token', job, False, JSONEncoder())

    assert markup == dedent('''
        <div data-hypernova-key="MyCoolComponentjs" data-hypernova-id="my-unique-token"></div>
        <script
          type="application/json"
          data-hypernova-key="MyCoolComponentjs"
          data-hypernova-id="my-unique-token"
        ><!--{"title": "sup"}--></script>
    ''')
コード例 #8
0
    def test_batch_request_with_component_errors(self, spy_plugin_controller, test_data, batch_request):
        data = test_data[0]
        token_1 = batch_request.render('MyComponent1.js', data[0])
        token_2 = batch_request.render('MyComponent2.js', data[1])
        job_2 = Job(name='MyComponent2.js', data=data[1])

        fake_response_json = {
            'error': None,
            'results': {
                token_1.identifier: {
                    'error': None,
                    'html': '<div>wow such SSR</div>',
                },
                token_2.identifier: {
                    'error': {
                        'name': 'SomeError',
                        'message': 'we goofed',
                        'stack': ['line 1', 'line 2']
                    },
                    'html': None,
                }
            }
        }

        with mock.patch('fido.fetch') as mock_fetch:
            mock_fetch.return_value.wait.return_value.json.return_value = fake_response_json
            response = batch_request.submit()

        if batch_request.max_batch_size is None:
            assert mock_fetch.call_count == 1
        else:
            # Division (rounded-up) up to get total number of calls
            jobs_count = len(batch_request.jobs)
            max_batch_size = batch_request.max_batch_size
            assert mock_fetch.call_count == (jobs_count + (max_batch_size - 1)) // max_batch_size

        assert response == {
            token_1.identifier: JobResult(
                error=None,
                html='<div>wow such SSR</div>',
                job=Job(name='MyComponent1.js', data=data[0])
            ),
            token_2.identifier: JobResult(
                error=HypernovaError(
                    name='SomeError',
                    message='we goofed',
                    stack=['line 1', 'line 2'],
                ),
                html=render_blank_markup(token_2.identifier, job_2, True, batch_request.json_encoder),
                job=job_2,
            )
        }
コード例 #9
0
def test_render_blank_markup_with_custom_json_encoder():
    job = Job('MyCoolComponent.js', data={'a complex subject': 4.3 + 2.1j})
    markup = render_blank_markup('my-unique-token', job, False,
                                 ComplexJSONEncoder())

    assert markup == dedent('''
        <div data-hypernova-key="MyCoolComponentjs" data-hypernova-id="my-unique-token"></div>
        <script
          type="application/json"
          data-hypernova-key="MyCoolComponentjs"
          data-hypernova-id="my-unique-token"
        ><!--{"a complex subject": [4.3, 2.1]}--></script>
    ''')
コード例 #10
0
    def test_batch_request_with_application_error(
        self,
        spy_plugin_controller,
        test_data,
        batch_request,
        mock_hypernova_query,
    ):
        data = test_data[0]
        job = Job(name='MyComponent.js', data=data[0], context={})
        token = batch_request.render('MyComponent.js', data[0])

        fake_response_json = {
            'error': {
                'name': 'SomeError',
                'message': 'yikes',
                'stack': ['line 1', 'line 2']
            }
        }

        mock_hypernova_query.return_value.json.return_value = fake_response_json
        response = batch_request.submit()

        if batch_request.max_batch_size is None:
            assert mock_hypernova_query.call_count == 1
        else:
            # Division (rounded-up) up to get total number of calls
            jobs_count = len(batch_request.jobs)
            max_batch_size = batch_request.max_batch_size
            batch_count = (jobs_count + (max_batch_size - 1)) // max_batch_size
            assert mock_hypernova_query.call_count == batch_count
            mock_hypernova_query.assert_called_with(mock.ANY, mock.ANY,
                                                    mock.ANY, batch_count == 1,
                                                    {})

        assert response == {
            token.identifier:
            JobResult(
                error=HypernovaError(
                    name='SomeError',
                    message='yikes',
                    stack=['line 1', 'line 2'],
                ),
                html=render_blank_markup(token.identifier, job, True,
                                         batch_request.json_encoder),
                job=job,
            ),
        }
コード例 #11
0
def create_fallback_response(jobs,
                             throw_client_error,
                             json_encoder,
                             error=None):
    """Create a response dict for falling back to client-side rendering.

    :rtype: Dict[str, Job]
    """
    return {
        identifier: JobResult(
            error=error,
            html=render_blank_markup(identifier, job, throw_client_error,
                                     json_encoder),
            job=job,
        )
        for identifier, job in jobs.items()
    }
コード例 #12
0
    def test_batch_request_with_unhealthy_service(
        self,
        spy_plugin_controller,
        test_data,
        batch_request,
        mock_hypernova_query,
    ):
        data = test_data[0]
        job = Job(name='MyComponent.js', data=data[0], context={})
        token = batch_request.render('MyComponent.js', data[0])

        mock_hypernova_query.return_value.json.side_effect = HypernovaQueryError(
            'oh no')
        response = batch_request.submit()

        if batch_request.max_batch_size is None:
            assert mock_hypernova_query.call_count == 1
        else:
            # Division (rounded-up) up to get total number of calls
            jobs_count = len(batch_request.jobs)
            max_batch_size = batch_request.max_batch_size
            batch_count = (jobs_count + (max_batch_size - 1)) // max_batch_size
            assert mock_hypernova_query.call_count == batch_count
            mock_hypernova_query.assert_called_with(mock.ANY, mock.ANY,
                                                    mock.ANY, batch_count == 1,
                                                    {})

        assert response == {
            token.identifier:
            JobResult(
                error=HypernovaError(
                    name='HypernovaQueryError',
                    message='oh no',
                    stack=mock.ANY,
                ),
                html=render_blank_markup(token.identifier, job, True,
                                         batch_request.json_encoder),
                job=job,
            ),
        }
コード例 #13
0
def test_create_fallback_response(throw_client_error):
    jobs = {
        'some-unique-id': Job(
            name='FooBar.js',
            data={'baz': 1234},
        ),
        'some-other-unique-id': Job(
            name='MyComponent.js',
            data={'title': 'sup'},
        ),
    }

    expected_response = {
        identifier: JobResult(
            error=None,
            html=render_blank_markup(identifier, job, throw_client_error),
            job=job,
        )
        for identifier, job in jobs.items()
    }

    assert create_fallback_response(jobs, throw_client_error) == expected_response