Exemple #1
0
    def test_update_prod_info(self):
        """ Update a product information. """
        test_prod_id = 111
        test_prod_name = "ab"
        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name)
        prod_info.save()

        # update
        test_new_qty = 10
        test_used_qty = 30
        test_open_boxed_qty = 40
        test_restock_level = 20
        test_restock_amt = 66
        prod_info.new_qty = test_new_qty
        prod_info.used_qty = test_used_qty
        prod_info.open_boxed_qty = test_open_boxed_qty
        prod_info.restock_level = test_restock_level
        prod_info.restock_amt = test_restock_amt

        prod_infos = ProductInformation.list_all()
        self.assertEqual(1, len(prod_infos))
        self.assertIsNotNone(prod_infos[0])
        self.assert_fields_equal(prod_infos[0], test_prod_id, test_prod_name,
                                 test_new_qty, test_used_qty,
                                 test_open_boxed_qty, test_restock_level,
                                 test_restock_amt)
Exemple #2
0
    def test_construct_prod_info(self):
        """ Construct a product information and assert it exists. """
        # Test with only mandatory fields.
        test_prod_id = 1
        test_prod_name = "asdf"
        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name)
        self.assertIsNotNone(prod_info)
        self.assert_fields_equal(prod_info, test_prod_id, test_prod_name, None,
                                 None, None, None, None)

        # Test with all fields.
        test_prod_id = 10
        test_prod_name = "zxcv"
        test_new_qty = 2
        test_used_qty = 3
        test_open_boxed_qty = 4
        test_restock_level = 5
        test_restock_amt = 6

        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name,
                                       new_qty=test_new_qty,
                                       used_qty=test_used_qty,
                                       open_boxed_qty=test_open_boxed_qty,
                                       restock_level=test_restock_level,
                                       restock_amt=test_restock_amt)
        self.assertIsNotNone(prod_info)
        self.assert_fields_equal(prod_info, test_prod_id, test_prod_name,
                                 test_new_qty, test_used_qty,
                                 test_open_boxed_qty, test_restock_level,
                                 test_restock_amt)
    def test_query_by_quantity(self):
        """ Query by the total quantity """
        ProductInformation(prod_id=88,
                           new_qty=1,
                           used_qty=1,
                           open_boxed_qty=1,
                           restock_level=0).save()
        ProductInformation(prod_id=99,
                           new_qty=2,
                           used_qty=2,
                           open_boxed_qty=2,
                           restock_level=0).save()

        response = self.app.get(PATH_INVENTORY_QUERY_BY_QUANTITY.format(3))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        data = json.loads(response.data)
        self.assertEqual(88, data[0]['prod_id'])

        response = self.app.get(PATH_INVENTORY_QUERY_BY_QUANTITY.format(6))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        data = json.loads(response.data)
        self.assertEqual(99, data[0]['prod_id'])

        response = self.app.get(PATH_INVENTORY_QUERY_BY_QUANTITY.format(5))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(json.loads(response.data), [])
Exemple #4
0
    def test_automatic_restock(self):
        """ Test automatic restocking functionality """
        prod_info = ProductInformation(prod_id=1, prod_name='Storm Trooper', \
                                       new_qty=20, used_qty=30, open_boxed_qty=40, \
                                       restock_level=1000, restock_amt=100)
        prod_info.save()

        retrived_prod_info = ProductInformation.find(prod_id=1)
        self.assertIsNotNone(retrived_prod_info)
        total_qty = retrived_prod_info.new_qty + retrived_prod_info.used_qty \
                + retrived_prod_info.open_boxed_qty
        self.assertEqual(total_qty, 1090)
Exemple #5
0
 def test_deserialize_prod_info(self):
     """ Test deserialization of a product information. """
     test_prod_id = 119
     test_prod_name = "fire"
     data = {PROD_ID: test_prod_id, PROD_NAME: test_prod_name}
     prod_info = ProductInformation()
     prod_info.deserialize(data)
     self.assertIsNotNone(prod_info)
     self.assert_fields_equal(prod_info, test_prod_id, test_prod_name,
                              DEFAULT_NEW_QTY, DEFAULT_USED_QTY,
                              DEFAULT_OPEN_BOXED_QTY, DEFAULT_RESTOCK_LEVEL,
                              DEFALUT_RESTOCK_AMT)
