Example #1
0
    def save_transaction(cls, user_id, isbns, prices, quantities):
        transactions = []
        email_trans = []
        for isbn, price, quantity in zip(isbns, prices, quantities):
            book = BooksModel.find_by_isbn(isbn)
            cls.check_stock(book, quantity)
            transaction = TransactionsModel(user_id, isbn, price, quantity)
            transactions.append(transaction.json())
            email_trans.append(transaction.email_text())
            db.session.add(transaction)
            user = UsersModel.find_by_id(user_id)

            book_library = LibraryModel.find_by_id_and_isbn(
                user.id, transaction.isbn)
            if book_library:  # if the book was already in library
                if book_library.library_type == LibraryType.WishList:  # if it was in the wish list
                    book_library.library_type = LibraryType.Bought  # change it to bought
                    book_library.state = State.Pending
            else:  # if it wasnt in the library, enter it
                entry = LibraryModel(book.isbn, user.id, LibraryType.Bought,
                                     State.Pending)
                db.session.add(entry)

        cls.it_transaction += 1
        db.session.commit()
        cls.send_email(user_id, email_trans)
        return transactions
Example #2
0
    def test_basic_put_book(self):
        with self.app.app_context():
            self.basic_setup()
            res = self.client.post(
                "/api/book",
                data=self.data_old,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(201, res.status_code)

            self.assertEqual(
                BooksModel.find_by_isbn(self.isbn).json(),
                json.loads(res.data))
            res = self.client.put(
                f"/api/book/{self.isbn}",
                data=self.data_new,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(200, res.status_code)
Example #3
0
    def test_post_book_with_minimum_attributes(self):
        with self.app.app_context():
            self.admin_setup()

            isbn = 9780553803716
            data = {
                "isbn": isbn,
                "stock": 10,
                "precio": 7.79,
                "titulo": "Foundation",
            }

            res = self.client.post(
                "/api/book",
                data=data,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(201, res.status_code)
            self.assertEqual(
                BooksModel.find_by_isbn(isbn).json(), json.loads(res.data))

            res = self.client.post(
                "/api/book",
                data=data,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(409, res.status_code)
Example #4
0
 def get(self, isbn):
     data = parse_reviews()
     with lock:
         book = BooksModel.find_by_isbn(isbn)
     if not book:
         return {"message": f"Book with ['isbn':{isbn}] not found"}, 404
     return {"book": book.json(**data)}, 200
Example #5
0
    def test_basic_put_book_vendible(self):
        with self.app.app_context():
            self.basic_setup()
            data_new = {
                "sinopsis": self.sinopsis,
                "precio": 8.60,
                "stock": 9,
                "vendible": False
            }

            res = self.client.post(
                "/api/book",
                data=self.data_old,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(201, res.status_code)
            self.assertEqual(
                BooksModel.find_by_isbn(self.isbn).json(),
                json.loads(res.data))

            res = self.client.put(
                f"/api/book/{self.isbn}",
                data=self.data_new,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(200, res.status_code)
Example #6
0
 def json(self):
     _ignore = self.isbn  # Forces execution to parse properly the class, fixing the bug of transient data
     atr = self.__dict__.copy()
     del atr["_sa_instance_state"]
     atr['date'] = self.date.strftime('%d-%m-%Y')
     atr['book'] = BooksModel.find_by_isbn(atr['isbn']).json()
     return atr
Example #7
0
    def post(self, email):
        data = parse_entry()
        with lock:
            user = check_user(email)

            if not BooksModel.find_by_isbn(data['isbn']):
                return {
                    "message": f"Book with ['isbn': {data['isbn']}] Not Found"
                }, 404

            if LibraryModel.find_by_id_and_isbn(user.id,
                                                data['isbn']) is not None:
                return {
                    "message":
                    f"Entry with ['email': {email}, 'isbn': {data['isbn']}] already exists"
                }, 409

            data['user_id'] = user.id
            try:
                entry = LibraryModel(**data)
                entry.save_to_db()
            except Exception as e:
                return {"message": str(e)}, 500

        return entry.json(), 201
Example #8
0
    def test_model_add(self):
        with self.app.app_context():
            date = datetime.now()
            book = BooksModel(1, 1, 1.0, "titulo", "autor", "editorial",
                              "sinposis", "url", date)

            book.save_to_db()
            self.assertEqual(book, BooksModel.find_by_isbn(book.isbn))
Example #9
0
    def test_post_book(self):
        with self.app.app_context():
            self.admin_setup()

            sinopsis = "For twelve thousand years the Galactic Empire has ruled supreme. Now it is dying. But only " \
                       "Hari Seldon, creator of the revolutionary science of psychohistory, can see into the future " \
                       "-- to a dark age of ignorance, barbarism, and warfare that will last thirty thousand years. " \
                       "To preserve knowledge and save mankind, Seldon gathers the best minds in the Empire -- both " \
                       "scientists and scholars -- and brings them to a bleak planet at the edge of the Galaxy to " \
                       "serve as a beacon of hope for a future generations. He calls his sanctuary the " \
                       "Foundation.\nBut soon the fledgling Foundation finds itself at the mercy of corrupt warlords " \
                       "rising in the wake of the receding Empire. Mankind's last best hope is faced with an " \
                       "agonizing choice: submit to the barbarians and be overrun -- or fight them and be destroyed. "
            isbn = 9780553803716
            data = {
                "isbn":
                isbn,
                "stock":
                10,
                "precio":
                7.79,
                "titulo":
                "Foundation",
                "autor":
                "Isaac Asimov",
                "editorial":
                "Bantam Books",
                "sinopsis":
                sinopsis,
                "url_imagen":
                "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1417900846l"
                "/29579.jpg",
                "fecha_de_publicacion":
                "2001-06-01"
            }

            res = self.client.post(
                "/api/book",
                data=data,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(201, res.status_code)
            self.assertEqual(
                BooksModel.find_by_isbn(isbn).json(), json.loads(res.data))

            res = self.client.post(
                "/api/book",
                data=data,
                headers={
                    "Authorization":
                    'Basic ' + base64.b64encode(
                        (self.token + ":").encode('ascii')).decode('ascii')
                })
            self.assertEqual(409, res.status_code)
Example #10
0
 def json(self):
     """
     Returns a dictionary with paris of string of name of attribute and it's value. In case of Enum it just returns
     the name of the enum object (Enum.name).
     """
     _ignore = self.isbn  # Forces execution to parse properly the class, fixing the bug of transient data
     atr = self.__dict__.copy()
     atr['book'] = BooksModel.find_by_isbn(self.isbn).json()
     del atr['isbn']
     del atr["_sa_instance_state"]
     return {
         atr: value if not isinstance(value, Enum) else value.name
         for atr, value in atr.items()
     }
Example #11
0
def check_keys(email, isbn):
    user = check_user(email)

    book = BooksModel.find_by_isbn(isbn)
    if book is None:
        abort(404,
              message={"message": f"Book with ['isbn': {isbn}] Not Found"})

    library = LibraryModel.find_by_id_and_isbn(user.id, isbn)
    if library is None:
        abort(404,
              message={
                  "message":
                  f"Entry with ['email': {email}, 'isbn': {isbn}] Not Found"
              })
    return library
Example #12
0
    def put(self, isbn):
        data = parse_book(minimal=True)
        check_constraints_book(data)
        with lock:
            book = BooksModel.find_by_isbn(isbn)
            if book is None:
                return {
                    "message":
                    "Book with ['isbn': " + str(isbn) + "] Not Found"
                }, 404
            try:
                book.update_from_db(data)
            except Exception as e:
                return {"message": str(e)}, 500

            return {"book": book.json()}, 200
Example #13
0
    def test_model_update(self):
        with self.app.app_context():
            book = BooksModel(1, 1, 1, "test")
            book.save_to_db()
            book2 = BooksModel(2, 1, 1, "test2")
            book2.save_to_db()

            entry = LibraryModel(book.isbn, 1, LibraryType.Bought, State.Finished)
            entry.save_to_db()

            data = {"isbn": book2.isbn, "user_id": 2, "state": "Reading", "visible": True, "library_type": "WishList"}
            entry.update_from_db(data)

            expected_json = data
            expected_json["book"] = BooksModel.find_by_isbn(book2.isbn).json()
            del expected_json["isbn"]
            self.assertEqual(expected_json, entry.json())
Example #14
0
 def save_to_db(self):
     if self.score < 1 or self.score > 5:
         raise ValueError(
             "Invalid value for score attribute: Value must be an integer from 1 to 5, both included."
         )
     if ReviewsModel.find_by_isbn_user_id(self.isbn,
                                          self.user_id) is not None:
         raise Exception(
             f"Given user already posted a review. Did you meant to update it?"
         )
     if UsersModel.find_by_id(self.user_id) is None:
         raise Exception("User with given id doesn't exist")
     if BooksModel.find_by_isbn(self.isbn) is None:
         raise Exception("Book with given isbn doesn't exist")
     ScoresModel.add_review(self)
     db.session.add(self)
     db.session.commit()
Example #15
0
    def post(self):
        data = parse_book()
        check_constraints_book(data)
        with lock:
            book = BooksModel.find_by_isbn(data["isbn"])
            if book:
                return {
                    "message":
                    f"A book with same isbn {data['isbn']} already exists"
                }, 409
            try:
                del data['vendible']  # always set to True when post
                book = BooksModel(**data)
                book.save_to_db()
            except Exception as e:
                return {"message": str(e)}, 500

        return book.json(), 201
Example #16
0
    def get(self):
        parser = reqparse.RequestParser(bundle_errors=True)
        parser.add_argument(
            'numBooks',
            type=int,
            required=False,
            help="In this field goes the number of the books to show")
        data = parser.parse_args()
        isbns = TransactionsModel.best_sellers()

        return {
            'books':
            list(
                islice(
                    filter(
                        lambda book: book['vendible'],
                        map(
                            lambda x: BooksModel.find_by_isbn(x).json(
                                score=True), isbns)), data['numBooks']))
        }, 200
Example #17
0
 def post(self):
     data = parse_transaction()
     with lock:
         user = UsersModel.find_by_email(data['email'])
         if user is None:
             return {"message": f"User with ['email': {data['email']}] Not Found"}, 404
         if user != g.user:
             return {"message": "Invalid transaction, can only post yours"}, 401
         for isbn, quantity in zip(data['isbns'], data['quantities']):
             book = BooksModel.find_by_isbn(isbn)
             if book is None:
                 return {"message": "Book with ['isbn': " + str(isbn) + "] Not Found"}, 404
             if quantity > book.stock:
                 return {"message": "Not enough stock for book with 'isbn': " + str(isbn) + "only "
                                    + str(book.stock) + " available"}, 404
         try:
             transactions = TransactionsModel.save_transaction(user.id, data['isbns'], data['prices'],
                                                               data['quantities'])
         except Exception as ex:
             return {'message': str(ex)}, 500
     return {'transactions': transactions}, 201
Example #18
0
    def delete(self, isbn):
        with lock:
            book = BooksModel.find_by_isbn(isbn)

            if book is None:
                return {
                    "message": f"Book with ['isbn': {isbn}] Not Found"
                }, 404

            if not book.vendible:
                return {
                    "message":
                    f"Book with ['isbn': {isbn}] was previously removed"
                }, 409

            try:
                book.delete_from_db()
            except Exception as e:
                return {"message": str(e)}, 500

        return {"message": f"Book with ['isbn': {isbn}] deleted"}, 200
Example #19
0
def check_user_and_book(user_model, isbn, ignore_if_admin=False):
    if not user_model:
        abort(404, message={"message": f"User Not Found"})

    if not BooksModel.find_by_isbn(isbn):
        abort(404,
              message={"message": f"Book with ['isbn': {isbn}] Not Found"})

    if ignore_if_admin:
        # First statement checks if the role is user and that it doesn't try to modify an other user
        # Second statement checks if the user who wants to modify it's not and Admin
        if (g.user.role is not Roles.User
                or g.user != user_model) and g.user.role is not Roles.Admin:
            abort(401,
                  message={
                      "message": "Invalid user to remove, can only be yourself"
                  })
    else:
        if g.user != user_model:
            abort(401,
                  message={
                      "message": "Invalid user to remove, can only be yourself"
                  })
Example #20
0
 def post_book_invalid(self, data):
     res = self.client.post("/api/book", data=data, headers={
         "Authorization": 'Basic ' + base64.b64encode((self.token + ":").encode('ascii')).decode('ascii')
     })
     self.assertEqual(400, res.status_code)
     self.assertIsNone(BooksModel.find_by_isbn(data["isbn"]))
Example #21
0
 def save_to_db(self):
     if BooksModel.find_by_isbn(self.isbn) is None:
         raise Exception("Book with isbn doesn't exist")
     db.session.add(self)
     db.session.commit()