def test_blueprint_response_many(api, schema):
    bp = Blueprint('test', 'test', url_prefix='/test')

    @bp.route('/single')
    @bp.response(schema)
    def single():
        pass

    @bp.route('/many')
    @bp.response(schema(many=True))
    def many():
        pass

    api.register_blueprint(bp)

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

    schema_ref = build_ref('schema', 'Doc')

    response = paths['/test/single']['get']['responses']['200']
    assert (response['content']['application/json']['schema'] == schema_ref)

    response = paths['/test/many']['get']['responses']['200']
    assert (response['content']['application/json']['schema']['items'] ==
            schema_ref)
def test_blueprint_pagination(api, schema):
    bp = Blueprint('test', __name__, url_prefix='/test')

    @bp.route('/')
    @bp.arguments(schema, location='query')
    @bp.paginate()
    def func():
        pass

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

    # Check parameters are documented
    parameters = spec['paths']['/test/']['get']['parameters']

    # Page
    assert parameters[1]['name'] == 'page'
    assert parameters[1]['in'] == 'query'
    assert parameters[1]['schema']['type'] == 'integer'
    assert parameters[1]['schema']['default'] == 1
    assert parameters[1]['schema']['minimum'] == 1

    # Page size
    assert parameters[2]['name'] == 'page_size'
    assert parameters[2]['in'] == 'query'
    assert parameters[2]['required'] is False
    assert parameters[2]['schema']['type'] == 'integer'
    assert parameters[2]['schema']['default'] == 10
    assert parameters[2]['schema']['minimum'] == 1
    assert parameters[2]['schema']['maximum'] == 100
def test_blueprint_response_example(api):
    bp = Blueprint('test', 'test', url_prefix='/test')

    examples = {
        'example 1': {
            'name': 'Rick'
        },
        'example 2': {
            'name': 'Something else'
        }
    }

    @bp.route('/single')
    @bp.response(example=examples['example 1'])
    def single():
        pass

    @bp.route('/multiple')
    @bp.response(examples=examples)
    def multiple():
        pass

    api.register_blueprint(bp)

    single = api.spec.to_dict()['paths']['/test/single']['get']

    assert (single['responses']['200']['content']['application/json']
            ['example'] == examples['example 1'])

    multiple = api.spec.to_dict()['paths']['/test/multiple']['get']
    assert (multiple['responses']['200']['content']['application/json']
            ['examples'] == examples)
def test_blueprint_response_headers(api):
    bp = Blueprint('test', 'test', url_prefix='/test')

    headers = {'Set-Cookie': {'description': 'Sets the auth cookie'}}

    @bp.route('/')
    @bp.response(headers=headers)
    def func():
        pass

    api.register_blueprint(bp)

    get = api.spec.to_dict()['paths']['/test/']['get']
    assert get['responses']['200']['headers'] == headers
def test_blueprint_response_werkzeug_response(api, schema):
    bp = Blueprint('test', 'test', url_prefix='/test')
    client = api._app.test_client()

    @bp.route('/response')
    @bp.response(schema)
    def func():
        return jsonify({'test': 'test'}), 201, {'X-header': 'test'}

    api.register_blueprint(bp)

    rv = client.get('/test/response')
    assert rv.status_code == 201
    assert rv.status == '201 CREATED'
    assert rv.json == {'test': 'test'}
    assert rv.headers['X-header'] == 'test'
def test_blueprint_alt_response(api):
    bp = Blueprint('test', 'test', url_prefix='/test')

    @bp.route('/')
    @bp.response(code=200)
    @bp.alt_response('BAD_REQUEST', code=400)
    def func():
        pass

    api.register_blueprint(bp)
    spec = api.spec.to_dict()['paths']['/test/']['get']

    assert '200' in spec['responses']
    assert '400' in spec['responses']
    assert 'default' in spec['responses']
    assert (spec['responses']['400'] == build_ref('response', 'BAD_REQUEST'))
    assert (spec['responses']['default'] == build_ref('response',
                                                      'DEFAULT_ERROR'))
def test_blueprint_response_description(api):
    bp = Blueprint('test', 'test', url_prefix='/test')

    @bp.route('/no_desc')
    @bp.response(code=204)
    def func_1():
        pass

    @bp.route('/desc')
    @bp.response(code=204, description='Test')
    def func_2():
        pass

    api.register_blueprint(bp)

    get_1 = api.spec.to_dict()['paths']['/test/no_desc']['get']
    assert (get_1['responses']['204']['description'] == http.HTTPStatus(
        204).phrase)

    get_2 = api.spec.to_dict()['paths']['/test/desc']['get']
    assert get_2['responses']['204']['description'] == 'Test'
示例#8
0
from flask.views import MethodView
from flask_login import current_user
from backend.models import Order
from backend.models import OrderSheet
from backend.extensions import Blueprint, roles_required, unnest
from .schemas import OrderSchema, OrderTableSchema, TimeLineSchema
from backend.plugins import db
from flask_smorest import abort

bp = Blueprint('orders', 'orders', description='Request and change orders')


