<commit_before>"""Test Blueprint extra features"""

import json
import pytest

from flask import jsonify
from flask.views import MethodView

from flask_rest_api import Api
from flask_rest_api.blueprint import Blueprint, HTTP_METHODS
from flask_rest_api.exceptions import InvalidLocationError

LOCATIONS_MAPPING = (
    ('querystring', 'query',),
    ('query', 'query',),
    ('json', 'body',),
    ('form', 'formData',),
    ('headers', 'header',),
    ('files', 'formData',),
)

class TestBlueprint():
    """Test Blueprint class"""

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    @pytest.mark.parametrize(
        # Also test 'json/body' is default
        'location_map', LOCATIONS_MAPPING + ((None, 'body'),))
    def test_blueprint_arguments_location(
            self, app, schemas, location_map, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, openapi_location = location_map

        if location is not None:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                """Dummy view func"""
        else:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema)
            def func():
                """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/']['get']
        if openapi_location != 'body' or openapi_version == '2.0':
            loc = get['parameters'][0]['in']
            assert loc == openapi_location
            assert 'requestBody' not in get
        else:
            # In OpenAPI v3, 'body' parameter is in 'requestBody'
            assert 'parameters' not in get
            assert 'requestBody' in get

    def test_blueprint_arguments_location_invalid(self, app, schemas):
        blp = Blueprint('test', __name__, url_prefix='/test')
        with pytest.raises(InvalidLocationError):
            blp.arguments(schemas.DocSchema, location='invalid')

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    @pytest.mark.parametrize('location_map', LOCATIONS_MAPPING)
    @pytest.mark.parametrize('required', (True, False, None))
    def test_blueprint_arguments_required(
            self, app, schemas, required, location_map, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, _ = location_map

        if required is None:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                pass
        else:
            @blp.route('/')
            @blp.arguments(
                schemas.DocSchema, required=required, location=location)
            def func():
                pass

        api.register_blueprint(blp)
        get = api.spec.to_dict()['paths']['/test/']['get']
        if location == 'json':
            if openapi_version == '2.0':
                parameters = get['parameters']
                # One parameter: the schema
                assert len(parameters) == 1
                assert 'schema' in parameters[0]
                assert 'requestBody' not in get
                # Check required defaults to True
                assert parameters[0]['required'] == (required is not False)
            else:
                # Body parameter in 'requestBody'
                assert 'requestBody' in get
                # Check required defaults to True
                assert get['requestBody']['required'] == (
                    required is not False)
        else:
            parameters = get['parameters']
            # One parameter: the 'field' field in DocSchema
            assert len(parameters) == 1
            assert parameters[0]['name'] == 'field'
            assert 'requestBody' not in get
            # Check the required parameter has no impact.
            # Only the required attribute of the field matters
            assert parameters[0]['required'] is False

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    def test_blueprint_arguments_multiple(self, app, schemas, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/', methods=('POST', ))
        @blp.arguments(schemas.DocSchema)
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        def func(document, query_args):
            return jsonify({
                'document': document,
                'query_args': query_args,
            })

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['post']['parameters']
        assert parameters[0]['name'] == 'arg1'
        assert parameters[0]['in'] == 'query'
        assert parameters[1]['name'] == 'arg2'
        assert parameters[1]['in'] == 'query'

        if openapi_version == '2.0':
            assert len(parameters) == 3
            assert parameters[2]['in'] == 'body'
            assert 'field' in parameters[2]['schema']['properties']
        else:
            assert len(parameters) == 2
            assert 'field' in spec['paths']['/test/']['post']['requestBody'][
                'content']['application/json']['schema']['properties']

        # Check parameters are passed as arguments to view function
        item_data = {'field': 12}
        response = client.post(
            '/test/',
            data=json.dumps(item_data),
            content_type='application/json',
            query_string={'arg1': 'test'}
        )
        assert response.status_code == 200
        assert response.json == {
            'document': {'db_field': 12},
            'query_args': {'arg1': 'test'},
        }

    @pytest.mark.parametrize('openapi_version', ['2.0', '3.0.1'])
    def test_blueprint_response_schema(self, app, openapi_version, schemas):
        """Check response schema is correctly documented.

        More specifically, check that:
        - plural response is documented as array in the spec
        - schema is document in the right place w.r.t. OpenAPI version
        """
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        api.definition('Doc')(schemas.DocSchema)

        @blp.route('/schema_many_false')
        @blp.response(schemas.DocSchema(many=False))
        def many_false():
            pass

        @blp.route('/schema_many_true')
        @blp.response(schemas.DocSchema(many=True))
        def many_true():
            pass

        api.register_blueprint(blp)

        paths = api.spec.to_dict()['paths']

        response = paths['/test/schema_many_false']['get']['responses'][200]
        if openapi_version == '2.0':
            schema = response['schema']
            assert schema == {'$ref': '#/definitions/Doc'}
        else:
            schema = (
                response['content']['application/json']['schema'])
            assert schema == {'$ref': '#/components/schemas/Doc'}

        response = paths['/test/schema_many_true']['get']['responses'][200]
        if openapi_version == '2.0':
            schema = response['schema']['items']
            assert schema == {'$ref': '#/definitions/Doc'}
        else:
            schema = (
                response['content']['application/json']['schema']['items'])
            assert schema == {'$ref': '#/components/schemas/Doc'}

    def test_blueprint_pagination(self, app, schemas):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        @blp.paginate()
        def func():
            """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['get']['parameters']
        # Page
        assert parameters[0]['name'] == 'page'
        assert parameters[0]['in'] == 'query'
        assert parameters[0]['type'] == 'integer'
        assert parameters[0]['required'] is False
        assert parameters[0]['default'] == 1
        assert parameters[0]['minimum'] == 1
        # Page size
        assert parameters[1]['name'] == 'page_size'
        assert parameters[1]['in'] == 'query'
        assert parameters[1]['type'] == 'integer'
        assert parameters[1]['required'] is False
        assert parameters[1]['default'] == 10
        assert parameters[1]['minimum'] == 1
        assert parameters[1]['maximum'] == 100
        # Other query string parameters
        assert parameters[1]['in'] == 'query'
        assert parameters[2]['name'] == 'arg1'
        assert parameters[2]['in'] == 'query'
        assert parameters[3]['name'] == 'arg2'
        assert parameters[3]['in'] == 'query'

    def test_blueprint_doc_function(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/', methods=('PUT', 'PATCH', ))
        @blp.doc(summary='Dummy func', description='Do dummy stuff')
        def view_func():
            pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        for method in ('put', 'patch', ):
            assert path[method]['summary'] == 'Dummy func'
            assert path[method]['description'] == 'Do dummy stuff'

    def test_blueprint_doc_method_view(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            @blp.doc(summary='Dummy put', description='Do dummy put')
            def put(self):
                pass

            @blp.doc(summary='Dummy patch', description='Do dummy patch')
            def patch(self):
                pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        for method in ('put', 'patch', ):
            assert path[method]['summary'] == 'Dummy {}'.format(method)
            assert path[method]['description'] == 'Do dummy {}'.format(method)

    def test_blueprint_doc_info_from_docstring(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            def get(self):
                """Docstring get summary"""

            def put(self):
                """Docstring put summary

                Docstring put description
                """

            @blp.doc(
                summary='Decorator patch summary',
                description='Decorator patch description'
            )
            def patch(self):
                """Docstring patch summary

                Docstring patch description
                """

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']

        assert path['get']['summary'] == 'Docstring get summary'
        assert 'description' not in path['get']
        assert path['put']['summary'] == 'Docstring put summary'
        assert path['put']['description'] == 'Docstring put description'
        # @doc decorator overrides docstring
        assert path['patch']['summary'] == 'Decorator patch summary'
        assert path['patch']['description'] == 'Decorator patch description'

    def test_blueprint_enforce_method_order(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            def post(self):
                pass

            def put(self):
                pass

            def options(self):
                pass

            def patch(self):
                pass

            def head(self):
                pass

            def delete(self):
                pass

            def get(self):
                pass

        api.register_blueprint(blp)
        methods_spec = api.spec.to_dict()['paths']['/test/']
        assert list(methods_spec.keys()) == [m.lower() for m in HTTP_METHODS]

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    def test_blueprint_multiple_routes_per_view_func(
            self, app, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        def func():
            pass

        # Blueprint.route ensures a different endpoint is used for each route.
        # Otherwise, the second call would erase the doc from the first.
        blp.route('/route_1')(blp.doc(description='Route 1')(func))
        blp.route('/route_2')(blp.doc(description='Route 2')(func))

        api.register_blueprint(blp)
        paths = api.spec.to_dict()['paths']

        assert paths['/test/route_1']['get']['description'] == 'Route 1'
        assert paths['/test/route_2']['get']['description'] == 'Route 2'

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    def test_blueprint_multiple_routes_per_method_view(
            self, app, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        # Blueprint.route ensures a different endpoint is used for each route.
        # Otherwise, this would break in Blueprint.route when calling as_view
        # for the second time with the same endpoint.
        @blp.route('/route_1')
        @blp.route('/route_2')
        class Resource(MethodView):

            def get(self):
                pass

        api.register_blueprint(blp)
        paths = api.spec.to_dict()['paths']

        assert 'get' in paths['/test/route_1']
        assert 'get' in paths['/test/route_2']
<commit_msg>Don't call Blueprint.route on same view func with different decorators<commit_after>"""Test Blueprint extra features"""

import json
import pytest

from flask import jsonify
from flask.views import MethodView

from flask_rest_api import Api
from flask_rest_api.blueprint import Blueprint, HTTP_METHODS
from flask_rest_api.exceptions import InvalidLocationError

LOCATIONS_MAPPING = (
    ('querystring', 'query',),
    ('query', 'query',),
    ('json', 'body',),
    ('form', 'formData',),
    ('headers', 'header',),
    ('files', 'formData',),
)

class TestBlueprint():
    """Test Blueprint class"""

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    @pytest.mark.parametrize(
        # Also test 'json/body' is default
        'location_map', LOCATIONS_MAPPING + ((None, 'body'),))
    def test_blueprint_arguments_location(
            self, app, schemas, location_map, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, openapi_location = location_map

        if location is not None:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                """Dummy view func"""
        else:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema)
            def func():
                """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/']['get']
        if openapi_location != 'body' or openapi_version == '2.0':
            loc = get['parameters'][0]['in']
            assert loc == openapi_location
            assert 'requestBody' not in get
        else:
            # In OpenAPI v3, 'body' parameter is in 'requestBody'
            assert 'parameters' not in get
            assert 'requestBody' in get

    def test_blueprint_arguments_location_invalid(self, app, schemas):
        blp = Blueprint('test', __name__, url_prefix='/test')
        with pytest.raises(InvalidLocationError):
            blp.arguments(schemas.DocSchema, location='invalid')

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    @pytest.mark.parametrize('location_map', LOCATIONS_MAPPING)
    @pytest.mark.parametrize('required', (True, False, None))
    def test_blueprint_arguments_required(
            self, app, schemas, required, location_map, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, _ = location_map

        if required is None:
            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                pass
        else:
            @blp.route('/')
            @blp.arguments(
                schemas.DocSchema, required=required, location=location)
            def func():
                pass

        api.register_blueprint(blp)
        get = api.spec.to_dict()['paths']['/test/']['get']
        if location == 'json':
            if openapi_version == '2.0':
                parameters = get['parameters']
                # One parameter: the schema
                assert len(parameters) == 1
                assert 'schema' in parameters[0]
                assert 'requestBody' not in get
                # Check required defaults to True
                assert parameters[0]['required'] == (required is not False)
            else:
                # Body parameter in 'requestBody'
                assert 'requestBody' in get
                # Check required defaults to True
                assert get['requestBody']['required'] == (
                    required is not False)
        else:
            parameters = get['parameters']
            # One parameter: the 'field' field in DocSchema
            assert len(parameters) == 1
            assert parameters[0]['name'] == 'field'
            assert 'requestBody' not in get
            # Check the required parameter has no impact.
            # Only the required attribute of the field matters
            assert parameters[0]['required'] is False

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    def test_blueprint_arguments_multiple(self, app, schemas, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/', methods=('POST', ))
        @blp.arguments(schemas.DocSchema)
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        def func(document, query_args):
            return jsonify({
                'document': document,
                'query_args': query_args,
            })

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['post']['parameters']
        assert parameters[0]['name'] == 'arg1'
        assert parameters[0]['in'] == 'query'
        assert parameters[1]['name'] == 'arg2'
        assert parameters[1]['in'] == 'query'

        if openapi_version == '2.0':
            assert len(parameters) == 3
            assert parameters[2]['in'] == 'body'
            assert 'field' in parameters[2]['schema']['properties']
        else:
            assert len(parameters) == 2
            assert 'field' in spec['paths']['/test/']['post']['requestBody'][
                'content']['application/json']['schema']['properties']

        # Check parameters are passed as arguments to view function
        item_data = {'field': 12}
        response = client.post(
            '/test/',
            data=json.dumps(item_data),
            content_type='application/json',
            query_string={'arg1': 'test'}
        )
        assert response.status_code == 200
        assert response.json == {
            'document': {'db_field': 12},
            'query_args': {'arg1': 'test'},
        }

    @pytest.mark.parametrize('openapi_version', ['2.0', '3.0.1'])
    def test_blueprint_response_schema(self, app, openapi_version, schemas):
        """Check response schema is correctly documented.

        More specifically, check that:
        - plural response is documented as array in the spec
        - schema is document in the right place w.r.t. OpenAPI version
        """
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        api.definition('Doc')(schemas.DocSchema)

        @blp.route('/schema_many_false')
        @blp.response(schemas.DocSchema(many=False))
        def many_false():
            pass

        @blp.route('/schema_many_true')
        @blp.response(schemas.DocSchema(many=True))
        def many_true():
            pass

        api.register_blueprint(blp)

        paths = api.spec.to_dict()['paths']

        response = paths['/test/schema_many_false']['get']['responses'][200]
        if openapi_version == '2.0':
            schema = response['schema']
            assert schema == {'$ref': '#/definitions/Doc'}
        else:
            schema = (
                response['content']['application/json']['schema'])
            assert schema == {'$ref': '#/components/schemas/Doc'}

        response = paths['/test/schema_many_true']['get']['responses'][200]
        if openapi_version == '2.0':
            schema = response['schema']['items']
            assert schema == {'$ref': '#/definitions/Doc'}
        else:
            schema = (
                response['content']['application/json']['schema']['items'])
            assert schema == {'$ref': '#/components/schemas/Doc'}

    def test_blueprint_pagination(self, app, schemas):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        @blp.paginate()
        def func():
            """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['get']['parameters']
        # Page
        assert parameters[0]['name'] == 'page'
        assert parameters[0]['in'] == 'query'
        assert parameters[0]['type'] == 'integer'
        assert parameters[0]['required'] is False
        assert parameters[0]['default'] == 1
        assert parameters[0]['minimum'] == 1
        # Page size
        assert parameters[1]['name'] == 'page_size'
        assert parameters[1]['in'] == 'query'
        assert parameters[1]['type'] == 'integer'
        assert parameters[1]['required'] is False
        assert parameters[1]['default'] == 10
        assert parameters[1]['minimum'] == 1
        assert parameters[1]['maximum'] == 100
        # Other query string parameters
        assert parameters[1]['in'] == 'query'
        assert parameters[2]['name'] == 'arg1'
        assert parameters[2]['in'] == 'query'
        assert parameters[3]['name'] == 'arg2'
        assert parameters[3]['in'] == 'query'

    def test_blueprint_doc_function(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/', methods=('PUT', 'PATCH', ))
        @blp.doc(summary='Dummy func', description='Do dummy stuff')
        def view_func():
            pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        for method in ('put', 'patch', ):
            assert path[method]['summary'] == 'Dummy func'
            assert path[method]['description'] == 'Do dummy stuff'

    def test_blueprint_doc_method_view(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            @blp.doc(summary='Dummy put', description='Do dummy put')
            def put(self):
                pass

            @blp.doc(summary='Dummy patch', description='Do dummy patch')
            def patch(self):
                pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        for method in ('put', 'patch', ):
            assert path[method]['summary'] == 'Dummy {}'.format(method)
            assert path[method]['description'] == 'Do dummy {}'.format(method)

    def test_blueprint_doc_info_from_docstring(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            def get(self):
                """Docstring get summary"""

            def put(self):
                """Docstring put summary

                Docstring put description
                """

            @blp.doc(
                summary='Decorator patch summary',
                description='Decorator patch description'
            )
            def patch(self):
                """Docstring patch summary

                Docstring patch description
                """

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']

        assert path['get']['summary'] == 'Docstring get summary'
        assert 'description' not in path['get']
        assert path['put']['summary'] == 'Docstring put summary'
        assert path['put']['description'] == 'Docstring put description'
        # @doc decorator overrides docstring
        assert path['patch']['summary'] == 'Decorator patch summary'
        assert path['patch']['description'] == 'Decorator patch description'

    def test_blueprint_enforce_method_order(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        class Resource(MethodView):

            def post(self):
                pass

            def put(self):
                pass

            def options(self):
                pass

            def patch(self):
                pass

            def head(self):
                pass

            def delete(self):
                pass

            def get(self):
                pass

        api.register_blueprint(blp)
        methods_spec = api.spec.to_dict()['paths']['/test/']
        assert list(methods_spec.keys()) == [m.lower() for m in HTTP_METHODS]

    @pytest.mark.parametrize('openapi_version', ('2.0', '3.0.1'))
    @pytest.mark.parametrize('as_method_view', (True, False))
    def test_blueprint_multiple_routes_per_view(
            self, app, as_method_view, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        if as_method_view:
            # Blueprint.route ensures a different endpoint is used for each
            # route. Otherwise, this would break in Blueprint.route when
            # calling as_view for the second time with the same endpoint.
            @blp.route('/route_1')
            @blp.route('/route_2')
            class Resource(MethodView):

                def get(self):
                    pass

        else:
            @blp.route('/route_1')
            @blp.route('/route_2')
            def func():
                pass

        api.register_blueprint(blp)
        paths = api.spec.to_dict()['paths']

        assert 'get' in paths['/test/route_1']
        assert 'get' in paths['/test/route_2']
<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function

from tests.core import mock
from trakt import Trakt
from trakt.interfaces.calendars import Base

from datetime import date, datetime
from dateutil.tz import tzutc
from hamcrest import *
from httmock import HTTMock
import pytest

def test_all_dvd():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/dvd'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_all_movies():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/movies'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_all_shows():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(4))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 4),
        'first_aired': datetime(2014, 7, 14, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E03
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 3),
        'first_aired': datetime(2014, 7, 14, 2, tzinfo=tzutc())
    }))

    # True Blood S07E05
    assert_that(items[2], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 5),
        'first_aired': datetime(2014, 7, 21, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E04
    assert_that(items[3], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 4),
        'first_aired': datetime(2014, 7, 21, 2, tzinfo=tzutc())
    }))

def test_all_shows_new():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].new()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(1))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

def test_all_shows_premieres():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].premieres()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(2))

    # The Leftovers S01E01
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

    # The Walking Dead S05E01
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '153021'),
            'title': 'The Walking Dead',
            'year': 2010
        }),

        'pk': (5, 1),
        'first_aired': datetime(2014, 10, 13, 1, tzinfo=tzutc())
    }))

