Esempio n. 1
0
def test_prepare_document(db_conn, vases_table):
    schema = vases_schema
    create_test_data_set(db_conn, vases_table)
    data = {
        'id':
        'ZdhhJQ9U9YJaanmfMEpm05qc',
        'name':
        ' celestial ',
        'shape':
        'round',
        'plants': [
            {
                'species': 'zzplant',
                'quantity': 2
            },
            {
                'species': 'rubbertree',
                'quantity': 1
            },
        ],
        'soil': {
            'color': 'black'
        }
    }
    result, errors = util.prepare_document(schema, data, db_conn)
    assert not errors
    result = omit(result, (
        'id',
        'modified',
        'created',
    ))
    assert result == omit(data, ('id', ))
def test_prepare_row(db_conn):
    schema = vases_schema
    create_test_data_set(db_conn)
    data = {
        'id':
        uuid.uuid4(),
        'name':
        ' celestial ',
        'shape':
        'round',
        'plants': [
            {
                'species': 'zzplant',
                'quantity': 2
            },
            {
                'species': 'rubbertree',
                'quantity': 1
            },
        ],
        'soil': {
            'color': 'black'
        }
    }
    result, errors = util.prepare_row(db_conn, schema, data)
    assert not errors
    result = omit(result, (
        'id',
        'modified',
        'created',
    ))
    assert result == omit(data, ('id', ))
Esempio n. 3
0
def instance_entities(data):
    """
    Given a kind and some json, call insert on that kind
    and return the results.
    A little safer.
    """

    fields = ('id', 'created', 'modified',
              'entity_id', 'previous_id', 'status', 'available')
    entities = []
    if 'cards' in data:
        for card_data in data['cards']:
            kind = card_data.get('kind')
            if kind in card_map:
                entities.push(
                    card_map[kind](omit(card_data, fields))
                )
    if 'units' in data:
        entities = entities + [
            Unit(omit(unit_data, fields))
            for unit_data in data['units']
        ]
    if 'subjects' in data:
        entities = entities + [
            Subject(omit(subject_data, fields))
            for subject_data in data['subjects']
        ]
    return entities
Esempio n. 4
0
def instance_new_entity(data):
    """
    Save as above, but a little safer.
    """

    fields = ('id', 'created', 'modified', 'entity_id', 'previous_id',
              'status', 'available')
    if 'card' in data:
        return Card(omit(data['card'], fields))
        # TODO-1 This needs to also get the right card kind...
    elif 'unit' in data:
        return Unit(omit(data['unit'], fields))
    elif 'set' in data:
        return Set(omit(data['set'], fields))
Esempio n. 5
0
def instance_new_entity(data):
    """
    Save as above, but a little safer.
    """

    fields = ('id', 'created', 'modified',
              'entity_id', 'previous_id', 'status', 'available')
    if 'card' in data:
        return Card(omit(data['card'], fields))
        # TODO-1 This needs to also get the right card kind...
    elif 'unit' in data:
        return Unit(omit(data['unit'], fields))
    elif 'set' in data:
        return Set(omit(data['set'], fields))
Esempio n. 6
0
    def update(self, data):
        """
        Overwrite update method to remove password.
        """

        data = omit(data, ("password",))
        return super().update(data)
Esempio n. 7
0
def instance_post_facade(data):
    """
    Create the correct kind of post based on the `kind` field.
    """

    data = omit(data, ('id', 'created', 'modified'))
    return instance(data)
Esempio n. 8
0
def instance_post_facade(data):
    """
    Create the correct kind of post based on the `kind` field.
    """

    data = omit(data, ('id', 'created', 'modified'))
    return instance(data)
Esempio n. 9
0
def instance_post_facade(data):
    """
    Create the correct kind of post based on the `kind` field.
    """

    data = omit(data, ("id", "created", "modified"))
    return instance(data)
Esempio n. 10
0
def insert_document(schema, data, db_conn):
    """
    Create a new document.
    Return document and errors if failed.
    """

    data = omit(data, ('id', 'created', 'modified'))
    return save_document(schema, data, db_conn)
Esempio n. 11
0
def create_post_facade(db_conn, data):
    """
    Create the correct kind of post based on the `kind` field.
    """

    data = omit(data, ('id', 'created', 'modified'))
    model = instance(data)
    return model.save(db_conn)
Esempio n. 12
0
def test_prepare_document(db_conn, vases_table):
    schema = vases_schema
    create_test_data_set(db_conn, vases_table)
    data = {
        'id': 'ZdhhJQ9U9YJaanmfMEpm05qc',
        'name': ' celestial ',
        'shape': 'round',
        'plants': [
            {'species': 'zzplant', 'quantity': 2},
            {'species': 'rubbertree', 'quantity': 1},
        ],
        'soil': {'color': 'black'}
    }
    result, errors = util.prepare_document(schema, data, db_conn)
    assert not errors
    result = omit(result, ('id', 'modified', 'created',))
    assert result == omit(data, ('id',))