@bp.route('/sheet/<sheet_id_or_latest>')
class Orders(MethodView):
    @roles_required('view-only', 'planner', 'administrator')
    @bp.response(OrderTableSchema)
    @bp.alt_response('UNAUTHORIZED', code=401)
    @bp.alt_response('NOT_FOUND', code=404)
    def get(self, sheet_id_or_latest):
        """
        Get a list of orders from an order sheet.

        In case `sheet_id_or_latest` is `latest`, the most recently uploaded
        order sheet will be requested.

        Required roles: view-only, planner, administrator
        """
        is_view_only = current_user.role == 'view-only'
        order_sheet = OrderSheet.query.get_sheet_or_404(
            sheet_id_or_latest, is_view_only)
        return order_sheet
示例#9
0
from flask.views import MethodView
from flask_smorest import abort
from flask_login import current_user
from .schemas import PlanningSchema
from backend.plugins import db
from backend.extensions import roles_required, Blueprint
from backend.models import Planning
from backend.models import TruckSheet, OrderSheet

bp = Blueprint('plannings',
               'plannings',
               description='Publish and view plannings')


@bp.route('/')
class Plannings(MethodView):
    @roles_required('view-only', 'planner', 'administrator')
    @bp.response(PlanningSchema(many=True))
    @bp.paginate()
    def get(self, pagination_parameters):
        """
        Get a list of plannings in the system.

        The list is served in pages. These can be controlled using
        the parameters in the query string.

        Roles required: View-only, planner, administrator
        """
        # Get a list of plannings according to the page
        # and page_size parameters
        pagination = Planning.query. \
示例#10
0
from flask.views import MethodView
from flask_login import current_user
from flask_smorest import abort
from backend.models import Order, Truck, TruckSheet
from backend.extensions import Blueprint, roles_required, unnest
from .schemas import TruckSchema, TruckTableSchema
from backend.plugins import db

bp = Blueprint('trucks',
               'trucks',
               description='Request and change truck availability')


@bp.route('/sheet/<sheet_id_or_latest>')
class Trucks(MethodView):
    @roles_required('view-only', 'planner', 'administrator')
    @bp.response(TruckTableSchema)
    @bp.alt_response('NOT_FOUND', code=404)
    def get(self, sheet_id_or_latest):
        """
        Get a list of truck from a truck sheet.

        In case `sheet_id_or_latest` is `latest`, the most recently uploaded
        truck sheet will be used.

        Required roles: planner, administrator
        """
        is_view_only = current_user.role == 'view-only'
        truck_sheet = TruckSheet.query.get_sheet_or_404(
            sheet_id_or_latest, is_view_only)
        return truck_sheet
示例#11
0
import time
import io
from flask import send_file
from flask.views import MethodView
from flask_login import current_user
from sqlalchemy import func, and_
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Font, Border, Side
from backend.plugins import db
from backend.models import Order, OrderSheet
from backend.extensions import Blueprint, roles_required

bp = Blueprint('reports',
               'reports',
               description='Get report like first rides assignment')


@bp.route('/firstrides/<sheet_id_or_latest>')
class FirstRides(MethodView):

    @bp.response(code=200)
    @bp.alt_response("NOT_FOUND", code=404)
    @roles_required('view-only', 'planner', 'administrator')
    def get(self, sheet_id_or_latest):
        """
        Get a workbook containing a first rides report from an order sheet.

        In case 'sheet_id_or_latest is 'latest', the most recently uploaded
        order sheet will be used.

        Required roles: view-only, planner, administrator
示例#12
0
from flask.views import MethodView
from flask_login import login_user, logout_user, current_user
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from backend.plugins import db
from backend.extensions import Blueprint, roles_required
from flask_smorest import abort
from .schemas import LoginArguments, AccountInfo
from backend.models import User

bp = Blueprint('authentication',
               'authentication',
               description='Authenticate and manage users')


@bp.route('/login')
class Login(MethodView):
    @bp.arguments(LoginArguments)
    @bp.response(AccountInfo,
                 headers={
                     "Set-Cookie": {
                         "schema": {
                             "type": "string",
                             "example":
                             "session=abcdefg123456; Path=/; HttpOnly"
                         },
                         "description": "Setting the authorization cookie"
                     }
                 })
    @bp.alt_response('UNAUTHORIZED', code=401)
    def post(self, args):
示例#13
0
from flask.views import MethodView
from flask_smorest import abort
from xlrd import XLRDError
from marshmallow.exceptions import ValidationError
from .schemas import FileSchema, SheetSchema
from .SheetParser import TruckAvailabilityParser, OrderListParser
from backend.plugins import db
from backend.models import OrderSheet, TruckSheet
from backend.extensions import Blueprint, roles_required

bp = Blueprint('sheets', 'sheets', description='Upload and parse sheets')


@bp.route('/')
class Sheets(MethodView):
    @roles_required('planner', 'administrator')
    @bp.arguments(FileSchema, location='files')
    @bp.response(SheetSchema, code=200)
    @bp.alt_response("BAD_REQUEST", code=400)
    def post(self, file):
        """
        Parses the orders and truck availability sheets files.
        """
        file_1 = file.pop('file_1')  # file_1 is required, so is always here

        try:
            missing_columns = None  # stores the missing columns of a parser

            for Parser in (
                    TruckAvailabilityParser,  # pragma: no branch
                    OrderListParser):