def test_my_dvd():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/dvd'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_my_movies():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/movies'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_my_shows():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(4))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 4),
        'first_aired': datetime(2014, 7, 14, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E03
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 3),
        'first_aired': datetime(2014, 7, 14, 2, tzinfo=tzutc())
    }))

    # True Blood S07E05
    assert_that(items[2], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 5),
        'first_aired': datetime(2014, 7, 21, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E04
    assert_that(items[3], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 4),
        'first_aired': datetime(2014, 7, 21, 2, tzinfo=tzutc())
    }))

def test_my_shows_new():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].new()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(1))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

def test_my_shows_premieres():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].premieres()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(2))

    # The Leftovers S01E01
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

    # The Walking Dead S05E01
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '153021'),
            'title': 'The Walking Dead',
            'year': 2010
        }),

        'pk': (5, 1),
        'first_aired': datetime(2014, 10, 13, 1, tzinfo=tzutc())
    }))

def test_new_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Trakt['calendars/all/dvd'].new()

        with pytest.raises(ValueError):
            Trakt['calendars/all/movies'].new()

def test_premieres_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Trakt['calendars/all/dvd'].premieres()

        with pytest.raises(ValueError):
            Trakt['calendars/all/movies'].premieres()

def test_get_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Base(None).get('invalid', 'movies')

        with pytest.raises(ValueError):
            Base(None).get('all', 'invalid')