Esempio n. 13
0
def create_post_facade(db_conn, data):
    """
    Create the correct kind of post based on the `kind` field.
    """

    data = omit(data, ('id', 'created', 'modified'))
    model = instance(data)
    return model.save(db_conn)
Esempio n. 14
0
def instance_new_entity(data):
    """
    Given a kind and some json, call insert on that kind
    and return the results.
    A little safer.
    """

    fields = ('id', 'created', 'modified', 'entity_id', 'previous_id',
              'status', 'available')
    if 'card' in data:
        kind = data['card'].get('kind')
        if kind in card_map:
            return card_map[kind](omit(data['card'], fields))
    elif 'unit' in data:
        return Unit(omit(data['unit'], fields))
    elif 'set' in data:
        return Set(omit(data['set'], fields))
Esempio n. 15
0
def instance_new_entity(data):
    """
    Given a kind and some json, call insert on that kind
    and return the results.
    A little safer.
    """

    fields = ('id', 'created', 'modified',
              'entity_id', 'previous_id', 'status', 'available')
    if 'card' in data:
        kind = data['card'].get('kind')
        if kind in card_map:
            return card_map[kind](omit(data['card'], fields))
    elif 'unit' in data:
        return Unit(omit(data['unit'], fields))
    elif 'set' in data:
        return Set(omit(data['set'], fields))
Esempio n. 16
0
    def insert(cls, data):
        """
        Create a new model instance.
        Return model and errors if failed.
        """

        assert isinstance(data, dict)
        data = omit(data, ('id', 'created', 'modified'))
        instance = cls(data)
        return instance.save()
Esempio n. 17
0
def test_add_default_fields():
    schema = vases_schema
    data = {}
    data2 = util.add_default_fields(schema, data)
    data2 = omit(data2, ('id', 'created', 'modified',))
    assert data2 == {
        'plants': [],
        'shape': 'round',
        'soil': {'color': 'brown'},
    }
Esempio n. 18
0
    def update(self, data):
        """
        Update the model in the database.
        Return model and errors if failed.
        """

        assert isinstance(data, dict)
        data = omit(data, ('id', 'created', 'modified'))
        extend(self.data, data)
        return self.save()
Esempio n. 19
0
def update_user(prev_data, data, db_conn):
    """
    Overwrite update method to remove password.
    """

    schema = user_schema
    data = omit(data, ('password',))
    data, errors = update_document(schema, prev_data, data, db_conn)
    if not errors:
        add_user_to_es(data)
    return data, errors
Esempio n. 20
0
def update_user(prev_data, data, db_conn):
    """
    Overwrite update method to remove password.
    """

    schema = user_schema
    data = omit(data, ('password',))
    data, errors = update_document(schema, prev_data, data, db_conn)
    if not errors:
        add_user_to_es(data)
    return data, errors
Esempio n. 21
0
def test_omit():
    """
    Expect to omit given keys and return a new dict.
    """

    d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

    assert util.omit(d, ('a', 'c')) == {
        'b': 2,
        'd': 4,
    }
Esempio n. 22
0
def update_document(schema, prev_data, data, db_conn):
    """
    Update the document in the database.
    Return document and errors if failed.
    NOTICE: `prev_data` should be the _return_ of `insert_document`, not the
            originally provided data.
    """

    data = omit(data, ('id', 'created', 'modified'))
    data = extend({}, prev_data, data)
    return save_document(schema, data, db_conn)
Esempio n. 23
0
def list_posts(params, db_conn):
    """
    Get a list of posts in Sagefy.
    """

    skip = params.get('skip') or 0
    limit = params.get('limit') or 10
    params = omit(params, (
        'skip',
        'limit',
    ))
    query = (r.table(post_schema['tablename']).filter(params).order_by(
        r.asc('created')).skip(skip).limit(limit))
    return list(query.run(db_conn))
Esempio n. 24
0
def update_post(prev_data, data, db_conn):
    """
    Update an existing post.
    """

    schema = get_post_schema(data)
    data2 = omit(data, ('id', 'created', 'modified'))
    data2 = extend({}, prev_data, data2)
    data, errors = validate_post(data2, db_conn)
    if errors:
        return data, errors
    data, errors = update_document(schema, prev_data, data, db_conn)
    if not errors:
        add_post_to_es(data, db_conn)
    return data, errors
Esempio n. 25
0
def insert_row(db_conn, schema, query, data):
    """
  Validate a row, then insert the row.
  """

    data = omit(data, ('id', 'created', 'modified'))
    # TODO-2 is it possible to have postgres do this work of
    #    validating/preparing?
    data, errors = prepare_row(db_conn, schema, data)
    if errors:
        return None, errors
    data = bundle_fields(schema, data)
    data = convert_fields_to_pgjson(data)  # TODO-1 fix this
    data, errors = save_row(db_conn, query, data)
    return data, errors