Exemple #6
0
    def test_find_by_name(self):
        """ Test find by the product name """
        ProductInformation(prod_id=1234, prod_name="foo").save()
        ProductInformation(prod_id=4321, prod_name="bar").save()

        result = ProductInformation.find_by_name("foo")
        self.assertEqual(1, len(result))
        self.assertEqual(1234, result[0].prod_id)

        ProductInformation(prod_id=5678, prod_name="foo").save()

        result = ProductInformation.find_by_name("foo")
        self.assertEqual(2, len(result))
Exemple #7
0
 def test_delete_prod_info(self):
     """ Delete a product information """
     prod_info = ProductInformation(prod_id=110, prod_name="qwe")
     prod_info.save()
     self.assertEqual(1, len(ProductInformation.list_all()))
     prod_info.delete()
     self.assertEqual(0, len(ProductInformation.list_all()))
Exemple #8
0
 def test_automatic_restock_exception(self):
     """ Test automatic_restock() when property is not initialized. """
     # Missing 'restock_level'
     prod_info = ProductInformation(prod_id=1, prod_name='Storm Trooper', \
                                    new_qty=20, used_qty=30, open_boxed_qty=40, \
                                    restock_amt=100)
     self.assertRaises(DataValidationError, prod_info.automatic_restock)
Exemple #9
0
def get_prod_info(prod_id):
    """
    Return ProductInformation identified by prod_id.
    ---
    tags:
      -     Inventory
    produces:
      -     application/json
    parameters:
      -     name: prod_id
            in: path
            description: ID of Inventory entry to retrieve
            type: integer
            required: true
    responses:
        200:
            description: Inventory entry returned
            schema:
                $ref: '#/definitions/Product'
        404:
            description: Inventory entry not found
    """
    app.logger.info("GET received, retrieve id {}.".format(prod_id))
    prod_info = ProductInformation.find(prod_id)
    if not prod_info:
        raise NotFound(NOT_FOUND_MSG.format(prod_id))
    return jsonify(prod_info.serialize()), status.HTTP_200_OK
Exemple #10
0
    def test_restock(self):
        """ Test manual restocking function. """
        prod_info = ProductInformation()

        # when new_qty is None.
        test_restock_amt = 19
        self.assertRaises(DataValidationError, prod_info.restock,
                          test_restock_amt)

        # wwhen new_qty is not None.
        test_new_qty = 3
        prod_info.new_qty = test_new_qty
        prod_info.restock(test_restock_amt)
        self.assertIsNotNone(prod_info)
        self.assert_fields_equal(prod_info, None, None,
                                 test_new_qty + test_restock_amt, None, None,
                                 None, None)
Exemple #11
0
    def test_deserialize_bad_data(self):
        """ Test deserialization of bad data. """
        prod_info = ProductInformation()

        # Input data is not of JSON format.
        data = "this is not a dictionary"
        self.assertRaises(DataValidationError, prod_info.deserialize, data)

        # Optional fields contain values smaller than defaults.
        prod_info = ProductInformation(prod_id=1,
                                       prod_name="ert",
                                       new_qty=-1,
                                       used_qty=-1,
                                       open_boxed_qty=-1,
                                       restock_level=-2,
                                       restock_amt=-1)
        self.assertRaises(DataValidationError, prod_info.deserialize, data)
 def setUp(self):
     """ Runs before each test """
     server.init_db()
     db.drop_all()
     db.create_all()
     # automatic restock will be triggered when the 2 products are saved to database.
     ProductInformation(prod_id=1,
                        prod_name='a',
                        new_qty=1,
                        used_qty=1,
                        open_boxed_qty=1,
                        restock_level=10,
                        restock_amt=10).save()
     ProductInformation(prod_id=2,
                        prod_name='b',
                        new_qty=2,
                        used_qty=2,
                        open_boxed_qty=2,
                        restock_level=20,
                        restock_amt=20).save()
     self.app = server.app.test_client()
