Пример #1
0
def convert_precondition(precond):
    from google.cloud.firestore_v1 import Client

    if precond.HasField("exists"):
        return Client.write_option(exists=precond.exists)

    assert precond.HasField("update_time")
    return Client.write_option(last_update_time=precond.update_time)
Пример #2
0
def convert_precondition(precond):
    from google.cloud.firestore_v1 import Client

    if precond.HasField("exists"):
        return Client.write_option(exists=precond.exists)

    assert precond.HasField("update_time")
    return Client.write_option(last_update_time=precond.update_time)
Пример #3
0
def _make_client_document(firestore_api, testcase):
    from google.cloud.firestore_v1 import Client
    from google.cloud.firestore_v1.client import DEFAULT_DATABASE
    import google.auth.credentials

    _, project, _, database, _, doc_path = testcase.doc_ref_path.split("/", 5)
    assert database == DEFAULT_DATABASE

    # Attach the fake GAPIC to a real client.
    credentials = mock.Mock(spec=google.auth.credentials.Credentials)
    client = Client(project=project, credentials=credentials)
    client._firestore_api_internal = firestore_api
    return client, client.document(doc_path)
Пример #4
0
def _make_client_document(firestore_api, testcase):
    from google.cloud.firestore_v1 import Client
    from google.cloud.firestore_v1.client import DEFAULT_DATABASE
    import google.auth.credentials

    _, project, _, database, _, doc_path = testcase.doc_ref_path.split("/", 5)
    assert database == DEFAULT_DATABASE

    # Attach the fake GAPIC to a real client.
    credentials = mock.Mock(spec=google.auth.credentials.Credentials)
    client = Client(project=project, credentials=credentials)
    client._firestore_api_internal = firestore_api
    return client, client.document(doc_path)
Пример #5
0
def process_message(db: Client, message: Message):
    if not message.text:
        return
    chat_doc = db.collection("chats").document(str(message.chat_id))
    chat_doc.set(message.chat.to_dict())

    chat_doc.collection("messages").document(str(message.message_id)).set(
        message.to_dict()
    )

    user = message.from_user
    try:
        db.collection("users").document(str(user.id)).create(user.to_dict())
    except AlreadyExists:
        logging.info("%s already existed", user.first_name)
Пример #6
0
def auto_update_dispatcher_from_firebase_repliers(db: Client,
                                                  dp: Dispatcher) -> Watch:
    # Create a callback on_snapshot function to capture changes
    def on_snapshot(col_snapshot, changes, read_time):
        existing_handlers: list = dp.handlers[0]
        existing_handlers.remove(UNKNOWN_COMMAND_ERROR_HANDLER)
        for change in changes:
            doc: dict = change.document.to_dict()
            id: str = change.document.id
            logging.info("%s replier %s - %r", change.type.name, id, doc)

            for h in existing_handlers:
                # delete the old handler regardless, because firebase sends "ADDED" events more than once
                if getattr(h, "name", "") == id:
                    existing_handlers.remove(h)

            if change.type.name in ("ADDED", "MODIFIED"):
                # then just add it back again
                dp.add_handler(
                    create_replier(name=id, **doc).to_message_handler())
            elif change.type.name == "REMOVED":
                pass

        # make sure the "unknown command" handler is the last in the list
        existing_handlers.append(UNKNOWN_COMMAND_ERROR_HANDLER)

    query_watch = db.collection(u"repliers").on_snapshot(on_snapshot)
    return query_watch
Пример #7
0
def configure_db():
    client = Client(
        project="firedantic-test",
        credentials=Mock(spec=google.auth.credentials.Credentials),
    )

    prefix = str(uuid.uuid4()) + "-"
    configure(client, prefix)
Пример #8
0
def get_firebase_repliers(db: Client) -> list[BaseReplier]:
    for ref in db.collection("repliers").get():
        ref_dict = ref.to_dict()
        try:
            yield create_replier(name=ref.id, **ref_dict)
        except Exception as exc:
            logging.exception("Could not load replier %s - %r",
                              ref.id,
                              ref_dict,
                              exc_info=exc)