Esempio n. 26
0
    def insert(cls, db_conn, data):
        """
        When a user creates a new version,
        don't accept certain fields.

        Also, find the previous_id.
        """

        data = omit(data, ('status', 'available'))

        if 'entity_id' in data:
            latest = cls.get_latest_accepted(db_conn, data['entity_id'])
            data['previous_id'] = latest['id']

        return super().insert(db_conn, data)
Esempio n. 27
0
def test_add_default_fields():
    schema = vases_schema
    data = {}
    data2 = util.add_default_fields(schema, data)
    data2 = omit(data2, (
        'id',
        'created',
        'modified',
    ))
    assert data2 == {
        'plants': [],
        'shape': 'round',
        'soil': {
            'color': 'brown'
        },
    }
Esempio n. 28
0
def create_topic_route(request):
    """
    Create a new topic.
    The first post (or proposal) must be provided.
    """

    db_conn = request['db_conn']

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    # ## STEP 1) Create post and topic (and entity) instances
    topic_data = request['params'].get('topic')
    post_data = request['params'].get('post')
    if not topic_data:
        return 400, {
            'errors': [{
                'name': 'topic',
                'message': 'Missing topic data.'
            }],
            'ref': 'zknSd46f2hRNjSjVHCg6YLwN'
        }
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.'
            }],
            'ref': 'Qki4oWX4nTdNAjYI8z5iNawr'
        }
    topic_data = omit(topic_data, ('id', 'created', 'modified'))
    topic_data['user_id'] = current_user['id']
    topic_data, topic_errors = validate_topic(topic_data, db_conn)

    post_data = omit(post_data, (
        'id',
        'created',
        'modified',
    ))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic_data['id']
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post and topic (and entity) instances
    errors = prefix_error_names('topic.', topic_errors)
    errors = errors + prefix_error_names('post.', post_.validate(db_conn))
    if post_kind == 'proposal':
        errors = (errors +
                  prefix_error_names('entity.', entity.validate(db_conn)))
    if len(errors):
        return 400, {'errors': errors, 'ref': 'TAY5pX3ghWBkSIVGTHzpQySa'}

    # ## STEP 3) Save post and topic (and entity)
    topic_data, topic_errors = insert_topic(topic_data, db_conn)
    post_['topic_id'] = topic_data['id']
    post_.save(db_conn)
    if post_kind == 'proposal':
        entity.save(db_conn)

    # ## STEP 4) Add author as a follower
    insert_follow(
        {
            'user_id': current_user['id'],
            'entity': {
                'id': topic_data['id'],
                'kind': 'topic',
            }
        }, db_conn)
    # TODO-2 also follow the entity automatically IF needed

    # ## STEP 5) Send out any needed notices
    send_notices(db_conn,
                 entity_id=topic_data['entity']['id'],
                 entity_kind=topic_data['entity']['kind'],
                 notice_kind='create_topic',
                 notice_data={
                     'user_name': current_user['name'],
                     'topic_name': topic_data['name'],
                     'entity_kind': topic_data['entity']['kind'],
                     'entity_name': topic_data['entity']['id'],
                 })

    if post_kind == 'proposal':
        send_notices(db_conn,
                     entity_id=topic_data['entity']['id'],
                     entity_kind=topic_data['entity']['kind'],
                     notice_kind='create_proposal',
                     notice_data={
                         'user_name': current_user['name'],
                         'topic_name': topic_data['name'],
                         'entity_kind': topic_data['entity']['kind'],
                         'entity_name': topic_data['entity']['id'],
                     })

    # ## STEP 5) Return response
    return 200, {'topic': deliver_topic(topic_data), 'post': post_.deliver()}