Exemple #13
0
    def test_find_by_condition(self):
        """ Test find by the product condition """
        ProductInformation(prod_id=1234,
                           new_qty=1,
                           used_qty=0,
                           open_boxed_qty=0).save()
        ProductInformation(prod_id=4321,
                           new_qty=0,
                           used_qty=2,
                           open_boxed_qty=0).save()
        ProductInformation(prod_id=5678,
                           new_qty=1,
                           used_qty=0,
                           open_boxed_qty=3).save()

        result = ProductInformation.find_by_condition("new")
        self.assertEqual(2, len(result))

        result = ProductInformation.find_by_condition("used")
        self.assertEqual(1, len(result))
        self.assertEqual(4321, result[0].prod_id)

        result = ProductInformation.find_by_condition("open-boxed")
        self.assertEqual(1, len(result))
        self.assertEqual(5678, result[0].prod_id)
Exemple #14
0
def restock_action(prod_id):
    """
    Restock new quantity.

    This endpoint will update the number of new_qty of the given prod_id.
    ---
    tags:
        -   Inventory
    consumes:
        -   application/json
    definitions:
        Restock_Amount:
            type: object
            properties:
                restock_amt:
                    type: integer
                    minimum: 0
                    description: Amount to be added to the product's new_amt field.
    parameters:
        -   name: prod_id
            in: path
            description: ID of product.
            type: integer
            required: true
        -   in: body
            name: body
            required: true
            schema:
                id: data
                $ref: '#/definitions/Restock_Amount'
    responses:
        200:
            description: Product restocked successfully.
        400:
            description: Bad Request (invalid input data)
    """
    check_content_type(JSON)
    app.logger.info("PUT received, restock id {} with {}.".format(
        prod_id, request.get_json()))
    prod_info = ProductInformation.find(prod_id)
    if not prod_info:
        raise NotFound(NOT_FOUND_MSG.format(prod_id))

    data = request.get_json()
    add_amt = data.get('restock_amt')
    if (len(list(data.keys())) != 1) or (add_amt is None) or (add_amt < 0):
        raise BadRequest("Please only give 'restock_amt' as input.")

    prod_info.restock(add_amt)
    prod_info.save()
    return make_response(jsonify(prod_info.serialize()), status.HTTP_200_OK)
Exemple #15
0
    def test_serialize_prod_info(self):
        """ Test serialize() function """
        test_prod_id = 911
        test_prod_name = "nebula"
        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name)
        data = prod_info.serialize()

        self.assertIsNotNone(data)
        self.assertIn(PROD_ID, data)
        self.assertEqual(test_prod_id, data[PROD_ID])
        self.assertIn(PROD_NAME, data)
        self.assertEqual(test_prod_name, data[PROD_NAME])
        self.assertIn(NEW_QTY, data)
        self.assertIsNone(data[NEW_QTY])
        self.assertIn(USED_QTY, data)
        self.assertIsNone(data[USED_QTY])
        self.assertIn(OPEN_BOXED_QTY, data)
        self.assertIsNone(data[OPEN_BOXED_QTY])
        self.assertIn(RESTOCK_LEVEL, data)
        self.assertIsNone(data[RESTOCK_LEVEL])
        self.assertIn(RESTOCK_AMT, data)
        self.assertIsNone(data[RESTOCK_AMT])