Пример #9
0
def parse_query(testcase):
    # 'query' testcase contains:
    # - 'coll_path':  collection ref path.
    # - 'clauses':  array of one or more 'Clause' elements
    # - 'query': the actual google.firestore_v1.StructuredQuery message
    #            to be constructed.
    # - 'is_error' (as other testcases).
    #
    # 'Clause' elements are unions of:
    # - 'select':  [field paths]
    # - 'where': (field_path, op, json_value)
    # - 'order_by': (field_path, direction)
    # - 'offset': int
    # - 'limit': int
    # - 'start_at': 'Cursor'
    # - 'start_after': 'Cursor'
    # - 'end_at': 'Cursor'
    # - 'end_before': 'Cursor'
    #
    # 'Cursor' contains either:
    # - 'doc_snapshot': 'DocSnapshot'
    # - 'json_values': [string]
    #
    # 'DocSnapshot' contains:
    # 'path': str
    # 'json_data': str
    from google.auth.credentials import Credentials
    from google.cloud.firestore_v1 import Client
    from google.cloud.firestore_v1 import Query

    _directions = {"asc": Query.ASCENDING, "desc": Query.DESCENDING}

    credentials = mock.create_autospec(Credentials)
    client = Client("projectID", credentials)
    path = parse_path(testcase.coll_path)
    collection = client.collection(*path)
    query = collection

    for clause in testcase.clauses:

        if "select" in clause:
            field_paths = [
                ".".join(field_path.field)
                for field_path in clause.select.fields
            ]
            query = query.select(field_paths)
        elif "where" in clause:
            path = ".".join(clause.where.path.field)
            value = convert_data(json.loads(clause.where.json_value))
            query = query.where(path, clause.where.op, value)
        elif "order_by" in clause:
            path = ".".join(clause.order_by.path.field)
            direction = clause.order_by.direction
            direction = _directions.get(direction, direction)
            query = query.order_by(path, direction=direction)
        elif "offset" in clause:
            query = query.offset(clause.offset)
        elif "limit" in clause:
            query = query.limit(clause.limit)
        elif "start_at" in clause:
            cursor = parse_cursor(clause.start_at, client)
            query = query.start_at(cursor)
        elif "start_after" in clause:
            cursor = parse_cursor(clause.start_after, client)
            query = query.start_after(cursor)
        elif "end_at" in clause:
            cursor = parse_cursor(clause.end_at, client)
            query = query.end_at(cursor)
        elif "end_before" in clause:
            cursor = parse_cursor(clause.end_before, client)
            query = query.end_before(cursor)
        else:  # pragma: NO COVER
            raise ValueError("Unknown query clause: {}".format(clause))

    return query
Пример #10
0
def test_listen_testprotos(test_proto):  # pragma: NO COVER
    # test_proto.listen has 'reponses' messages,
    # 'google.firestore_v1.ListenResponse'
    # and then an expected list of 'snapshots' (local 'Snapshot'), containing
    # 'docs' (list of 'google.firestore_v1.Document'),
    # 'changes' (list lof local 'DocChange', and 'read_time' timestamp.
    from google.cloud.firestore_v1 import Client
    from google.cloud.firestore_v1 import DocumentReference
    from google.cloud.firestore_v1 import DocumentSnapshot
    from google.cloud.firestore_v1 import Watch
    import google.auth.credentials

    testcase = test_proto.listen
    testname = test_proto.description

    credentials = mock.Mock(spec=google.auth.credentials.Credentials)
    client = Client(project="project", credentials=credentials)
    modulename = "google.cloud.firestore_v1.watch"
    with mock.patch("%s.Watch.ResumableBidiRpc" % modulename, DummyRpc):
        with mock.patch("%s.Watch.BackgroundConsumer" % modulename,
                        DummyBackgroundConsumer):
            with mock.patch(  # conformance data sets WATCH_TARGET_ID to 1
                    "%s.WATCH_TARGET_ID" % modulename, 1):
                snapshots = []

                def callback(keys, applied_changes, read_time):
                    snapshots.append((keys, applied_changes, read_time))

                collection = DummyCollection(client=client)
                query = DummyQuery(parent=collection)
                watch = Watch.for_query(query, callback, DocumentSnapshot,
                                        DocumentReference)
                # conformance data has db string as this
                db_str = "projects/projectID/databases/(default)"
                watch._firestore._database_string_internal = db_str

                wrapped_responses = [
                    firestore.ListenResponse.wrap(proto)
                    for proto in testcase.responses
                ]
                if testcase.is_error:
                    try:
                        for proto in wrapped_responses:
                            watch.on_snapshot(proto)
                    except RuntimeError:
                        # listen-target-add-wrong-id.textpro
                        # listen-target-remove.textpro
                        pass

                else:
                    for proto in wrapped_responses:
                        watch.on_snapshot(proto)

                    assert len(snapshots) == len(testcase.snapshots)
                    for i, (expected_snapshot, actual_snapshot) in enumerate(
                            zip(testcase.snapshots, snapshots)):
                        expected_changes = expected_snapshot.changes
                        actual_changes = actual_snapshot[1]
                        if len(expected_changes) != len(actual_changes):
                            raise AssertionError(
                                "change length mismatch in %s (snapshot #%s)" %
                                (testname, i))
                        for y, (expected_change, actual_change) in enumerate(
                                zip(expected_changes, actual_changes)):
                            expected_change_kind = expected_change.kind
                            actual_change_kind = actual_change.type.value
                            if expected_change_kind != actual_change_kind:
                                raise AssertionError(
                                    "change type mismatch in %s (snapshot #%s, change #%s')"
                                    % (testname, i, y))