Esempio n. 29
0
def create_post_route(request, topic_id):
    """
    Create a new post on a given topic.
    Proposal: must include entity (card, unit, or set) information.
    Vote: must refer to a valid proposal.
    """

    db_conn = request['db_conn']

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    topic = get_topic({'id': topic_id}, db_conn)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM',
        }

    # ## STEP 1) Create post (and entity) instances
    post_data = request['params'].get('post')
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.',
            }],
            'ref': 'ykQpZwJKq54MTCxgkx0p6baW'
        }
    post_data = omit(post_data, (
        'id',
        'created',
        'modified',
    ))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic_id
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post (and entity) instances
    errors = prefix_error_names('post.', post_.validate(db_conn))
    if post_kind == 'proposal':
        errors = (errors +
                  prefix_error_names('entity.', entity.validate(db_conn)))
    if len(errors):
        return 400, {'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7'}

    # ## STEP 3) Save post (and entity)
    post_.save(db_conn)
    if post_kind == 'proposal':
        entity.save(db_conn)

    # ## STEP 4) Add author as a follower
    insert_follow(
        {
            'user_id': current_user['id'],
            'entity': {
                'id': topic['id'],
                'kind': 'topic',
            }
        }, db_conn)
    # TODO-2 also follow the entity

    # ## STEP 5) Make updates based on proposal / vote status
    if post_kind == 'proposal':
        update_entity_status(db_conn, post_)
    if post_kind == 'vote':
        proposal = Proposal.get(db_conn, id=post_['replies_to_id'])
        update_entity_status(db_conn, proposal)

    # ## STEP 6) Send notices
    if post_kind == 'proposal':
        send_notices(db_conn,
                     entity_id=topic['entity']['id'],
                     entity_kind=topic['entity']['kind'],
                     notice_kind='create_proposal',
                     notice_data={
                         'user_name': current_user['name'],
                         'topic_name': topic['name'],
                         'entity_kind': topic['entity']['kind'],
                         'entity_name': topic['entity']['id'],
                     })

    # ## STEP 7) Return response
    return 200, {'post': post_.deliver()}
Esempio n. 30
0
def create_topic_route(request):
    """
    Create a new topic.
    The first post (or proposal) must be provided.
    """

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    # ## STEP 1) Create post and topic (and entity) instances
    topic_data = request['params'].get('topic')
    post_data = request['params'].get('post')
    if not topic_data:
        return 400, {
            'errors': [{
                'name': 'topic',
                'message': 'Missing topic data.'
            }],
            'ref': 'zknSd46f2hRNjSjVHCg6YLwN'
        }
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.'
            }],
            'ref': 'Qki4oWX4nTdNAjYI8z5iNawr'
        }
    topic_data = omit(topic_data, ('id', 'created', 'modified'))
    topic_data['user_id'] = current_user['id']
    topic = Topic(topic_data)
    post_data = omit(post_data, ('id', 'created', 'modified',))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic['id']
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post and topic (and entity) instances
    errors = prefix_error_names('topic.', topic.validate())
    errors = errors + prefix_error_names('post.', post_.validate())
    if post_kind == 'proposal':
        errors = errors + prefix_error_names('entity.', entity.validate())
    if len(errors):
        return 400, {
            'errors': errors,
            'ref': 'TAY5pX3ghWBkSIVGTHzpQySa'
        }

    # ## STEP 3) Save post and topic (and entity)
    topic.save()
    post_.save()
    if post_kind == 'proposal':
        entity.save()

    # ## STEP 4) Add author as a follower
    Follow.insert({
        'user_id': current_user['id'],
        'entity': {
            'id': topic['id'],
            'kind': 'topic',
        }
    })
    # TODO-2 also follow the entity automatically IF needed

    # ## STEP 5) Send out any needed notifications
    send_notices(
        entity_id=topic['entity']['id'],
        entity_kind=topic['entity']['kind'],
        notice_kind='create_topic',
        notice_data={
            'user_name': current_user['name'],
            'topic_name': topic['name'],
            'entity_kind': topic['entity']['kind'],
            'entity_name': topic['entity']['id'],
        }
    )

    # ## STEP 5) Return response
    return 200, {'topic': topic.deliver(), 'post': post_.deliver()}
Esempio n. 31
0
def create_post_route(request, topic_id):
    """
    Create a new post on a given topic.
    Proposal: must include entity (card, unit, or set) information.
    Vote: must refer to a valid proposal.
    """

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    topic = Topic.get(id=topic_id)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM',
        }

    # ## STEP 1) Create post (and entity) instances
    post_data = request['params'].get('post')
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.',
            }],
            'ref': 'ykQpZwJKq54MTCxgkx0p6baW'
        }
    post_data = omit(post_data, ('id', 'created', 'modified',))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic_id
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post (and entity) instances
    errors = prefix_error_names('post.', post_.validate())
    if post_kind == 'proposal':
        errors = errors + prefix_error_names('entity.', entity.validate())
    if len(errors):
        return 400, {
            'errors': errors,
            'ref': 'tux33ztgFj9ittSpS7WKIkq7'
        }

    # ## STEP 3) Save post (and entity)
    post_.save()
    if post_kind == 'proposal':
        entity.save()

    # ## STEP 4) Add author as a follower
    Follow.insert({
        'user_id': current_user['id'],
        'entity': {
            'id': topic['id'],
            'kind': 'topic',
        }
    })
    # TODO-2 also follow the entity

    # ## STEP 5) Make updates based on proposal / vote status
    if post_kind == 'proposal':
        update_entity_status(post_)
    if post_kind == 'vote':
        proposal = Proposal.get(id=post_['replies_to_id'])
        update_entity_status(proposal)

    # ## STEP 6) Return response
    return 200, {'post': post_.deliver()}