def test_start_date():
    with HTTMock(mock.calendars_all_period, mock.unknown):
        items = Trakt['calendars/all/movies'].get(start_date=datetime(2015, 10, 15))

    assert_that(items, not_none())

def test_days():
    with HTTMock(mock.calendars_all_period, mock.unknown):
        items = Trakt['calendars/all/movies'].get(days=14)

    assert_that(items, not_none())
<commit_msg>Ignored warnings for hamcrest in [tests/test_calendars.py]<commit_after># flake8: noqa: F403, F405
from __future__ import absolute_import, division, print_function

from tests.core import mock
from trakt import Trakt
from trakt.interfaces.calendars import Base

from datetime import date, datetime
from dateutil.tz import tzutc
from hamcrest import *
from httmock import HTTMock
import pytest

def test_all_dvd():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/dvd'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_all_movies():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/movies'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_all_shows():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(4))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 4),
        'first_aired': datetime(2014, 7, 14, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E03
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 3),
        'first_aired': datetime(2014, 7, 14, 2, tzinfo=tzutc())
    }))

    # True Blood S07E05
    assert_that(items[2], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 5),
        'first_aired': datetime(2014, 7, 21, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E04
    assert_that(items[3], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 4),
        'first_aired': datetime(2014, 7, 21, 2, tzinfo=tzutc())
    }))

def test_all_shows_new():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].new()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(1))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

def test_all_shows_premieres():
    with HTTMock(mock.fixtures, mock.unknown):
        items = Trakt['calendars/all/shows'].premieres()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(2))

    # The Leftovers S01E01
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

    # The Walking Dead S05E01
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '153021'),
            'title': 'The Walking Dead',
            'year': 2010
        }),

        'pk': (5, 1),
        'first_aired': datetime(2014, 10, 13, 1, tzinfo=tzutc())
    }))

def test_my_dvd():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/dvd'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_my_movies():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/movies'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(3))

    # Guardians of the Galaxy (2014)
    assert_that(items[0], has_properties({
        'pk': ('imdb', 'tt2015381'),
        'title': u'Guardians of the Galaxy',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Get On Up (2014)
    assert_that(items[1], has_properties({
        'pk': ('imdb', 'tt2473602'),
        'title': u'Get On Up',
        'year': 2014,

        'released': date(2014, 8, 1)
    }))

    # Teenage Mutant Ninja Turtles (2014)
    assert_that(items[2], has_properties({
        'pk': ('imdb', 'tt1291150'),
        'title': u'Teenage Mutant Ninja Turtles',
        'year': 2014,

        'released': date(2014, 8, 8)
    }))

def test_my_shows():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].get()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(4))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 4),
        'first_aired': datetime(2014, 7, 14, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E03
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 3),
        'first_aired': datetime(2014, 7, 14, 2, tzinfo=tzutc())
    }))

    # True Blood S07E05
    assert_that(items[2], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '82283'),
            'title': 'True Blood',
            'year': 2008
        }),

        'pk': (7, 5),
        'first_aired': datetime(2014, 7, 21, 1, tzinfo=tzutc())
    }))

    # The Leftovers S01E04
    assert_that(items[3], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 4),
        'first_aired': datetime(2014, 7, 21, 2, tzinfo=tzutc())
    }))

def test_my_shows_new():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].new()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(1))

    # True Blood S07E04
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

def test_my_shows_premieres():
    with HTTMock(mock.calendars_my, mock.unknown):
        with Trakt.configuration.auth('mock', 'mock'):
            items = Trakt['calendars/my/shows'].premieres()

    # Ensure request was successful
    assert_that(items, not_none())
    assert_that(items, has_length(2))

    # The Leftovers S01E01
    assert_that(items[0], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '269689'),
            'title': 'The Leftovers',
            'year': 2014
        }),

        'pk': (1, 1),
        'first_aired': datetime(2014, 6, 30, 2, tzinfo=tzutc())
    }))

    # The Walking Dead S05E01
    assert_that(items[1], has_properties({
        'show': has_properties({
            'pk': ('tvdb', '153021'),
            'title': 'The Walking Dead',
            'year': 2010
        }),

        'pk': (5, 1),
        'first_aired': datetime(2014, 10, 13, 1, tzinfo=tzutc())
    }))

def test_new_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Trakt['calendars/all/dvd'].new()

        with pytest.raises(ValueError):
            Trakt['calendars/all/movies'].new()

def test_premieres_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Trakt['calendars/all/dvd'].premieres()

        with pytest.raises(ValueError):
            Trakt['calendars/all/movies'].premieres()

def test_get_validation():
    with HTTMock(mock.fixtures, mock.unknown):
        with pytest.raises(ValueError):
            Base(None).get('invalid', 'movies')

        with pytest.raises(ValueError):
            Base(None).get('all', 'invalid')

def test_start_date():
    with HTTMock(mock.calendars_all_period, mock.unknown):
        items = Trakt['calendars/all/movies'].get(start_date=datetime(2015, 10, 15))

    assert_that(items, not_none())

def test_days():
    with HTTMock(mock.calendars_all_period, mock.unknown):
        items = Trakt['calendars/all/movies'].get(days=14)

    assert_that(items, not_none())
<|endoftext|>


<commit_before>import time

from osbrain import run_agent

from common import nsaddr  # pragma: no flakes
from common import nsproxy  # pragma: no flakes

def log_received_to_list(agent, message, topic=None):
    agent.received_list.append(message)