Exemple #16
0
    def test_deserialize_update_prod_info(self):
        """ Test deserialization while updating product information. """
        #create entry in order check deserialization
        test_prod_id = 1
        test_prod_name = "asdf"
        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name)
        self.assertIsNotNone(prod_info)
        self.assert_fields_equal(prod_info, test_prod_id, test_prod_name, None,
                                 None, None, None, None)

        #test deserialize_update when
        test_prod_name = "fire"
        data = {PROD_NAME: test_prod_name, RESTOCK_AMT: 5}
        prod_info.deserialize_update(data)
        self.assertIsNotNone(prod_info)
        self.assert_fields_equal(prod_info, test_prod_id, test_prod_name, None,
                                 None, None, None, 5)

        #test deserilaize_update when prod_id is provided
        update_prod_id = 3
        test_prod_name = "fire"
        data = {
            PROD_ID: update_prod_id,
            PROD_NAME: test_prod_name,
            RESTOCK_AMT: 5
        }
        prod_info = ProductInformation()
        self.assertRaises(DataValidationError, prod_info.deserialize_update,
                          data)

        # Optional fields contain values smaller than defaults.
        prod_info = ProductInformation(prod_name="ert",
                                       new_qty=-1,
                                       used_qty=-1,
                                       open_boxed_qty=-1,
                                       restock_level=-2,
                                       restock_amt=-1)
        self.assertRaises(DataValidationError, prod_info.deserialize_update,
                          data)
Exemple #17
0
def update_prod_info(prod_id):
    """
    Update ProdcutInformation

    This endpoint will update product inventory information (by id) based on data posted in the body
    ---
    tags:
        -   Inventory
    consumes:
        -   application/json
    produces:
        -   application/json
    parameters:
        -   name: prod_id
            in: path
            description: ID of product information to be updated
            type: integer
            required: true
        -   in: body
            name: body
            schema:
                id: data
                $ref: '#/definitions/Product'
    responses:
        200:
            description: Inventory information Updated
            schema:
                $ref: '#/definitions/Product'
        400:
            description: Bad Request (the posted data was not valid)
    """
    check_content_type(JSON)
    app.logger.info("PUT received, update id {} with payload {}.".format(
        prod_id, request.get_json()))
    prod_info = ProductInformation.find(prod_id)
    if not prod_info:
        raise NotFound(NOT_FOUND_MSG.format(prod_id))

    prod_info.deserialize_update(request.get_json())
    prod_info.save()
    return make_response(jsonify(prod_info.serialize()), status.HTTP_200_OK)
Exemple #18
0
    def test_create_prod_info(self):
        """ Create a new prodct information and add it to the data table """
        prod_infos = ProductInformation.list_all()
        self.assertEqual(prod_infos, [])

        test_prod_id = 11
        test_prod_name = "a"
        prod_info = ProductInformation(prod_id=test_prod_id,
                                       prod_name=test_prod_name)
        prod_info.save()
        prod_infos = ProductInformation.list_all()

        self.assertEqual(1, len(prod_infos))
        self.assertIsNotNone(prod_infos[0])
        self.assert_fields_equal(prod_infos[0], test_prod_id, test_prod_name,
                                 None, None, None, None, None)
Exemple #19
0
def delete_prod_info(prod_id):
    """
    Deletes a ProductInformation
    This endpoint will delete a ProductInformation based on the prod_id specified in the path.
    Should always return 200 OK.
    ---
    tags:
        -   Inventory
    parameters:
        -   in: path
            name: prod_id
            type: integer
            required: true
            description: prod_id of the product information to be deleted.
    responses:
        200:
            description: Product information deleted.
    """
    app.logger.info("DELETE received, delete id {}.".format(prod_id))
    prod_info = ProductInformation.find(prod_id)
    if prod_info:
        prod_info.delete()
    return make_response('', status.HTTP_200_OK)
Exemple #20
0
    def test_find_by_quantity(self):
        """ Test find by the product quantity """
        ProductInformation(prod_id=1234,
                           new_qty=1,
                           used_qty=2,
                           open_boxed_qty=3).save()
        ProductInformation(prod_id=4321,
                           new_qty=5,
                           used_qty=1,
                           open_boxed_qty=2).save()

        result = ProductInformation.find_by_quantity(1)
        self.assertEqual(0, len(result))

        result = ProductInformation.find_by_quantity(6)
        self.assertEqual(1, len(result))
        self.assertEqual(1234, result[0].prod_id)

        result = ProductInformation.find_by_quantity(8)
        self.assertEqual(1, len(result))
        self.assertEqual(4321, result[0].prod_id)

        result = ProductInformation.find_by_quantity(-1)
        self.assertEqual(0, len(result))
