def test_book_views_shared_books(self, config_valid, book_valid, requests_standard_settings, requests_user_token_settings, user_valid): self.add_book(book_valid, config_valid, requests_standard_settings) response = requests.post(url=f'{config_valid["root_url"]}/books', data=to_json([book_valid]).encode('utf-8'), **requests_standard_settings) assert response.status_code == 200 book_id = from_json(response.content.decode('utf-8'))['items'][0]['id'] response = requests.post( url=f'{config_valid["root_url"]}/books/{book_id}/share', data=to_json({ 'username': '******' }).encode('utf-8'), **requests_standard_settings) assert response.status_code == 204 response = requests.get( url= f'{config_valid["root_url"]}/books?includes=page_count&view=shared_books', **requests_user_token_settings) assert response.status_code == 200 books = json.loads(response.content.decode('utf-8')) assert books['total'] assert books['page_count'] > 0 assert len(books['items']) >= 1 book_id = from_json(response.content.decode( 'utf-8'))['items'][0]['owner_id'] == user_valid['username']
def index_book(self, book: model.Book): word_frequency = Indexer.word_frequency(book.text) _id_list = list(word_frequency.keys()) existing_words = self.word_repo.find_by_ids(_id_list)['items'] LOGGER.info(existing_words) existing_words_by_ids = {word.id: word for word in existing_words} new_words = [] for word_id in _id_list: existing_word = existing_words_by_ids.get(word_id) if existing_word is not None: LOGGER.debug(existing_word.index) frequency = word_frequency.get(existing_word.name) LOGGER.debug(type(existing_word.index)) index = dict(from_json(existing_word.index)) # if index.get(book.id) is not None: index[book.id] = frequency existing_word.count = reduce(lambda a, b: a + b, index.values()) existing_word.index = to_json(index) else: word_count = word_frequency[word_id] new_words.append( model.Word(id=word_id, name=word_id, index=to_json({book.id: word_count}), count=word_count)) self.word_repo.update_all([*existing_words, *new_words])
def book_updated_event_valid(app_context, book_small_valid): from lorem_ipsum import model from lorem_ipsum.repo import Word, Event event_repo = app_context.event_repo event = model.Event(id=event_repo.next_id(), name=str(model.Events.BOOK_UPDATED), data=to_json({'new': to_json(book_small_valid)}), created_at=datetime.utcnow()) _event_entity = lorem_ipsum.repo.Event(**event.as_dict()) orig_query = lorem_ipsum.repo.Transaction.session.query.return_value def query_side_effect(args): # print(f'Mock {args}') if args == Event: orig_query.count.return_value = 1 orig_query.filter.return_value.first.return_value = _event_entity orig_query.filter.return_value.limit.return_value.offset.return_value = [ _event_entity ] if args == Word: index = {book_small_valid['id']: 1} orig_query.filter.return_value.order_by.return_value = [ lorem_ipsum.repo.Word(id=word, name=word, index=to_json(index), count=1) for word in ['just', 'a', 'sample', 'page'] ] return orig_query lorem_ipsum.repo.Transaction.session.query.side_effect = query_side_effect yield event
def random_book(): """ Generate random book --- parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: query name: no_of_paged description: Limit the number of items returned type: integer responses: 200: description: Random book schema: $ref: '#/definitions/Book' 401: description: Authentication error 403: description: Authorization error """ no_of_pages = int(request.args.get('no_of_pages', 1)) LOGGER.info(f'Generate book, no_of_pages=[{no_of_pages}]]...') result = app_context().book_service.random(no_of_pages=no_of_pages, owner_id=g.user.username) return response({"status_code": '200', 'body': to_json(result)})
def test_word_add(self, word_valid, config_valid, requests_standard_settings): response = requests.post(url=f'{config_valid["root_url"]}/words', data=to_json([word_valid]).encode('utf-8'), **requests_standard_settings) assert from_json(response.content.decode('utf-8'))['items'][0]['name'] assert 200 == response.status_code
def test_word_add_insufficient_permissions(self, config_valid, word_valid, requests_user_token_settings): response = requests.post(url=f'{config_valid["root_url"]}/words', data=to_json([word_valid]).encode('utf-8'), **requests_user_token_settings) assert 403 == response.status_code assert from_json(response.content.decode('utf-8')) == 'Forbidden.'
def test_book_add_insufficient_permissions( self, config_valid, book_valid, requests_moderator_token_settings): response = requests.post(url=f'{config_valid["root_url"]}/books', data=to_json([book_valid]).encode('utf-8'), **requests_moderator_token_settings) assert response.status_code == 403 assert from_json(response.content.decode('utf-8')) == 'Forbidden.'
def get_all_books(): """ Get books --- definitions: - schema: id: BookPaginationResult type: object properties: total: type: integer description: Total number of items. items: type: array description: List of books items: oneOf: - $ref: "#/definitions/Book" parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: query name: limit description: Limit the number of items returned type: integer - in: query name: offset description: Offset of items result type: integer - in: query name: includes description: List of fields to include, separated by comma type: string - in: query name: view description: Books view: my_books, shared_books type: string responses: 200: description: List of books schema: $ref: '#/definitions/BookPaginationResult' 401: description: Authentication error 403: description: Authorization error """ _limit = int(request.args.get('limit', 20)) _offset = int(request.args.get('offset', 1)) _view = BookViews.from_value(request.args.get('view', BookViews.MY_BOOKS.value)) _includes = request.args.get('includes') LOGGER.info(f'Get all data [limit={_limit}, offset=[{_offset}], view={_view}]...') result = app_context().book_service.get_all(limit=_limit, offset=_offset, includes=_includes, owner_id=g.user.username, view=_view) return response({"status_code": '200', 'body': to_json(result)})
def random(no_of_pages: int, owner_id: str): _faker = faker.Faker() _book = {f'page_{page}': [_faker.text(max_nb_chars=100) for i in range(30)] for page in range(no_of_pages)} return {"author": _faker.name(), "title": _faker.text(max_nb_chars=100), "book": to_json(_book), "no_of_pages": no_of_pages, "owner_id": owner_id }
def user_valid_list_one_request(user_valid1, request_valid_admin): import app import lorem_ipsum.views as api flask.request.data = to_json([user_valid1]).encode('utf-8') lorem_ipsum.repo.Transaction.session.query.return_value.filter.return_value.first.return_value = lorem_ipsum.repo.User( **user_valid1) yield user_valid1 # print(lorem_ipsum.repo.Transaction.session.mock_calls) api.app_context().user_service.delete(user_valid1['username'])
def raw_metrics(fields=''): LOGGER.debug('Metrics...') _metrics = {} try: _metrics = to_json(lorem_ipsum.create_app_context().metrics_service.metrics(fields.split(','))) except: e = sys.exc_info()[0] LOGGER.exception('Could not get metrics...') print(e) return _metrics
def book_valid_add_request_user(book_valid, book_valid_user, admin_token_valid): # from flask import request import app with app.app.test_request_context( headers={'X-Token-String': admin_token_valid}): # book_valid = book_valid lorem_ipsum.repo.Transaction.session.query.return_value.filter.return_value.first.return_value = lorem_ipsum.repo.Book( **book_valid) flask.request.data = to_json([book_valid]).encode('utf-8') yield book_valid
def word_valid_add_request(word_valid, admin_token_valid, request_valid_admin): # from flask import request import app lorem_ipsum.repo.Transaction.session.query.return_value.filter.return_value.first.return_value = lorem_ipsum.repo.Word( **word_valid) lorem_ipsum.repo.Transaction.session.query.return_value.count.return_value = 3 lorem_ipsum.repo.Transaction.session.query.return_value.order_by.return_value.limit.return_value.offset.return_value = [ lorem_ipsum.repo.Word(**word_valid), lorem_ipsum.repo.Word(**word_valid) ] flask.request.data = to_json([word_valid]).encode('utf-8') yield word_valid
def user_valid_list_request(user_valid2, app_valid): import app import lorem_ipsum.views as api with app.app.test_request_context(): api.app_context().user_service.save([user_valid2]) flask.request.data = to_json([user_valid2]).encode('utf-8') lorem_ipsum.repo.Transaction.session.query.return_value.count.return_value = 1 lorem_ipsum.repo.Transaction.session.query.return_value.limit.return_value = [ lorem_ipsum.repo.User(**user_valid2) ] yield user_valid2 api.app_context().user_service.delete(user_valid2['username'])
def book_words_valid(): _faker = faker.Faker() _book = { f'page_{page}': [_faker.text(max_nb_chars=100) for i in range(30)] for page in range(10) } yield { "author": _faker.name(), "title": _faker.text(max_nb_chars=5), "book": to_json(_book), "no_of_pages": 10, }
def save(self, data_records): saved_records = [] for record in data_records: book_repo = self._app_context.book_repo event_repo = self._app_context.event_repo book = None old_book = None if record.get('id') is not None: book = book_repo.get(record['id']) old_book = book if book is None: record['id'] = self._app_context.book_repo.next_id() book = Book.from_dict(record) event = Event(id=event_repo.next_id(), name=str(Events.BOOK_UPDATED), data=to_json({'new': to_json(book.as_dict()), 'old': to_json(old_book.as_dict()) if old_book else None}) ) saved_records.append(book_repo.save(book).as_dict()) event_repo.save(event) return {'items': saved_records, 'total': len(saved_records)}
def book_small_valid(): _book = { f'page_{page}': ["Just a sample page." for i in range(1)] for page in range(1) } yield { 'id': str(uuid.uuid4()), "author": "My Author", "title": "My Book", "owner_id": "system", "book": to_json(_book), "no_of_pages": 10, }
def handle_book_updated(self, event: model.Event): LOGGER.info(f'Handling book updated event {event.id}...') started_at = datetime.datetime.utcnow() book = model.Book.from_dict(from_json(from_json(event.data)['new'])) Indexer(self._app_context).index_book(book) event_repo = self._app_context.event_repo event_repo.save( model.Event(id=event_repo.next_id(), name=str(model.Events.BOOK_INDEXED), data=to_json({ 'started_at': started_at, 'completed_at': datetime.datetime.utcnow(), 'book_id': book.id }))) LOGGER.info(f'Handled book updated event {event.id}...')
def stats_top_words_valid_request(word_valid, admin_token_valid): # from flask import request import app with app.app.test_request_context( headers={'X-Token-String': admin_token_valid}): # book_valid = book_valid lorem_ipsum.repo.Transaction.session.query.return_value.filter.return_value.first.return_value = lorem_ipsum.repo.Word( **word_valid) lorem_ipsum.repo.Transaction.session.query.return_value.count.return_value = 3 lorem_ipsum.repo.Transaction.session.query.return_value.limit.return_value.offset.return_value = [ lorem_ipsum.repo.Word(**word_valid), lorem_ipsum.repo.Word(**word_valid) ] flask.request.data = to_json([word_valid]).encode('utf-8') yield word_valid
def get_book(id): """ Get book --- definitions: - schema: id: Book properties: id: type: string description: book id (uuid) no_of_pages: type: integer description: Number of pages author: type: string description: book author full name title: type: string description: book title book: type: string description: book content as JSON containing a list of pages parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: path name: id description: Unique id of the book required: true type: string responses: 200: description: Book found schema: $ref: '#/definitions/Book' 401: description: Authentication error 403: description: Authorization error """ LOGGER.info('Get all data...') result = app_context().book_service.get(id) return response({"status_code": '200', 'body': to_json(result)})
def get_word(id): """ Get word --- definitions: - schema: id: Word properties: id: type: string description: word id (same as word name at this point) count: type: integer description: Word frequency index: type: string description: Word index name: type: string description: Word name, could be different than id parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: path name: id description: Unique id of the word required: true type: string responses: 200: description: Word found schema: $ref: '#/definitions/Word' 401: description: Authentication error 403: description: Authorization error """ LOGGER.info('Get all data...') result = app_context().word_service.get(id) return response({"status_code": '200', 'body': to_json(result)})
def query_side_effect(args): # print(f'Mock {args}') if args == Event: orig_query.count.return_value = 1 orig_query.filter.return_value.first.return_value = _event_entity orig_query.filter.return_value.limit.return_value.offset.return_value = [ _event_entity ] if args == Word: index = {book_small_valid['id']: 1} orig_query.filter.return_value.order_by.return_value = [ lorem_ipsum.repo.Word(id=word, name=word, index=to_json(index), count=1) for word in ['just', 'a', 'sample', 'page'] ] return orig_query
def search_books_by_query(): """ Search books --- parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: query name: limit description: Limit the number of items returned type: integer - in: query name: offset description: Offset of items result type: integer - in: query name: query description: Search query, e.g. word to search for type: string responses: 200: description: List of books schema: $ref: '#/definitions/BookPaginationResult' 401: description: Authentication error 403: description: Authorization error """ _limit = int(request.args.get('limit', 20)) _offset = int(request.args.get('offset', 1)) _query = request.args.get('query', '') LOGGER.info(f'Get all data [limit={_limit}, offset=[{_offset}], _query=[{_query}]]...') result = app_context().book_service.search(query=_query) return response({"status_code": '200', 'body': to_json(result)})
def save_book(): """ Save books --- parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. - in: body name: books required: true description: List of Books to be created schema: type: array items: oneOf: - $ref: "#/definitions/Book" responses: 200: description: List of books created schema: $ref: '#/definitions/BookPaginationResult' 401: description: Authentication error 403: description: Authorization error """ LOGGER.info('Adding data...') _request = from_json(request.data.decode('utf-8')) for _book in _request: _book['owner_id'] = g.user.username result = app_context().book_service.save(_request) return response({"status_code": '200', 'body': to_json({"items": result['items'], "total": result['total']})})
def get_stats(): """ Get stats, e.g. total no of books, pages and words --- definitions: - schema: id: Stats properties: no_of_books: type: integer description: no of books no_of_pages: type: integer description: no of pages no_of_words: type: integer description: no of pages parameters: - in: header name: X-Token-String required: true type: string description: Access token JWT. responses: 200: description: Stats ok schema: $ref: '#/definitions/Stats' 401: description: Authentication error 403: description: Authorization error """ LOGGER.info('Get stats...') result = app_context().stats_service.get() return response({"status_code": '200', 'body': to_json(result)})
def validate_user(): LOGGER.info('Validating user...') _request = from_json(request.data.decode('utf-8')) result = app_context().user_service.validate(_request) return response({"status_code": '200', 'body': to_json(result)})
def get_all_users(): LOGGER.info('Get all users...') LOGGER.info(request.headers) _limit = int(request.args.get('limit', 1)) result = app_context().user_service.get_all(limit=_limit) return response({"status_code": '200', 'body': to_json({"items": result['items'], "total": result['total']})})
def get_user(username): LOGGER.info('Get user...') result = app_context().user_service.get(username) return response({"status_code": '200', 'body': to_json(result)})
def get_config(): LOGGER.info(app.config) LOGGER.info(request.headers) public_config = {k: v for (k, v) in app_context().config.items() if 'password' not in k} return response({"status_code": '200', 'body': to_json(public_config)})
def get_all_words(): _limit = int(request.args.get('limit', 20)) _offset = int(request.args.get('offset', 1)) LOGGER.info(f'Get all data [limit={_limit}, offset=[{_offset}]]...') result = app_context().word_service.get_all(limit=_limit, offset=_offset) return response({"status_code": '200', 'body': to_json({"items": result['items'], "total": result['total']})})