def test_pubsub_topics_pickle(nsaddr):
    """
    Simple publisher-subscriber pattern test.

    Different messages sent with different agents subscribed to different
    topics are tested within this method.
    """
    a0 = run_agent('a0')
    a1 = run_agent('a1')
    a2 = run_agent('a2')
    a3 = run_agent('a3')
    a4 = run_agent('a4')
    a5 = run_agent('a5')

    for agent in (a1, a2, a3, a4, a5):
        agent.set_attr(received_list=[])

    addr = a0.bind('PUB', alias='pub', serializer='pickle')

    a1.connect(addr, handler=log_received_to_list)
    a2.connect(addr, handler={'foo': log_received_to_list})
    a3.connect(addr, handler={'bar': log_received_to_list,
                              'foo': log_received_to_list})
    a4.connect(addr, handler={'bar': log_received_to_list})
    a5.connect(addr, handler={'fo': log_received_to_list})

    # Give some time for all the agents to connect
    time.sleep(0.1)

    # Send some messages
    message_01 = 'Hello'
    a0.send('pub', message_01)

    message_02 = 'World'
    a0.send('pub', message_02, topic='foo')

    message_03 = 'FOO'
    a0.send('pub', message_03, topic='foobar')

    message_04 = 'BAR'
    a0.send('pub', message_04, topic='fo')

    # Give some time for all the agents to handle the message
    time.sleep(0.1)

    # Check each agent received the corresponding messages
    assert message_01 in a1.get_attr('received_list')
    assert message_02 in a1.get_attr('received_list')
    assert message_03 in a1.get_attr('received_list')
    assert message_04 in a1.get_attr('received_list')

    assert message_01 not in a2.get_attr('received_list')
    assert message_02 in a2.get_attr('received_list')
    assert message_03 in a2.get_attr('received_list')
    assert message_04 not in a2.get_attr('received_list')

    assert message_01 not in a3.get_attr('received_list')
    assert message_02 in a3.get_attr('received_list')
    assert message_03 in a3.get_attr('received_list')
    assert message_04 not in a3.get_attr('received_list')

    assert message_01 not in a4.get_attr('received_list')
    assert message_02 not in a4.get_attr('received_list')
    assert message_03 not in a4.get_attr('received_list')
    assert message_04 not in a4.get_attr('received_list')

    assert message_01 not in a5.get_attr('received_list')
    assert message_02 in a5.get_attr('received_list')
    assert message_03 in a5.get_attr('received_list')
    assert message_04 in a5.get_attr('received_list')

def test_pubsub_topics_json(nsaddr):
    """
    Simple publisher-subscriber pattern test.

    Different messages sent with different agents subscribed to different
    topics are tested within this method.
    """
    a0 = run_agent('a0')
    a1 = run_agent('a1')
    a2 = run_agent('a2')
    a3 = run_agent('a3')
    a4 = run_agent('a4')
    a5 = run_agent('a5')

    for agent in (a1, a2, a3, a4, a5):
        agent.set_attr(received_list=[])

    addr = a0.bind('PUB', alias='pub', serializer='json')

    a1.connect(addr, handler=log_received_to_list)
    a2.connect(addr, handler={'foo': log_received_to_list})
    a3.connect(addr, handler={'bar': log_received_to_list,
                              'foo': log_received_to_list})
    a4.connect(addr, handler={'bar': log_received_to_list})
    a5.connect(addr, handler={'fo': log_received_to_list})

    # Give some time for all the agents to connect
    time.sleep(0.1)

    # Send some messages
    message_01 = 'Hello'
    a0.send('pub', message_01)

    message_02 = 'World'
    a0.send('pub', message_02, topic='foo')

    message_03 = 'FOO'
    a0.send('pub', message_03, topic='foobar')

    message_04 = 'BAR'
    a0.send('pub', message_04, topic='fo')

    # Give some time for all the agents to handle the message
    time.sleep(0.1)

    # Check each agent received the corresponding messages
    assert message_01 in a1.get_attr('received_list')
    assert message_02 in a1.get_attr('received_list')
    assert message_03 in a1.get_attr('received_list')
    assert message_04 in a1.get_attr('received_list')

    assert message_01 not in a2.get_attr('received_list')
    assert message_02 in a2.get_attr('received_list')
    assert message_03 in a2.get_attr('received_list')
    assert message_04 not in a2.get_attr('received_list')

    assert message_01 not in a3.get_attr('received_list')
    assert message_02 in a3.get_attr('received_list')
    assert message_03 in a3.get_attr('received_list')
    assert message_04 not in a3.get_attr('received_list')

    assert message_01 not in a4.get_attr('received_list')
    assert message_02 not in a4.get_attr('received_list')
    assert message_03 not in a4.get_attr('received_list')
    assert message_04 not in a4.get_attr('received_list')

    assert message_01 not in a5.get_attr('received_list')
    assert message_02 in a5.get_attr('received_list')
    assert message_03 in a5.get_attr('received_list')
    assert message_04 in a5.get_attr('received_list')

def test_pubsub_topics_raw(nsaddr):
    """
    Simple publisher-subscriber pattern test.

    Different messages sent with different agents subscribed to different
    topics are tested within this method.

    In the raw version of PUBSUB, we want to replicate the raw message passing
    of ZMQ, in which the topic is passed along the message and it is the
    responsability of the handler to split them.
    """
    a0 = run_agent('a0')
    a1 = run_agent('a1')
    a2 = run_agent('a2')
    a3 = run_agent('a3')
    a4 = run_agent('a4')
    a5 = run_agent('a5')

    for agent in (a1, a2, a3, a4, a5):
        agent.set_attr(received_list=[])

    addr = a0.bind('PUB', alias='pub', serializer='raw')

    a1.connect(addr, handler=log_received_to_list)
    a2.connect(addr, handler={'foo': log_received_to_list})
    a3.connect(addr, handler={'bar': log_received_to_list,
                              'foo': log_received_to_list})
    a4.connect(addr, handler={'bar': log_received_to_list})
    a5.connect(addr, handler={'fo': log_received_to_list})

    # Give some time for all the agents to connect
    time.sleep(0.1)

    # Send some messages
    message_01 = b'Hello'
    a0.send('pub', message_01)

    message_02 = b'World'
    a0.send('pub', message_02, topic='foo')

    message_03 = b'FOO'
    a0.send('pub', message_03, topic='foobar')

    message_04 = b'BAR'
    a0.send('pub', message_04, topic='fo')

    # Give some time for all the agents to handle the message
    time.sleep(0.1)

    # Check each agent received the corresponding messages
    assert message_01 in a1.get_attr('received_list')
    assert b'fooWorld' in a1.get_attr('received_list')
    assert b'foobarFOO' in a1.get_attr('received_list')
    assert b'foBAR' in a1.get_attr('received_list')

    assert message_01 not in a2.get_attr('received_list')
    assert b'fooWorld' in a2.get_attr('received_list')
    assert b'foobarFOO' in a2.get_attr('received_list')
    assert b'foBAR' not in a2.get_attr('received_list')

    assert message_01 not in a3.get_attr('received_list')
    assert b'fooWorld' in a3.get_attr('received_list')
    assert b'foobarFOO' in a3.get_attr('received_list')
    assert b'foBAR' not in a3.get_attr('received_list')

    assert message_01 not in a4.get_attr('received_list')
    assert b'fooWorld' not in a4.get_attr('received_list')
    assert b'foobarFOO' not in a4.get_attr('received_list')
    assert b'foBAR' not in a4.get_attr('received_list')

    assert message_01 not in a5.get_attr('received_list')
    assert b'fooWorld' in a5.get_attr('received_list')
    assert b'foobarFOO' in a5.get_attr('received_list')
    assert b'foBAR' in a5.get_attr('received_list')
<commit_msg>Simplify tests using parametrize mark<commit_after>import time

import pytest

from osbrain import run_agent
from osbrain.address import AgentAddressSerializer

from common import nsaddr  # pragma: no flakes
from common import nsproxy  # pragma: no flakes

def log_received_to_list(agent, message, topic=None):
    agent.received_list.append(message)