Exemple #21
0
def init_db():
    """ Initialies the SQLAlchemy app """
    ProductInformation.init_db()
Exemple #22
0
def query_prod_info():
    """
    Retrieve a list of all the products in the inventory & query specific entries in the Inventory system
    This endpoint will return all the details of the products in the inventory unless a query parameter is specificed
    ---
    tags:
      -     Inventory
    description: The inventory endpoint allows you to query the inventory
    parameters:
      -     name: prod_name
            in: query
            description: the name of the product you are looking for
            required: false
            type: string
      -     name: quantity
            in: query
            description: if you want to check how many products have a specfic quantity
            required: false
            type: integer
      -     name: condition
            in: query
            description: if you want to find all the products of a certain condition (e.g. new, used, open_boxed)
            required: false
            type: string
            enum:
                - new
                - used
                - open_boxed

    responses:
      400:
          description: Bad Request (invalid posted data)
      200:
          description: An array of all the products
          schema:
            type: array
            items:
              schema:
                $ref: '#/definitions/Product'
    """
    if request.args:
        app.logger.info("GET received, List all that satisfy {}.".format(
            request.args.to_dict()))
    else:
        app.logger.info("GET received, List all.")

    all_prod_info = []
    if request.args.get('prod_name'):
        prod_name = request.args.get('prod_name')
        all_prod_info = ProductInformation.find_by_name(prod_name)
    elif request.args.get('quantity'):
        quantity = request.args.get('quantity')
        try:
            quantity = int(quantity)
            all_prod_info = ProductInformation.find_by_quantity(quantity)
        except ValueError:
            abort(status.HTTP_400_BAD_REQUEST, INVALID_PARAMETER_MSG)
    elif request.args.get('condition'):
        condition = request.args.get('condition')
        if condition in ['new', 'used', 'open-boxed']:
            all_prod_info = ProductInformation.find_by_condition(condition)
        else:
            abort(status.HTTP_400_BAD_REQUEST, INVALID_PARAMETER_MSG)
    elif not request.args:
        all_prod_info = ProductInformation.list_all()
    else:
        abort(status.HTTP_400_BAD_REQUEST, INVALID_PARAMETER_MSG)

    results = [prod_info.serialize() for prod_info in all_prod_info]
    return jsonify(results), status.HTTP_200_OK
Exemple #23
0
def create_prod_info():
    """
    Creates a ProductInformation
    This endpoint will create a ProductInformation based the data in the body that is posted
    ---
    tags:
        -   Inventory
    consumes:
        -   application/json
    produces:
        -   application/json
    definitions:
        Product:
            type: object
            properties:
                prod_id:
                    type: integer
                    description: Unique ID of the product.
                prod_name:
                    type: string
                    description: Name for the product.
                new_qty:
                    type: integer
                    description: Quantity of condition "new".
                used_qty:
                    type: integer
                    description: Quantity of condition "used".
                open_boxed_qty:
                    type: integer
                    description: Quantity of condition "open boxed".
                restock_level:
                    type: integer
                    minimum: -1
                    description: Bottom line of a product's quantity with condition "new".
                restock_amt:
                    type: integer
                    description: Quantity to be added to a product's quantity with condition "new".
    parameters:
        -   in: body
            name: body
            required: true
            schema:
                id: data
                required:
                    - prod_id
                    - prod_name
                $ref: '#/definitions/Product'

    responses:
        201:
            description: Product information created
            schema:
                $ref: '#/definitions/Product'
        400:
            description: Bad Request (invalid posted data)
    """
    check_content_type(JSON)
    app.logger.info("POST received, create with payload {}.".format(
        request.get_json()))
    prod_info = ProductInformation()
    prod_info.deserialize(request.get_json())

    if ProductInformation.find(prod_info.prod_id):
        raise BadRequest(CANNOT_CREATE_MSG.format(prod_info.prod_id))

    prod_info.save()
    message = prod_info.serialize()
    location_url = url_for(GET_PROD_INFO,
                           prod_id=prod_info.prod_id,
                           _external=True)
    return make_response(jsonify(message), status.HTTP_201_CREATED,
                         {LOCATION: location_url})