Пример #11
0
def process_replier(db: Client, name: str, type: ReplierType, pattern: str,
                    replies: list[str]):
    db.collection("repliers").document(name).create(
        dict(type=type.value, pattern=pattern, data=replies))
Пример #12
0
def parse_query(testcase):
    # 'query' testcase contains:
    # - 'coll_path':  collection ref path.
    # - 'clauses':  array of one or more 'Clause' elements
    # - 'query': the actual google.firestore_v1.StructuredQuery message
    #            to be constructed.
    # - 'is_error' (as other testcases).
    #
    # 'Clause' elements are unions of:
    # - 'select':  [field paths]
    # - 'where': (field_path, op, json_value)
    # - 'order_by': (field_path, direction)
    # - 'offset': int
    # - 'limit': int
    # - 'start_at': 'Cursor'
    # - 'start_after': 'Cursor'
    # - 'end_at': 'Cursor'
    # - 'end_before': 'Cursor'
    #
    # 'Cursor' contains either:
    # - 'doc_snapshot': 'DocSnapshot'
    # - 'json_values': [string]
    #
    # 'DocSnapshot' contains:
    # 'path': str
    # 'json_data': str
    from google.auth.credentials import Credentials
    from google.cloud.firestore_v1 import Client
    from google.cloud.firestore_v1 import Query

    _directions = {"asc": Query.ASCENDING, "desc": Query.DESCENDING}

    credentials = mock.create_autospec(Credentials)
    client = Client("projectID", credentials)
    path = parse_path(testcase.coll_path)
    collection = client.collection(*path)
    query = collection

    for clause in testcase.clauses:
        kind = clause.WhichOneof("clause")

        if kind == "select":
            field_paths = [
                ".".join(field_path.field) for field_path in clause.select.fields
            ]
            query = query.select(field_paths)
        elif kind == "where":
            path = ".".join(clause.where.path.field)
            value = convert_data(json.loads(clause.where.json_value))
            query = query.where(path, clause.where.op, value)
        elif kind == "order_by":
            path = ".".join(clause.order_by.path.field)
            direction = clause.order_by.direction
            direction = _directions.get(direction, direction)
            query = query.order_by(path, direction=direction)
        elif kind == "offset":
            query = query.offset(clause.offset)
        elif kind == "limit":
            query = query.limit(clause.limit)
        elif kind == "start_at":
            cursor = parse_cursor(clause.start_at, client)
            query = query.start_at(cursor)
        elif kind == "start_after":
            cursor = parse_cursor(clause.start_after, client)
            query = query.start_after(cursor)
        elif kind == "end_at":
            cursor = parse_cursor(clause.end_at, client)
            query = query.end_at(cursor)
        elif kind == "end_before":
            cursor = parse_cursor(clause.end_before, client)
            query = query.end_before(cursor)
        else:  # pragma: NO COVER
            raise ValueError("Unknown query clause: {}".format(kind))

    return query
Пример #13
0
def create_client():
    return Client()