@pytest.mark.parametrize(
    'serializer',
    AgentAddressSerializer.SERIALIZER_SEPARATOR
)
def test_pubsub_topics_separator(nsaddr, serializer):
    """
    Simple publisher-subscriber pattern test using serializers that
    require a separation in message composition.

    Different messages sent with different agents subscribed to different
    topics are tested within this method.
    """
    a0 = run_agent('a0')
    a1 = run_agent('a1')
    a2 = run_agent('a2')
    a3 = run_agent('a3')
    a4 = run_agent('a4')
    a5 = run_agent('a5')

    for agent in (a1, a2, a3, a4, a5):
        agent.set_attr(received_list=[])

    addr = a0.bind('PUB', alias='pub', serializer=serializer)

    a1.connect(addr, handler=log_received_to_list)
    a2.connect(addr, handler={'foo': log_received_to_list})
    a3.connect(addr, handler={'bar': log_received_to_list,
                              'foo': log_received_to_list})
    a4.connect(addr, handler={'bar': log_received_to_list})
    a5.connect(addr, handler={'fo': log_received_to_list})

    # Give some time for all the agents to connect
    time.sleep(0.1)

    # Send some messages
    message_01 = 'Hello'
    a0.send('pub', message_01)

    message_02 = 'World'
    a0.send('pub', message_02, topic='foo')

    message_03 = 'FOO'
    a0.send('pub', message_03, topic='foobar')

    message_04 = 'BAR'
    a0.send('pub', message_04, topic='fo')

    # Give some time for all the agents to handle the message
    time.sleep(0.1)

    # Check each agent received the corresponding messages
    assert message_01 in a1.get_attr('received_list')
    assert message_02 in a1.get_attr('received_list')
    assert message_03 in a1.get_attr('received_list')
    assert message_04 in a1.get_attr('received_list')

    assert message_01 not in a2.get_attr('received_list')
    assert message_02 in a2.get_attr('received_list')
    assert message_03 in a2.get_attr('received_list')
    assert message_04 not in a2.get_attr('received_list')

    assert message_01 not in a3.get_attr('received_list')
    assert message_02 in a3.get_attr('received_list')
    assert message_03 in a3.get_attr('received_list')
    assert message_04 not in a3.get_attr('received_list')

    assert message_01 not in a4.get_attr('received_list')
    assert message_02 not in a4.get_attr('received_list')
    assert message_03 not in a4.get_attr('received_list')
    assert message_04 not in a4.get_attr('received_list')

    assert message_01 not in a5.get_attr('received_list')
    assert message_02 in a5.get_attr('received_list')
    assert message_03 in a5.get_attr('received_list')
    assert message_04 in a5.get_attr('received_list')

@pytest.mark.parametrize(
    'serializer',
    AgentAddressSerializer.SERIALIZER_SIMPLE
)
def test_pubsub_topics_raw(nsaddr, serializer):
    """
    Simple publisher-subscriber pattern test.

    Different messages sent with different agents subscribed to different
    topics are tested within this method.

    In the raw version of PUBSUB, we want to replicate the raw message passing
    of ZMQ, in which the topic is passed along the message and it is the
    responsability of the handler to split them.
    """
    a0 = run_agent('a0')
    a1 = run_agent('a1')
    a2 = run_agent('a2')
    a3 = run_agent('a3')
    a4 = run_agent('a4')
    a5 = run_agent('a5')

    for agent in (a1, a2, a3, a4, a5):
        agent.set_attr(received_list=[])

    addr = a0.bind('PUB', alias='pub', serializer=serializer)

    a1.connect(addr, handler=log_received_to_list)
    a2.connect(addr, handler={'foo': log_received_to_list})
    a3.connect(addr, handler={'bar': log_received_to_list,
                              'foo': log_received_to_list})
    a4.connect(addr, handler={'bar': log_received_to_list})
    a5.connect(addr, handler={'fo': log_received_to_list})

    # Give some time for all the agents to connect
    time.sleep(0.1)

    # Send some messages
    message_01 = b'Hello'
    a0.send('pub', message_01)

    message_02 = b'World'
    a0.send('pub', message_02, topic='foo')

    message_03 = b'FOO'
    a0.send('pub', message_03, topic='foobar')

    message_04 = b'BAR'
    a0.send('pub', message_04, topic='fo')

    # Give some time for all the agents to handle the message
    time.sleep(0.1)

    # Check each agent received the corresponding messages
    assert message_01 in a1.get_attr('received_list')
    assert b'fooWorld' in a1.get_attr('received_list')
    assert b'foobarFOO' in a1.get_attr('received_list')
    assert b'foBAR' in a1.get_attr('received_list')

    assert message_01 not in a2.get_attr('received_list')
    assert b'fooWorld' in a2.get_attr('received_list')
    assert b'foobarFOO' in a2.get_attr('received_list')
    assert b'foBAR' not in a2.get_attr('received_list')

    assert message_01 not in a3.get_attr('received_list')
    assert b'fooWorld' in a3.get_attr('received_list')
    assert b'foobarFOO' in a3.get_attr('received_list')
    assert b'foBAR' not in a3.get_attr('received_list')

    assert message_01 not in a4.get_attr('received_list')
    assert b'fooWorld' not in a4.get_attr('received_list')
    assert b'foobarFOO' not in a4.get_attr('received_list')
    assert b'foBAR' not in a4.get_attr('received_list')

    assert message_01 not in a5.get_attr('received_list')
    assert b'fooWorld' in a5.get_attr('received_list')
    assert b'foobarFOO' in a5.get_attr('received_list')
    assert b'foBAR' in a5.get_attr('received_list')
<|endoftext|>


<commit_before>import os
import threading

import pytest

from doit.filewatch import FileModifyWatcher

class TestFileWatcher(object):
    def testInit(self, restore_cwd, tmpdir):
        dir1 = 'data3'
        files = ('data/w1.txt', 'data/w2.txt')
        tmpdir.mkdir('data')
        for fname in files:
            tmpdir.join(fname).open('a').close()
        os.chdir(tmpdir.strpath)

        fw = FileModifyWatcher((files[0], files[1], dir1))
        # file_list contains absolute paths
        assert 2 == len(fw.file_list)
        assert os.path.abspath(files[0]) in fw.file_list
        assert os.path.abspath(files[1]) in fw.file_list
        # watch_dirs
        assert 2 == len(fw.watch_dirs)
        assert tmpdir.join('data') in fw.watch_dirs
        assert tmpdir.join('data3') in fw.watch_dirs
        # notify_dirs
        assert 1 == len(fw.notify_dirs)
        assert tmpdir.join('data3') in fw.notify_dirs

    def testUnsuportedPlatform(self, monkeypatch):
        monkeypatch.setattr(FileModifyWatcher, 'supported_platforms', ())
        pytest.raises(Exception, FileModifyWatcher, [])

    def testHandleEventNotSubclassed(self):
        fw = FileModifyWatcher([])
        pytest.raises(NotImplementedError, fw.handle_event, None)

    def testLoop(self, restore_cwd, tmpdir):
        files = ['data/w1.txt', 'data/w2.txt', 'data/w3.txt']
        stop_file = 'data/stop'
        tmpdir.mkdir('data')
        for fname in files + [stop_file]:
            tmpdir.join(fname).open('a').close()
        os.chdir(tmpdir.strpath)

        fw = FileModifyWatcher((files[0], files[1], stop_file))
        events = []
        should_stop = []
        started = []
        def handle_event(event):
            events.append(event.pathname)
            if event.pathname.endswith("stop"):
                should_stop.append(True)
        fw.handle_event = handle_event

        def loop_callback(notifier):
            started.append(True)
            # force loop to stop
            if should_stop:
                raise KeyboardInterrupt
        loop_thread = threading.Thread(target=fw.loop, args=(loop_callback,))
        loop_thread.daemon = True
        loop_thread.start()

        # wait watcher to be ready
        while not started: # pragma: no cover
            assert loop_thread.isAlive()

        # write in watched file
        fd = open(files[0], 'w')
        fd.write("hi")
        fd.close()
        # write in non-watched file
        fd = open(files[2], 'w')
        fd.write("hi")
        fd.close()
        # write in another watched file
        fd = open(files[1], 'w')
        fd.write("hi")
        fd.close()

        # tricky to stop watching
        fd = open(stop_file, 'w')
        fd.write("hi")
        fd.close()
        loop_thread.join(1)
        assert not loop_thread.isAlive()

        assert os.path.abspath(files[0]) == events[0]
        assert os.path.abspath(files[1]) == events[1]
<commit_msg>try to improve flaky test.<commit_after>import os
import time
import threading

import pytest

from doit.filewatch import FileModifyWatcher

class TestFileWatcher(object):
    def testInit(self, restore_cwd, tmpdir):
        dir1 = 'data3'
        files = ('data/w1.txt', 'data/w2.txt')
        tmpdir.mkdir('data')
        for fname in files:
            tmpdir.join(fname).open('a').close()
        os.chdir(tmpdir.strpath)

        fw = FileModifyWatcher((files[0], files[1], dir1))
        # file_list contains absolute paths
        assert 2 == len(fw.file_list)
        assert os.path.abspath(files[0]) in fw.file_list
        assert os.path.abspath(files[1]) in fw.file_list
        # watch_dirs
        assert 2 == len(fw.watch_dirs)
        assert tmpdir.join('data') in fw.watch_dirs
        assert tmpdir.join('data3') in fw.watch_dirs
        # notify_dirs
        assert 1 == len(fw.notify_dirs)
        assert tmpdir.join('data3') in fw.notify_dirs

    def testUnsuportedPlatform(self, monkeypatch):
        monkeypatch.setattr(FileModifyWatcher, 'supported_platforms', ())
        pytest.raises(Exception, FileModifyWatcher, [])

    def testHandleEventNotSubclassed(self):
        fw = FileModifyWatcher([])
        pytest.raises(NotImplementedError, fw.handle_event, None)

    def testLoop(self, restore_cwd, tmpdir):
        files = ['data/w1.txt', 'data/w2.txt', 'data/w3.txt']
        stop_file = 'data/stop'
        tmpdir.mkdir('data')
        for fname in files + [stop_file]:
            tmpdir.join(fname).open('a').close()
        os.chdir(tmpdir.strpath)

        fw = FileModifyWatcher((files[0], files[1], stop_file))
        events = []
        should_stop = []
        started = []
        def handle_event(event):
            events.append(event.pathname)
            if event.pathname.endswith("stop"):
                should_stop.append(True)
        fw.handle_event = handle_event

        def loop_callback(notifier):
            started.append(True)
            # force loop to stop
            if should_stop:
                raise KeyboardInterrupt
        loop_thread = threading.Thread(target=fw.loop, args=(loop_callback,))
        loop_thread.daemon = True
        loop_thread.start()

        # wait watcher to be ready
        while not started: # pragma: no cover
            time.sleep(0.01)
            assert loop_thread.isAlive()

        # write in watched file
        fd = open(files[0], 'w')
        fd.write("hi")
        fd.close()
        # write in non-watched file
        fd = open(files[2], 'w')
        fd.write("hi")
        fd.close()
        # write in another watched file
        fd = open(files[1], 'w')
        fd.write("hi")
        fd.close()

        # tricky to stop watching
        fd = open(stop_file, 'w')
        fd.write("hi")
        fd.close()
        loop_thread.join(1)
        assert not loop_thread.isAlive()

        assert os.path.abspath(files[0]) == events[0]
        assert os.path.abspath(files[1]) == events[1]
<|endoftext|>


<commit_before>#!/usr/bin/python3.6
"""Create a new Django webapp with a virtualenv.  Defaults to
your free domain, the latest version of Django and Python 3.5

Usage:
  pa_start_django_webapp_with_virtualenv.py [--domain=<domain> --django=<django-version> --python=<python-version>] [--nuke]

Options:
  --domain=<domain>         Domain name, eg www.mydomain.com   [default: your-username.pythonanywhere.com]
  --django=<django-version> Django version, eg "1.8.4"  [default: latest]
  --python=<python-version> Python version, eg "2.7"    [default: 3.6]
  --nuke                    *Irrevocably* delete any existing web app config on this domain. Irrevocably.
"""

from docopt import docopt
import getpass
import os
import requests
import shutil
import subprocess
from textwrap import dedent

from snakesay import snakesay

API_ENDPOINT = 'https://www.pythonanywhere.com/api/v0/user/{username}/webapps/'
PYTHON_VERSIONS = {
    '2.7': 'python27',
    '3.4': 'python34',
    '3.5': 'python35',
    '3.6': 'python36',
}

class SanityException(Exception):
    pass

class AuthenticationError(Exception):
    pass

def call_api(url, method, **kwargs):
    response = requests.request(
        method=method,
        url=url,
        headers={'Authorization': 'Token {}'.format(os.environ['API_TOKEN'])},
        **kwargs
    )
    if response.status_code == 401:
        print(response, response.text)
        raise AuthenticationError('Authentication error {} calling API: {}'.format(
            response.status_code, response.text
        ))
    return response

def _virtualenv_path(domain):
    return os.path.join(os.environ['WORKON_HOME'], domain)

def _project_folder(domain):
    return os.path.expanduser('~/' + domain)

def sanity_checks(domain, nuke):
    print(snakesay('Running sanity checks'))
    token = os.environ.get('API_TOKEN')
    if not token:
        raise SanityException(dedent(
            '''
            Could not find your API token.
            You may need to create it on the Accounts page?
            You will also need to close this console and open a new one once you've done that.
            '''
        ))

    if nuke:
        return
    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/'
    response = call_api(url, 'get')
    if response.status_code == 200:
        raise SanityException('You already have a webapp for {}.\n\nUse the --nuke option if you want to replace it.'.format(domain))
    if os.path.exists(_virtualenv_path(domain)):
        raise SanityException('You already have a virtualenv for {}.\n\nUse the --nuke option if you want to replace it.'.format(domain))
    project_folder = _project_folder(domain)
    if os.path.exists(project_folder):
        raise SanityException('You already have a project folder at {}.\n\nUse the --nuke option if you want to replace it.'.format(project_folder))

def create_virtualenv(name, python_version, django_version, nuke):
    print(snakesay(f'Creating virtualenv with Python{python_version} and Django=={django_version}'))
    pip_install = 'pip install django'
    if django_version != 'latest':
        pip_install += '==' + django_version
    command = 'mkvirtualenv --python=/usr/bin/python{python_version} {name} && {pip_install}'.format(
        name=name, python_version=python_version, pip_install=pip_install
    )
    if nuke:
        command = 'rmvirtualenv {name} && {old_command}'.format(
            name=name, old_command=command
        )
    subprocess.check_call(['bash', '-c', 'source virtualenvwrapper.sh && {}'.format(command)])
    return _virtualenv_path(name)

def start_django_project(domain, virtualenv_path, nuke):
    print(snakesay('Starting Django project'))
    target_folder = _project_folder(domain)
    if nuke:
        shutil.rmtree(target_folder)
    os.mkdir(target_folder)
    subprocess.check_call([
        os.path.join(virtualenv_path, 'bin/django-admin.py'),
        'startproject',
        'mysite',
        target_folder
    ])
    return target_folder

def run_collectstatic(virtualenv_path, target_folder):
    print(snakesay('Running collectstatic'))

    subprocess.check_call([
        os.path.join(virtualenv_path, 'bin/python'),
        os.path.join(target_folder, 'manage.py'),
        'collectstatic',
        '--noinput',
    ])

def update_settings_file(domain, project_path):
    print(snakesay('Updating settings.py'))

    with open(os.path.join(project_path, 'mysite', 'settings.py')) as f:
        settings = f.read()
    new_settings = settings.replace(
        'ALLOWED_HOSTS = []',
        "ALLOWED_HOSTS = [{!r}]".format(domain)
    )
    new_settings += dedent(
        """
        MEDIA_URL = '/media/'
        STATIC_ROOT = os.path.join(BASE_DIR, 'static')
        MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
        """
    )
    with open(os.path.join(project_path, 'mysite', 'settings.py'), 'w') as f:
        f.write(new_settings)

def create_webapp(domain, python_version, virtualenv_path, project_path, nuke):
    print(snakesay('Creating web app via API'))
    if nuke:
        webapp_url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/'
        call_api(webapp_url, 'delete')
    post_url = API_ENDPOINT.format(username=getpass.getuser())
    patch_url = post_url + domain + '/'
    response = call_api(post_url, 'post', data={
        'domain_name': domain, 'python_version': PYTHON_VERSIONS[python_version]},
    )
    if not response.ok or response.json().get('status') == 'ERROR':
        raise Exception('POST to create webapp via API failed, got {}:{}'.format(response, response.text))
    response = call_api(patch_url, 'patch', data={'virtualenv_path': virtualenv_path})
    if not response.ok:
        raise Exception('PATCH to set virtualenv path via API failed, got {}:{}'.format(response, response.text))

def add_static_file_mappings(domain, project_path):
    print(snakesay('Adding static files mappings for /static/ and /media/'))

    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/static_files/'
    call_api(url, 'post', json=dict(
        url='/static/', path=os.path.join(project_path, 'static')
    ))
    call_api(url, 'post', json=dict(
        url='/media/', path=os.path.join(project_path, 'media')
    ))

def update_wsgi_file(wsgi_file_path, project_path):
    print(snakesay(f'Updating wsgi file at {wsgi_file_path}'))

    template = open(os.path.join(os.path.dirname(__file__), 'wsgi_file_template.py')).read()
    with open(wsgi_file_path, 'w') as f:
        f.write(template.format(project_path=project_path))

def reload_webapp(domain):
    print(snakesay(f'Reloading {domain} via API'))
    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/reload/'
    response = call_api(url, 'post')
    if not response.ok:
        raise Exception('POST to reload webapp via API failed, got {}:{}'.format(response, response.text))

def main(domain, django_version, python_version, nuke):
    if domain == 'your-username.pythonanywhere.com':
        username = getpass.getuser().lower()
        domain = '{}.pythonanywhere.com'.format(username)
    sanity_checks(domain, nuke=nuke)
    virtualenv_path = create_virtualenv(domain, python_version, django_version, nuke=nuke)
    project_path = start_django_project(domain, virtualenv_path, nuke=nuke)
    update_settings_file(domain, project_path)
    run_collectstatic(virtualenv_path, project_path)
    create_webapp(domain, python_version, virtualenv_path, project_path, nuke=nuke)
    add_static_file_mappings(domain, project_path)
    wsgi_file_path = '/var/www/' + domain.replace('.', '_') + '_wsgi.py'
    update_wsgi_file(wsgi_file_path, project_path)
    reload_webapp(domain)

    print(snakesay(f'All done!  Your site is now live at https://{domain}'))

if __name__ == '__main__':
    arguments = docopt(__doc__)
    main(arguments['--domain'], arguments['--django'], arguments['--python'], nuke=arguments.get('--nuke'))

<commit_msg>Fix incorrect ref to 3.5 in help. by: Harry<commit_after>#!/usr/bin/python3.6
"""Create a new Django webapp with a virtualenv.  Defaults to
your free domain, the latest version of Django and Python 3.6

Usage:
  pa_start_django_webapp_with_virtualenv.py [--domain=<domain> --django=<django-version> --python=<python-version>] [--nuke]

Options:
  --domain=<domain>         Domain name, eg www.mydomain.com   [default: your-username.pythonanywhere.com]
  --django=<django-version> Django version, eg "1.8.4"  [default: latest]
  --python=<python-version> Python version, eg "2.7"    [default: 3.6]
  --nuke                    *Irrevocably* delete any existing web app config on this domain. Irrevocably.
"""

from docopt import docopt
import getpass
import os
import requests
import shutil
import subprocess
from textwrap import dedent

from snakesay import snakesay

API_ENDPOINT = 'https://www.pythonanywhere.com/api/v0/user/{username}/webapps/'
PYTHON_VERSIONS = {
    '2.7': 'python27',
    '3.4': 'python34',
    '3.5': 'python35',
    '3.6': 'python36',
}

class SanityException(Exception):
    pass

class AuthenticationError(Exception):
    pass

def call_api(url, method, **kwargs):
    response = requests.request(
        method=method,
        url=url,
        headers={'Authorization': 'Token {}'.format(os.environ['API_TOKEN'])},
        **kwargs
    )
    if response.status_code == 401:
        print(response, response.text)
        raise AuthenticationError('Authentication error {} calling API: {}'.format(
            response.status_code, response.text
        ))
    return response

def _virtualenv_path(domain):
    return os.path.join(os.environ['WORKON_HOME'], domain)

def _project_folder(domain):
    return os.path.expanduser('~/' + domain)

def sanity_checks(domain, nuke):
    print(snakesay('Running sanity checks'))
    token = os.environ.get('API_TOKEN')
    if not token:
        raise SanityException(dedent(
            '''
            Could not find your API token.
            You may need to create it on the Accounts page?
            You will also need to close this console and open a new one once you've done that.
            '''
        ))

    if nuke:
        return
    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/'
    response = call_api(url, 'get')
    if response.status_code == 200:
        raise SanityException('You already have a webapp for {}.\n\nUse the --nuke option if you want to replace it.'.format(domain))
    if os.path.exists(_virtualenv_path(domain)):
        raise SanityException('You already have a virtualenv for {}.\n\nUse the --nuke option if you want to replace it.'.format(domain))
    project_folder = _project_folder(domain)
    if os.path.exists(project_folder):
        raise SanityException('You already have a project folder at {}.\n\nUse the --nuke option if you want to replace it.'.format(project_folder))

def create_virtualenv(name, python_version, django_version, nuke):
    print(snakesay(f'Creating virtualenv with Python{python_version} and Django=={django_version}'))
    pip_install = 'pip install django'
    if django_version != 'latest':
        pip_install += '==' + django_version
    command = 'mkvirtualenv --python=/usr/bin/python{python_version} {name} && {pip_install}'.format(
        name=name, python_version=python_version, pip_install=pip_install
    )
    if nuke:
        command = 'rmvirtualenv {name} && {old_command}'.format(
            name=name, old_command=command
        )
    subprocess.check_call(['bash', '-c', 'source virtualenvwrapper.sh && {}'.format(command)])
    return _virtualenv_path(name)

def start_django_project(domain, virtualenv_path, nuke):
    print(snakesay('Starting Django project'))
    target_folder = _project_folder(domain)
    if nuke:
        shutil.rmtree(target_folder)
    os.mkdir(target_folder)
    subprocess.check_call([
        os.path.join(virtualenv_path, 'bin/django-admin.py'),
        'startproject',
        'mysite',
        target_folder
    ])
    return target_folder

def run_collectstatic(virtualenv_path, target_folder):
    print(snakesay('Running collectstatic'))

    subprocess.check_call([
        os.path.join(virtualenv_path, 'bin/python'),
        os.path.join(target_folder, 'manage.py'),
        'collectstatic',
        '--noinput',
    ])

def update_settings_file(domain, project_path):
    print(snakesay('Updating settings.py'))

    with open(os.path.join(project_path, 'mysite', 'settings.py')) as f:
        settings = f.read()
    new_settings = settings.replace(
        'ALLOWED_HOSTS = []',
        "ALLOWED_HOSTS = [{!r}]".format(domain)
    )
    new_settings += dedent(
        """
        MEDIA_URL = '/media/'
        STATIC_ROOT = os.path.join(BASE_DIR, 'static')
        MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
        """
    )
    with open(os.path.join(project_path, 'mysite', 'settings.py'), 'w') as f:
        f.write(new_settings)

def create_webapp(domain, python_version, virtualenv_path, project_path, nuke):
    print(snakesay('Creating web app via API'))
    if nuke:
        webapp_url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/'
        call_api(webapp_url, 'delete')
    post_url = API_ENDPOINT.format(username=getpass.getuser())
    patch_url = post_url + domain + '/'
    response = call_api(post_url, 'post', data={
        'domain_name': domain, 'python_version': PYTHON_VERSIONS[python_version]},
    )
    if not response.ok or response.json().get('status') == 'ERROR':
        raise Exception('POST to create webapp via API failed, got {}:{}'.format(response, response.text))
    response = call_api(patch_url, 'patch', data={'virtualenv_path': virtualenv_path})
    if not response.ok:
        raise Exception('PATCH to set virtualenv path via API failed, got {}:{}'.format(response, response.text))

def add_static_file_mappings(domain, project_path):
    print(snakesay('Adding static files mappings for /static/ and /media/'))

    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/static_files/'
    call_api(url, 'post', json=dict(
        url='/static/', path=os.path.join(project_path, 'static')
    ))
    call_api(url, 'post', json=dict(
        url='/media/', path=os.path.join(project_path, 'media')
    ))

def update_wsgi_file(wsgi_file_path, project_path):
    print(snakesay(f'Updating wsgi file at {wsgi_file_path}'))

    template = open(os.path.join(os.path.dirname(__file__), 'wsgi_file_template.py')).read()
    with open(wsgi_file_path, 'w') as f:
        f.write(template.format(project_path=project_path))

def reload_webapp(domain):
    print(snakesay(f'Reloading {domain} via API'))
    url = API_ENDPOINT.format(username=getpass.getuser()) + domain + '/reload/'
    response = call_api(url, 'post')
    if not response.ok:
        raise Exception('POST to reload webapp via API failed, got {}:{}'.format(response, response.text))

def main(domain, django_version, python_version, nuke):
    if domain == 'your-username.pythonanywhere.com':
        username = getpass.getuser().lower()
        domain = '{}.pythonanywhere.com'.format(username)
    sanity_checks(domain, nuke=nuke)
    virtualenv_path = create_virtualenv(domain, python_version, django_version, nuke=nuke)
    project_path = start_django_project(domain, virtualenv_path, nuke=nuke)
    update_settings_file(domain, project_path)
    run_collectstatic(virtualenv_path, project_path)
    create_webapp(domain, python_version, virtualenv_path, project_path, nuke=nuke)
    add_static_file_mappings(domain, project_path)
    wsgi_file_path = '/var/www/' + domain.replace('.', '_') + '_wsgi.py'
    update_wsgi_file(wsgi_file_path, project_path)
    reload_webapp(domain)

    print(snakesay(f'All done!  Your site is now live at https://{domain}'))

if __name__ == '__main__':
    arguments = docopt(__doc__)
    main(arguments['--domain'], arguments['--django'], arguments['--python'], nuke=arguments.get('--nuke'))

<|endoftext|>


<commit_before>from debile.master.dimport import dimport
from debile.master.interface import DebileMasterInterface, NAMESPACE
from debile.master.orm import Base, Builder, Person

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

import os
import unittest

class DebileInterfaceTestCase(unittest.TestCase):
    def setUp(self):
        # setup the database
        engine = create_engine(os.environ['DATABASE_URI'],
                               implicit_returning=False)

        Session = sessionmaker()
        Session.configure(bind=engine)
        self.session = Session()
        Base.metadata.drop_all(self.session.bind)

        # feed database
        class Args:
            pass
        args = Args()
        args.file = 'tests/resources/debile.yaml'
        args.force = False
        dimport(args, self.session)

        # some more setting up
        u = self.session.query(Person).filter_by(
            email='clement@mux.me'
        ).first()
        NAMESPACE.user = u

        self.blade01_key = None
        with open('tests/resources/blade01.pgp') as f:
            self.blade01_key = f.read()

    def test_create_builder(self):
        interface = DebileMasterInterface(pgp_keyring=u'tests/resources/keyring')
        NAMESPACE.session = self.session
        interface.create_builder('blade01', self.blade01_key, ip='10.0.0.1')

        b = self.session.query(Builder).filter_by(name='blade01').one()

        assert b.ssl is None
        assert b.ip == '10.0.0.1'
        assert b.pgp == '7C367D02AF6D20DCF2BFB686E8D62122F818733D'
<commit_msg>make it work without travis<commit_after>from debile.master.dimport import dimport
from debile.master.interface import DebileMasterInterface, NAMESPACE
from debile.master.orm import Base, Builder, Person

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

import os
import unittest

class DebileInterfaceTestCase(unittest.TestCase):
    def setUp(self):
        # setup the database
        if 'DATABASE_URI' in os.environ:
            db_URI = os.environ['DATABASE_URI']
        else:
            db_URI = 'postgres://postgres:@localhost:5432/debile_tests'
        engine = create_engine(db_URI,
                               implicit_returning=False)

        Session = sessionmaker()
        Session.configure(bind=engine)
        self.session = Session()
        Base.metadata.drop_all(self.session.bind)

        # feed database
        class Args:
            pass
        args = Args()
        args.file = 'tests/resources/debile.yaml'
        args.force = False
        dimport(args, self.session)

        # some more setting up
        u = self.session.query(Person).filter_by(
            email='clement@mux.me'
        ).first()
        NAMESPACE.user = u

        self.blade01_key = None
        with open('tests/resources/blade01.pgp') as f:
            self.blade01_key = f.read()

    def test_create_builder(self):
        interface = DebileMasterInterface(pgp_keyring=u'tests/resources/keyring')
        NAMESPACE.session = self.session
        interface.create_builder('blade01', self.blade01_key, ip='10.0.0.1')

        b = self.session.query(Builder).filter_by(name='blade01').one()

        assert b.ssl is None
        assert b.ip == '10.0.0.1'
        assert b.pgp == '7C367D02AF6D20DCF2BFB686E8D62122F818733D'
<|endoftext|>


<commit_before>from language_explorer import settings, constants
from language_explorer.language_sources.jpharvest import JPHarvestAdapter
from tests.test_baseclasses import BaseAdapterTestCase
import unittest

__author__ = 'esteele'

class TestJPHarvestAdapter(BaseAdapterTestCase):

    def setUp(self):
        self.source = JPHarvestAdapter(settings.JPHARVEST_DB_URL)

    @unittest.skip("Review - can't explain why this has regressed")
    def test_all_iso_keys(self):
        keys = self.source.get_language_iso_keys()
        self.assertEquals(len(keys), 67)
        self.assertEquals(keys[0], "aer")
        self.assertEquals(keys[-1], "zmt")
        self._do_test_all_iso_keys_common()

    def test_primary_name_retrieval(self):
        iso_primary_name_pairs = [
            ("aly", "Alyawarr"),  # normal
            ("are", "Arrarnta, Western"),  # spaces and commas
            ("kuy", "Kuuku-Ya'u"),  # single quote
            ("tcs", "Torres Strait Creole"),  # three words
        ]
        self._do_test_primary_name_retrieval(iso_primary_name_pairs)

    def test_alternate_name_retrieval(self):
        iso_alternate_name_pairs = [
            ("djb", []),  # No alternates
            ("djj", ["Gunavidji"]),  # One alternate
            ("amx", ["Anmatyerr", "Anmatjirra"]),  # Two alternates
            ("aer", ["Upper Aranda", "Eastern Aranda", "Arunta"]),  # spaces
            ("tgz", ["Tarkalag", "Targa-lag", "Takalak", "Dagalang",
                     "Da:galag"]),  # Names with colons and dashes
        ]
        self._do_test_alternate_name_retrieval(iso_alternate_name_pairs)

    def test_classification_retrieval(self):
        # Not implemented
        self.assertEquals([], self.source.get_classification("dummy"))

    def test_get_translation_info_for_iso(self):
        # Convenience
        STATE = constants.TRANSLATION_STATE_STATE_KEY
        YEAR = constants.TRANSLATION_STATE_YEAR_KEY
        iso_translation_pairs = [
            ("are", {STATE: constants.TRANSLATION_STATE_NEW_TESTAMENT,
                     YEAR: 1956}),  # NT + portions date
            ("dif", {STATE: constants.TRANSLATION_STATE_NEW_TESTAMENT,
                     YEAR: 1897}),  # No portions date, only NT date
            ("rop", {STATE: constants.TRANSLATION_STATE_WHOLE_BIBLE,
                     YEAR: 2007}),  # Whole bible
            ("aly", {STATE: constants.TRANSLATION_STATE_PORTIONS,
                     YEAR: 2003}),  # Range in portions
            ("adg", {STATE: constants.TRANSLATION_STATE_NO_SCRIPTURE,
                     YEAR: constants.TRANSLATION_STATE_UNKNOWN_YEAR}),
            # No matches
            ("bdy", {STATE: constants.TRANSLATION_STATE_PORTIONS,
                     YEAR: constants.TRANSLATION_STATE_POSITIVE_YEAR})
            # bdy has no translation date
        ]
        self._do_test_get_translation_info(iso_translation_pairs)
<commit_msg>Update JPH gives more australian languages<commit_after>from language_explorer import settings, constants
from language_explorer.language_sources.jpharvest import JPHarvestAdapter
from tests.test_baseclasses import BaseAdapterTestCase
import unittest

__author__ = 'esteele'

class TestJPHarvestAdapter(BaseAdapterTestCase):

    def setUp(self):
        self.source = JPHarvestAdapter(settings.JPHARVEST_DB_URL)

    def test_all_iso_keys(self):
        keys = self.source.get_language_iso_keys()
        self.assertEquals(len(keys), 82)
        self.assertEquals(keys[0], "adt")
        self.assertEquals(keys[-1], "zmt")
        self._do_test_all_iso_keys_common()

    def test_primary_name_retrieval(self):
        iso_primary_name_pairs = [
            ("aly", "Alyawarr"),  # normal
            ("are", "Arrarnta, Western"),  # spaces and commas
            ("kuy", "Kuuku-Ya'u"),  # single quote
            ("tcs", "Torres Strait Creole"),  # three words
        ]
        self._do_test_primary_name_retrieval(iso_primary_name_pairs)

    def test_alternate_name_retrieval(self):
        iso_alternate_name_pairs = [
            ("djb", []),  # No alternates
            ("djj", ["Gunavidji"]),  # One alternate
            ("amx", ["Anmatyerr", "Anmatjirra"]),  # Two alternates
            ("aer", ["Upper Aranda", "Eastern Aranda", "Arunta"]),  # spaces
            ("tgz", ["Tarkalag", "Targa-lag", "Takalak", "Dagalang",
                     "Da:galag"]),  # Names with colons and dashes
        ]
        self._do_test_alternate_name_retrieval(iso_alternate_name_pairs)

    def test_classification_retrieval(self):
        # Not implemented
        self.assertEquals([], self.source.get_classification("dummy"))

    def test_get_translation_info_for_iso(self):
        # Convenience
        STATE = constants.TRANSLATION_STATE_STATE_KEY
        YEAR = constants.TRANSLATION_STATE_YEAR_KEY
        iso_translation_pairs = [
            ("are", {STATE: constants.TRANSLATION_STATE_NEW_TESTAMENT,
                     YEAR: 1956}),  # NT + portions date
            ("dif", {STATE: constants.TRANSLATION_STATE_NEW_TESTAMENT,
                     YEAR: 1897}),  # No portions date, only NT date
            ("rop", {STATE: constants.TRANSLATION_STATE_WHOLE_BIBLE,
                     YEAR: 2007}),  # Whole bible
            ("aly", {STATE: constants.TRANSLATION_STATE_PORTIONS,
                     YEAR: 2003}),  # Range in portions
            ("adg", {STATE: constants.TRANSLATION_STATE_NO_SCRIPTURE,
                     YEAR: constants.TRANSLATION_STATE_UNKNOWN_YEAR}),
            # No matches
            ("bdy", {STATE: constants.TRANSLATION_STATE_PORTIONS,
                     YEAR: constants.TRANSLATION_STATE_POSITIVE_YEAR})
            # bdy has no translation date
        ]
        self._do_test_get_translation_info(iso_translation_pairs)
<|endoftext|>