diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000000..eaf91e2ac64 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AirBnB_clone_v3.iml b/.idea/AirBnB_clone_v3.iml new file mode 100644 index 00000000000..4e7029ca8c6 --- /dev/null +++ b/.idea/AirBnB_clone_v3.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000000..105ce2da2d6 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000000..f8a22e9456d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000000..c3e6da60a8a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000000..35eb1ddfbbc --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/0-setup_web_static.sh b/0-setup_web_static.sh index 3b2de157983..5b68972082b 100755 --- a/0-setup_web_static.sh +++ b/0-setup_web_static.sh @@ -1,12 +1,12 @@ -#!/usr/bin/env bash -# sets up the web servers for the deployment of web_static - -sudo apt-get -y update -sudo apt-get -y upgrade -sudo apt-get -y install nginx -sudo mkdir -p /data/web_static/releases/test /data/web_static/shared -echo "This is a test" | sudo tee /data/web_static/releases/test/index.html -sudo ln -sf /data/web_static/releases/test/ /data/web_static/current -sudo chown -hR ubuntu:ubuntu /data/ -sudo sed -i '38i\\tlocation /hbnb_static/ {\n\t\talias /data/web_static/current/;\n\t}\n' /etc/nginx/sites-available/default -sudo service nginx start +#!/usr/bin/env bash +# sets up the web servers for the deployment of web_static + +sudo apt-get -y update +sudo apt-get -y upgrade +sudo apt-get -y install nginx +sudo mkdir -p /data/web_static/releases/test /data/web_static/shared +echo "This is a test" | sudo tee /data/web_static/releases/test/index.html +sudo ln -sf /data/web_static/releases/test/ /data/web_static/current +sudo chown -hR ubuntu:ubuntu /data/ +sudo sed -i '38i\\tlocation /hbnb_static/ {\n\t\talias /data/web_static/current/;\n\t}\n' /etc/nginx/sites-available/default +sudo service nginx start diff --git a/1-pack_web_static.py b/1-pack_web_static.py index f08a8aea659..e4edb0f1a81 100644 --- a/1-pack_web_static.py +++ b/1-pack_web_static.py @@ -1,22 +1,22 @@ -#!/usr/bin/python3 -""" -Fabric script that generates a tgz archive from the contents of the web_static -folder of the AirBnB Clone repo -""" - -from datetime import datetime -from fabric.api import local -from os.path import isdir - - -def do_pack(): - """generates a tgz archive""" - try: - date = datetime.now().strftime("%Y%m%d%H%M%S") - if isdir("versions") is False: - local("mkdir versions") - file_name = "versions/web_static_{}.tgz".format(date) - local("tar -cvzf {} web_static".format(file_name)) - return file_name - except: - return None +#!/usr/bin/python3 +""" +Fabric script that generates a tgz archive from the contents of the web_static +folder of the AirBnB Clone repo +""" + +from datetime import datetime +from fabric.api import local +from os.path import isdir + + +def do_pack(): + """generates a tgz archive""" + try: + date = datetime.now().strftime("%Y%m%d%H%M%S") + if isdir("versions") is False: + local("mkdir versions") + file_name = "versions/web_static_{}.tgz".format(date) + local("tar -cvzf {} web_static".format(file_name)) + return file_name + except: + return None diff --git a/2-do_deploy_web_static.py b/2-do_deploy_web_static.py index aa5ab7852c6..ca48f2542d5 100644 --- a/2-do_deploy_web_static.py +++ b/2-do_deploy_web_static.py @@ -1,30 +1,30 @@ -#!/usr/bin/python3 -""" -Fabric script based on the file 1-pack_web_static.py that distributes an -archive to the web servers -""" - -from fabric.api import put, run, env -from os.path import exists -env.hosts = ['142.44.167.228', '144.217.246.195'] - - -def do_deploy(archive_path): - """distributes an archive to the web servers""" - if exists(archive_path) is False: - return False - try: - file_n = archive_path.split("/")[-1] - no_ext = file_n.split(".")[0] - path = "/data/web_static/releases/" - put(archive_path, '/tmp/') - run('mkdir -p {}{}/'.format(path, no_ext)) - run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) - run('rm /tmp/{}'.format(file_n)) - run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) - run('rm -rf {}{}/web_static'.format(path, no_ext)) - run('rm -rf /data/web_static/current') - run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) - return True - except: - return False +#!/usr/bin/python3 +""" +Fabric script based on the file 1-pack_web_static.py that distributes an +archive to the web servers +""" + +from fabric.api import put, run, env +from os.path import exists +env.hosts = ['142.44.167.228', '144.217.246.195'] + + +def do_deploy(archive_path): + """distributes an archive to the web servers""" + if exists(archive_path) is False: + return False + try: + file_n = archive_path.split("/")[-1] + no_ext = file_n.split(".")[0] + path = "/data/web_static/releases/" + put(archive_path, '/tmp/') + run('mkdir -p {}{}/'.format(path, no_ext)) + run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) + run('rm /tmp/{}'.format(file_n)) + run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) + run('rm -rf {}{}/web_static'.format(path, no_ext)) + run('rm -rf /data/web_static/current') + run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) + return True + except: + return False diff --git a/3-deploy_web_static.py b/3-deploy_web_static.py index f7e7e254b5e..3ac7718e594 100644 --- a/3-deploy_web_static.py +++ b/3-deploy_web_static.py @@ -1,52 +1,52 @@ -#!/usr/bin/python3 -""" -Fabric script based on the file 2-do_deploy_web_static.py that creates and -distributes an archive to the web servers -""" - -from fabric.api import env, local, put, run -from datetime import datetime -from os.path import exists, isdir -env.hosts = ['142.44.167.228', '144.217.246.195'] - - -def do_pack(): - """generates a tgz archive""" - try: - date = datetime.now().strftime("%Y%m%d%H%M%S") - if isdir("versions") is False: - local("mkdir versions") - file_name = "versions/web_static_{}.tgz".format(date) - local("tar -cvzf {} web_static".format(file_name)) - return file_name - except: - return None - - -def do_deploy(archive_path): - """distributes an archive to the web servers""" - if exists(archive_path) is False: - return False - try: - file_n = archive_path.split("/")[-1] - no_ext = file_n.split(".")[0] - path = "/data/web_static/releases/" - put(archive_path, '/tmp/') - run('mkdir -p {}{}/'.format(path, no_ext)) - run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) - run('rm /tmp/{}'.format(file_n)) - run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) - run('rm -rf {}{}/web_static'.format(path, no_ext)) - run('rm -rf /data/web_static/current') - run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) - return True - except: - return False - - -def deploy(): - """creates and distributes an archive to the web servers""" - archive_path = do_pack() - if archive_path is None: - return False - return do_deploy(archive_path) +#!/usr/bin/python3 +""" +Fabric script based on the file 2-do_deploy_web_static.py that creates and +distributes an archive to the web servers +""" + +from fabric.api import env, local, put, run +from datetime import datetime +from os.path import exists, isdir +env.hosts = ['142.44.167.228', '144.217.246.195'] + + +def do_pack(): + """generates a tgz archive""" + try: + date = datetime.now().strftime("%Y%m%d%H%M%S") + if isdir("versions") is False: + local("mkdir versions") + file_name = "versions/web_static_{}.tgz".format(date) + local("tar -cvzf {} web_static".format(file_name)) + return file_name + except: + return None + + +def do_deploy(archive_path): + """distributes an archive to the web servers""" + if exists(archive_path) is False: + return False + try: + file_n = archive_path.split("/")[-1] + no_ext = file_n.split(".")[0] + path = "/data/web_static/releases/" + put(archive_path, '/tmp/') + run('mkdir -p {}{}/'.format(path, no_ext)) + run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) + run('rm /tmp/{}'.format(file_n)) + run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) + run('rm -rf {}{}/web_static'.format(path, no_ext)) + run('rm -rf /data/web_static/current') + run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) + return True + except: + return False + + +def deploy(): + """creates and distributes an archive to the web servers""" + archive_path = do_pack() + if archive_path is None: + return False + return do_deploy(archive_path) diff --git a/AUTHORS b/AUTHORS index 64b26acdc14..58ae0b34678 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,5 @@ -# This file lists all individuals having contributed content to the repository. - - -Jennifer Huang <133@holbertonschool.com> -Alexa Orrico <210@holbertonschool.com> -Joann Vuong <130@holbertonschool.com> +# This file lists all individuals having contributed content to the repository. + + +Tuyizere Victor + diff --git a/README.md b/README.md index f1d72de6355..cb4c28ff5bc 100644 --- a/README.md +++ b/README.md @@ -1,162 +1,162 @@ -# AirBnB Clone - The Console -The console is the first segment of the AirBnB project at Holberton School that will collectively cover fundamental concepts of higher level programming. The goal of AirBnB project is to eventually deploy our server a simple copy of the AirBnB Website(HBnB). A command interpreter is created in this segment to manage objects for the AirBnB(HBnB) website. - -#### Functionalities of this command interpreter: -* Create a new object (ex: a new User or a new Place) -* Retrieve an object from a file, a database etc... -* Do operations on objects (count, compute stats, etc...) -* Update attributes of an object -* Destroy an object - -## Table of Content -* [Environment](#environment) -* [Installation](#installation) -* [File Descriptions](#file-descriptions) -* [Usage](#usage) -* [Examples of use](#examples-of-use) -* [Bugs](#bugs) -* [Authors](#authors) -* [License](#license) - -## Environment -This project is interpreted/tested on Ubuntu 14.04 LTS using python3 (version 3.4.3) - -## Installation -* Clone this repository: `git clone "https://github.com/alexaorrico/AirBnB_clone.git"` -* Access AirBnb directory: `cd AirBnB_clone` -* Run hbnb(interactively): `./console` and enter command -* Run hbnb(non-interactively): `echo "" | ./console.py` - -## File Descriptions -[console.py](console.py) - the console contains the entry point of the command interpreter. -List of commands this console current supports: -* `EOF` - exits console -* `quit` - exits console -* `` - overwrites default emptyline method and does nothing -* `create` - Creates a new instance of`BaseModel`, saves it (to the JSON file) and prints the id -* `destroy` - Deletes an instance based on the class name and id (save the change into the JSON file). -* `show` - Prints the string representation of an instance based on the class name and id. -* `all` - Prints all string representation of all instances based or not on the class name. -* `update` - Updates an instance based on the class name and id by adding or updating attribute (save the change into the JSON file). - -#### `models/` directory contains classes used for this project: -[base_model.py](/models/base_model.py) - The BaseModel class from which future classes will be derived -* `def __init__(self, *args, **kwargs)` - Initialization of the base model -* `def __str__(self)` - String representation of the BaseModel class -* `def save(self)` - Updates the attribute `updated_at` with the current datetime -* `def to_dict(self)` - returns a dictionary containing all keys/values of the instance - -Classes inherited from Base Model: -* [amenity.py](/models/amenity.py) -* [city.py](/models/city.py) -* [place.py](/models/place.py) -* [review.py](/models/review.py) -* [state.py](/models/state.py) -* [user.py](/models/user.py) - -#### `/models/engine` directory contains File Storage class that handles JASON serialization and deserialization : -[file_storage.py](/models/engine/file_storage.py) - serializes instances to a JSON file & deserializes back to instances -* `def all(self)` - returns the dictionary __objects -* `def new(self, obj)` - sets in __objects the obj with key .id -* `def save(self)` - serializes __objects to the JSON file (path: __file_path) -* ` def reload(self)` - deserializes the JSON file to __objects - -#### `/tests` directory contains all unit test cases for this project: -[/test_models/test_base_model.py](/tests/test_models/test_base_model.py) - Contains the TestBaseModel and TestBaseModelDocs classes -TestBaseModelDocs class: -* `def setUpClass(cls)`- Set up for the doc tests -* `def test_pep8_conformance_base_model(self)` - Test that models/base_model.py conforms to PEP8 -* `def test_pep8_conformance_test_base_model(self)` - Test that tests/test_models/test_base_model.py conforms to PEP8 -* `def test_bm_module_docstring(self)` - Test for the base_model.py module docstring -* `def test_bm_class_docstring(self)` - Test for the BaseModel class docstring -* `def test_bm_func_docstrings(self)` - Test for the presence of docstrings in BaseModel methods - -TestBaseModel class: -* `def test_is_base_model(self)` - Test that the instatiation of a BaseModel works -* `def test_created_at_instantiation(self)` - Test created_at is a pub. instance attribute of type datetime -* `def test_updated_at_instantiation(self)` - Test updated_at is a pub. instance attribute of type datetime -* `def test_diff_datetime_objs(self)` - Test that two BaseModel instances have different datetime objects - -[/test_models/test_amenity.py](/tests/test_models/test_amenity.py) - Contains the TestAmenityDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_amenity(self)` - Test that models/amenity.py conforms to PEP8 -* `def test_pep8_conformance_test_amenity(self)` - Test that tests/test_models/test_amenity.py conforms to PEP8 -* `def test_amenity_module_docstring(self)` - Test for the amenity.py module docstring -* `def test_amenity_class_docstring(self)` - Test for the Amenity class docstring - -[/test_models/test_city.py](/tests/test_models/test_city.py) - Contains the TestCityDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_city(self)` - Test that models/city.py conforms to PEP8 -* `def test_pep8_conformance_test_city(self)` - Test that tests/test_models/test_city.py conforms to PEP8 -* `def test_city_module_docstring(self)` - Test for the city.py module docstring -* `def test_city_class_docstring(self)` - Test for the City class docstring - -[/test_models/test_file_storage.py](/tests/test_models/test_file_storage.py) - Contains the TestFileStorageDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_file_storage(self)` - Test that models/file_storage.py conforms to PEP8 -* `def test_pep8_conformance_test_file_storage(self)` - Test that tests/test_models/test_file_storage.py conforms to PEP8 -* `def test_file_storage_module_docstring(self)` - Test for the file_storage.py module docstring -* `def test_file_storage_class_docstring(self)` - Test for the FileStorage class docstring - -[/test_models/test_place.py](/tests/test_models/test_place.py) - Contains the TestPlaceDoc class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_place(self)` - Test that models/place.py conforms to PEP8. -* `def test_pep8_conformance_test_place(self)` - Test that tests/test_models/test_place.py conforms to PEP8. -* `def test_place_module_docstring(self)` - Test for the place.py module docstring -* `def test_place_class_docstring(self)` - Test for the Place class docstring - -[/test_models/test_review.py](/tests/test_models/test_review.py) - Contains the TestReviewDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_review(self)` - Test that models/review.py conforms to PEP8 -* `def test_pep8_conformance_test_review(self)` - Test that tests/test_models/test_review.py conforms to PEP8 -* `def test_review_module_docstring(self)` - Test for the review.py module docstring -* `def test_review_class_docstring(self)` - Test for the Review class docstring - -[/test_models/state.py](/tests/test_models/test_state.py) - Contains the TestStateDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_state(self)` - Test that models/state.py conforms to PEP8 -* `def test_pep8_conformance_test_state(self)` - Test that tests/test_models/test_state.py conforms to PEP8 -* `def test_state_module_docstring(self)` - Test for the state.py module docstring -* `def test_state_class_docstring(self)` - Test for the State class docstring - -[/test_models/user.py](/tests/test_models/test_user.py) - Contains the TestUserDocs class: -* `def setUpClass(cls)` - Set up for the doc tests -* `def test_pep8_conformance_user(self)` - Test that models/user.py conforms to PEP8 -* `def test_pep8_conformance_test_user(self)` - Test that tests/test_models/test_user.py conforms to PEP8 -* `def test_user_module_docstring(self)` - Test for the user.py module docstring -* `def test_user_class_docstring(self)` - Test for the User class docstring - - -## Examples of use -``` -vagrantAirBnB_clone$./console.py -(hbnb) help - -Documented commands (type help ): -======================================== -EOF all create destroy help quit show update - -(hbnb) all MyModel -** class doesn't exist ** -(hbnb) create BaseModel -7da56403-cc45-4f1c-ad32-bfafeb2bb050 -(hbnb) all BaseModel -[[BaseModel] (7da56403-cc45-4f1c-ad32-bfafeb2bb050) {'updated_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772167), 'id': '7da56403-cc45-4f1c-ad32-bfafeb2bb050', 'created_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772123)}] -(hbnb) show BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 -[BaseModel] (7da56403-cc45-4f1c-ad32-bfafeb2bb050) {'updated_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772167), 'id': '7da56403-cc45-4f1c-ad32-bfafeb2bb050', 'created_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772123)} -(hbnb) destroy BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 -(hbnb) show BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 -** no instance found ** -(hbnb) quit -``` - -## Bugs -No known bugs at this time. - -## Authors -Alexa Orrico - [Github](https://github.com/alexaorrico) / [Twitter](https://twitter.com/alexa_orrico) -Jennifer Huang - [Github](https://github.com/jhuang10123) / [Twitter](https://twitter.com/earthtojhuang) - -Second part of Airbnb: Joann Vuong -## License -Public Domain. No copy write protection. +# AirBnB Clone - The Console +The console is the first segment of the AirBnB project at Holberton School that will collectively cover fundamental concepts of higher level programming. The goal of AirBnB project is to eventually deploy our server a simple copy of the AirBnB Website(HBnB). A command interpreter is created in this segment to manage objects for the AirBnB(HBnB) website. + +#### Functionalities of this command interpreter: +* Create a new object (ex: a new User or a new Place) +* Retrieve an object from a file, a database etc... +* Do operations on objects (count, compute stats, etc...) +* Update attributes of an object +* Destroy an object + +## Table of Content +* [Environment](#environment) +* [Installation](#installation) +* [File Descriptions](#file-descriptions) +* [Usage](#usage) +* [Examples of use](#examples-of-use) +* [Bugs](#bugs) +* [Authors](#authors) +* [License](#license) + +## Environment +This project is interpreted/tested on Ubuntu 14.04 LTS using python3 (version 3.4.3) + +## Installation +* Clone this repository: `git clone "https://github.com/alexaorrico/AirBnB_clone.git"` +* Access AirBnb directory: `cd AirBnB_clone` +* Run hbnb(interactively): `./console` and enter command +* Run hbnb(non-interactively): `echo "" | ./console.py` + +## File Descriptions +[console.py](console.py) - the console contains the entry point of the command interpreter. +List of commands this console current supports: +* `EOF` - exits console +* `quit` - exits console +* `` - overwrites default emptyline method and does nothing +* `create` - Creates a new instance of`BaseModel`, saves it (to the JSON file) and prints the id +* `destroy` - Deletes an instance based on the class name and id (save the change into the JSON file). +* `show` - Prints the string representation of an instance based on the class name and id. +* `all` - Prints all string representation of all instances based or not on the class name. +* `update` - Updates an instance based on the class name and id by adding or updating attribute (save the change into the JSON file). + +#### `models/` directory contains classes used for this project: +[base_model.py](/models/base_model.py) - The BaseModel class from which future classes will be derived +* `def __init__(self, *args, **kwargs)` - Initialization of the base model +* `def __str__(self)` - String representation of the BaseModel class +* `def save(self)` - Updates the attribute `updated_at` with the current datetime +* `def to_dict(self)` - returns a dictionary containing all keys/values of the instance + +Classes inherited from Base Model: +* [amenity.py](/models/amenity.py) +* [city.py](/models/city.py) +* [place.py](/models/place.py) +* [review.py](/models/review.py) +* [state.py](/models/state.py) +* [user.py](/models/user.py) + +#### `/models/engine` directory contains File Storage class that handles JASON serialization and deserialization : +[file_storage.py](/models/engine/file_storage.py) - serializes instances to a JSON file & deserializes back to instances +* `def all(self)` - returns the dictionary __objects +* `def new(self, obj)` - sets in __objects the obj with key .id +* `def save(self)` - serializes __objects to the JSON file (path: __file_path) +* ` def reload(self)` - deserializes the JSON file to __objects + +#### `/tests` directory contains all unit test cases for this project: +[/test_models/test_base_model.py](/tests/test_models/test_base_model.py) - Contains the TestBaseModel and TestBaseModelDocs classes +TestBaseModelDocs class: +* `def setUpClass(cls)`- Set up for the doc tests +* `def test_pep8_conformance_base_model(self)` - Test that models/base_model.py conforms to PEP8 +* `def test_pep8_conformance_test_base_model(self)` - Test that tests/test_models/test_base_model.py conforms to PEP8 +* `def test_bm_module_docstring(self)` - Test for the base_model.py module docstring +* `def test_bm_class_docstring(self)` - Test for the BaseModel class docstring +* `def test_bm_func_docstrings(self)` - Test for the presence of docstrings in BaseModel methods + +TestBaseModel class: +* `def test_is_base_model(self)` - Test that the instatiation of a BaseModel works +* `def test_created_at_instantiation(self)` - Test created_at is a pub. instance attribute of type datetime +* `def test_updated_at_instantiation(self)` - Test updated_at is a pub. instance attribute of type datetime +* `def test_diff_datetime_objs(self)` - Test that two BaseModel instances have different datetime objects + +[/test_models/test_amenity.py](/tests/test_models/test_amenity.py) - Contains the TestAmenityDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_amenity(self)` - Test that models/amenity.py conforms to PEP8 +* `def test_pep8_conformance_test_amenity(self)` - Test that tests/test_models/test_amenity.py conforms to PEP8 +* `def test_amenity_module_docstring(self)` - Test for the amenity.py module docstring +* `def test_amenity_class_docstring(self)` - Test for the Amenity class docstring + +[/test_models/test_city.py](/tests/test_models/test_city.py) - Contains the TestCityDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_city(self)` - Test that models/city.py conforms to PEP8 +* `def test_pep8_conformance_test_city(self)` - Test that tests/test_models/test_city.py conforms to PEP8 +* `def test_city_module_docstring(self)` - Test for the city.py module docstring +* `def test_city_class_docstring(self)` - Test for the City class docstring + +[/test_models/test_file_storage.py](/tests/test_models/test_file_storage.py) - Contains the TestFileStorageDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_file_storage(self)` - Test that models/file_storage.py conforms to PEP8 +* `def test_pep8_conformance_test_file_storage(self)` - Test that tests/test_models/test_file_storage.py conforms to PEP8 +* `def test_file_storage_module_docstring(self)` - Test for the file_storage.py module docstring +* `def test_file_storage_class_docstring(self)` - Test for the FileStorage class docstring + +[/test_models/test_place.py](/tests/test_models/test_place.py) - Contains the TestPlaceDoc class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_place(self)` - Test that models/place.py conforms to PEP8. +* `def test_pep8_conformance_test_place(self)` - Test that tests/test_models/test_place.py conforms to PEP8. +* `def test_place_module_docstring(self)` - Test for the place.py module docstring +* `def test_place_class_docstring(self)` - Test for the Place class docstring + +[/test_models/test_review.py](/tests/test_models/test_review.py) - Contains the TestReviewDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_review(self)` - Test that models/review.py conforms to PEP8 +* `def test_pep8_conformance_test_review(self)` - Test that tests/test_models/test_review.py conforms to PEP8 +* `def test_review_module_docstring(self)` - Test for the review.py module docstring +* `def test_review_class_docstring(self)` - Test for the Review class docstring + +[/test_models/state.py](/tests/test_models/test_state.py) - Contains the TestStateDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_state(self)` - Test that models/state.py conforms to PEP8 +* `def test_pep8_conformance_test_state(self)` - Test that tests/test_models/test_state.py conforms to PEP8 +* `def test_state_module_docstring(self)` - Test for the state.py module docstring +* `def test_state_class_docstring(self)` - Test for the State class docstring + +[/test_models/user.py](/tests/test_models/test_user.py) - Contains the TestUserDocs class: +* `def setUpClass(cls)` - Set up for the doc tests +* `def test_pep8_conformance_user(self)` - Test that models/user.py conforms to PEP8 +* `def test_pep8_conformance_test_user(self)` - Test that tests/test_models/test_user.py conforms to PEP8 +* `def test_user_module_docstring(self)` - Test for the user.py module docstring +* `def test_user_class_docstring(self)` - Test for the User class docstring + + +## Examples of use +``` +vagrantAirBnB_clone$./console.py +(hbnb) help + +Documented commands (type help ): +======================================== +EOF all create destroy help quit show update + +(hbnb) all MyModel +** class doesn't exist ** +(hbnb) create BaseModel +7da56403-cc45-4f1c-ad32-bfafeb2bb050 +(hbnb) all BaseModel +[[BaseModel] (7da56403-cc45-4f1c-ad32-bfafeb2bb050) {'updated_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772167), 'id': '7da56403-cc45-4f1c-ad32-bfafeb2bb050', 'created_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772123)}] +(hbnb) show BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 +[BaseModel] (7da56403-cc45-4f1c-ad32-bfafeb2bb050) {'updated_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772167), 'id': '7da56403-cc45-4f1c-ad32-bfafeb2bb050', 'created_at': datetime.datetime(2017, 9, 28, 9, 50, 46, 772123)} +(hbnb) destroy BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 +(hbnb) show BaseModel 7da56403-cc45-4f1c-ad32-bfafeb2bb050 +** no instance found ** +(hbnb) quit +``` + +## Bugs +No known bugs at this time. + +## Authors +Alexa Orrico - [Github](https://github.com/alexaorrico) / [Twitter](https://twitter.com/alexa_orrico) +Jennifer Huang - [Github](https://github.com/jhuang10123) / [Twitter](https://twitter.com/earthtojhuang) + +Second part of Airbnb: Joann Vuong +## License +Public Domain. No copy write protection. diff --git a/__pycache__/console.cpython-37.pyc b/__pycache__/console.cpython-37.pyc new file mode 100644 index 00000000000..c56e8292949 Binary files /dev/null and b/__pycache__/console.cpython-37.pyc differ diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/api/__pycache__/__init__.cpython-37.pyc b/api/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..d39565db664 Binary files /dev/null and b/api/__pycache__/__init__.cpython-37.pyc differ diff --git a/api/v1/__init__.py b/api/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/api/v1/__pycache__/__init__.cpython-37.pyc b/api/v1/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..15eb3883dc2 Binary files /dev/null and b/api/v1/__pycache__/__init__.cpython-37.pyc differ diff --git a/api/v1/__pycache__/app.cpython-37.pyc b/api/v1/__pycache__/app.cpython-37.pyc new file mode 100644 index 00000000000..66908d99e14 Binary files /dev/null and b/api/v1/__pycache__/app.cpython-37.pyc differ diff --git a/api/v1/app.py b/api/v1/app.py new file mode 100644 index 00000000000..47df20b4e77 --- /dev/null +++ b/api/v1/app.py @@ -0,0 +1,32 @@ +#!/usr/bin/python3 +"""Flask web application""" + +from flask import Flask, Blueprint, make_response, jsonify +from api.v1.views import app_views +from models import storage +from os import getenv +from flask_cors import CORS + + +app = Flask(__name__) +app.register_blueprint(app_views) + +cors = CORS(app, resources={r"/*": {"origins": "0.0.0.0"}}) + + +@app.teardown_appcontext +def teardown_context(exception): + """Calls storage.close() at the end of the request""" + storage.close() + + +@app.errorhandler(404) +def not_found(error): + """Handler for 404 errors""" + return make_response(jsonify({"error": "Not found"}), 404) + + +if __name__ == "__main__": + host = getenv("HBNB_API_HOST", '0.0.0.0') + port = getenv("HBNB_API_PORT", '5000') + app.run(host=host, port=port, threaded=True, debug=True) \ No newline at end of file diff --git a/api/v1/views/__init__.py b/api/v1/views/__init__.py new file mode 100644 index 00000000000..dc519395048 --- /dev/null +++ b/api/v1/views/__init__.py @@ -0,0 +1,10 @@ +#!/usr/bin/python3 +""" Blueprint for API """ +from flask import Blueprint + +app_views = Blueprint('app_views', __name__, url_prefix='/api/v1') + +# Wildcard import is still expected +from api.v1.views.index import * +from api.v1.views.amenities import * +from api.v1.views.users import * \ No newline at end of file diff --git a/api/v1/views/__pycache__/__init__.cpython-37.pyc b/api/v1/views/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..dbaf4c12cd1 Binary files /dev/null and b/api/v1/views/__pycache__/__init__.cpython-37.pyc differ diff --git a/api/v1/views/__pycache__/amenities.cpython-37.pyc b/api/v1/views/__pycache__/amenities.cpython-37.pyc new file mode 100644 index 00000000000..ba3eed5e44e Binary files /dev/null and b/api/v1/views/__pycache__/amenities.cpython-37.pyc differ diff --git a/api/v1/views/__pycache__/index.cpython-37.pyc b/api/v1/views/__pycache__/index.cpython-37.pyc new file mode 100644 index 00000000000..3fae89553f2 Binary files /dev/null and b/api/v1/views/__pycache__/index.cpython-37.pyc differ diff --git a/api/v1/views/__pycache__/users.cpython-37.pyc b/api/v1/views/__pycache__/users.cpython-37.pyc new file mode 100644 index 00000000000..b5d8dfb8657 Binary files /dev/null and b/api/v1/views/__pycache__/users.cpython-37.pyc differ diff --git a/api/v1/views/amenities.py b/api/v1/views/amenities.py new file mode 100644 index 00000000000..aeaf3586329 --- /dev/null +++ b/api/v1/views/amenities.py @@ -0,0 +1,94 @@ +#!/usr/bin/python3 +""" objects that handles all default RestFul API actions for Amenities""" +from models.amenity import Amenity +from models import storage +from api.v1.views import app_views +from flask import abort, jsonify, make_response, request +from flasgger.utils import swag_from + + +@app_views.route('/amenities', methods=['GET'], strict_slashes=False) +@swag_from('documentation/amenity/all_amenities.yml') +def get_amenities(): + """ + Retrieves a list of all amenities + """ + all_amenities = storage.all(Amenity).values() + list_amenities = [] + for amenity in all_amenities: + list_amenities.append(amenity.to_dict()) + return jsonify(list_amenities) + + +@app_views.route('/amenities//', methods=['GET'], + strict_slashes=False) +@swag_from('documentation/amenity/get_amenity.yml', methods=['GET']) +def get_amenity(amenity_id): + """ Retrieves an amenity """ + amenity = storage.get(Amenity, amenity_id) + if not amenity: + abort(404) + + return jsonify(amenity.to_dict()) + + +@app_views.route('/amenities/', methods=['DELETE'], + strict_slashes=False) +@swag_from('documentation/amenity/delete_amenity.yml', methods=['DELETE']) +def delete_amenity(amenity_id): + """ + Deletes an amenity Object + """ + + amenity = storage.get(Amenity, amenity_id) + + if not amenity: + abort(404) + + storage.delete(amenity) + storage.save() + + return make_response(jsonify({}), 200) + + +@app_views.route('/amenities', methods=['POST'], strict_slashes=False) +@swag_from('documentation/amenity/post_amenity.yml', methods=['POST']) +def post_amenity(): + """ + Creates an amenity + """ + if not request.get_json(): + abort(400, description="Not a JSON") + + if 'name' not in request.get_json(): + abort(400, description="Missing name") + + data = request.get_json() + instance = Amenity(**data) + instance.save() + return make_response(jsonify(instance.to_dict()), 201) + + +@app_views.route('/amenities/', methods=['PUT'], + strict_slashes=False) +@swag_from('documentation/amenity/put_amenity.yml', methods=['PUT']) +def put_amenity(amenity_id): + """ + Updates an amenity + """ + if not request.get_json(): + abort(400, description="Not a JSON") + + ignore = ['id', 'created_at', 'updated_at'] + + amenity = storage.get(Amenity, amenity_id) + + if not amenity: + abort(404) + + data = request.get_json() + for key, value in data.items(): + if key not in ignore: + setattr(amenity, key, value) + storage.save() + return make_response(jsonify(amenity.to_dict()), 200) \ No newline at end of file diff --git a/api/v1/views/cities.py b/api/v1/views/cities.py new file mode 100644 index 00000000000..6ef1c2fb87f --- /dev/null +++ b/api/v1/views/cities.py @@ -0,0 +1,110 @@ +#!/usr/bin/python3 +""" +route for handling State objects and operations +""" +from flask import jsonify, abort, request +from api.v1.views import app_views, storage +from models.city import City + + +@app_views.route("/states//cities", methods=["GET"], + strict_slashes=False) +def city_by_state(state_id): + """ + retrieves all City objects from a specific state + :return: json of all cities in a state or 404 on error + """ + city_list = [] + state_obj = storage.get("State", state_id) + + if state_obj is None: + abort(404) + for obj in state_obj.cities: + city_list.append(obj.to_json()) + + return jsonify(city_list) + + +@app_views.route("/states//cities", methods=["POST"], + strict_slashes=False) +def city_create(state_id): + """ + create city route + param: state_id - state id + :return: newly created city obj + """ + city_json = request.get_json(silent=True) + if city_json is None: + abort(400, 'Not a JSON') + + if not storage.get("State", str(state_id)): + abort(404) + + if "name" not in city_json: + abort(400, 'Missing name') + + city_json["state_id"] = state_id + + new_city = City(**city_json) + new_city.save() + resp = jsonify(new_city.to_json()) + resp.status_code = 201 + + return resp + + +@app_views.route("/cities/", methods=["GET"], + strict_slashes=False) +def city_by_id(city_id): + """ + gets a specific City object by ID + :param city_id: city object id + :return: city obj with the specified id or error + """ + + fetched_obj = storage.get("City", str(city_id)) + + if fetched_obj is None: + abort(404) + + return jsonify(fetched_obj.to_json()) + + +@app_views.route("cities/", methods=["PUT"], strict_slashes=False) +def city_put(city_id): + """ + updates specific City object by ID + :param city_id: city object ID + :return: city object and 200 on success, or 400 or 404 on failure + """ + city_json = request.get_json(silent=True) + if city_json is None: + abort(400, 'Not a JSON') + fetched_obj = storage.get("City", str(city_id)) + if fetched_obj is None: + abort(404) + for key, val in city_json.items(): + if key not in ["id", "created_at", "updated_at", "state_id"]: + setattr(fetched_obj, key, val) + fetched_obj.save() + return jsonify(fetched_obj.to_json()) + + +@app_views.route("/cities/", methods=["DELETE"], + strict_slashes=False) +def city_delete_by_id(city_id): + """ + deletes City by id + :param city_id: city object id + :return: empty dict with 200 or 404 if not found + """ + + fetched_obj = storage.get("City", str(city_id)) + + if fetched_obj is None: + abort(404) + + storage.delete(fetched_obj) + storage.save() + + return jsonify({}) \ No newline at end of file diff --git a/api/v1/views/index.py b/api/v1/views/index.py new file mode 100644 index 00000000000..6379d8348f2 --- /dev/null +++ b/api/v1/views/index.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +"""JSON file status """ +from api.v1.views import app_views +from flask import jsonify +from models import storage + + +@app_views.route('/status', strict_slashes=False) +def status(): + return jsonify({"status": "OK"}) + + +@app_views.route('/stats') +def stats(): + """ + Returns the count of all objects by type + """ + classes = { + 'amenities': 'Amenity', + 'cities': 'City', + 'places': 'Place', + 'reviews': 'Review', + 'states': 'State', + 'users': 'User' + } + counts = {} + for key, value in classes.items(): + counts[key] = storage.count(value) + return jsonify(counts) \ No newline at end of file diff --git a/api/v1/views/states.py b/api/v1/views/states.py new file mode 100644 index 00000000000..1cba3ef8647 --- /dev/null +++ b/api/v1/views/states.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 +""" +Handles all default RESTful API actions for State objects +""" + +from api.v1.views import app_views +from flask import jsonify, abort, request +from models import storage +from models.state import State + + +@app_views.route('/states', methods=['GET'], strict_slashes=False) +def get_all_states(): + """Retrieves the list of all State objects""" + states = storage.all(State).values() + state_list = [] + for state in states: + state_list.append(state.to_dict()) + return jsonify(state_list) + + +@app_views.route('/states/', methods=['GET'], strict_slashes=False) +def get_state_by_id(state_id): + """Retrieves a State object by its id""" + state = storage.get(State, state_id) + if state is None: + abort(404) + return jsonify(state.to_dict()) + + +@app_views.route('/states/', methods=['DELETE'], + strict_slashes=False) +def delete_state(state_id): + """Deletes a State object by its id""" + state = storage.get(State, state_id) + if state is None: + abort(404) + storage.delete(state) + storage.save() + return jsonify({}), 200 + + +@app_views.route('/states', methods=['POST'], strict_slashes=False) +def create_state(): + """Creates a State object""" + req_json = request.get_json() + if req_json is None: + abort(400, "Not a JSON") + if 'name' not in req_json: + abort(400, "Missing name") + state = State(**req_json) + storage.new(state) + storage.save() + return jsonify(state.to_dict()), 201 + + +@app_views.route('/states/', methods=['PUT'], strict_slashes=False) +def update_state(state_id): + """Updates a State object by its id""" + state = storage.get(State, state_id) + if state is None: + abort(404) + req_json = request.get_json() + if req_json is None: + abort(400, "Not a JSON") + for key, value in req_json.items(): + if key not in ('id', 'created_at', 'updated_at'): + setattr(state, key, value) + storage.save() + return jsonify(state.to_dict()), 200 \ No newline at end of file diff --git a/api/v1/views/users.py b/api/v1/views/users.py new file mode 100644 index 00000000000..70bd9f9cd26 --- /dev/null +++ b/api/v1/views/users.py @@ -0,0 +1,95 @@ +#!/usr/bin/python3 +""" objects that handle all default RestFul API actions for Users """ +from models.user import User +from models import storage +from api.v1.views import app_views +from flask import abort, jsonify, make_response, request +from flasgger.utils import swag_from + + +@app_views.route('/users', methods=['GET'], strict_slashes=False) +@swag_from('documentation/user/all_users.yml') +def get_users(): + """ + Retrieves the list of all user objects + or a specific user + """ + all_users = storage.all(User).values() + list_users = [] + for user in all_users: + list_users.append(user.to_dict()) + return jsonify(list_users) + + +@app_views.route('/users/', methods=['GET'], strict_slashes=False) +@swag_from('documentation/user/get_user.yml', methods=['GET']) +def get_user(user_id): + """ Retrieves an user """ + user = storage.get(User, user_id) + if not user: + abort(404) + + return jsonify(user.to_dict()) + + +@app_views.route('/users/', methods=['DELETE'], + strict_slashes=False) +@swag_from('documentation/user/delete_user.yml', methods=['DELETE']) +def delete_user(user_id): + """ + Deletes a user Object + """ + + user = storage.get(User, user_id) + + if not user: + abort(404) + + storage.delete(user) + storage.save() + + return make_response(jsonify({}), 200) + + +@app_views.route('/users', methods=['POST'], strict_slashes=False) +@swag_from('documentation/user/post_user.yml', methods=['POST']) +def post_user(): + """ + Creates a user + """ + if not request.get_json(): + abort(400, description="Not a JSON") + + if 'email' not in request.get_json(): + abort(400, description="Missing email") + if 'password' not in request.get_json(): + abort(400, description="Missing password") + + data = request.get_json() + instance = User(**data) + instance.save() + return make_response(jsonify(instance.to_dict()), 201) + + +@app_views.route('/users/', methods=['PUT'], strict_slashes=False) +@swag_from('documentation/user/put_user.yml', methods=['PUT']) +def put_user(user_id): + """ + Updates a user + """ + user = storage.get(User, user_id) + + if not user: + abort(404) + + if not request.get_json(): + abort(400, description="Not a JSON") + + ignore = ['id', 'email', 'created_at', 'updated_at'] + + data = request.get_json() + for key, value in data.items(): + if key not in ignore: + setattr(user, key, value) + storage.save() + return make_response(jsonify(user.to_dict()), 200) \ No newline at end of file diff --git a/api/views/__init__.py b/api/views/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/api/views/cities.py b/api/views/cities.py new file mode 100644 index 00000000000..6ef1c2fb87f --- /dev/null +++ b/api/views/cities.py @@ -0,0 +1,110 @@ +#!/usr/bin/python3 +""" +route for handling State objects and operations +""" +from flask import jsonify, abort, request +from api.v1.views import app_views, storage +from models.city import City + + +@app_views.route("/states//cities", methods=["GET"], + strict_slashes=False) +def city_by_state(state_id): + """ + retrieves all City objects from a specific state + :return: json of all cities in a state or 404 on error + """ + city_list = [] + state_obj = storage.get("State", state_id) + + if state_obj is None: + abort(404) + for obj in state_obj.cities: + city_list.append(obj.to_json()) + + return jsonify(city_list) + + +@app_views.route("/states//cities", methods=["POST"], + strict_slashes=False) +def city_create(state_id): + """ + create city route + param: state_id - state id + :return: newly created city obj + """ + city_json = request.get_json(silent=True) + if city_json is None: + abort(400, 'Not a JSON') + + if not storage.get("State", str(state_id)): + abort(404) + + if "name" not in city_json: + abort(400, 'Missing name') + + city_json["state_id"] = state_id + + new_city = City(**city_json) + new_city.save() + resp = jsonify(new_city.to_json()) + resp.status_code = 201 + + return resp + + +@app_views.route("/cities/", methods=["GET"], + strict_slashes=False) +def city_by_id(city_id): + """ + gets a specific City object by ID + :param city_id: city object id + :return: city obj with the specified id or error + """ + + fetched_obj = storage.get("City", str(city_id)) + + if fetched_obj is None: + abort(404) + + return jsonify(fetched_obj.to_json()) + + +@app_views.route("cities/", methods=["PUT"], strict_slashes=False) +def city_put(city_id): + """ + updates specific City object by ID + :param city_id: city object ID + :return: city object and 200 on success, or 400 or 404 on failure + """ + city_json = request.get_json(silent=True) + if city_json is None: + abort(400, 'Not a JSON') + fetched_obj = storage.get("City", str(city_id)) + if fetched_obj is None: + abort(404) + for key, val in city_json.items(): + if key not in ["id", "created_at", "updated_at", "state_id"]: + setattr(fetched_obj, key, val) + fetched_obj.save() + return jsonify(fetched_obj.to_json()) + + +@app_views.route("/cities/", methods=["DELETE"], + strict_slashes=False) +def city_delete_by_id(city_id): + """ + deletes City by id + :param city_id: city object id + :return: empty dict with 200 or 404 if not found + """ + + fetched_obj = storage.get("City", str(city_id)) + + if fetched_obj is None: + abort(404) + + storage.delete(fetched_obj) + storage.save() + + return jsonify({}) \ No newline at end of file diff --git a/api/views/index.py b/api/views/index.py new file mode 100644 index 00000000000..6379d8348f2 --- /dev/null +++ b/api/views/index.py @@ -0,0 +1,29 @@ +#!/usr/bin/python3 +"""JSON file status """ +from api.v1.views import app_views +from flask import jsonify +from models import storage + + +@app_views.route('/status', strict_slashes=False) +def status(): + return jsonify({"status": "OK"}) + + +@app_views.route('/stats') +def stats(): + """ + Returns the count of all objects by type + """ + classes = { + 'amenities': 'Amenity', + 'cities': 'City', + 'places': 'Place', + 'reviews': 'Review', + 'states': 'State', + 'users': 'User' + } + counts = {} + for key, value in classes.items(): + counts[key] = storage.count(value) + return jsonify(counts) \ No newline at end of file diff --git a/api/views/places.py b/api/views/places.py new file mode 100644 index 00000000000..30988878ca8 --- /dev/null +++ b/api/views/places.py @@ -0,0 +1,115 @@ +#!/usr/bin/python3 +""" +route for handling Place objects and operations +""" +from flask import jsonify, abort, request +from api.v1.views import app_views, storage +from models.place import Place + + +@app_views.route("/cities//places", methods=["GET"], + strict_slashes=False) +def places_by_city(city_id): + """ + retrieves all Place objects by city + :return: json of all Places + """ + place_list = [] + city_obj = storage.get("City", str(city_id)) + for obj in city_obj.places: + place_list.append(obj.to_json()) + + return jsonify(place_list) + + +@app_views.route("/cities//places", methods=["POST"], + strict_slashes=False) +def place_create(city_id): + """ + create place route + :return: newly created Place obj + """ + place_json = request.get_json(silent=True) + if place_json is None: + abort(400, 'Not a JSON') + if not storage.get("User", place_json["user_id"]): + abort(404) + if not storage.get("City", city_id): + abort(404) + if "user_id" not in place_json: + abort(400, 'Missing user_id') + if "name" not in place_json: + abort(400, 'Missing name') + + place_json["city_id"] = city_id + + new_place = Place(**place_json) + new_place.save() + resp = jsonify(new_place.to_json()) + resp.status_code = 201 + + return resp + + +@app_views.route("/places/", methods=["GET"], + strict_slashes=False) +def place_by_id(place_id): + """ + gets a specific Place object by ID + :param place_id: place object id + :return: place obj with the specified id or error + """ + + fetched_obj = storage.get("Place", str(place_id)) + + if fetched_obj is None: + abort(404) + + return jsonify(fetched_obj.to_json()) + + +@app_views.route("/places/", methods=["PUT"], + strict_slashes=False) +def place_put(place_id): + """ + updates specific Place object by ID + :param place_id: Place object ID + :return: Place object and 200 on success, or 400 or 404 on failure + """ + place_json = request.get_json(silent=True) + + if place_json is None: + abort(400, 'Not a JSON') + + fetched_obj = storage.get("Place", str(place_id)) + + if fetched_obj is None: + abort(404) + + for key, val in place_json.items(): + if key not in ["id", "created_at", "updated_at", "user_id", "city_id"]: + setattr(fetched_obj, key, val) + + fetched_obj.save() + + return jsonify(fetched_obj.to_json()) + + +@app_views.route("/places/", methods=["DELETE"], + strict_slashes=False) +def place_delete_by_id(place_id): + """ + deletes Place by id + :param place_id: Place object id + :return: empty dict with 200 or 404 if not found + """ + + fetched_obj = storage.get("Place", str(place_id)) + + if fetched_obj is None: + abort(404) + + storage.delete(fetched_obj) + storage.save() + + return jsonify({}) \ No newline at end of file diff --git a/api/views/users.py b/api/views/users.py new file mode 100644 index 00000000000..318b3a4144e --- /dev/null +++ b/api/views/users.py @@ -0,0 +1,71 @@ +#!/usr/bin/python3 +""" +Defines the views for the User object RESTful API actions +""" + +from api.v1.views import app_views +from flask import jsonify, make_response, abort, request +from models import storage +from models.user import User + + +@app_views.route('/users', methods=['GET'], strict_slashes=False) +def get_users(): + """Retrieves the list of all User objects""" + users_list = [] + users = storage.all("User") + for user in users.values(): + users_list.append(user.to_dict()) + return jsonify(users_list) + + +@app_views.route('/users/', methods=['GET'], strict_slashes=False) +def get_user(user_id): + """Retrieves a User object""" + user = storage.get(User, user_id) + if user is None: + abort(404) + return jsonify(user.to_dict()) + + +@app_views.route("users/", + methods=['DELETE'], strict_slashes=False) +def delete_user(user_id): + """Deletes a User object""" + user = storage.get(User, user_id) + if user is None: + abort(404) + storage.delete(user) + storage.save() + return make_response(jsonify({})) + + +@app_views.route('/users', methods=['POST'], strict_slashes=False) +def create_user(): + """Creates a User""" + if not request.get_json(): + abort(400, 'Not a JSON') + if 'email' not in request.get_json(): + abort(400, 'Missing email') + if 'password' not in request.get_json(): + abort(400, 'Missing password') + user = User(**request.get_json()) + storage.new(user) + storage.save() + return make_response(jsonify(user.to_dict()), 201) + + +@app_views.route("/users/", methods=['PUT'], strict_slashes=False) +def update_user(user_id): + """Updates a User object""" + user = storage.get(User, user_id) + if user is None: + abort(404) + if not request.get_json(): + abort(400, 'Not a JSON') + ignore = ['id', 'email', 'created_at', 'updated_at'] + for key, value in request.get_json().items(): + if key not in ignore: + setattr(user, key, value) + storage.save() + return make_response(jsonify(user.to_dict()), 200) \ No newline at end of file diff --git a/console.py b/console.py index 4798f9ac76b..b96e92cfe0b 100755 --- a/console.py +++ b/console.py @@ -1,164 +1,164 @@ -#!/usr/bin/python3 -""" console """ - -import cmd -from datetime import datetime -import models -from models.amenity import Amenity -from models.base_model import BaseModel -from models.city import City -from models.place import Place -from models.review import Review -from models.state import State -from models.user import User -import shlex # for splitting the line along spaces except in double quotes - -classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, - "Place": Place, "Review": Review, "State": State, "User": User} - - -class HBNBCommand(cmd.Cmd): - """ HBNH console """ - prompt = '(hbnb) ' - - def do_EOF(self, arg): - """Exits console""" - return True - - def emptyline(self): - """ overwriting the emptyline method """ - return False - - def do_quit(self, arg): - """Quit command to exit the program""" - return True - - def _key_value_parser(self, args): - """creates a dictionary from a list of strings""" - new_dict = {} - for arg in args: - if "=" in arg: - kvp = arg.split('=', 1) - key = kvp[0] - value = kvp[1] - if value[0] == value[-1] == '"': - value = shlex.split(value)[0].replace('_', ' ') - else: - try: - value = int(value) - except: - try: - value = float(value) - except: - continue - new_dict[key] = value - return new_dict - - def do_create(self, arg): - """Creates a new instance of a class""" - args = arg.split() - if len(args) == 0: - print("** class name missing **") - return False - if args[0] in classes: - new_dict = self._key_value_parser(args[1:]) - instance = classes[args[0]](**new_dict) - else: - print("** class doesn't exist **") - return False - print(instance.id) - instance.save() - - def do_show(self, arg): - """Prints an instance as a string based on the class and id""" - args = shlex.split(arg) - if len(args) == 0: - print("** class name missing **") - return False - if args[0] in classes: - if len(args) > 1: - key = args[0] + "." + args[1] - if key in models.storage.all(): - print(models.storage.all()[key]) - else: - print("** no instance found **") - else: - print("** instance id missing **") - else: - print("** class doesn't exist **") - - def do_destroy(self, arg): - """Deletes an instance based on the class and id""" - args = shlex.split(arg) - if len(args) == 0: - print("** class name missing **") - elif args[0] in classes: - if len(args) > 1: - key = args[0] + "." + args[1] - if key in models.storage.all(): - models.storage.all().pop(key) - models.storage.save() - else: - print("** no instance found **") - else: - print("** instance id missing **") - else: - print("** class doesn't exist **") - - def do_all(self, arg): - """Prints string representations of instances""" - args = shlex.split(arg) - obj_list = [] - if len(args) == 0: - obj_dict = models.storage.all() - elif args[0] in classes: - obj_dict = models.storage.all(classes[args[0]]) - else: - print("** class doesn't exist **") - return False - for key in obj_dict: - obj_list.append(str(obj_dict[key])) - print("[", end="") - print(", ".join(obj_list), end="") - print("]") - - def do_update(self, arg): - """Update an instance based on the class name, id, attribute & value""" - args = shlex.split(arg) - integers = ["number_rooms", "number_bathrooms", "max_guest", - "price_by_night"] - floats = ["latitude", "longitude"] - if len(args) == 0: - print("** class name missing **") - elif args[0] in classes: - if len(args) > 1: - k = args[0] + "." + args[1] - if k in models.storage.all(): - if len(args) > 2: - if len(args) > 3: - if args[0] == "Place": - if args[2] in integers: - try: - args[3] = int(args[3]) - except: - args[3] = 0 - elif args[2] in floats: - try: - args[3] = float(args[3]) - except: - args[3] = 0.0 - setattr(models.storage.all()[k], args[2], args[3]) - models.storage.all()[k].save() - else: - print("** value missing **") - else: - print("** attribute name missing **") - else: - print("** no instance found **") - else: - print("** instance id missing **") - else: - print("** class doesn't exist **") - -if __name__ == '__main__': - HBNBCommand().cmdloop() +#!/usr/bin/python3 +""" console """ + +import cmd +from datetime import datetime +import models +from models.amenity import Amenity +from models.base_model import BaseModel +from models.city import City +from models.place import Place +from models.review import Review +from models.state import State +from models.user import User +import shlex # for splitting the line along spaces except in double quotes + +classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, + "Place": Place, "Review": Review, "State": State, "User": User} + + +class HBNBCommand(cmd.Cmd): + """ HBNH console """ + prompt = '(hbnb) ' + + def do_EOF(self, arg): + """Exits console""" + return True + + def emptyline(self): + """ overwriting the emptyline method """ + return False + + def do_quit(self, arg): + """Quit command to exit the program""" + return True + + def _key_value_parser(self, args): + """creates a dictionary from a list of strings""" + new_dict = {} + for arg in args: + if "=" in arg: + kvp = arg.split('=', 1) + key = kvp[0] + value = kvp[1] + if value[0] == value[-1] == '"': + value = shlex.split(value)[0].replace('_', ' ') + else: + try: + value = int(value) + except: + try: + value = float(value) + except: + continue + new_dict[key] = value + return new_dict + + def do_create(self, arg): + """Creates a new instance of a class""" + args = arg.split() + if len(args) == 0: + print("** class name missing **") + return False + if args[0] in classes: + new_dict = self._key_value_parser(args[1:]) + instance = classes[args[0]](**new_dict) + else: + print("** class doesn't exist **") + return False + print(instance.id) + instance.save() + + def do_show(self, arg): + """Prints an instance as a string based on the class and id""" + args = shlex.split(arg) + if len(args) == 0: + print("** class name missing **") + return False + if args[0] in classes: + if len(args) > 1: + key = args[0] + "." + args[1] + if key in models.storage.all(): + print(models.storage.all()[key]) + else: + print("** no instance found **") + else: + print("** instance id missing **") + else: + print("** class doesn't exist **") + + def do_destroy(self, arg): + """Deletes an instance based on the class and id""" + args = shlex.split(arg) + if len(args) == 0: + print("** class name missing **") + elif args[0] in classes: + if len(args) > 1: + key = args[0] + "." + args[1] + if key in models.storage.all(): + models.storage.all().pop(key) + models.storage.save() + else: + print("** no instance found **") + else: + print("** instance id missing **") + else: + print("** class doesn't exist **") + + def do_all(self, arg): + """Prints string representations of instances""" + args = shlex.split(arg) + obj_list = [] + if len(args) == 0: + obj_dict = models.storage.all() + elif args[0] in classes: + obj_dict = models.storage.all(classes[args[0]]) + else: + print("** class doesn't exist **") + return False + for key in obj_dict: + obj_list.append(str(obj_dict[key])) + print("[", end="") + print(", ".join(obj_list), end="") + print("]") + + def do_update(self, arg): + """Update an instance based on the class name, id, attribute & value""" + args = shlex.split(arg) + integers = ["number_rooms", "number_bathrooms", "max_guest", + "price_by_night"] + floats = ["latitude", "longitude"] + if len(args) == 0: + print("** class name missing **") + elif args[0] in classes: + if len(args) > 1: + k = args[0] + "." + args[1] + if k in models.storage.all(): + if len(args) > 2: + if len(args) > 3: + if args[0] == "Place": + if args[2] in integers: + try: + args[3] = int(args[3]) + except: + args[3] = 0 + elif args[2] in floats: + try: + args[3] = float(args[3]) + except: + args[3] = 0.0 + setattr(models.storage.all()[k], args[2], args[3]) + models.storage.all()[k].save() + else: + print("** value missing **") + else: + print("** attribute name missing **") + else: + print("** no instance found **") + else: + print("** instance id missing **") + else: + print("** class doesn't exist **") + +if __name__ == '__main__': + HBNBCommand().cmdloop() diff --git a/file.json b/file.json new file mode 100644 index 00000000000..3776e86a8a2 --- /dev/null +++ b/file.json @@ -0,0 +1 @@ +{"Amenity.2deb101e-20fe-4510-8cee-6ece0bd3091f": {"id": "2deb101e-20fe-4510-8cee-6ece0bd3091f", "created_at": "2025-02-17T22:11:45.886819", "updated_at": "2025-02-17T22:11:45.886819", "__class__": "Amenity"}, "BaseModel.411f9624-5258-4b40-980a-10cd6633b720": {"id": "411f9624-5258-4b40-980a-10cd6633b720", "created_at": "2025-02-17T22:11:45.886841", "updated_at": "2025-02-17T22:11:45.886841", "__class__": "BaseModel"}, "City.bc43f572-3d9c-4555-a63e-605c47af9b7c": {"id": "bc43f572-3d9c-4555-a63e-605c47af9b7c", "created_at": "2025-02-17T22:11:45.886864", "updated_at": "2025-02-17T22:11:45.886864", "__class__": "City"}, "Place.fcf12ad4-9c39-4478-a472-d5353205a514": {"id": "fcf12ad4-9c39-4478-a472-d5353205a514", "created_at": "2025-02-17T22:11:45.886886", "updated_at": "2025-02-17T22:11:45.886886", "__class__": "Place"}, "Review.41a9031e-2298-411b-a222-671cd5499d9a": {"id": "41a9031e-2298-411b-a222-671cd5499d9a", "created_at": "2025-02-17T22:11:45.886914", "updated_at": "2025-02-17T22:11:45.886914", "__class__": "Review"}, "State.f7e14bc7-b84b-4e0d-bd97-884b854ed398": {"id": "f7e14bc7-b84b-4e0d-bd97-884b854ed398", "created_at": "2025-02-17T22:11:45.886936", "updated_at": "2025-02-17T22:11:45.886936", "__class__": "State"}, "User.ec93d2e4-4e64-4134-9b28-ad8e2314e213": {"id": "ec93d2e4-4e64-4134-9b28-ad8e2314e213", "created_at": "2025-02-17T22:11:45.886944", "updated_at": "2025-02-17T22:11:45.886944", "__class__": "User"}} \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py index defef6378c1..b9c20b35504 100755 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,17 +1,16 @@ -#!/usr/bin/python3 -""" -initialize the models package -""" - -from os import getenv - - -storage_t = getenv("HBNB_TYPE_STORAGE") - -if storage_t == "db": - from models.engine.db_storage import DBStorage - storage = DBStorage() -else: - from models.engine.file_storage import FileStorage - storage = FileStorage() -storage.reload() +#!/usr/bin/python3 +""" +initialize the models package +""" + +from os import getenv + +storage_t = getenv("HBNB_TYPE_STORAGE") + +if storage_t == "db": + from models.engine.db_storage import DBStorage + storage = DBStorage() +else: + from models.engine.file_storage import FileStorage + storage = FileStorage() +storage.reload() diff --git a/models/__pycache__/__init__.cpython-37.pyc b/models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..e495b8fe535 Binary files /dev/null and b/models/__pycache__/__init__.cpython-37.pyc differ diff --git a/models/__pycache__/amenity.cpython-37.pyc b/models/__pycache__/amenity.cpython-37.pyc new file mode 100644 index 00000000000..3bf26c158a0 Binary files /dev/null and b/models/__pycache__/amenity.cpython-37.pyc differ diff --git a/models/__pycache__/base_model.cpython-37.pyc b/models/__pycache__/base_model.cpython-37.pyc new file mode 100644 index 00000000000..29016112f34 Binary files /dev/null and b/models/__pycache__/base_model.cpython-37.pyc differ diff --git a/models/__pycache__/city.cpython-37.pyc b/models/__pycache__/city.cpython-37.pyc new file mode 100644 index 00000000000..889b18b55f1 Binary files /dev/null and b/models/__pycache__/city.cpython-37.pyc differ diff --git a/models/__pycache__/place.cpython-37.pyc b/models/__pycache__/place.cpython-37.pyc new file mode 100644 index 00000000000..07a4e9905ef Binary files /dev/null and b/models/__pycache__/place.cpython-37.pyc differ diff --git a/models/__pycache__/review.cpython-37.pyc b/models/__pycache__/review.cpython-37.pyc new file mode 100644 index 00000000000..c41d3086c7a Binary files /dev/null and b/models/__pycache__/review.cpython-37.pyc differ diff --git a/models/__pycache__/state.cpython-37.pyc b/models/__pycache__/state.cpython-37.pyc new file mode 100644 index 00000000000..d4191da3825 Binary files /dev/null and b/models/__pycache__/state.cpython-37.pyc differ diff --git a/models/__pycache__/user.cpython-37.pyc b/models/__pycache__/user.cpython-37.pyc new file mode 100644 index 00000000000..2f0bcb4ccc2 Binary files /dev/null and b/models/__pycache__/user.cpython-37.pyc differ diff --git a/models/amenity.py b/models/amenity.py index 557728bafdc..18335f7e935 100755 --- a/models/amenity.py +++ b/models/amenity.py @@ -1,21 +1,21 @@ -#!/usr/bin/python -""" holds class Amenity""" -import models -from models.base_model import BaseModel, Base -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String -from sqlalchemy.orm import relationship - - -class Amenity(BaseModel, Base): - """Representation of Amenity """ - if models.storage_t == 'db': - __tablename__ = 'amenities' - name = Column(String(128), nullable=False) - else: - name = "" - - def __init__(self, *args, **kwargs): - """initializes Amenity""" - super().__init__(*args, **kwargs) +#!/usr/bin/python +""" holds class Amenity""" +import models +from models.base_model import BaseModel, Base +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship + + +class Amenity(BaseModel, Base): + """Representation of Amenity """ + if models.storage_t == 'db': + __tablename__ = 'amenities' + name = Column(String(128), nullable=False) + else: + name = "" + + def __init__(self, *args, **kwargs): + """initializes Amenity""" + super().__init__(*args, **kwargs) diff --git a/models/base_model.py b/models/base_model.py index 9a86addb366..32128b54cf0 100755 --- a/models/base_model.py +++ b/models/base_model.py @@ -1,75 +1,75 @@ -#!/usr/bin/python3 -""" -Contains class BaseModel -""" - -from datetime import datetime -import models -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String, DateTime -from sqlalchemy.ext.declarative import declarative_base -import uuid - -time = "%Y-%m-%dT%H:%M:%S.%f" - -if models.storage_t == "db": - Base = declarative_base() -else: - Base = object - - -class BaseModel: - """The BaseModel class from which future classes will be derived""" - if models.storage_t == "db": - id = Column(String(60), primary_key=True) - created_at = Column(DateTime, default=datetime.utcnow) - updated_at = Column(DateTime, default=datetime.utcnow) - - def __init__(self, *args, **kwargs): - """Initialization of the base model""" - if kwargs: - for key, value in kwargs.items(): - if key != "__class__": - setattr(self, key, value) - if kwargs.get("created_at", None) and type(self.created_at) is str: - self.created_at = datetime.strptime(kwargs["created_at"], time) - else: - self.created_at = datetime.utcnow() - if kwargs.get("updated_at", None) and type(self.updated_at) is str: - self.updated_at = datetime.strptime(kwargs["updated_at"], time) - else: - self.updated_at = datetime.utcnow() - if kwargs.get("id", None) is None: - self.id = str(uuid.uuid4()) - else: - self.id = str(uuid.uuid4()) - self.created_at = datetime.utcnow() - self.updated_at = self.created_at - - def __str__(self): - """String representation of the BaseModel class""" - return "[{:s}] ({:s}) {}".format(self.__class__.__name__, self.id, - self.__dict__) - - def save(self): - """updates the attribute 'updated_at' with the current datetime""" - self.updated_at = datetime.utcnow() - models.storage.new(self) - models.storage.save() - - def to_dict(self): - """returns a dictionary containing all keys/values of the instance""" - new_dict = self.__dict__.copy() - if "created_at" in new_dict: - new_dict["created_at"] = new_dict["created_at"].strftime(time) - if "updated_at" in new_dict: - new_dict["updated_at"] = new_dict["updated_at"].strftime(time) - new_dict["__class__"] = self.__class__.__name__ - if "_sa_instance_state" in new_dict: - del new_dict["_sa_instance_state"] - return new_dict - - def delete(self): - """delete the current instance from the storage""" - models.storage.delete(self) +#!/usr/bin/python3 +""" +Contains class BaseModel +""" + +from datetime import datetime +import models +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String, DateTime +from sqlalchemy.ext.declarative import declarative_base +import uuid + +time = "%Y-%m-%dT%H:%M:%S.%f" + +if models.storage_t == "db": + Base = declarative_base() +else: + Base = object + + +class BaseModel: + """The BaseModel class from which future classes will be derived""" + if models.storage_t == "db": + id = Column(String(60), primary_key=True) + created_at = Column(DateTime, default=datetime.utcnow) + updated_at = Column(DateTime, default=datetime.utcnow) + + def __init__(self, *args, **kwargs): + """Initialization of the base model""" + if kwargs: + for key, value in kwargs.items(): + if key != "__class__": + setattr(self, key, value) + if kwargs.get("created_at", None) and type(self.created_at) is str: + self.created_at = datetime.strptime(kwargs["created_at"], time) + else: + self.created_at = datetime.utcnow() + if kwargs.get("updated_at", None) and type(self.updated_at) is str: + self.updated_at = datetime.strptime(kwargs["updated_at"], time) + else: + self.updated_at = datetime.utcnow() + if kwargs.get("id", None) is None: + self.id = str(uuid.uuid4()) + else: + self.id = str(uuid.uuid4()) + self.created_at = datetime.utcnow() + self.updated_at = self.created_at + + def __str__(self): + """String representation of the BaseModel class""" + return "[{:s}] ({:s}) {}".format(self.__class__.__name__, self.id, + self.__dict__) + + def save(self): + """updates the attribute 'updated_at' with the current datetime""" + self.updated_at = datetime.utcnow() + models.storage.new(self) + models.storage.save() + + def to_dict(self): + """returns a dictionary containing all keys/values of the instance""" + new_dict = self.__dict__.copy() + if "created_at" in new_dict: + new_dict["created_at"] = new_dict["created_at"].strftime(time) + if "updated_at" in new_dict: + new_dict["updated_at"] = new_dict["updated_at"].strftime(time) + new_dict["__class__"] = self.__class__.__name__ + if "_sa_instance_state" in new_dict: + del new_dict["_sa_instance_state"] + return new_dict + + def delete(self): + """delete the current instance from the storage""" + models.storage.delete(self) diff --git a/models/city.py b/models/city.py index 8c46f0d2f4c..60f69a31dd2 100755 --- a/models/city.py +++ b/models/city.py @@ -1,24 +1,24 @@ -#!/usr/bin/python -""" holds class City""" -import models -from models.base_model import BaseModel, Base -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship - - -class City(BaseModel, Base): - """Representation of city """ - if models.storage_t == "db": - __tablename__ = 'cities' - state_id = Column(String(60), ForeignKey('states.id'), nullable=False) - name = Column(String(128), nullable=False) - places = relationship("Place", backref="cities") - else: - state_id = "" - name = "" - - def __init__(self, *args, **kwargs): - """initializes city""" - super().__init__(*args, **kwargs) +#!/usr/bin/python +""" holds class City""" +import models +from models.base_model import BaseModel, Base +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship + + +class City(BaseModel, Base): + """Representation of city """ + if models.storage_t == "db": + __tablename__ = 'cities' + state_id = Column(String(60), ForeignKey('states.id'), nullable=False) + name = Column(String(128), nullable=False) + places = relationship("Place", backref="cities") + else: + state_id = "" + name = "" + + def __init__(self, *args, **kwargs): + """initializes city""" + super().__init__(*args, **kwargs) diff --git a/models/engine/__pycache__/__init__.cpython-37.pyc b/models/engine/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..815187d12b0 Binary files /dev/null and b/models/engine/__pycache__/__init__.cpython-37.pyc differ diff --git a/models/engine/__pycache__/db_storage.cpython-37.pyc b/models/engine/__pycache__/db_storage.cpython-37.pyc new file mode 100644 index 00000000000..be3cecf3dd0 Binary files /dev/null and b/models/engine/__pycache__/db_storage.cpython-37.pyc differ diff --git a/models/engine/__pycache__/file_storage.cpython-37.pyc b/models/engine/__pycache__/file_storage.cpython-37.pyc new file mode 100644 index 00000000000..6b52019d919 Binary files /dev/null and b/models/engine/__pycache__/file_storage.cpython-37.pyc differ diff --git a/models/engine/db_storage.py b/models/engine/db_storage.py index b8e7d291e6f..ef66c8fd391 100755 --- a/models/engine/db_storage.py +++ b/models/engine/db_storage.py @@ -1,76 +1,117 @@ -#!/usr/bin/python3 -""" -Contains the class DBStorage -""" - -import models -from models.amenity import Amenity -from models.base_model import BaseModel, Base -from models.city import City -from models.place import Place -from models.review import Review -from models.state import State -from models.user import User -from os import getenv -import sqlalchemy -from sqlalchemy import create_engine -from sqlalchemy.orm import scoped_session, sessionmaker - -classes = {"Amenity": Amenity, "City": City, - "Place": Place, "Review": Review, "State": State, "User": User} - - -class DBStorage: - """interaacts with the MySQL database""" - __engine = None - __session = None - - def __init__(self): - """Instantiate a DBStorage object""" - HBNB_MYSQL_USER = getenv('HBNB_MYSQL_USER') - HBNB_MYSQL_PWD = getenv('HBNB_MYSQL_PWD') - HBNB_MYSQL_HOST = getenv('HBNB_MYSQL_HOST') - HBNB_MYSQL_DB = getenv('HBNB_MYSQL_DB') - HBNB_ENV = getenv('HBNB_ENV') - self.__engine = create_engine('mysql+mysqldb://{}:{}@{}/{}'. - format(HBNB_MYSQL_USER, - HBNB_MYSQL_PWD, - HBNB_MYSQL_HOST, - HBNB_MYSQL_DB)) - if HBNB_ENV == "test": - Base.metadata.drop_all(self.__engine) - - def all(self, cls=None): - """query on the current database session""" - new_dict = {} - for clss in classes: - if cls is None or cls is classes[clss] or cls is clss: - objs = self.__session.query(classes[clss]).all() - for obj in objs: - key = obj.__class__.__name__ + '.' + obj.id - new_dict[key] = obj - return (new_dict) - - def new(self, obj): - """add the object to the current database session""" - self.__session.add(obj) - - def save(self): - """commit all changes of the current database session""" - self.__session.commit() - - def delete(self, obj=None): - """delete from the current database session obj if not None""" - if obj is not None: - self.__session.delete(obj) - - def reload(self): - """reloads data from the database""" - Base.metadata.create_all(self.__engine) - sess_factory = sessionmaker(bind=self.__engine, expire_on_commit=False) - Session = scoped_session(sess_factory) - self.__session = Session - - def close(self): - """call remove() method on the private session attribute""" - self.__session.remove() +#!/usr/bin/python3 +""" +Contains the class DBStorage +""" + +import models +from models.amenity import Amenity +from models.base_model import BaseModel, Base +from models.city import City +from models.place import Place +from models.review import Review +from models.state import State +from models.user import User +from os import getenv +import sqlalchemy +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker + +classes = {"Amenity": Amenity, "City": City, + "Place": Place, "Review": Review, "State": State, "User": User} + + +class DBStorage: + """interaacts with the MySQL database""" + __engine = None + __session = None + + def __init__(self): + """Instantiate a DBStorage object""" + HBNB_MYSQL_USER = getenv('HBNB_MYSQL_USER') + HBNB_MYSQL_PWD = getenv('HBNB_MYSQL_PWD') + HBNB_MYSQL_HOST = getenv('HBNB_MYSQL_HOST') + HBNB_MYSQL_DB = getenv('HBNB_MYSQL_DB') + HBNB_ENV = getenv('HBNB_ENV') + self.__engine = create_engine('mysql+mysqldb://{}:{}@{}/{}'. + format(HBNB_MYSQL_USER, + HBNB_MYSQL_PWD, + HBNB_MYSQL_HOST, + HBNB_MYSQL_DB)) + if HBNB_ENV == "test": + Base.metadata.drop_all(self.__engine) + + def all(self, cls=None): + """query on the current database session""" + new_dict = {} + for clss in classes: + if cls is None or cls is classes[clss] or cls is clss: + objs = self.__session.query(classes[clss]).all() + for obj in objs: + key = obj.__class__.__name__ + '.' + obj.id + new_dict[key] = obj + return (new_dict) + + def new(self, obj): + """add the object to the current database session""" + self.__session.add(obj) + + def save(self): + """commit all changes of the current database session""" + self.__session.commit() + + def delete(self, obj=None): + """delete from the current database session obj if not None""" + if obj is not None: + self.__session.delete(obj) + + def reload(self): + """reloads data from the database""" + Base.metadata.create_all(self.__engine) + sess_factory = sessionmaker(bind=self.__engine, expire_on_commit=False) + Session = scoped_session(sess_factory) + self.__session = Session + + def close(self): + """call remove() method on the private session attribute""" + self.__session.remove() + + def get(self, cls, id): + + """Retrieve one object by class and id""" + if cls and id: + return self.__session.query(cls).filter_by(id=id).first() + return None + + def count(self, cls=None): + """Count the number of objects in storage matching the given class. + If no class is passed, return the count of all objects. + """ + if cls: + return self.__session.query(cls).count() + else: + total = 0 + for cls in classes.values(): + total += self.__session.query(cls).count() + return total + """ + Retrieves object of a class or all objects of that class + """ + if id and isinstance(id, str): + if cls and (cls in classes.keys() or cls in classes.values()): + all_objs = self.all(cls) + for key, value in all_objs.items(): + if id == value.id and key.split('.')[1] == id: + return value + return + + def count(self, cls=None): + """ + Returns the occurrence of a class or all classes + """ + occurrence = 0 + if cls: + if cls in classes.keys() or cls in classes.values(): + occurrence = len(self.all(cls)) + if not cls: + occurrence = len(self.all()) + return occurrence diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index c8cb8c1764d..b003e0944ec 100755 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -1,70 +1,70 @@ -#!/usr/bin/python3 -""" -Contains the FileStorage class -""" - -import json -from models.amenity import Amenity -from models.base_model import BaseModel -from models.city import City -from models.place import Place -from models.review import Review -from models.state import State -from models.user import User - -classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, - "Place": Place, "Review": Review, "State": State, "User": User} - - -class FileStorage: - """serializes instances to a JSON file & deserializes back to instances""" - - # string - path to the JSON file - __file_path = "file.json" - # dictionary - empty but will store all objects by .id - __objects = {} - - def all(self, cls=None): - """returns the dictionary __objects""" - if cls is not None: - new_dict = {} - for key, value in self.__objects.items(): - if cls == value.__class__ or cls == value.__class__.__name__: - new_dict[key] = value - return new_dict - return self.__objects - - def new(self, obj): - """sets in __objects the obj with key .id""" - if obj is not None: - key = obj.__class__.__name__ + "." + obj.id - self.__objects[key] = obj - - def save(self): - """serializes __objects to the JSON file (path: __file_path)""" - json_objects = {} - for key in self.__objects: - json_objects[key] = self.__objects[key].to_dict() - with open(self.__file_path, 'w') as f: - json.dump(json_objects, f) - - def reload(self): - """deserializes the JSON file to __objects""" - try: - with open(self.__file_path, 'r') as f: - jo = json.load(f) - for key in jo: - self.__objects[key] = classes[jo[key]["__class__"]](**jo[key]) - except: - pass - - def delete(self, obj=None): - """delete obj from __objects if it’s inside""" - if obj is not None: - key = obj.__class__.__name__ + '.' + obj.id - if key in self.__objects: - del self.__objects[key] - - def close(self): - """call reload() method for deserializing the JSON file to objects""" - self.reload() +#!/usr/bin/python3 +""" +Contains the FileStorage class +""" + +import json +from models.amenity import Amenity +from models.base_model import BaseModel +from models.city import City +from models.place import Place +from models.review import Review +from models.state import State +from models.user import User + +classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, + "Place": Place, "Review": Review, "State": State, "User": User} + + +class FileStorage: + """serializes instances to a JSON file & deserializes back to instances""" + + # string - path to the JSON file + __file_path = "file.json" + # dictionary - empty but will store all objects by .id + __objects = {} + + def all(self, cls=None): + """returns the dictionary __objects""" + if cls is not None: + new_dict = {} + for key, value in self.__objects.items(): + if cls == value.__class__ or cls == value.__class__.__name__: + new_dict[key] = value + return new_dict + return self.__objects + + def new(self, obj): + """sets in __objects the obj with key .id""" + if obj is not None: + key = obj.__class__.__name__ + "." + obj.id + self.__objects[key] = obj + + def save(self): + """serializes __objects to the JSON file (path: __file_path)""" + json_objects = {} + for key in self.__objects: + json_objects[key] = self.__objects[key].to_dict() + with open(self.__file_path, 'w') as f: + json.dump(json_objects, f) + + def reload(self): + """deserializes the JSON file to __objects""" + try: + with open(self.__file_path, 'r') as f: + jo = json.load(f) + for key in jo: + self.__objects[key] = classes[jo[key]["__class__"]](**jo[key]) + except Exception: + pass + + def delete(self, obj=None): + """delete obj from __objects if it’s inside""" + if obj is not None: + key = obj.__class__.__name__ + '.' + obj.id + if key in self.__objects: + del self.__objects[key] + + def close(self): + """call reload() method for deserializing the JSON file to objects""" + self.reload() diff --git a/models/place.py b/models/place.py index 0aed5a744e6..3f28f8a5143 100755 --- a/models/place.py +++ b/models/place.py @@ -1,78 +1,78 @@ -#!/usr/bin/python -""" holds class Place""" -import models -from models.base_model import BaseModel, Base -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String, Integer, Float, ForeignKey, Table -from sqlalchemy.orm import relationship - -if models.storage_t == 'db': - place_amenity = Table('place_amenity', Base.metadata, - Column('place_id', String(60), - ForeignKey('places.id', onupdate='CASCADE', - ondelete='CASCADE'), - primary_key=True), - Column('amenity_id', String(60), - ForeignKey('amenities.id', onupdate='CASCADE', - ondelete='CASCADE'), - primary_key=True)) - - -class Place(BaseModel, Base): - """Representation of Place """ - if models.storage_t == 'db': - __tablename__ = 'places' - city_id = Column(String(60), ForeignKey('cities.id'), nullable=False) - user_id = Column(String(60), ForeignKey('users.id'), nullable=False) - name = Column(String(128), nullable=False) - description = Column(String(1024), nullable=True) - number_rooms = Column(Integer, nullable=False, default=0) - number_bathrooms = Column(Integer, nullable=False, default=0) - max_guest = Column(Integer, nullable=False, default=0) - price_by_night = Column(Integer, nullable=False, default=0) - latitude = Column(Float, nullable=True) - longitude = Column(Float, nullable=True) - reviews = relationship("Review", backref="place") - amenities = relationship("Amenity", secondary="place_amenity", - backref="place_amenities", - viewonly=False) - else: - city_id = "" - user_id = "" - name = "" - description = "" - number_rooms = 0 - number_bathrooms = 0 - max_guest = 0 - price_by_night = 0 - latitude = 0.0 - longitude = 0.0 - amenity_ids = [] - - def __init__(self, *args, **kwargs): - """initializes Place""" - super().__init__(*args, **kwargs) - - if models.storage_t != 'db': - @property - def reviews(self): - """getter attribute returns the list of Review instances""" - from models.review import Review - review_list = [] - all_reviews = models.storage.all(Review) - for review in all_reviews.values(): - if review.place_id == self.id: - review_list.append(review) - return review_list - - @property - def amenities(self): - """getter attribute returns the list of Amenity instances""" - from models.amenity import Amenity - amenity_list = [] - all_amenities = models.storage.all(Amenity) - for amenity in all_amenities.values(): - if amenity.place_id == self.id: - amenity_list.append(amenity) - return amenity_list +#!/usr/bin/python +""" holds class Place""" +import models +from models.base_model import BaseModel, Base +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String, Integer, Float, ForeignKey, Table +from sqlalchemy.orm import relationship + +if models.storage_t == 'db': + place_amenity = Table('place_amenity', Base.metadata, + Column('place_id', String(60), + ForeignKey('places.id', onupdate='CASCADE', + ondelete='CASCADE'), + primary_key=True), + Column('amenity_id', String(60), + ForeignKey('amenities.id', onupdate='CASCADE', + ondelete='CASCADE'), + primary_key=True)) + + +class Place(BaseModel, Base): + """Representation of Place """ + if models.storage_t == 'db': + __tablename__ = 'places' + city_id = Column(String(60), ForeignKey('cities.id'), nullable=False) + user_id = Column(String(60), ForeignKey('users.id'), nullable=False) + name = Column(String(128), nullable=False) + description = Column(String(1024), nullable=True) + number_rooms = Column(Integer, nullable=False, default=0) + number_bathrooms = Column(Integer, nullable=False, default=0) + max_guest = Column(Integer, nullable=False, default=0) + price_by_night = Column(Integer, nullable=False, default=0) + latitude = Column(Float, nullable=True) + longitude = Column(Float, nullable=True) + reviews = relationship("Review", backref="place") + amenities = relationship("Amenity", secondary="place_amenity", + backref="place_amenities", + viewonly=False) + else: + city_id = "" + user_id = "" + name = "" + description = "" + number_rooms = 0 + number_bathrooms = 0 + max_guest = 0 + price_by_night = 0 + latitude = 0.0 + longitude = 0.0 + amenity_ids = [] + + def __init__(self, *args, **kwargs): + """initializes Place""" + super().__init__(*args, **kwargs) + + if models.storage_t != 'db': + @property + def reviews(self): + """getter attribute returns the list of Review instances""" + from models.review import Review + review_list = [] + all_reviews = models.storage.all(Review) + for review in all_reviews.values(): + if review.place_id == self.id: + review_list.append(review) + return review_list + + @property + def amenities(self): + """getter attribute returns the list of Amenity instances""" + from models.amenity import Amenity + amenity_list = [] + all_amenities = models.storage.all(Amenity) + for amenity in all_amenities.values(): + if amenity.place_id == self.id: + amenity_list.append(amenity) + return amenity_list diff --git a/models/review.py b/models/review.py index cd6c1d1ff98..b6e8e835424 100755 --- a/models/review.py +++ b/models/review.py @@ -1,24 +1,24 @@ -#!/usr/bin/python -""" holds class Review""" -import models -from models.base_model import BaseModel, Base -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String, ForeignKey - - -class Review(BaseModel, Base): - """Representation of Review """ - if models.storage_t == 'db': - __tablename__ = 'reviews' - place_id = Column(String(60), ForeignKey('places.id'), nullable=False) - user_id = Column(String(60), ForeignKey('users.id'), nullable=False) - text = Column(String(1024), nullable=False) - else: - place_id = "" - user_id = "" - text = "" - - def __init__(self, *args, **kwargs): - """initializes Review""" - super().__init__(*args, **kwargs) +#!/usr/bin/python +""" holds class Review""" +import models +from models.base_model import BaseModel, Base +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String, ForeignKey + + +class Review(BaseModel, Base): + """Representation of Review """ + if models.storage_t == 'db': + __tablename__ = 'reviews' + place_id = Column(String(60), ForeignKey('places.id'), nullable=False) + user_id = Column(String(60), ForeignKey('users.id'), nullable=False) + text = Column(String(1024), nullable=False) + else: + place_id = "" + user_id = "" + text = "" + + def __init__(self, *args, **kwargs): + """initializes Review""" + super().__init__(*args, **kwargs) diff --git a/models/state.py b/models/state.py index ca5c8961d80..5eabc55360c 100755 --- a/models/state.py +++ b/models/state.py @@ -1,34 +1,34 @@ -#!/usr/bin/python3 -""" holds class State""" -import models -from models.base_model import BaseModel, Base -from models.city import City -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship - - -class State(BaseModel, Base): - """Representation of state """ - if models.storage_t == "db": - __tablename__ = 'states' - name = Column(String(128), nullable=False) - cities = relationship("City", backref="state") - else: - name = "" - - def __init__(self, *args, **kwargs): - """initializes state""" - super().__init__(*args, **kwargs) - - if models.storage_t != "db": - @property - def cities(self): - """getter for list of city instances related to the state""" - city_list = [] - all_cities = models.storage.all(City) - for city in all_cities.values(): - if city.state_id == self.id: - city_list.append(city) - return city_list +#!/usr/bin/python3 +""" holds class State""" +import models +from models.base_model import BaseModel, Base +from models.city import City +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship + + +class State(BaseModel, Base): + """Representation of state """ + if models.storage_t == "db": + __tablename__ = 'states' + name = Column(String(128), nullable=False) + cities = relationship("City", backref="state") + else: + name = "" + + def __init__(self, *args, **kwargs): + """initializes state""" + super().__init__(*args, **kwargs) + + if models.storage_t != "db": + @property + def cities(self): + """getter for list of city instances related to the state""" + city_list = [] + all_cities = models.storage.all(City) + for city in all_cities.values(): + if city.state_id == self.id: + city_list.append(city) + return city_list diff --git a/models/user.py b/models/user.py index 36b1b70b994..32bcc0fcb4b 100755 --- a/models/user.py +++ b/models/user.py @@ -1,29 +1,29 @@ -#!/usr/bin/python3 -""" holds class User""" -import models -from models.base_model import BaseModel, Base -from os import getenv -import sqlalchemy -from sqlalchemy import Column, String -from sqlalchemy.orm import relationship - - -class User(BaseModel, Base): - """Representation of a user """ - if models.storage_t == 'db': - __tablename__ = 'users' - email = Column(String(128), nullable=False) - password = Column(String(128), nullable=False) - first_name = Column(String(128), nullable=True) - last_name = Column(String(128), nullable=True) - places = relationship("Place", backref="user") - reviews = relationship("Review", backref="user") - else: - email = "" - password = "" - first_name = "" - last_name = "" - - def __init__(self, *args, **kwargs): - """initializes user""" - super().__init__(*args, **kwargs) +#!/usr/bin/python3 +""" holds class User""" +import models +from models.base_model import BaseModel, Base +from os import getenv +import sqlalchemy +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship + + +class User(BaseModel, Base): + """Representation of a user """ + if models.storage_t == 'db': + __tablename__ = 'users' + email = Column(String(128), nullable=False) + password = Column(String(128), nullable=False) + first_name = Column(String(128), nullable=True) + last_name = Column(String(128), nullable=True) + places = relationship("Place", backref="user") + reviews = relationship("Review", backref="user") + else: + email = "" + password = "" + first_name = "" + last_name = "" + + def __init__(self, *args, **kwargs): + """initializes user""" + super().__init__(*args, **kwargs) diff --git a/setup_mysql_dev.sql b/setup_mysql_dev.sql index 30fc4cd108d..384c5f57c42 100644 --- a/setup_mysql_dev.sql +++ b/setup_mysql_dev.sql @@ -1,7 +1,7 @@ --- prepares a MySQL server for the project - -CREATE DATABASE IF NOT EXISTS hbnb_dev_db; -CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost' IDENTIFIED BY 'hbnb_dev_pwd'; -GRANT ALL PRIVILEGES ON `hbnb_dev_db`.* TO 'hbnb_dev'@'localhost'; -GRANT SELECT ON `performance_schema`.* TO 'hbnb_dev'@'localhost'; -FLUSH PRIVILEGES; +-- prepares a MySQL server for the project + +CREATE DATABASE IF NOT EXISTS hbnb_dev_db; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost' IDENTIFIED BY 'hbnb_dev_pwd'; +GRANT ALL PRIVILEGES ON `hbnb_dev_db`.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON `performance_schema`.* TO 'hbnb_dev'@'localhost'; +FLUSH PRIVILEGES; diff --git a/setup_mysql_test.sql b/setup_mysql_test.sql index ddb44205f78..0f6dc86ca97 100644 --- a/setup_mysql_test.sql +++ b/setup_mysql_test.sql @@ -1,7 +1,7 @@ --- prepares a MySQL server for the project - -CREATE DATABASE IF NOT EXISTS hbnb_test_db; -CREATE USER IF NOT EXISTS 'hbnb_test'@'localhost' IDENTIFIED BY 'hbnb_test_pwd'; -GRANT ALL PRIVILEGES ON `hbnb_test_db`.* TO 'hbnb_test'@'localhost'; -GRANT SELECT ON `performance_schema`.* TO 'hbnb_test'@'localhost'; -FLUSH PRIVILEGES; +-- prepares a MySQL server for the project + +CREATE DATABASE IF NOT EXISTS hbnb_test_db; +CREATE USER IF NOT EXISTS 'hbnb_test'@'localhost' IDENTIFIED BY 'hbnb_test_pwd'; +GRANT ALL PRIVILEGES ON `hbnb_test_db`.* TO 'hbnb_test'@'localhost'; +GRANT SELECT ON `performance_schema`.* TO 'hbnb_test'@'localhost'; +FLUSH PRIVILEGES; diff --git a/tests/__pycache__/test_console.cpython-37.pyc b/tests/__pycache__/test_console.cpython-37.pyc new file mode 100644 index 00000000000..73ef548310e Binary files /dev/null and b/tests/__pycache__/test_console.cpython-37.pyc differ diff --git a/tests/test_console.py b/tests/test_console.py index 015e5c46886..5f14855da24 100755 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -1,41 +1,42 @@ -#!/usr/bin/python3 -""" -Contains the class TestConsoleDocs -""" - -import console -import inspect -import pep8 -import unittest -HBNBCommand = console.HBNBCommand - - -class TestConsoleDocs(unittest.TestCase): - """Class for testing documentation of the console""" - def test_pep8_conformance_console(self): - """Test that console.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['console.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_console(self): - """Test that tests/test_console.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_console.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_console_module_docstring(self): - """Test for the console.py module docstring""" - self.assertIsNot(console.__doc__, None, - "console.py needs a docstring") - self.assertTrue(len(console.__doc__) >= 1, - "console.py needs a docstring") - - def test_HBNBCommand_class_docstring(self): - """Test for the HBNBCommand class docstring""" - self.assertIsNot(HBNBCommand.__doc__, None, - "HBNBCommand class needs a docstring") - self.assertTrue(len(HBNBCommand.__doc__) >= 1, - "HBNBCommand class needs a docstring") +#!/usr/bin/python3 +""" +Contains the class TestConsoleDocs +""" + +import console +import inspect +import pep8 +import unittest +HBNBCommand = console.HBNBCommand + + +class TestConsoleDocs(unittest.TestCase): + """Class for testing documentation of the console""" + + def test_pep8_conformance_console(self): + """Test that console.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['console.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_console(self): + """Test that tests/test_console.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_console.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_console_module_docstring(self): + """Test for the console.py module docstring""" + self.assertIsNot(console.__doc__, None, + "console.py needs a docstring") + self.assertTrue(len(console.__doc__) >= 1, + "console.py needs a docstring") + + def test_HBNBCommand_class_docstring(self): + """Test for the HBNBCommand class docstring""" + self.assertIsNot(HBNBCommand.__doc__, None, + "HBNBCommand class needs a docstring") + self.assertTrue(len(HBNBCommand.__doc__) >= 1, + "HBNBCommand class needs a docstring") diff --git a/tests/test_models/__pycache__/__init__.cpython-37.pyc b/tests/test_models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..3c29daa56b2 Binary files /dev/null and b/tests/test_models/__pycache__/__init__.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_amenity.cpython-37.pyc b/tests/test_models/__pycache__/test_amenity.cpython-37.pyc new file mode 100644 index 00000000000..17a38c57cb8 Binary files /dev/null and b/tests/test_models/__pycache__/test_amenity.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_base_model.cpython-37.pyc b/tests/test_models/__pycache__/test_base_model.cpython-37.pyc new file mode 100644 index 00000000000..84b11a23675 Binary files /dev/null and b/tests/test_models/__pycache__/test_base_model.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_city.cpython-37.pyc b/tests/test_models/__pycache__/test_city.cpython-37.pyc new file mode 100644 index 00000000000..4021b05a10a Binary files /dev/null and b/tests/test_models/__pycache__/test_city.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_place.cpython-37.pyc b/tests/test_models/__pycache__/test_place.cpython-37.pyc new file mode 100644 index 00000000000..aa907a3e68f Binary files /dev/null and b/tests/test_models/__pycache__/test_place.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_review.cpython-37.pyc b/tests/test_models/__pycache__/test_review.cpython-37.pyc new file mode 100644 index 00000000000..b3aa1b4d50d Binary files /dev/null and b/tests/test_models/__pycache__/test_review.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_state.cpython-37.pyc b/tests/test_models/__pycache__/test_state.cpython-37.pyc new file mode 100644 index 00000000000..407fa0a8ce2 Binary files /dev/null and b/tests/test_models/__pycache__/test_state.cpython-37.pyc differ diff --git a/tests/test_models/__pycache__/test_user.cpython-37.pyc b/tests/test_models/__pycache__/test_user.cpython-37.pyc new file mode 100644 index 00000000000..bd1a76ce68d Binary files /dev/null and b/tests/test_models/__pycache__/test_user.cpython-37.pyc differ diff --git a/tests/test_models/test_amenity.py b/tests/test_models/test_amenity.py index 66b0bb69bc2..8b90905a5b0 100755 --- a/tests/test_models/test_amenity.py +++ b/tests/test_models/test_amenity.py @@ -1,106 +1,106 @@ -#!/usr/bin/python3 -""" -Contains the TestAmenityDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import amenity -from models.base_model import BaseModel -import pep8 -import unittest -Amenity = amenity.Amenity - - -class TestAmenityDocs(unittest.TestCase): - """Tests to check the documentation and style of Amenity class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.amenity_f = inspect.getmembers(Amenity, inspect.isfunction) - - def test_pep8_conformance_amenity(self): - """Test that models/amenity.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/amenity.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_amenity(self): - """Test that tests/test_models/test_amenity.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_amenity.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_amenity_module_docstring(self): - """Test for the amenity.py module docstring""" - self.assertIsNot(amenity.__doc__, None, - "amenity.py needs a docstring") - self.assertTrue(len(amenity.__doc__) >= 1, - "amenity.py needs a docstring") - - def test_amenity_class_docstring(self): - """Test for the Amenity class docstring""" - self.assertIsNot(Amenity.__doc__, None, - "Amenity class needs a docstring") - self.assertTrue(len(Amenity.__doc__) >= 1, - "Amenity class needs a docstring") - - def test_amenity_func_docstrings(self): - """Test for the presence of docstrings in Amenity methods""" - for func in self.amenity_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestAmenity(unittest.TestCase): - """Test the Amenity class""" - def test_is_subclass(self): - """Test that Amenity is a subclass of BaseModel""" - amenity = Amenity() - self.assertIsInstance(amenity, BaseModel) - self.assertTrue(hasattr(amenity, "id")) - self.assertTrue(hasattr(amenity, "created_at")) - self.assertTrue(hasattr(amenity, "updated_at")) - - def test_name_attr(self): - """Test that Amenity has attribute name, and it's as an empty string""" - amenity = Amenity() - self.assertTrue(hasattr(amenity, "name")) - if models.storage_t == 'db': - self.assertEqual(amenity.name, None) - else: - self.assertEqual(amenity.name, "") - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - am = Amenity() - print(am.__dict__) - new_d = am.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in am.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - am = Amenity() - new_d = am.to_dict() - self.assertEqual(new_d["__class__"], "Amenity") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], am.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], am.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - amenity = Amenity() - string = "[Amenity] ({}) {}".format(amenity.id, amenity.__dict__) - self.assertEqual(string, str(amenity)) +#!/usr/bin/python3 +""" +Contains the TestAmenityDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import amenity +from models.base_model import BaseModel +import pep8 +import unittest +Amenity = amenity.Amenity + + +class TestAmenityDocs(unittest.TestCase): + """Tests to check the documentation and style of Amenity class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.amenity_f = inspect.getmembers(Amenity, inspect.isfunction) + + def test_pep8_conformance_amenity(self): + """Test that models/amenity.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/amenity.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_amenity(self): + """Test that tests/test_models/test_amenity.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_amenity.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_amenity_module_docstring(self): + """Test for the amenity.py module docstring""" + self.assertIsNot(amenity.__doc__, None, + "amenity.py needs a docstring") + self.assertTrue(len(amenity.__doc__) >= 1, + "amenity.py needs a docstring") + + def test_amenity_class_docstring(self): + """Test for the Amenity class docstring""" + self.assertIsNot(Amenity.__doc__, None, + "Amenity class needs a docstring") + self.assertTrue(len(Amenity.__doc__) >= 1, + "Amenity class needs a docstring") + + def test_amenity_func_docstrings(self): + """Test for the presence of docstrings in Amenity methods""" + for func in self.amenity_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestAmenity(unittest.TestCase): + """Test the Amenity class""" + def test_is_subclass(self): + """Test that Amenity is a subclass of BaseModel""" + amenity = Amenity() + self.assertIsInstance(amenity, BaseModel) + self.assertTrue(hasattr(amenity, "id")) + self.assertTrue(hasattr(amenity, "created_at")) + self.assertTrue(hasattr(amenity, "updated_at")) + + def test_name_attr(self): + """Test that Amenity has attribute name, and it's as an empty string""" + amenity = Amenity() + self.assertTrue(hasattr(amenity, "name")) + if models.storage_t == 'db': + self.assertEqual(amenity.name, None) + else: + self.assertEqual(amenity.name, "") + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + am = Amenity() + print(am.__dict__) + new_d = am.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in am.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + am = Amenity() + new_d = am.to_dict() + self.assertEqual(new_d["__class__"], "Amenity") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], am.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], am.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + amenity = Amenity() + string = "[Amenity] ({}) {}".format(amenity.id, amenity.__dict__) + self.assertEqual(string, str(amenity)) diff --git a/tests/test_models/test_base_model.py b/tests/test_models/test_base_model.py index 231dab48ccd..fcebad2417b 100644 --- a/tests/test_models/test_base_model.py +++ b/tests/test_models/test_base_model.py @@ -1,160 +1,180 @@ -#!/usr/bin/python3 -"""Test BaseModel for expected behavior and documentation""" -from datetime import datetime -import inspect -import models -import pep8 as pycodestyle -import time -import unittest -from unittest import mock -BaseModel = models.base_model.BaseModel -module_doc = models.base_model.__doc__ - - -class TestBaseModelDocs(unittest.TestCase): - """Tests to check the documentation and style of BaseModel class""" - - @classmethod - def setUpClass(self): - """Set up for docstring tests""" - self.base_funcs = inspect.getmembers(BaseModel, inspect.isfunction) - - def test_pep8_conformance(self): - """Test that models/base_model.py conforms to PEP8.""" - for path in ['models/base_model.py', - 'tests/test_models/test_base_model.py']: - with self.subTest(path=path): - errors = pycodestyle.Checker(path).check_all() - self.assertEqual(errors, 0) - - def test_module_docstring(self): - """Test for the existence of module docstring""" - self.assertIsNot(module_doc, None, - "base_model.py needs a docstring") - self.assertTrue(len(module_doc) > 1, - "base_model.py needs a docstring") - - def test_class_docstring(self): - """Test for the BaseModel class docstring""" - self.assertIsNot(BaseModel.__doc__, None, - "BaseModel class needs a docstring") - self.assertTrue(len(BaseModel.__doc__) >= 1, - "BaseModel class needs a docstring") - - def test_func_docstrings(self): - """Test for the presence of docstrings in BaseModel methods""" - for func in self.base_funcs: - with self.subTest(function=func): - self.assertIsNot( - func[1].__doc__, - None, - "{:s} method needs a docstring".format(func[0]) - ) - self.assertTrue( - len(func[1].__doc__) > 1, - "{:s} method needs a docstring".format(func[0]) - ) - - -class TestBaseModel(unittest.TestCase): - """Test the BaseModel class""" - def test_instantiation(self): - """Test that object is correctly created""" - inst = BaseModel() - self.assertIs(type(inst), BaseModel) - inst.name = "Holberton" - inst.number = 89 - attrs_types = { - "id": str, - "created_at": datetime, - "updated_at": datetime, - "name": str, - "number": int - } - for attr, typ in attrs_types.items(): - with self.subTest(attr=attr, typ=typ): - self.assertIn(attr, inst.__dict__) - self.assertIs(type(inst.__dict__[attr]), typ) - self.assertEqual(inst.name, "Holberton") - self.assertEqual(inst.number, 89) - - def test_datetime_attributes(self): - """Test that two BaseModel instances have different datetime objects - and that upon creation have identical updated_at and created_at - value.""" - tic = datetime.now() - inst1 = BaseModel() - toc = datetime.now() - self.assertTrue(tic <= inst1.created_at <= toc) - time.sleep(1e-4) - tic = datetime.now() - inst2 = BaseModel() - toc = datetime.now() - self.assertTrue(tic <= inst2.created_at <= toc) - self.assertEqual(inst1.created_at, inst1.updated_at) - self.assertEqual(inst2.created_at, inst2.updated_at) - self.assertNotEqual(inst1.created_at, inst2.created_at) - self.assertNotEqual(inst1.updated_at, inst2.updated_at) - - def test_uuid(self): - """Test that id is a valid uuid""" - inst1 = BaseModel() - inst2 = BaseModel() - for inst in [inst1, inst2]: - uuid = inst.id - with self.subTest(uuid=uuid): - self.assertIs(type(uuid), str) - self.assertRegex(uuid, - '^[0-9a-f]{8}-[0-9a-f]{4}' - '-[0-9a-f]{4}-[0-9a-f]{4}' - '-[0-9a-f]{12}$') - self.assertNotEqual(inst1.id, inst2.id) - - def test_to_dict(self): - """Test conversion of object attributes to dictionary for json""" - my_model = BaseModel() - my_model.name = "Holberton" - my_model.my_number = 89 - d = my_model.to_dict() - expected_attrs = ["id", - "created_at", - "updated_at", - "name", - "my_number", - "__class__"] - self.assertCountEqual(d.keys(), expected_attrs) - self.assertEqual(d['__class__'], 'BaseModel') - self.assertEqual(d['name'], "Holberton") - self.assertEqual(d['my_number'], 89) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - bm = BaseModel() - new_d = bm.to_dict() - self.assertEqual(new_d["__class__"], "BaseModel") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], bm.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], bm.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - inst = BaseModel() - string = "[BaseModel] ({}) {}".format(inst.id, inst.__dict__) - self.assertEqual(string, str(inst)) - - @mock.patch('models.storage') - def test_save(self, mock_storage): - """Test that save method updates `updated_at` and calls - `storage.save`""" - inst = BaseModel() - old_created_at = inst.created_at - old_updated_at = inst.updated_at - inst.save() - new_created_at = inst.created_at - new_updated_at = inst.updated_at - self.assertNotEqual(old_updated_at, new_updated_at) - self.assertEqual(old_created_at, new_created_at) - self.assertTrue(mock_storage.new.called) - self.assertTrue(mock_storage.save.called) +#!/usr/bin/python3 +"""Test BaseModel for expected behavior and documentation""" +from datetime import datetime, timedelta +import inspect +import models +import pep8 as pycodestyle +import time +import unittest +from models.base_model import BaseModel +from unittest import mock +# BaseModel = models.base_model.BaseModel +module_doc = models.base_model.__doc__ + + +class TestBaseModelDocs(unittest.TestCase): + """Tests to check the documentation and style of BaseModel class""" + + @classmethod + def setUpClass(self): + """Set up for docstring tests""" + self.base_funcs = inspect.getmembers(BaseModel, inspect.isfunction) + + def test_pep8_conformance(self): + """Test that models/base_model.py conforms to PEP8.""" + for path in ['models/base_model.py', + 'tests/test_models/test_base_model.py']: + with self.subTest(path=path): + errors = pycodestyle.Checker(path).check_all() + self.assertEqual(errors, 0) + + def test_module_docstring(self): + """Test for the existence of module docstring""" + self.assertIsNot(module_doc, None, + "base_model.py needs a docstring") + self.assertTrue(len(module_doc) > 1, + "base_model.py needs a docstring") + + def test_class_docstring(self): + """Test for the BaseModel class docstring""" + self.assertIsNot(BaseModel.__doc__, None, + "BaseModel class needs a docstring") + self.assertTrue(len(BaseModel.__doc__) >= 1, + "BaseModel class needs a docstring") + + def test_func_docstrings(self): + """Test for the presence of docstrings in BaseModel methods""" + for func in self.base_funcs: + with self.subTest(function=func): + self.assertIsNot( + func[1].__doc__, + None, + "{:s} method needs a docstring".format(func[0]) + ) + self.assertTrue( + len(func[1].__doc__) > 1, + "{:s} method needs a docstring".format(func[0]) + ) + + +class TestBaseModel(unittest.TestCase): + """Test the BaseModel class""" + def test_instantiation(self): + """Test that object is correctly created""" + inst = BaseModel() + self.assertIs(type(inst), BaseModel) + inst.name = "Holberton" + inst.number = 89 + attrs_types = { + "id": str, + "created_at": datetime, + "updated_at": datetime, + "name": str, + "number": int + } + for attr, typ in attrs_types.items(): + with self.subTest(attr=attr, typ=typ): + self.assertIn(attr, inst.__dict__) + self.assertIs(type(inst.__dict__[attr]), typ) + self.assertEqual(inst.name, "Holberton") + self.assertEqual(inst.number, 89) + + def test_datetime_attributes(self): + """Test that two BaseModel instances have different datetime objects + and that upon creation have identical updated_at and created_at + value.""" + # Create first instance and get timestamps + tic = datetime.utcnow() + inst1 = BaseModel() + toc = datetime.utcnow() + + # Allow a tolerance of 100 milliseconds + tolerance = timedelta(milliseconds=100) + + # Check timestamps within the tolerance window + self.assertTrue(tic <= inst1.created_at <= toc + tolerance, + f"inst1.created_at=" + f"{inst1.created_at}, tic={tic}, toc={toc}") + + # Small delay to ensure difference + time.sleep(0.01) + + # Create second instance and get timestamps + tic = datetime.utcnow() + inst2 = BaseModel() + toc = datetime.utcnow() + + self.assertTrue(tic <= inst2.created_at <= toc + tolerance, + f"inst2.created_at=" + f"{inst2.created_at}, tic={tic}, toc={toc}") + + # Ensure created_at and updated_at are identical at creation + self.assertEqual(inst1.created_at, inst1.updated_at) + self.assertEqual(inst2.created_at, inst2.updated_at) + + # Ensure different instances have different timestamps + self.assertNotEqual(inst1.created_at, inst2.created_at) + self.assertNotEqual(inst1.updated_at, inst2.updated_at) + + def test_uuid(self): + """Test that id is a valid uuid""" + inst1 = BaseModel() + inst2 = BaseModel() + for inst in [inst1, inst2]: + uuid = inst.id + with self.subTest(uuid=uuid): + self.assertIs(type(uuid), str) + self.assertRegex(uuid, + '^[0-9a-f]{8}-[0-9a-f]{4}' + '-[0-9a-f]{4}-[0-9a-f]{4}' + '-[0-9a-f]{12}$') + self.assertNotEqual(inst1.id, inst2.id) + + def test_to_dict(self): + """Test conversion of object attributes to dictionary for json""" + my_model = BaseModel() + my_model.name = "Holberton" + my_model.my_number = 89 + d = my_model.to_dict() + expected_attrs = ["id", + "created_at", + "updated_at", + "name", + "my_number", + "__class__"] + self.assertCountEqual(d.keys(), expected_attrs) + self.assertEqual(d['__class__'], 'BaseModel') + self.assertEqual(d['name'], "Holberton") + self.assertEqual(d['my_number'], 89) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + bm = BaseModel() + new_d = bm.to_dict() + self.assertEqual(new_d["__class__"], "BaseModel") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], bm.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], bm.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + inst = BaseModel() + string = "[BaseModel] ({}) {}".format(inst.id, inst.__dict__) + self.assertEqual(string, str(inst)) + + @mock.patch('models.storage') + def test_save(self, mock_storage): + """Test that save method updates `updated_at` and calls + `storage.save`""" + inst = BaseModel() + old_created_at = inst.created_at + old_updated_at = inst.updated_at + inst.save() + new_created_at = inst.created_at + new_updated_at = inst.updated_at + self.assertNotEqual(old_updated_at, new_updated_at) + self.assertEqual(old_created_at, new_created_at) + self.assertTrue(mock_storage.new.called) + self.assertTrue(mock_storage.save.called) diff --git a/tests/test_models/test_city.py b/tests/test_models/test_city.py index 1ed666115b6..87ed873bbef 100755 --- a/tests/test_models/test_city.py +++ b/tests/test_models/test_city.py @@ -1,114 +1,114 @@ -#!/usr/bin/python3 -""" -Contains the TestCityDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import city -from models.base_model import BaseModel -import pep8 -import unittest -City = city.City - - -class TestCityDocs(unittest.TestCase): - """Tests to check the documentation and style of City class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.city_f = inspect.getmembers(City, inspect.isfunction) - - def test_pep8_conformance_city(self): - """Test that models/city.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/city.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_city(self): - """Test that tests/test_models/test_city.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_city.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_city_module_docstring(self): - """Test for the city.py module docstring""" - self.assertIsNot(city.__doc__, None, - "city.py needs a docstring") - self.assertTrue(len(city.__doc__) >= 1, - "city.py needs a docstring") - - def test_city_class_docstring(self): - """Test for the City class docstring""" - self.assertIsNot(City.__doc__, None, - "City class needs a docstring") - self.assertTrue(len(City.__doc__) >= 1, - "City class needs a docstring") - - def test_city_func_docstrings(self): - """Test for the presence of docstrings in City methods""" - for func in self.city_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestCity(unittest.TestCase): - """Test the City class""" - def test_is_subclass(self): - """Test that City is a subclass of BaseModel""" - city = City() - self.assertIsInstance(city, BaseModel) - self.assertTrue(hasattr(city, "id")) - self.assertTrue(hasattr(city, "created_at")) - self.assertTrue(hasattr(city, "updated_at")) - - def test_name_attr(self): - """Test that City has attribute name, and it's an empty string""" - city = City() - self.assertTrue(hasattr(city, "name")) - if models.storage_t == 'db': - self.assertEqual(city.name, None) - else: - self.assertEqual(city.name, "") - - def test_state_id_attr(self): - """Test that City has attribute state_id, and it's an empty string""" - city = City() - self.assertTrue(hasattr(city, "state_id")) - if models.storage_t == 'db': - self.assertEqual(city.state_id, None) - else: - self.assertEqual(city.state_id, "") - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - c = City() - new_d = c.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in c.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - c = City() - new_d = c.to_dict() - self.assertEqual(new_d["__class__"], "City") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], c.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], c.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - city = City() - string = "[City] ({}) {}".format(city.id, city.__dict__) - self.assertEqual(string, str(city)) +#!/usr/bin/python3 +""" +Contains the TestCityDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import city +from models.base_model import BaseModel +import pep8 +import unittest +City = city.City + + +class TestCityDocs(unittest.TestCase): + """Tests to check the documentation and style of City class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.city_f = inspect.getmembers(City, inspect.isfunction) + + def test_pep8_conformance_city(self): + """Test that models/city.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/city.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_city(self): + """Test that tests/test_models/test_city.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_city.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_city_module_docstring(self): + """Test for the city.py module docstring""" + self.assertIsNot(city.__doc__, None, + "city.py needs a docstring") + self.assertTrue(len(city.__doc__) >= 1, + "city.py needs a docstring") + + def test_city_class_docstring(self): + """Test for the City class docstring""" + self.assertIsNot(City.__doc__, None, + "City class needs a docstring") + self.assertTrue(len(City.__doc__) >= 1, + "City class needs a docstring") + + def test_city_func_docstrings(self): + """Test for the presence of docstrings in City methods""" + for func in self.city_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestCity(unittest.TestCase): + """Test the City class""" + def test_is_subclass(self): + """Test that City is a subclass of BaseModel""" + city = City() + self.assertIsInstance(city, BaseModel) + self.assertTrue(hasattr(city, "id")) + self.assertTrue(hasattr(city, "created_at")) + self.assertTrue(hasattr(city, "updated_at")) + + def test_name_attr(self): + """Test that City has attribute name, and it's an empty string""" + city = City() + self.assertTrue(hasattr(city, "name")) + if models.storage_t == 'db': + self.assertEqual(city.name, None) + else: + self.assertEqual(city.name, "") + + def test_state_id_attr(self): + """Test that City has attribute state_id, and it's an empty string""" + city = City() + self.assertTrue(hasattr(city, "state_id")) + if models.storage_t == 'db': + self.assertEqual(city.state_id, None) + else: + self.assertEqual(city.state_id, "") + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + c = City() + new_d = c.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in c.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + c = City() + new_d = c.to_dict() + self.assertEqual(new_d["__class__"], "City") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], c.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], c.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + city = City() + string = "[City] ({}) {}".format(city.id, city.__dict__) + self.assertEqual(string, str(city)) diff --git a/tests/test_models/test_engine/__pycache__/__init__.cpython-37.pyc b/tests/test_models/test_engine/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000000..e6b10fec071 Binary files /dev/null and b/tests/test_models/test_engine/__pycache__/__init__.cpython-37.pyc differ diff --git a/tests/test_models/test_engine/__pycache__/test_db_storage.cpython-37.pyc b/tests/test_models/test_engine/__pycache__/test_db_storage.cpython-37.pyc new file mode 100644 index 00000000000..41a98c6b502 Binary files /dev/null and b/tests/test_models/test_engine/__pycache__/test_db_storage.cpython-37.pyc differ diff --git a/tests/test_models/test_engine/__pycache__/test_file_storage.cpython-37.pyc b/tests/test_models/test_engine/__pycache__/test_file_storage.cpython-37.pyc new file mode 100644 index 00000000000..0020f2e8781 Binary files /dev/null and b/tests/test_models/test_engine/__pycache__/test_file_storage.cpython-37.pyc differ diff --git a/tests/test_models/test_engine/test_db_storage.py b/tests/test_models/test_engine/test_db_storage.py index 766e625b5af..a8adafb672c 100755 --- a/tests/test_models/test_engine/test_db_storage.py +++ b/tests/test_models/test_engine/test_db_storage.py @@ -1,88 +1,115 @@ -#!/usr/bin/python3 -""" -Contains the TestDBStorageDocs and TestDBStorage classes -""" - -from datetime import datetime -import inspect -import models -from models.engine import db_storage -from models.amenity import Amenity -from models.base_model import BaseModel -from models.city import City -from models.place import Place -from models.review import Review -from models.state import State -from models.user import User -import json -import os -import pep8 -import unittest -DBStorage = db_storage.DBStorage -classes = {"Amenity": Amenity, "City": City, "Place": Place, - "Review": Review, "State": State, "User": User} - - -class TestDBStorageDocs(unittest.TestCase): - """Tests to check the documentation and style of DBStorage class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.dbs_f = inspect.getmembers(DBStorage, inspect.isfunction) - - def test_pep8_conformance_db_storage(self): - """Test that models/engine/db_storage.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/engine/db_storage.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_db_storage(self): - """Test tests/test_models/test_db_storage.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_engine/\ -test_db_storage.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_db_storage_module_docstring(self): - """Test for the db_storage.py module docstring""" - self.assertIsNot(db_storage.__doc__, None, - "db_storage.py needs a docstring") - self.assertTrue(len(db_storage.__doc__) >= 1, - "db_storage.py needs a docstring") - - def test_db_storage_class_docstring(self): - """Test for the DBStorage class docstring""" - self.assertIsNot(DBStorage.__doc__, None, - "DBStorage class needs a docstring") - self.assertTrue(len(DBStorage.__doc__) >= 1, - "DBStorage class needs a docstring") - - def test_dbs_func_docstrings(self): - """Test for the presence of docstrings in DBStorage methods""" - for func in self.dbs_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestFileStorage(unittest.TestCase): - """Test the FileStorage class""" - @unittest.skipIf(models.storage_t != 'db', "not testing db storage") - def test_all_returns_dict(self): - """Test that all returns a dictionaty""" - self.assertIs(type(models.storage.all()), dict) - - @unittest.skipIf(models.storage_t != 'db', "not testing db storage") - def test_all_no_class(self): - """Test that all returns all rows when no class is passed""" - - @unittest.skipIf(models.storage_t != 'db', "not testing db storage") - def test_new(self): - """test that new adds an object to the database""" - - @unittest.skipIf(models.storage_t != 'db', "not testing db storage") - def test_save(self): - """Test that save properly saves objects to file.json""" +#!/usr/bin/python3 +""" +Contains the TestDBStorageDocs and TestDBStorage classes +""" + +from datetime import datetime +import inspect +import models +from models.engine import db_storage +from models.amenity import Amenity +from models.base_model import BaseModel +from models.city import City +from models.place import Place +from models.review import Review +from models.state import State +from models.user import User +import json +import os +import pep8 +import unittest +DBStorage = db_storage.DBStorage +classes = {"Amenity": Amenity, "City": City, "Place": Place, + "Review": Review, "State": State, "User": User} + + +class TestDBStorageDocs(unittest.TestCase): + """Tests to check the documentation and style of DBStorage class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.dbs_f = inspect.getmembers(DBStorage, inspect.isfunction) + + def test_pep8_conformance_db_storage(self): + """Test that models/engine/db_storage.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/engine/db_storage.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_db_storage(self): + """Test tests/test_models/test_db_storage.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_engine/\ +test_db_storage.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_db_storage_module_docstring(self): + """Test for the db_storage.py module docstring""" + self.assertIsNot(db_storage.__doc__, None, + "db_storage.py needs a docstring") + self.assertTrue(len(db_storage.__doc__) >= 1, + "db_storage.py needs a docstring") + + def test_db_storage_class_docstring(self): + """Test for the DBStorage class docstring""" + self.assertIsNot(DBStorage.__doc__, None, + "DBStorage class needs a docstring") + self.assertTrue(len(DBStorage.__doc__) >= 1, + "DBStorage class needs a docstring") + + def test_dbs_func_docstrings(self): + """Test for the presence of docstrings in DBStorage methods""" + for func in self.dbs_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestFileStorage(unittest.TestCase): + """Test the FileStorage class""" + @unittest.skipIf(models.storage_t != 'db', "not testing db storage") + def test_all_returns_dict(self): + """Test that all returns a dictionaries""" + self.assertIs(type(models.storage.all()), dict) + + @unittest.skipIf(models.storage_t != 'db', "not testing db storage") + def test_all_no_class(self): + """Test that all returns all rows when no class is passed""" + pass + + @unittest.skipIf(models.storage_t != 'db', "not testing db storage") + def test_new(self): + """test that new adds an object to the database""" + pass + + @unittest.skipIf(models.storage_t != 'db', "not testing db storage") + def test_save(self): + """Test that save properly saves objects to file.json""" + pass + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_get(self): + """Test that retrieve objects from file.json""" + state = State(name='Kigali') + models.storage.new(state) + models.storage.save() + + state_obj = models.storage.get(State, state.id) + + self.assertEqual(state, state_obj) + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_count(self): + """Test that counts objects from file.json""" + objs_from_all = len(models.storage.all()) + objs_from_count = models.storage.count() + + self.assertEqual(objs_from_all, objs_from_count) + + states_from_all = len(models.storage.all(State)) + states_from_count = models.storage.count(State) + + self.assertEqual(states_from_all, states_from_count) diff --git a/tests/test_models/test_engine/test_file_storage.py b/tests/test_models/test_engine/test_file_storage.py index 1474a34fec0..e48fbd2396b 100755 --- a/tests/test_models/test_engine/test_file_storage.py +++ b/tests/test_models/test_engine/test_file_storage.py @@ -1,115 +1,139 @@ -#!/usr/bin/python3 -""" -Contains the TestFileStorageDocs classes -""" - -from datetime import datetime -import inspect -import models -from models.engine import file_storage -from models.amenity import Amenity -from models.base_model import BaseModel -from models.city import City -from models.place import Place -from models.review import Review -from models.state import State -from models.user import User -import json -import os -import pep8 -import unittest -FileStorage = file_storage.FileStorage -classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, - "Place": Place, "Review": Review, "State": State, "User": User} - - -class TestFileStorageDocs(unittest.TestCase): - """Tests to check the documentation and style of FileStorage class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.fs_f = inspect.getmembers(FileStorage, inspect.isfunction) - - def test_pep8_conformance_file_storage(self): - """Test that models/engine/file_storage.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/engine/file_storage.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_file_storage(self): - """Test tests/test_models/test_file_storage.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_engine/\ -test_file_storage.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_file_storage_module_docstring(self): - """Test for the file_storage.py module docstring""" - self.assertIsNot(file_storage.__doc__, None, - "file_storage.py needs a docstring") - self.assertTrue(len(file_storage.__doc__) >= 1, - "file_storage.py needs a docstring") - - def test_file_storage_class_docstring(self): - """Test for the FileStorage class docstring""" - self.assertIsNot(FileStorage.__doc__, None, - "FileStorage class needs a docstring") - self.assertTrue(len(FileStorage.__doc__) >= 1, - "FileStorage class needs a docstring") - - def test_fs_func_docstrings(self): - """Test for the presence of docstrings in FileStorage methods""" - for func in self.fs_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestFileStorage(unittest.TestCase): - """Test the FileStorage class""" - @unittest.skipIf(models.storage_t == 'db', "not testing file storage") - def test_all_returns_dict(self): - """Test that all returns the FileStorage.__objects attr""" - storage = FileStorage() - new_dict = storage.all() - self.assertEqual(type(new_dict), dict) - self.assertIs(new_dict, storage._FileStorage__objects) - - @unittest.skipIf(models.storage_t == 'db', "not testing file storage") - def test_new(self): - """test that new adds an object to the FileStorage.__objects attr""" - storage = FileStorage() - save = FileStorage._FileStorage__objects - FileStorage._FileStorage__objects = {} - test_dict = {} - for key, value in classes.items(): - with self.subTest(key=key, value=value): - instance = value() - instance_key = instance.__class__.__name__ + "." + instance.id - storage.new(instance) - test_dict[instance_key] = instance - self.assertEqual(test_dict, storage._FileStorage__objects) - FileStorage._FileStorage__objects = save - - @unittest.skipIf(models.storage_t == 'db', "not testing file storage") - def test_save(self): - """Test that save properly saves objects to file.json""" - storage = FileStorage() - new_dict = {} - for key, value in classes.items(): - instance = value() - instance_key = instance.__class__.__name__ + "." + instance.id - new_dict[instance_key] = instance - save = FileStorage._FileStorage__objects - FileStorage._FileStorage__objects = new_dict - storage.save() - FileStorage._FileStorage__objects = save - for key, value in new_dict.items(): - new_dict[key] = value.to_dict() - string = json.dumps(new_dict) - with open("file.json", "r") as f: - js = f.read() - self.assertEqual(json.loads(string), json.loads(js)) +#!/usr/bin/python3 +""" +Contains the TestFileStorageDocs classes +""" + +from datetime import datetime +import inspect +import models +from models.engine import file_storage +from models.amenity import Amenity +from models.base_model import BaseModel +from models.city import City +from models.place import Place +from models.review import Review +from models.state import State +from models.user import User +import json +import os +import pep8 +import unittest +FileStorage = file_storage.FileStorage +classes = {"Amenity": Amenity, "BaseModel": BaseModel, "City": City, + "Place": Place, "Review": Review, "State": State, "User": User} + + +class TestFileStorageDocs(unittest.TestCase): + """Tests to check the documentation and style of FileStorage class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.fs_f = inspect.getmembers(FileStorage, inspect.isfunction) + + def test_pep8_conformance_file_storage(self): + """Test that models/engine/file_storage.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/engine/file_storage.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_file_storage(self): + """Test tests/test_models/test_file_storage.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_engine/\ +test_file_storage.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_file_storage_module_docstring(self): + """Test for the file_storage.py module docstring""" + self.assertIsNot(file_storage.__doc__, None, + "file_storage.py needs a docstring") + self.assertTrue(len(file_storage.__doc__) >= 1, + "file_storage.py needs a docstring") + + def test_file_storage_class_docstring(self): + """Test for the FileStorage class docstring""" + self.assertIsNot(FileStorage.__doc__, None, + "FileStorage class needs a docstring") + self.assertTrue(len(FileStorage.__doc__) >= 1, + "FileStorage class needs a docstring") + + def test_fs_func_docstrings(self): + """Test for the presence of docstrings in FileStorage methods""" + for func in self.fs_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestFileStorage(unittest.TestCase): + """Test the FileStorage class""" + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_all_returns_dict(self): + """Test that all returns the FileStorage.__objects attr""" + storage = FileStorage() + new_dict = storage.all() + self.assertEqual(type(new_dict), dict) + self.assertIs(new_dict, storage._FileStorage__objects) + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_new(self): + """test that new adds an object to the FileStorage.__objects attr""" + storage = FileStorage() + save = FileStorage._FileStorage__objects + FileStorage._FileStorage__objects = {} + test_dict = {} + for key, value in classes.items(): + with self.subTest(key=key, value=value): + instance = value() + instance_key = instance.__class__.__name__ + "." + instance.id + storage.new(instance) + test_dict[instance_key] = instance + self.assertEqual(test_dict, storage._FileStorage__objects) + FileStorage._FileStorage__objects = save + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_save(self): + """Test that save properly saves objects to file.json""" + storage = FileStorage() + new_dict = {} + for key, value in classes.items(): + instance = value() + instance_key = instance.__class__.__name__ + "." + instance.id + new_dict[instance_key] = instance + save = FileStorage._FileStorage__objects + FileStorage._FileStorage__objects = new_dict + storage.save() + FileStorage._FileStorage__objects = save + for key, value in new_dict.items(): + new_dict[key] = value.to_dict() + string = json.dumps(new_dict) + with open("file.json", "r") as f: + js = f.read() + self.assertEqual(json.loads(string), json.loads(js)) + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_get(self): + """Test that retrieve objects from file.json""" + state = State(name='Kigali') + models.storage.new(state) + models.storage.save() + + state_obj = models.storage.get(State, state.id) + + self.assertEqual(state, state_obj) + + @unittest.skipIf(models.storage_t == 'db', "not testing file storage") + def test_count(self): + """Test that counts objects from file.json""" + objs_from_all = len(models.storage.all()) + objs_from_count = models.storage.count() + + self.assertEqual(objs_from_all, objs_from_count) + + states_from_all = len(models.storage.all(State)) + states_from_count = models.storage.count(State) + + self.assertEqual(states_from_all, states_from_count) diff --git a/tests/test_models/test_place.py b/tests/test_models/test_place.py index 233e7742e2c..00e132e1026 100755 --- a/tests/test_models/test_place.py +++ b/tests/test_models/test_place.py @@ -1,200 +1,200 @@ -#!/usr/bin/python3 -""" -Contains the TestPlaceDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import place -from models.base_model import BaseModel -import pep8 -import unittest -Place = place.Place - - -class TestPlaceDocs(unittest.TestCase): - """Tests to check the documentation and style of Place class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.place_f = inspect.getmembers(Place, inspect.isfunction) - - def test_pep8_conformance_place(self): - """Test that models/place.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/place.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_place(self): - """Test that tests/test_models/test_place.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_place.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_place_module_docstring(self): - """Test for the place.py module docstring""" - self.assertIsNot(place.__doc__, None, - "place.py needs a docstring") - self.assertTrue(len(place.__doc__) >= 1, - "place.py needs a docstring") - - def test_place_class_docstring(self): - """Test for the Place class docstring""" - self.assertIsNot(Place.__doc__, None, - "Place class needs a docstring") - self.assertTrue(len(Place.__doc__) >= 1, - "Place class needs a docstring") - - def test_place_func_docstrings(self): - """Test for the presence of docstrings in Place methods""" - for func in self.place_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestPlace(unittest.TestCase): - """Test the Place class""" - def test_is_subclass(self): - """Test that Place is a subclass of BaseModel""" - place = Place() - self.assertIsInstance(place, BaseModel) - self.assertTrue(hasattr(place, "id")) - self.assertTrue(hasattr(place, "created_at")) - self.assertTrue(hasattr(place, "updated_at")) - - def test_city_id_attr(self): - """Test Place has attr city_id, and it's an empty string""" - place = Place() - self.assertTrue(hasattr(place, "city_id")) - if models.storage_t == 'db': - self.assertEqual(place.city_id, None) - else: - self.assertEqual(place.city_id, "") - - def test_user_id_attr(self): - """Test Place has attr user_id, and it's an empty string""" - place = Place() - self.assertTrue(hasattr(place, "user_id")) - if models.storage_t == 'db': - self.assertEqual(place.user_id, None) - else: - self.assertEqual(place.user_id, "") - - def test_name_attr(self): - """Test Place has attr name, and it's an empty string""" - place = Place() - self.assertTrue(hasattr(place, "name")) - if models.storage_t == 'db': - self.assertEqual(place.name, None) - else: - self.assertEqual(place.name, "") - - def test_description_attr(self): - """Test Place has attr description, and it's an empty string""" - place = Place() - self.assertTrue(hasattr(place, "description")) - if models.storage_t == 'db': - self.assertEqual(place.description, None) - else: - self.assertEqual(place.description, "") - - def test_number_rooms_attr(self): - """Test Place has attr number_rooms, and it's an int == 0""" - place = Place() - self.assertTrue(hasattr(place, "number_rooms")) - if models.storage_t == 'db': - self.assertEqual(place.number_rooms, None) - else: - self.assertEqual(type(place.number_rooms), int) - self.assertEqual(place.number_rooms, 0) - - def test_number_bathrooms_attr(self): - """Test Place has attr number_bathrooms, and it's an int == 0""" - place = Place() - self.assertTrue(hasattr(place, "number_bathrooms")) - if models.storage_t == 'db': - self.assertEqual(place.number_bathrooms, None) - else: - self.assertEqual(type(place.number_bathrooms), int) - self.assertEqual(place.number_bathrooms, 0) - - def test_max_guest_attr(self): - """Test Place has attr max_guest, and it's an int == 0""" - place = Place() - self.assertTrue(hasattr(place, "max_guest")) - if models.storage_t == 'db': - self.assertEqual(place.max_guest, None) - else: - self.assertEqual(type(place.max_guest), int) - self.assertEqual(place.max_guest, 0) - - def test_price_by_night_attr(self): - """Test Place has attr price_by_night, and it's an int == 0""" - place = Place() - self.assertTrue(hasattr(place, "price_by_night")) - if models.storage_t == 'db': - self.assertEqual(place.price_by_night, None) - else: - self.assertEqual(type(place.price_by_night), int) - self.assertEqual(place.price_by_night, 0) - - def test_latitude_attr(self): - """Test Place has attr latitude, and it's a float == 0.0""" - place = Place() - self.assertTrue(hasattr(place, "latitude")) - if models.storage_t == 'db': - self.assertEqual(place.latitude, None) - else: - self.assertEqual(type(place.latitude), float) - self.assertEqual(place.latitude, 0.0) - - def test_longitude_attr(self): - """Test Place has attr longitude, and it's a float == 0.0""" - place = Place() - self.assertTrue(hasattr(place, "longitude")) - if models.storage_t == 'db': - self.assertEqual(place.longitude, None) - else: - self.assertEqual(type(place.longitude), float) - self.assertEqual(place.longitude, 0.0) - - @unittest.skipIf(models.storage_t == 'db', "not testing File Storage") - def test_amenity_ids_attr(self): - """Test Place has attr amenity_ids, and it's an empty list""" - place = Place() - self.assertTrue(hasattr(place, "amenity_ids")) - self.assertEqual(type(place.amenity_ids), list) - self.assertEqual(len(place.amenity_ids), 0) - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - p = Place() - new_d = p.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in p.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - p = Place() - new_d = p.to_dict() - self.assertEqual(new_d["__class__"], "Place") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], p.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], p.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - place = Place() - string = "[Place] ({}) {}".format(place.id, place.__dict__) - self.assertEqual(string, str(place)) +#!/usr/bin/python3 +""" +Contains the TestPlaceDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import place +from models.base_model import BaseModel +import pep8 +import unittest +Place = place.Place + + +class TestPlaceDocs(unittest.TestCase): + """Tests to check the documentation and style of Place class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.place_f = inspect.getmembers(Place, inspect.isfunction) + + def test_pep8_conformance_place(self): + """Test that models/place.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/place.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_place(self): + """Test that tests/test_models/test_place.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_place.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_place_module_docstring(self): + """Test for the place.py module docstring""" + self.assertIsNot(place.__doc__, None, + "place.py needs a docstring") + self.assertTrue(len(place.__doc__) >= 1, + "place.py needs a docstring") + + def test_place_class_docstring(self): + """Test for the Place class docstring""" + self.assertIsNot(Place.__doc__, None, + "Place class needs a docstring") + self.assertTrue(len(Place.__doc__) >= 1, + "Place class needs a docstring") + + def test_place_func_docstrings(self): + """Test for the presence of docstrings in Place methods""" + for func in self.place_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestPlace(unittest.TestCase): + """Test the Place class""" + def test_is_subclass(self): + """Test that Place is a subclass of BaseModel""" + place = Place() + self.assertIsInstance(place, BaseModel) + self.assertTrue(hasattr(place, "id")) + self.assertTrue(hasattr(place, "created_at")) + self.assertTrue(hasattr(place, "updated_at")) + + def test_city_id_attr(self): + """Test Place has attr city_id, and it's an empty string""" + place = Place() + self.assertTrue(hasattr(place, "city_id")) + if models.storage_t == 'db': + self.assertEqual(place.city_id, None) + else: + self.assertEqual(place.city_id, "") + + def test_user_id_attr(self): + """Test Place has attr user_id, and it's an empty string""" + place = Place() + self.assertTrue(hasattr(place, "user_id")) + if models.storage_t == 'db': + self.assertEqual(place.user_id, None) + else: + self.assertEqual(place.user_id, "") + + def test_name_attr(self): + """Test Place has attr name, and it's an empty string""" + place = Place() + self.assertTrue(hasattr(place, "name")) + if models.storage_t == 'db': + self.assertEqual(place.name, None) + else: + self.assertEqual(place.name, "") + + def test_description_attr(self): + """Test Place has attr description, and it's an empty string""" + place = Place() + self.assertTrue(hasattr(place, "description")) + if models.storage_t == 'db': + self.assertEqual(place.description, None) + else: + self.assertEqual(place.description, "") + + def test_number_rooms_attr(self): + """Test Place has attr number_rooms, and it's an int == 0""" + place = Place() + self.assertTrue(hasattr(place, "number_rooms")) + if models.storage_t == 'db': + self.assertEqual(place.number_rooms, None) + else: + self.assertEqual(type(place.number_rooms), int) + self.assertEqual(place.number_rooms, 0) + + def test_number_bathrooms_attr(self): + """Test Place has attr number_bathrooms, and it's an int == 0""" + place = Place() + self.assertTrue(hasattr(place, "number_bathrooms")) + if models.storage_t == 'db': + self.assertEqual(place.number_bathrooms, None) + else: + self.assertEqual(type(place.number_bathrooms), int) + self.assertEqual(place.number_bathrooms, 0) + + def test_max_guest_attr(self): + """Test Place has attr max_guest, and it's an int == 0""" + place = Place() + self.assertTrue(hasattr(place, "max_guest")) + if models.storage_t == 'db': + self.assertEqual(place.max_guest, None) + else: + self.assertEqual(type(place.max_guest), int) + self.assertEqual(place.max_guest, 0) + + def test_price_by_night_attr(self): + """Test Place has attr price_by_night, and it's an int == 0""" + place = Place() + self.assertTrue(hasattr(place, "price_by_night")) + if models.storage_t == 'db': + self.assertEqual(place.price_by_night, None) + else: + self.assertEqual(type(place.price_by_night), int) + self.assertEqual(place.price_by_night, 0) + + def test_latitude_attr(self): + """Test Place has attr latitude, and it's a float == 0.0""" + place = Place() + self.assertTrue(hasattr(place, "latitude")) + if models.storage_t == 'db': + self.assertEqual(place.latitude, None) + else: + self.assertEqual(type(place.latitude), float) + self.assertEqual(place.latitude, 0.0) + + def test_longitude_attr(self): + """Test Place has attr longitude, and it's a float == 0.0""" + place = Place() + self.assertTrue(hasattr(place, "longitude")) + if models.storage_t == 'db': + self.assertEqual(place.longitude, None) + else: + self.assertEqual(type(place.longitude), float) + self.assertEqual(place.longitude, 0.0) + + @unittest.skipIf(models.storage_t == 'db', "not testing File Storage") + def test_amenity_ids_attr(self): + """Test Place has attr amenity_ids, and it's an empty list""" + place = Place() + self.assertTrue(hasattr(place, "amenity_ids")) + self.assertEqual(type(place.amenity_ids), list) + self.assertEqual(len(place.amenity_ids), 0) + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + p = Place() + new_d = p.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in p.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + p = Place() + new_d = p.to_dict() + self.assertEqual(new_d["__class__"], "Place") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], p.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], p.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + place = Place() + string = "[Place] ({}) {}".format(place.id, place.__dict__) + self.assertEqual(string, str(place)) diff --git a/tests/test_models/test_review.py b/tests/test_models/test_review.py index 171b725b77f..a4188d8fd57 100755 --- a/tests/test_models/test_review.py +++ b/tests/test_models/test_review.py @@ -1,123 +1,123 @@ -#!/usr/bin/python3 -""" -Contains the TestReviewDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import review -from models.base_model import BaseModel -import pep8 -import unittest -Review = review.Review - - -class TestReviewDocs(unittest.TestCase): - """Tests to check the documentation and style of Review class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.review_f = inspect.getmembers(Review, inspect.isfunction) - - def test_pep8_conformance_review(self): - """Test that models/review.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/review.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_review(self): - """Test that tests/test_models/test_review.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_review.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_review_module_docstring(self): - """Test for the review.py module docstring""" - self.assertIsNot(review.__doc__, None, - "review.py needs a docstring") - self.assertTrue(len(review.__doc__) >= 1, - "review.py needs a docstring") - - def test_review_class_docstring(self): - """Test for the Review class docstring""" - self.assertIsNot(Review.__doc__, None, - "Review class needs a docstring") - self.assertTrue(len(Review.__doc__) >= 1, - "Review class needs a docstring") - - def test_review_func_docstrings(self): - """Test for the presence of docstrings in Review methods""" - for func in self.review_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestReview(unittest.TestCase): - """Test the Review class""" - def test_is_subclass(self): - """Test if Review is a subclass of BaseModel""" - review = Review() - self.assertIsInstance(review, BaseModel) - self.assertTrue(hasattr(review, "id")) - self.assertTrue(hasattr(review, "created_at")) - self.assertTrue(hasattr(review, "updated_at")) - - def test_place_id_attr(self): - """Test Review has attr place_id, and it's an empty string""" - review = Review() - self.assertTrue(hasattr(review, "place_id")) - if models.storage_t == 'db': - self.assertEqual(review.place_id, None) - else: - self.assertEqual(review.place_id, "") - - def test_user_id_attr(self): - """Test Review has attr user_id, and it's an empty string""" - review = Review() - self.assertTrue(hasattr(review, "user_id")) - if models.storage_t == 'db': - self.assertEqual(review.user_id, None) - else: - self.assertEqual(review.user_id, "") - - def test_text_attr(self): - """Test Review has attr text, and it's an empty string""" - review = Review() - self.assertTrue(hasattr(review, "text")) - if models.storage_t == 'db': - self.assertEqual(review.text, None) - else: - self.assertEqual(review.text, "") - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - r = Review() - new_d = r.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in r.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - r = Review() - new_d = r.to_dict() - self.assertEqual(new_d["__class__"], "Review") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], r.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], r.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - review = Review() - string = "[Review] ({}) {}".format(review.id, review.__dict__) - self.assertEqual(string, str(review)) +#!/usr/bin/python3 +""" +Contains the TestReviewDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import review +from models.base_model import BaseModel +import pep8 +import unittest +Review = review.Review + + +class TestReviewDocs(unittest.TestCase): + """Tests to check the documentation and style of Review class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.review_f = inspect.getmembers(Review, inspect.isfunction) + + def test_pep8_conformance_review(self): + """Test that models/review.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/review.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_review(self): + """Test that tests/test_models/test_review.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_review.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_review_module_docstring(self): + """Test for the review.py module docstring""" + self.assertIsNot(review.__doc__, None, + "review.py needs a docstring") + self.assertTrue(len(review.__doc__) >= 1, + "review.py needs a docstring") + + def test_review_class_docstring(self): + """Test for the Review class docstring""" + self.assertIsNot(Review.__doc__, None, + "Review class needs a docstring") + self.assertTrue(len(Review.__doc__) >= 1, + "Review class needs a docstring") + + def test_review_func_docstrings(self): + """Test for the presence of docstrings in Review methods""" + for func in self.review_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestReview(unittest.TestCase): + """Test the Review class""" + def test_is_subclass(self): + """Test if Review is a subclass of BaseModel""" + review = Review() + self.assertIsInstance(review, BaseModel) + self.assertTrue(hasattr(review, "id")) + self.assertTrue(hasattr(review, "created_at")) + self.assertTrue(hasattr(review, "updated_at")) + + def test_place_id_attr(self): + """Test Review has attr place_id, and it's an empty string""" + review = Review() + self.assertTrue(hasattr(review, "place_id")) + if models.storage_t == 'db': + self.assertEqual(review.place_id, None) + else: + self.assertEqual(review.place_id, "") + + def test_user_id_attr(self): + """Test Review has attr user_id, and it's an empty string""" + review = Review() + self.assertTrue(hasattr(review, "user_id")) + if models.storage_t == 'db': + self.assertEqual(review.user_id, None) + else: + self.assertEqual(review.user_id, "") + + def test_text_attr(self): + """Test Review has attr text, and it's an empty string""" + review = Review() + self.assertTrue(hasattr(review, "text")) + if models.storage_t == 'db': + self.assertEqual(review.text, None) + else: + self.assertEqual(review.text, "") + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + r = Review() + new_d = r.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in r.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + r = Review() + new_d = r.to_dict() + self.assertEqual(new_d["__class__"], "Review") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], r.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], r.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + review = Review() + string = "[Review] ({}) {}".format(review.id, review.__dict__) + self.assertEqual(string, str(review)) diff --git a/tests/test_models/test_state.py b/tests/test_models/test_state.py index 2ac2391d0c3..b415174c2f3 100755 --- a/tests/test_models/test_state.py +++ b/tests/test_models/test_state.py @@ -1,105 +1,105 @@ -#!/usr/bin/python3 -""" -Contains the TestStateDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import state -from models.base_model import BaseModel -import pep8 -import unittest -State = state.State - - -class TestStateDocs(unittest.TestCase): - """Tests to check the documentation and style of State class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.state_f = inspect.getmembers(State, inspect.isfunction) - - def test_pep8_conformance_state(self): - """Test that models/state.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/state.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_state(self): - """Test that tests/test_models/test_state.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_state.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_state_module_docstring(self): - """Test for the state.py module docstring""" - self.assertIsNot(state.__doc__, None, - "state.py needs a docstring") - self.assertTrue(len(state.__doc__) >= 1, - "state.py needs a docstring") - - def test_state_class_docstring(self): - """Test for the State class docstring""" - self.assertIsNot(State.__doc__, None, - "State class needs a docstring") - self.assertTrue(len(State.__doc__) >= 1, - "State class needs a docstring") - - def test_state_func_docstrings(self): - """Test for the presence of docstrings in State methods""" - for func in self.state_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestState(unittest.TestCase): - """Test the State class""" - def test_is_subclass(self): - """Test that State is a subclass of BaseModel""" - state = State() - self.assertIsInstance(state, BaseModel) - self.assertTrue(hasattr(state, "id")) - self.assertTrue(hasattr(state, "created_at")) - self.assertTrue(hasattr(state, "updated_at")) - - def test_name_attr(self): - """Test that State has attribute name, and it's as an empty string""" - state = State() - self.assertTrue(hasattr(state, "name")) - if models.storage_t == 'db': - self.assertEqual(state.name, None) - else: - self.assertEqual(state.name, "") - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - s = State() - new_d = s.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in s.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - s = State() - new_d = s.to_dict() - self.assertEqual(new_d["__class__"], "State") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], s.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], s.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - state = State() - string = "[State] ({}) {}".format(state.id, state.__dict__) - self.assertEqual(string, str(state)) +#!/usr/bin/python3 +""" +Contains the TestStateDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import state +from models.base_model import BaseModel +import pep8 +import unittest +State = state.State + + +class TestStateDocs(unittest.TestCase): + """Tests to check the documentation and style of State class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.state_f = inspect.getmembers(State, inspect.isfunction) + + def test_pep8_conformance_state(self): + """Test that models/state.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/state.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_state(self): + """Test that tests/test_models/test_state.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_state.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_state_module_docstring(self): + """Test for the state.py module docstring""" + self.assertIsNot(state.__doc__, None, + "state.py needs a docstring") + self.assertTrue(len(state.__doc__) >= 1, + "state.py needs a docstring") + + def test_state_class_docstring(self): + """Test for the State class docstring""" + self.assertIsNot(State.__doc__, None, + "State class needs a docstring") + self.assertTrue(len(State.__doc__) >= 1, + "State class needs a docstring") + + def test_state_func_docstrings(self): + """Test for the presence of docstrings in State methods""" + for func in self.state_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestState(unittest.TestCase): + """Test the State class""" + def test_is_subclass(self): + """Test that State is a subclass of BaseModel""" + state = State() + self.assertIsInstance(state, BaseModel) + self.assertTrue(hasattr(state, "id")) + self.assertTrue(hasattr(state, "created_at")) + self.assertTrue(hasattr(state, "updated_at")) + + def test_name_attr(self): + """Test that State has attribute name, and it's as an empty string""" + state = State() + self.assertTrue(hasattr(state, "name")) + if models.storage_t == 'db': + self.assertEqual(state.name, None) + else: + self.assertEqual(state.name, "") + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + s = State() + new_d = s.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in s.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + s = State() + new_d = s.to_dict() + self.assertEqual(new_d["__class__"], "State") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], s.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], s.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + state = State() + string = "[State] ({}) {}".format(state.id, state.__dict__) + self.assertEqual(string, str(state)) diff --git a/tests/test_models/test_user.py b/tests/test_models/test_user.py index f2ed662b971..d575eb6f6be 100755 --- a/tests/test_models/test_user.py +++ b/tests/test_models/test_user.py @@ -1,132 +1,132 @@ -#!/usr/bin/python3 -""" -Contains the TestUserDocs classes -""" - -from datetime import datetime -import inspect -import models -from models import user -from models.base_model import BaseModel -import pep8 -import unittest -User = user.User - - -class TestUserDocs(unittest.TestCase): - """Tests to check the documentation and style of User class""" - @classmethod - def setUpClass(cls): - """Set up for the doc tests""" - cls.user_f = inspect.getmembers(User, inspect.isfunction) - - def test_pep8_conformance_user(self): - """Test that models/user.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['models/user.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_pep8_conformance_test_user(self): - """Test that tests/test_models/test_user.py conforms to PEP8.""" - pep8s = pep8.StyleGuide(quiet=True) - result = pep8s.check_files(['tests/test_models/test_user.py']) - self.assertEqual(result.total_errors, 0, - "Found code style errors (and warnings).") - - def test_user_module_docstring(self): - """Test for the user.py module docstring""" - self.assertIsNot(user.__doc__, None, - "user.py needs a docstring") - self.assertTrue(len(user.__doc__) >= 1, - "user.py needs a docstring") - - def test_user_class_docstring(self): - """Test for the City class docstring""" - self.assertIsNot(User.__doc__, None, - "User class needs a docstring") - self.assertTrue(len(User.__doc__) >= 1, - "User class needs a docstring") - - def test_user_func_docstrings(self): - """Test for the presence of docstrings in User methods""" - for func in self.user_f: - self.assertIsNot(func[1].__doc__, None, - "{:s} method needs a docstring".format(func[0])) - self.assertTrue(len(func[1].__doc__) >= 1, - "{:s} method needs a docstring".format(func[0])) - - -class TestUser(unittest.TestCase): - """Test the User class""" - def test_is_subclass(self): - """Test that User is a subclass of BaseModel""" - user = User() - self.assertIsInstance(user, BaseModel) - self.assertTrue(hasattr(user, "id")) - self.assertTrue(hasattr(user, "created_at")) - self.assertTrue(hasattr(user, "updated_at")) - - def test_email_attr(self): - """Test that User has attr email, and it's an empty string""" - user = User() - self.assertTrue(hasattr(user, "email")) - if models.storage_t == 'db': - self.assertEqual(user.email, None) - else: - self.assertEqual(user.email, "") - - def test_password_attr(self): - """Test that User has attr password, and it's an empty string""" - user = User() - self.assertTrue(hasattr(user, "password")) - if models.storage_t == 'db': - self.assertEqual(user.password, None) - else: - self.assertEqual(user.password, "") - - def test_first_name_attr(self): - """Test that User has attr first_name, and it's an empty string""" - user = User() - self.assertTrue(hasattr(user, "first_name")) - if models.storage_t == 'db': - self.assertEqual(user.first_name, None) - else: - self.assertEqual(user.first_name, "") - - def test_last_name_attr(self): - """Test that User has attr last_name, and it's an empty string""" - user = User() - self.assertTrue(hasattr(user, "last_name")) - if models.storage_t == 'db': - self.assertEqual(user.last_name, None) - else: - self.assertEqual(user.last_name, "") - - def test_to_dict_creates_dict(self): - """test to_dict method creates a dictionary with proper attrs""" - u = User() - new_d = u.to_dict() - self.assertEqual(type(new_d), dict) - self.assertFalse("_sa_instance_state" in new_d) - for attr in u.__dict__: - if attr is not "_sa_instance_state": - self.assertTrue(attr in new_d) - self.assertTrue("__class__" in new_d) - - def test_to_dict_values(self): - """test that values in dict returned from to_dict are correct""" - t_format = "%Y-%m-%dT%H:%M:%S.%f" - u = User() - new_d = u.to_dict() - self.assertEqual(new_d["__class__"], "User") - self.assertEqual(type(new_d["created_at"]), str) - self.assertEqual(type(new_d["updated_at"]), str) - self.assertEqual(new_d["created_at"], u.created_at.strftime(t_format)) - self.assertEqual(new_d["updated_at"], u.updated_at.strftime(t_format)) - - def test_str(self): - """test that the str method has the correct output""" - user = User() - string = "[User] ({}) {}".format(user.id, user.__dict__) - self.assertEqual(string, str(user)) +#!/usr/bin/python3 +""" +Contains the TestUserDocs classes +""" + +from datetime import datetime +import inspect +import models +from models import user +from models.base_model import BaseModel +import pep8 +import unittest +User = user.User + + +class TestUserDocs(unittest.TestCase): + """Tests to check the documentation and style of User class""" + @classmethod + def setUpClass(cls): + """Set up for the doc tests""" + cls.user_f = inspect.getmembers(User, inspect.isfunction) + + def test_pep8_conformance_user(self): + """Test that models/user.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['models/user.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_user(self): + """Test that tests/test_models/test_user.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_models/test_user.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_user_module_docstring(self): + """Test for the user.py module docstring""" + self.assertIsNot(user.__doc__, None, + "user.py needs a docstring") + self.assertTrue(len(user.__doc__) >= 1, + "user.py needs a docstring") + + def test_user_class_docstring(self): + """Test for the City class docstring""" + self.assertIsNot(User.__doc__, None, + "User class needs a docstring") + self.assertTrue(len(User.__doc__) >= 1, + "User class needs a docstring") + + def test_user_func_docstrings(self): + """Test for the presence of docstrings in User methods""" + for func in self.user_f: + self.assertIsNot(func[1].__doc__, None, + "{:s} method needs a docstring".format(func[0])) + self.assertTrue(len(func[1].__doc__) >= 1, + "{:s} method needs a docstring".format(func[0])) + + +class TestUser(unittest.TestCase): + """Test the User class""" + def test_is_subclass(self): + """Test that User is a subclass of BaseModel""" + user = User() + self.assertIsInstance(user, BaseModel) + self.assertTrue(hasattr(user, "id")) + self.assertTrue(hasattr(user, "created_at")) + self.assertTrue(hasattr(user, "updated_at")) + + def test_email_attr(self): + """Test that User has attr email, and it's an empty string""" + user = User() + self.assertTrue(hasattr(user, "email")) + if models.storage_t == 'db': + self.assertEqual(user.email, None) + else: + self.assertEqual(user.email, "") + + def test_password_attr(self): + """Test that User has attr password, and it's an empty string""" + user = User() + self.assertTrue(hasattr(user, "password")) + if models.storage_t == 'db': + self.assertEqual(user.password, None) + else: + self.assertEqual(user.password, "") + + def test_first_name_attr(self): + """Test that User has attr first_name, and it's an empty string""" + user = User() + self.assertTrue(hasattr(user, "first_name")) + if models.storage_t == 'db': + self.assertEqual(user.first_name, None) + else: + self.assertEqual(user.first_name, "") + + def test_last_name_attr(self): + """Test that User has attr last_name, and it's an empty string""" + user = User() + self.assertTrue(hasattr(user, "last_name")) + if models.storage_t == 'db': + self.assertEqual(user.last_name, None) + else: + self.assertEqual(user.last_name, "") + + def test_to_dict_creates_dict(self): + """test to_dict method creates a dictionary with proper attrs""" + u = User() + new_d = u.to_dict() + self.assertEqual(type(new_d), dict) + self.assertFalse("_sa_instance_state" in new_d) + for attr in u.__dict__: + if attr is not "_sa_instance_state": + self.assertTrue(attr in new_d) + self.assertTrue("__class__" in new_d) + + def test_to_dict_values(self): + """test that values in dict returned from to_dict are correct""" + t_format = "%Y-%m-%dT%H:%M:%S.%f" + u = User() + new_d = u.to_dict() + self.assertEqual(new_d["__class__"], "User") + self.assertEqual(type(new_d["created_at"]), str) + self.assertEqual(type(new_d["updated_at"]), str) + self.assertEqual(new_d["created_at"], u.created_at.strftime(t_format)) + self.assertEqual(new_d["updated_at"], u.updated_at.strftime(t_format)) + + def test_str(self): + """test that the str method has the correct output""" + user = User() + string = "[User] ({}) {}".format(user.id, user.__dict__) + self.assertEqual(string, str(user)) diff --git a/web_flask/0-hello_route.py b/web_flask/0-hello_route.py index 194749fecd4..1a1a406958d 100755 --- a/web_flask/0-hello_route.py +++ b/web_flask/0-hello_route.py @@ -1,16 +1,16 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/1-hbnb_route.py b/web_flask/1-hbnb_route.py index f1829cfc6dc..84cecd8a432 100755 --- a/web_flask/1-hbnb_route.py +++ b/web_flask/1-hbnb_route.py @@ -1,22 +1,22 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/10-hbnb_filters.py b/web_flask/10-hbnb_filters.py index b6d8e50f797..c52a8e42d87 100755 --- a/web_flask/10-hbnb_filters.py +++ b/web_flask/10-hbnb_filters.py @@ -1,27 +1,27 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -from models import * -from models import storage -app = Flask(__name__) - - -@app.route('/hbnb_filters', strict_slashes=False) -def filters(): - """display a HTML page like 6-index.html from static""" - states = storage.all("State").values() - amenities = storage.all("Amenity").values() - return render_template('10-hbnb_filters.html', states=states, - amenities=amenities) - - -@app.teardown_appcontext -def teardown_db(exception): - """closes the storage on teardown""" - storage.close() - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +from models import * +from models import storage +app = Flask(__name__) + + +@app.route('/hbnb_filters', strict_slashes=False) +def filters(): + """display a HTML page like 6-index.html from static""" + states = storage.all("State").values() + amenities = storage.all("Amenity").values() + return render_template('10-hbnb_filters.html', states=states, + amenities=amenities) + + +@app.teardown_appcontext +def teardown_db(exception): + """closes the storage on teardown""" + storage.close() + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/2-c_route.py b/web_flask/2-c_route.py index bb3818a09b2..fa62b2c481d 100755 --- a/web_flask/2-c_route.py +++ b/web_flask/2-c_route.py @@ -1,28 +1,28 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - - -@app.route('/c/', strict_slashes=False) -def cisfun(text): - """display “C ” followed by the value of the text variable""" - return 'C ' + text.replace('_', ' ') - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + + +@app.route('/c/', strict_slashes=False) +def cisfun(text): + """display “C ” followed by the value of the text variable""" + return 'C ' + text.replace('_', ' ') + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/3-python_route.py b/web_flask/3-python_route.py index caf0f632694..76ba792e240 100755 --- a/web_flask/3-python_route.py +++ b/web_flask/3-python_route.py @@ -1,35 +1,35 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - - -@app.route('/c/', strict_slashes=False) -def cisfun(text): - """display “C ” followed by the value of the text variable""" - return 'C ' + text.replace('_', ' ') - - -@app.route('/python', strict_slashes=False) -@app.route('/python/', strict_slashes=False) -def pythoniscool(text='is cool'): - """display “Python ”, followed by the value of the text variable""" - return 'Python ' + text.replace('_', ' ') - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + + +@app.route('/c/', strict_slashes=False) +def cisfun(text): + """display “C ” followed by the value of the text variable""" + return 'C ' + text.replace('_', ' ') + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def pythoniscool(text='is cool'): + """display “Python ”, followed by the value of the text variable""" + return 'Python ' + text.replace('_', ' ') + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/4-number_route.py b/web_flask/4-number_route.py index f2948b12e11..fe437e28c18 100755 --- a/web_flask/4-number_route.py +++ b/web_flask/4-number_route.py @@ -1,41 +1,41 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - - -@app.route('/c/', strict_slashes=False) -def cisfun(text): - """display “C ” followed by the value of the text variable""" - return 'C ' + text.replace('_', ' ') - - -@app.route('/python', strict_slashes=False) -@app.route('/python/', strict_slashes=False) -def pythoniscool(text='is cool'): - """display “Python ”, followed by the value of the text variable""" - return 'Python ' + text.replace('_', ' ') - - -@app.route('/number/', strict_slashes=False) -def imanumber(n): - """display “n is a number” only if n is an integer""" - return "{:d} is a number".format(n) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + + +@app.route('/c/', strict_slashes=False) +def cisfun(text): + """display “C ” followed by the value of the text variable""" + return 'C ' + text.replace('_', ' ') + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def pythoniscool(text='is cool'): + """display “Python ”, followed by the value of the text variable""" + return 'Python ' + text.replace('_', ' ') + + +@app.route('/number/', strict_slashes=False) +def imanumber(n): + """display “n is a number” only if n is an integer""" + return "{:d} is a number".format(n) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/5-number_template.py b/web_flask/5-number_template.py index 17841a1a3a7..95aaf34272d 100755 --- a/web_flask/5-number_template.py +++ b/web_flask/5-number_template.py @@ -1,47 +1,47 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - - -@app.route('/c/', strict_slashes=False) -def cisfun(text): - """display “C ” followed by the value of the text variable""" - return 'C ' + text.replace('_', ' ') - - -@app.route('/python', strict_slashes=False) -@app.route('/python/', strict_slashes=False) -def pythoniscool(text='is cool'): - """display “Python ”, followed by the value of the text variable""" - return 'Python ' + text.replace('_', ' ') - - -@app.route('/number/', strict_slashes=False) -def imanumber(n): - """display “n is a number” only if n is an integer""" - return "{:d} is a number".format(n) - - -@app.route('/number_template/', strict_slashes=False) -def numbersandtemplates(n): - """display a HTML page only if n is an integer""" - return render_template('5-number.html', n=n) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + + +@app.route('/c/', strict_slashes=False) +def cisfun(text): + """display “C ” followed by the value of the text variable""" + return 'C ' + text.replace('_', ' ') + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def pythoniscool(text='is cool'): + """display “Python ”, followed by the value of the text variable""" + return 'Python ' + text.replace('_', ' ') + + +@app.route('/number/', strict_slashes=False) +def imanumber(n): + """display “n is a number” only if n is an integer""" + return "{:d} is a number".format(n) + + +@app.route('/number_template/', strict_slashes=False) +def numbersandtemplates(n): + """display a HTML page only if n is an integer""" + return render_template('5-number.html', n=n) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/6-number_odd_or_even.py b/web_flask/6-number_odd_or_even.py index 7875c4c7b32..eca19173d7f 100755 --- a/web_flask/6-number_odd_or_even.py +++ b/web_flask/6-number_odd_or_even.py @@ -1,58 +1,58 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -app = Flask(__name__) - - -@app.route('/', strict_slashes=False) -def index(): - """returns Hello HBNB!""" - return 'Hello HBNB!' - - -@app.route('/hbnb', strict_slashes=False) -def hbnb(): - """returns HBNB""" - return 'HBNB' - - -@app.route('/c/', strict_slashes=False) -def cisfun(text): - """display “C ” followed by the value of the text variable""" - return 'C ' + text.replace('_', ' ') - - -@app.route('/python', strict_slashes=False) -@app.route('/python/', strict_slashes=False) -def pythoniscool(text='is cool'): - """display “Python ”, followed by the value of the text variable""" - return 'Python ' + text.replace('_', ' ') - - -@app.route('/number/', strict_slashes=False) -def imanumber(n): - """display “n is a number” only if n is an integer""" - return "{:d} is a number".format(n) - - -@app.route('/number_template/', strict_slashes=False) -def numbersandtemplates(n): - """display a HTML page only if n is an integer""" - return render_template('5-number.html', n=n) - - -@app.route('/number_odd_or_even/', strict_slashes=False) -def numbersandevenness(n): - """display a HTML page only if n is an integer""" - if n % 2 == 0: - evenness = 'even' - else: - evenness = 'odd' - return render_template('6-number_odd_or_even.html', n=n, - evenness=evenness) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def index(): + """returns Hello HBNB!""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """returns HBNB""" + return 'HBNB' + + +@app.route('/c/', strict_slashes=False) +def cisfun(text): + """display “C ” followed by the value of the text variable""" + return 'C ' + text.replace('_', ' ') + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def pythoniscool(text='is cool'): + """display “Python ”, followed by the value of the text variable""" + return 'Python ' + text.replace('_', ' ') + + +@app.route('/number/', strict_slashes=False) +def imanumber(n): + """display “n is a number” only if n is an integer""" + return "{:d} is a number".format(n) + + +@app.route('/number_template/', strict_slashes=False) +def numbersandtemplates(n): + """display a HTML page only if n is an integer""" + return render_template('5-number.html', n=n) + + +@app.route('/number_odd_or_even/', strict_slashes=False) +def numbersandevenness(n): + """display a HTML page only if n is an integer""" + if n % 2 == 0: + evenness = 'even' + else: + evenness = 'odd' + return render_template('6-number_odd_or_even.html', n=n, + evenness=evenness) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/7-states_list.py b/web_flask/7-states_list.py index fa9ae29ae54..ca7c3bd0017 100755 --- a/web_flask/7-states_list.py +++ b/web_flask/7-states_list.py @@ -1,25 +1,25 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -from models import * -from models import storage -app = Flask(__name__) - - -@app.route('/states_list', strict_slashes=False) -def states_list(): - """display a HTML page with the states listed in alphabetical order""" - states = sorted(list(storage.all("State").values()), key=lambda x: x.name) - return render_template('7-states_list.html', states=states) - - -@app.teardown_appcontext -def teardown_db(exception): - """closes the storage on teardown""" - storage.close() - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +from models import * +from models import storage +app = Flask(__name__) + + +@app.route('/states_list', strict_slashes=False) +def states_list(): + """display a HTML page with the states listed in alphabetical order""" + states = sorted(list(storage.all("State").values()), key=lambda x: x.name) + return render_template('7-states_list.html', states=states) + + +@app.teardown_appcontext +def teardown_db(exception): + """closes the storage on teardown""" + storage.close() + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/8-cities_by_states.py b/web_flask/8-cities_by_states.py index 3d2ae2b733a..2d147f74528 100755 --- a/web_flask/8-cities_by_states.py +++ b/web_flask/8-cities_by_states.py @@ -1,25 +1,25 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -from models import * -from models import storage -app = Flask(__name__) - - -@app.route('/cities_by_states', strict_slashes=False) -def cities_by_states(): - """display the states and cities listed in alphabetical order""" - states = storage.all("State").values() - return render_template('8-cities_by_states.html', states=states) - - -@app.teardown_appcontext -def teardown_db(exception): - """closes the storage on teardown""" - storage.close() - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +from models import * +from models import storage +app = Flask(__name__) + + +@app.route('/cities_by_states', strict_slashes=False) +def cities_by_states(): + """display the states and cities listed in alphabetical order""" + states = storage.all("State").values() + return render_template('8-cities_by_states.html', states=states) + + +@app.teardown_appcontext +def teardown_db(exception): + """closes the storage on teardown""" + storage.close() + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/9-states.py b/web_flask/9-states.py index cf9f5a704ce..9b96145500e 100755 --- a/web_flask/9-states.py +++ b/web_flask/9-states.py @@ -1,28 +1,28 @@ -#!/usr/bin/python3 -""" -starts a Flask web application -""" - -from flask import Flask, render_template -from models import * -from models import storage -app = Flask(__name__) - - -@app.route('/states', strict_slashes=False) -@app.route('/states/', strict_slashes=False) -def states(state_id=None): - """display the states and cities listed in alphabetical order""" - states = storage.all("State") - if state_id is not None: - state_id = 'State.' + state_id - return render_template('9-states.html', states=states, state_id=state_id) - - -@app.teardown_appcontext -def teardown_db(exception): - """closes the storage on teardown""" - storage.close() - -if __name__ == '__main__': - app.run(host='0.0.0.0', port='5000') +#!/usr/bin/python3 +""" +starts a Flask web application +""" + +from flask import Flask, render_template +from models import * +from models import storage +app = Flask(__name__) + + +@app.route('/states', strict_slashes=False) +@app.route('/states/', strict_slashes=False) +def states(state_id=None): + """display the states and cities listed in alphabetical order""" + states = storage.all("State") + if state_id is not None: + state_id = 'State.' + state_id + return render_template('9-states.html', states=states, state_id=state_id) + + +@app.teardown_appcontext +def teardown_db(exception): + """closes the storage on teardown""" + storage.close() + +if __name__ == '__main__': + app.run(host='0.0.0.0', port='5000') diff --git a/web_flask/README.md b/web_flask/README.md index 01a9f866f51..e875b1c46e8 100644 --- a/web_flask/README.md +++ b/web_flask/README.md @@ -1 +1 @@ -# 0x04. AirBnB clone - Web framework +# 0x04. AirBnB clone - Web framework diff --git a/web_flask/static/styles/3-footer.css b/web_flask/static/styles/3-footer.css index 19fe711abab..44f4e0caf25 100644 --- a/web_flask/static/styles/3-footer.css +++ b/web_flask/static/styles/3-footer.css @@ -1,11 +1,11 @@ -footer { - position: fixed; - bottom: 0; - width: 100%; - background-color: white; - height: 60px; - border-top: 1px solid #CCCCCC; - display: flex; - justify-content: center; - align-items: center; -} +footer { + position: fixed; + bottom: 0; + width: 100%; + background-color: white; + height: 60px; + border-top: 1px solid #CCCCCC; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/web_flask/static/styles/3-header.css b/web_flask/static/styles/3-header.css index 70dd644d3ed..60735052a1f 100644 --- a/web_flask/static/styles/3-header.css +++ b/web_flask/static/styles/3-header.css @@ -1,15 +1,15 @@ -header { - width: 100%; - background-color: white; - height: 70px; - border-bottom: 1px solid #CCCCCC; - display: flex; - align-items: center; -} - -.logo { - width: 142px; - height: 60px; - background: url("../images/logo.png") no-repeat center; - padding-left: 20px; -} +header { + width: 100%; + background-color: white; + height: 70px; + border-bottom: 1px solid #CCCCCC; + display: flex; + align-items: center; +} + +.logo { + width: 142px; + height: 60px; + background: url("../images/logo.png") no-repeat center; + padding-left: 20px; +} diff --git a/web_flask/static/styles/4-common.css b/web_flask/static/styles/4-common.css index 1f2f05d3853..0d1b908da5a 100644 --- a/web_flask/static/styles/4-common.css +++ b/web_flask/static/styles/4-common.css @@ -1,15 +1,15 @@ -body { - margin: 0; - padding: 0; - color: #484848; - font-size: 14px; - font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; -} - -.container { - max-width: 1000px; - margin-top: 30px; - margin-bottom: 30px; - margin-left: auto; - margin-right: auto; -} +body { + margin: 0; + padding: 0; + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin-top: 30px; + margin-bottom: 30px; + margin-left: auto; + margin-right: auto; +} diff --git a/web_flask/static/styles/6-filters.css b/web_flask/static/styles/6-filters.css index 1c23a0fde82..c53fe173d12 100644 --- a/web_flask/static/styles/6-filters.css +++ b/web_flask/static/styles/6-filters.css @@ -1,91 +1,91 @@ -.filters { - background-color: white; - height: 70px; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - display: flex; - align-items: center; -} - -section.filters > button{ - font-size: 18px; - color: white; - background-color: #FF5A5F; - height: 48px; - border: 0px; - border-radius: 4px; - width: 20%; - margin-left: auto; - margin-right: 30px; - opacity: 1; -} - -section.filters > button:hover { - opacity: 0.9; -} - -.locations, .amenities { - height: 100%; - width: 25%; - padding-left: 50px; -} - -.locations { - border-right: 1px solid #DDDDDD; -} -.locations > h3, .amenities > h3 { - font-weight: 600; - margin: 12px 0 5px 0; -} - -.locations > h4, .amenities > h4 { - font-weight: 400; - font-size: 14px; - margin: 0 0 5px 0; -} - -.popover { - display: none; - position: relative; - left: -51px; - background-color: #FAFAFA; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - z-index: 1; - padding: 30px 50px 30px 0; - margin-top: 17px; -} - -.popover, .popover ul { - list-style-type: none; -} -.locations:hover > .popover { - display: block; -} - -.amenities:hover > .popover { - display: block; -} - -.popover h2 { - margin-top: 0px; - margin-bottom: 5px; -} - -.locations > .popover > li { - margin-bottom: 30px; - margin-left: 30px; -} -.locations > .popover > li > ul { - padding-left: 20px; -} -.locations > .popover > li > ul > li { - margin-bottom: 10px; -} - -.amenities > .popover > li { - margin-left: 50px; - margin-bottom: 10px; -} +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + display: flex; + align-items: center; +} + +section.filters > button{ + font-size: 18px; + color: white; + background-color: #FF5A5F; + height: 48px; + border: 0px; + border-radius: 4px; + width: 20%; + margin-left: auto; + margin-right: 30px; + opacity: 1; +} + +section.filters > button:hover { + opacity: 0.9; +} + +.locations, .amenities { + height: 100%; + width: 25%; + padding-left: 50px; +} + +.locations { + border-right: 1px solid #DDDDDD; +} +.locations > h3, .amenities > h3 { + font-weight: 600; + margin: 12px 0 5px 0; +} + +.locations > h4, .amenities > h4 { + font-weight: 400; + font-size: 14px; + margin: 0 0 5px 0; +} + +.popover { + display: none; + position: relative; + left: -51px; + background-color: #FAFAFA; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + z-index: 1; + padding: 30px 50px 30px 0; + margin-top: 17px; +} + +.popover, .popover ul { + list-style-type: none; +} +.locations:hover > .popover { + display: block; +} + +.amenities:hover > .popover { + display: block; +} + +.popover h2 { + margin-top: 0px; + margin-bottom: 5px; +} + +.locations > .popover > li { + margin-bottom: 30px; + margin-left: 30px; +} +.locations > .popover > li > ul { + padding-left: 20px; +} +.locations > .popover > li > ul > li { + margin-bottom: 10px; +} + +.amenities > .popover > li { + margin-left: 50px; + margin-bottom: 10px; +} diff --git a/web_flask/templates/10-hbnb_filters.html b/web_flask/templates/10-hbnb_filters.html index 261634b693f..a2fca9f92a5 100644 --- a/web_flask/templates/10-hbnb_filters.html +++ b/web_flask/templates/10-hbnb_filters.html @@ -1,55 +1,55 @@ - - - - - - - - - - AirBnb Clone - - -
- -
-
-
-
-

States

-

 

-
    - {% for state in states|sort(attribute='name') %} -
  • -

    {{ state.name }}:

    -
      - {% for city in state.cities|sort(attribute='name') %} -
    • {{ city.name }}
    • - {% endfor %} -
    -
  • - {% endfor %} -
-
-
-

Amenities

-

 

-
    - {% for amenity in amenities|sort(attribute='name') %} -
  • {{ amenity.name }}
  • - {% endfor %} -
-
- -
-
-
-

- Holberton School -

-
- - + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+
+

States

+

 

+
    + {% for state in states|sort(attribute='name') %} +
  • +

    {{ state.name }}:

    +
      + {% for city in state.cities|sort(attribute='name') %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+

Amenities

+

 

+
    + {% for amenity in amenities|sort(attribute='name') %} +
  • {{ amenity.name }}
  • + {% endfor %} +
+
+ +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_flask/templates/5-number.html b/web_flask/templates/5-number.html index 57887ff7469..b2c87732c2f 100644 --- a/web_flask/templates/5-number.html +++ b/web_flask/templates/5-number.html @@ -1,9 +1,9 @@ - - - - HBNB - - -

Number: {{ n }}

- - + + + + HBNB + + +

Number: {{ n }}

+ + diff --git a/web_flask/templates/6-number_odd_or_even.html b/web_flask/templates/6-number_odd_or_even.html index 188839655c4..92bb80a85cc 100644 --- a/web_flask/templates/6-number_odd_or_even.html +++ b/web_flask/templates/6-number_odd_or_even.html @@ -1,9 +1,9 @@ - - - - HBNB - - -

Number: {{ n }} is {{ evenness }}

- - + + + + HBNB + + +

Number: {{ n }} is {{ evenness }}

+ + diff --git a/web_flask/templates/7-states_list.html b/web_flask/templates/7-states_list.html index a274a32608f..a05d37b5608 100644 --- a/web_flask/templates/7-states_list.html +++ b/web_flask/templates/7-states_list.html @@ -1,14 +1,14 @@ - - - - HBNB - - -

States

-
    - {% for state in states %} -
  • {{ state.id }}: {{ state.name }}
  • - {% endfor %} -
- - + + + + HBNB + + +

States

+
    + {% for state in states %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/8-cities_by_states.html b/web_flask/templates/8-cities_by_states.html index 94993e8860c..589f5fea00c 100644 --- a/web_flask/templates/8-cities_by_states.html +++ b/web_flask/templates/8-cities_by_states.html @@ -1,20 +1,20 @@ - - - - HBNB - - -

States

-
    - {% for state in states|sort(attribute='name') %} -
  • {{ state.id }}: {{ state.name }} -
      - {% for city in state.cities|sort(attribute='name') %} -
    • {{ city.id }}: {{ city.name }}
    • - {% endfor %} -
    -
  • - {% endfor %} -
- - + + + + HBNB + + +

States

+
    + {% for state in states|sort(attribute='name') %} +
  • {{ state.id }}: {{ state.name }} +
      + {% for city in state.cities|sort(attribute='name') %} +
    • {{ city.id }}: {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/9-states.html b/web_flask/templates/9-states.html index 34d40291c01..b6876cca95f 100644 --- a/web_flask/templates/9-states.html +++ b/web_flask/templates/9-states.html @@ -1,27 +1,27 @@ - - - - HBNB - - - {% if not state_id %} -

States

-
    - {% for state in states.values()|sort(attribute='name') %} -
  • {{ state.id }}: {{ state.name }}
  • - {% endfor %} -
- {% elif state_id in states%} - {% set state = states[state_id] %} -

State: {{ state.name }}

-

Cities

-
    - {% for city in state.cities|sort(attribute='name') %} -
  • {{ city.id }}: {{ city.name }}
  • - {% endfor %} -
- {% else %} -

Not found!

- {% endif %} - - + + + + HBNB + + + {% if not state_id %} +

States

+
    + {% for state in states.values()|sort(attribute='name') %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ {% elif state_id in states%} + {% set state = states[state_id] %} +

State: {{ state.name }}

+

Cities

+
    + {% for city in state.cities|sort(attribute='name') %} +
  • {{ city.id }}: {{ city.name }}
  • + {% endfor %} +
+ {% else %} +

Not found!

+ {% endif %} + + diff --git a/web_static/0-index.html b/web_static/0-index.html index a79ac87bffa..52a4147603f 100644 --- a/web_static/0-index.html +++ b/web_static/0-index.html @@ -1,16 +1,16 @@ - - - - - AirBnB Clone - - -
-
-
-

- Holberton School -

-
- - + + + + + AirBnB Clone + + +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/1-index.html b/web_static/1-index.html index 26f13b490f9..93d30251ce4 100644 --- a/web_static/1-index.html +++ b/web_static/1-index.html @@ -1,22 +1,22 @@ - - - - - AirBnb Clone - - - -
-
-
-

- Holberton School -

-
- - + + + + + AirBnb Clone + + + +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/2-index.html b/web_static/2-index.html index b84d4b89f49..592b21ee15c 100644 --- a/web_static/2-index.html +++ b/web_static/2-index.html @@ -1,19 +1,19 @@ - - - - - AirBnb Clone - - - - - -
-
-
-

- Holberton School -

-
- - + + + + + AirBnb Clone + + + + + +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/3-index.html b/web_static/3-index.html index 2ff10b13403..922a00923d7 100644 --- a/web_static/3-index.html +++ b/web_static/3-index.html @@ -1,22 +1,22 @@ - - - - - AirBnb Clone - - - - - - -
- -
-
-

- Holberton School -

-
- - + + + + + AirBnb Clone + + + + + + +
+ +
+
+

+ Holberton School +

+
+ + diff --git a/web_static/4-index.html b/web_static/4-index.html index f09cdcd9d21..d66744dc761 100644 --- a/web_static/4-index.html +++ b/web_static/4-index.html @@ -1,30 +1,30 @@ - - - - - - - - - - AirBnb Clone - - -
- -
-
-
- -
-
-
-

- Holberton School -

-
- - + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+ +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/5-index.html b/web_static/5-index.html index 21511ed13c9..4d774250565 100644 --- a/web_static/5-index.html +++ b/web_static/5-index.html @@ -1,38 +1,38 @@ - - - - - - - - - - AirBnb Clone - - -
- -
-
-
-
-

States

-

California, New York...

-
-
-

Amenities

-

Laundry, Internet...

-
- -
-
-
-

- Holberton School -

-
- - + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+
+

States

+

California, New York...

+
+
+

Amenities

+

Laundry, Internet...

+
+ +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/6-index.html b/web_static/6-index.html index 7850206c7ee..d03f245059d 100644 --- a/web_static/6-index.html +++ b/web_static/6-index.html @@ -1,60 +1,60 @@ - - - - - - - - - - AirBnb Clone - - -
- -
-
-
-
-

States

-

California, New York...

-
    -
  • -

    California:

    -
      -
    • San Francisco
    • -
    • Mountain View
    • -
    -
  • -
  • -

    New York:

    -
      -
    • Manhattan
    • -
    • Brooklyn
    • -
    -
  • -
-
-
-

Amenities

-

Laundry, Internet...

-
    -
  • Laundry
  • -
  • Internet
  • -
  • Television
  • -
  • Pool
  • -
-
- -
-
-
-

- Holberton School -

-
- - + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+
+

States

+

California, New York...

+
    +
  • +

    California:

    +
      +
    • San Francisco
    • +
    • Mountain View
    • +
    +
  • +
  • +

    New York:

    +
      +
    • Manhattan
    • +
    • Brooklyn
    • +
    +
  • +
+
+
+

Amenities

+

Laundry, Internet...

+
    +
  • Laundry
  • +
  • Internet
  • +
  • Television
  • +
  • Pool
  • +
+
+ +
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/7-index.html b/web_static/7-index.html index 65dd2f57d5b..2cdd4393ed8 100644 --- a/web_static/7-index.html +++ b/web_static/7-index.html @@ -1,73 +1,73 @@ - - - - - - - - - - - AirBnb Clone - - -
- -
-
-
-
-

States

-

California, New York...

-
    -
  • -

    California:

    -
      -
    • San Francisco
    • -
    • Mountain View
    • -
    -
  • -
  • -

    New York:

    -
      -
    • Manhattan
    • -
    • Brooklyn
    • -
    -
  • -
-
-
-

Amenities

-

Laundry, Internet...

-
    -
  • Laundry
  • -
  • Internet
  • -
  • Television
  • -
  • Pool
  • -
-
- -
-
-

Places

-
-

My home

-
-
-

Tiny house

-
-
-

A suite

-
-
-
-
-

- Holberton School -

-
- - + + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+
+

States

+

California, New York...

+
    +
  • +

    California:

    +
      +
    • San Francisco
    • +
    • Mountain View
    • +
    +
  • +
  • +

    New York:

    +
      +
    • Manhattan
    • +
    • Brooklyn
    • +
    +
  • +
+
+
+

Amenities

+

Laundry, Internet...

+
    +
  • Laundry
  • +
  • Internet
  • +
  • Television
  • +
  • Pool
  • +
+
+ +
+
+

Places

+
+

My home

+
+
+

Tiny house

+
+
+

A suite

+
+
+
+
+

+ Holberton School +

+
+ + diff --git a/web_static/8-index.html b/web_static/8-index.html index c9518a774e4..187d41029fe 100644 --- a/web_static/8-index.html +++ b/web_static/8-index.html @@ -1,142 +1,142 @@ - - - - - - - - - - - AirBnb Clone - - -
- -
-
-
-
-

States

-

California, New York...

-
    -
  • -

    California:

    -
      -
    • San Francisco
    • -
    • Mountain View
    • -
    -
  • -
  • -

    New York:

    -
      -
    • Manhattan
    • -
    • Brooklyn
    • -
    -
  • -
-
-
-

Amenities

-

Laundry, Internet...

-
    -
  • Laundry
  • -
  • Internet
  • -
  • Television
  • -
  • Pool
  • -
-
- -
-
-

Places

-
-

My home

-
-

$80

-
-
-
-
-

2 Guests

-
-
-
-

1 Bedroom

-
-
-
-

1 Bathroom

-
-
-
-

Owner: Jon Snow

-
-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
-
-
-

Tiny house

-
-

$65

-
-
-
-
-

4 Guests

-
-
-
-

2 Bedroom

-
-
-
-

1 Bathroom

-
-
-
-

Owner: Daenerys Targaryen

-
-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
-
-
-

A suite

-
-

$190

-
-
-
-
-

6 Guests

-
-
-
-

3 Bedroom

-
-
-
-

2 Bathroom

-
-
-
-

Owner: Azor Ahai

-
-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
-
-
-
-
-

- Holberton School -

-
- - + + + + + + + + + + + AirBnb Clone + + +
+ +
+
+
+
+

States

+

California, New York...

+
    +
  • +

    California:

    +
      +
    • San Francisco
    • +
    • Mountain View
    • +
    +
  • +
  • +

    New York:

    +
      +
    • Manhattan
    • +
    • Brooklyn
    • +
    +
  • +
+
+
+

Amenities

+

Laundry, Internet...

+
    +
  • Laundry
  • +
  • Internet
  • +
  • Television
  • +
  • Pool
  • +
+
+ +
+
+

Places

+
+

My home

+
+

$80

+
+
+
+
+

2 Guests

+
+
+
+

1 Bedroom

+
+
+
+

1 Bathroom

+
+
+
+

Owner: Jon Snow

+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+

Tiny house

+
+

$65

+
+
+
+
+

4 Guests

+
+
+
+

2 Bedroom

+
+
+
+

1 Bathroom

+
+
+
+

Owner: Daenerys Targaryen

+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+

A suite

+
+

$190

+
+
+
+
+

6 Guests

+
+
+
+

3 Bedroom

+
+
+
+

2 Bathroom

+
+
+
+

Owner: Azor Ahai

+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+
+ + + diff --git a/web_static/README.md b/web_static/README.md index 5c4cc7dc35e..7306cf9232d 100644 --- a/web_static/README.md +++ b/web_static/README.md @@ -1,15 +1,15 @@ -# 0x01. AirBnB clone - Web static -At the end of this project you are expected to be able to explain to anyone, without the help of Google: -* What is HTML? -* How do you create an HTML page? -* What is a markup language? -* What is the DOM? -* What is an element / tag? -* What is an attribute? -* How does the browser load a webpage? -* What is CSS? -* How do you add style to an element? -* What is a class? -* What is a selector? -* How do you compute CSS Specificity Value? -* What are Box properties in CSS? +# 0x01. AirBnB clone - Web static +At the end of this project you are expected to be able to explain to anyone, without the help of Google: +* What is HTML? +* How do you create an HTML page? +* What is a markup language? +* What is the DOM? +* What is an element / tag? +* What is an attribute? +* How does the browser load a webpage? +* What is CSS? +* How do you add style to an element? +* What is a class? +* What is a selector? +* How do you compute CSS Specificity Value? +* What are Box properties in CSS? diff --git a/web_static/styles/2-common.css b/web_static/styles/2-common.css index 9798fcc7b53..49613a5e05f 100644 --- a/web_static/styles/2-common.css +++ b/web_static/styles/2-common.css @@ -1,4 +1,4 @@ -body { - margin: 0; - padding: 0; -} +body { + margin: 0; + padding: 0; +} diff --git a/web_static/styles/2-footer.css b/web_static/styles/2-footer.css index 26f80771cc2..f3233f99ed6 100644 --- a/web_static/styles/2-footer.css +++ b/web_static/styles/2-footer.css @@ -1,12 +1,12 @@ -footer { - position: fixed; - bottom: 0; - width: 100%; - background-color: #00FF00; - height: 60px; -} - -footer p { - text-align: center; - margin: 20px; -} +footer { + position: fixed; + bottom: 0; + width: 100%; + background-color: #00FF00; + height: 60px; +} + +footer p { + text-align: center; + margin: 20px; +} diff --git a/web_static/styles/2-header.css b/web_static/styles/2-header.css index bbf4f03a835..da57a95b89e 100644 --- a/web_static/styles/2-header.css +++ b/web_static/styles/2-header.css @@ -1,5 +1,5 @@ -header { - width: 100%; - background-color: #FF0000; - height: 70px; -} +header { + width: 100%; + background-color: #FF0000; + height: 70px; +} diff --git a/web_static/styles/3-common.css b/web_static/styles/3-common.css index 94b11981615..a3c659a3423 100644 --- a/web_static/styles/3-common.css +++ b/web_static/styles/3-common.css @@ -1,7 +1,7 @@ -body { - margin: 0; - padding: 0; - color: #484848; - font-size: 14px; - font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; -} +body { + margin: 0; + padding: 0; + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} diff --git a/web_static/styles/3-footer.css b/web_static/styles/3-footer.css index 19fe711abab..44f4e0caf25 100644 --- a/web_static/styles/3-footer.css +++ b/web_static/styles/3-footer.css @@ -1,11 +1,11 @@ -footer { - position: fixed; - bottom: 0; - width: 100%; - background-color: white; - height: 60px; - border-top: 1px solid #CCCCCC; - display: flex; - justify-content: center; - align-items: center; -} +footer { + position: fixed; + bottom: 0; + width: 100%; + background-color: white; + height: 60px; + border-top: 1px solid #CCCCCC; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/web_static/styles/3-header.css b/web_static/styles/3-header.css index 70dd644d3ed..60735052a1f 100644 --- a/web_static/styles/3-header.css +++ b/web_static/styles/3-header.css @@ -1,15 +1,15 @@ -header { - width: 100%; - background-color: white; - height: 70px; - border-bottom: 1px solid #CCCCCC; - display: flex; - align-items: center; -} - -.logo { - width: 142px; - height: 60px; - background: url("../images/logo.png") no-repeat center; - padding-left: 20px; -} +header { + width: 100%; + background-color: white; + height: 70px; + border-bottom: 1px solid #CCCCCC; + display: flex; + align-items: center; +} + +.logo { + width: 142px; + height: 60px; + background: url("../images/logo.png") no-repeat center; + padding-left: 20px; +} diff --git a/web_static/styles/4-common.css b/web_static/styles/4-common.css index 1f2f05d3853..0d1b908da5a 100644 --- a/web_static/styles/4-common.css +++ b/web_static/styles/4-common.css @@ -1,15 +1,15 @@ -body { - margin: 0; - padding: 0; - color: #484848; - font-size: 14px; - font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; -} - -.container { - max-width: 1000px; - margin-top: 30px; - margin-bottom: 30px; - margin-left: auto; - margin-right: auto; -} +body { + margin: 0; + padding: 0; + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin-top: 30px; + margin-bottom: 30px; + margin-left: auto; + margin-right: auto; +} diff --git a/web_static/styles/4-filters.css b/web_static/styles/4-filters.css index be2f3aa36d8..44826263e79 100644 --- a/web_static/styles/4-filters.css +++ b/web_static/styles/4-filters.css @@ -1,26 +1,26 @@ -.filters { - background-color: white; - height: 70px; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - display: flex; - justify-content: flex-end; - align-items: center; -} - -section.filters button{ - font-size: 18px; - color: white; - background-color: #FF5A5F; - height: 48px; - border: 0px; - border-radius: 4px; - width: 20%; - margin-right: 30px; - opacity: 1; -} - -section.filters button:hover { - opacity: 0.9; -} +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + display: flex; + justify-content: flex-end; + align-items: center; +} + +section.filters button{ + font-size: 18px; + color: white; + background-color: #FF5A5F; + height: 48px; + border: 0px; + border-radius: 4px; + width: 20%; + margin-right: 30px; + opacity: 1; +} + +section.filters button:hover { + opacity: 0.9; +} diff --git a/web_static/styles/5-filters.css b/web_static/styles/5-filters.css index 2b500f19e77..f3a6fc4102f 100644 --- a/web_static/styles/5-filters.css +++ b/web_static/styles/5-filters.css @@ -1,48 +1,48 @@ -.filters { - background-color: white; - height: 70px; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - display: flex; - justify-content: flex-start; - align-items: center; -} - -section.filters button{ - font-size: 18px; - color: white; - background-color: #FF5A5F; - height: 48px; - border: 0px; - border-radius: 4px; - width: 20%; - margin-left: auto; - margin-right: 30px; - opacity: 1; -} - -section.filters button:hover { - opacity: 0.9; -} - -.locations, .amenities { - height: 100%; - width: 25%; - padding-left: 50px; -} - -.locations { - border-right: 1px solid #DDDDDD; -} - -.locations h3, .amenities h3 { - font-weight: 600; - margin: 12px 0 5px 0; -} - -.locations h4, .amenities h4 { - font-weight: 400; - font-size: 14px; - margin: 0 0 0 0; -} +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + display: flex; + justify-content: flex-start; + align-items: center; +} + +section.filters button{ + font-size: 18px; + color: white; + background-color: #FF5A5F; + height: 48px; + border: 0px; + border-radius: 4px; + width: 20%; + margin-left: auto; + margin-right: 30px; + opacity: 1; +} + +section.filters button:hover { + opacity: 0.9; +} + +.locations, .amenities { + height: 100%; + width: 25%; + padding-left: 50px; +} + +.locations { + border-right: 1px solid #DDDDDD; +} + +.locations h3, .amenities h3 { + font-weight: 600; + margin: 12px 0 5px 0; +} + +.locations h4, .amenities h4 { + font-weight: 400; + font-size: 14px; + margin: 0 0 0 0; +} diff --git a/web_static/styles/6-filters.css b/web_static/styles/6-filters.css index 1c23a0fde82..c53fe173d12 100644 --- a/web_static/styles/6-filters.css +++ b/web_static/styles/6-filters.css @@ -1,91 +1,91 @@ -.filters { - background-color: white; - height: 70px; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - display: flex; - align-items: center; -} - -section.filters > button{ - font-size: 18px; - color: white; - background-color: #FF5A5F; - height: 48px; - border: 0px; - border-radius: 4px; - width: 20%; - margin-left: auto; - margin-right: 30px; - opacity: 1; -} - -section.filters > button:hover { - opacity: 0.9; -} - -.locations, .amenities { - height: 100%; - width: 25%; - padding-left: 50px; -} - -.locations { - border-right: 1px solid #DDDDDD; -} -.locations > h3, .amenities > h3 { - font-weight: 600; - margin: 12px 0 5px 0; -} - -.locations > h4, .amenities > h4 { - font-weight: 400; - font-size: 14px; - margin: 0 0 5px 0; -} - -.popover { - display: none; - position: relative; - left: -51px; - background-color: #FAFAFA; - width: 100%; - border: 1px solid #DDDDDD; - border-radius: 4px; - z-index: 1; - padding: 30px 50px 30px 0; - margin-top: 17px; -} - -.popover, .popover ul { - list-style-type: none; -} -.locations:hover > .popover { - display: block; -} - -.amenities:hover > .popover { - display: block; -} - -.popover h2 { - margin-top: 0px; - margin-bottom: 5px; -} - -.locations > .popover > li { - margin-bottom: 30px; - margin-left: 30px; -} -.locations > .popover > li > ul { - padding-left: 20px; -} -.locations > .popover > li > ul > li { - margin-bottom: 10px; -} - -.amenities > .popover > li { - margin-left: 50px; - margin-bottom: 10px; -} +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + display: flex; + align-items: center; +} + +section.filters > button{ + font-size: 18px; + color: white; + background-color: #FF5A5F; + height: 48px; + border: 0px; + border-radius: 4px; + width: 20%; + margin-left: auto; + margin-right: 30px; + opacity: 1; +} + +section.filters > button:hover { + opacity: 0.9; +} + +.locations, .amenities { + height: 100%; + width: 25%; + padding-left: 50px; +} + +.locations { + border-right: 1px solid #DDDDDD; +} +.locations > h3, .amenities > h3 { + font-weight: 600; + margin: 12px 0 5px 0; +} + +.locations > h4, .amenities > h4 { + font-weight: 400; + font-size: 14px; + margin: 0 0 5px 0; +} + +.popover { + display: none; + position: relative; + left: -51px; + background-color: #FAFAFA; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; + z-index: 1; + padding: 30px 50px 30px 0; + margin-top: 17px; +} + +.popover, .popover ul { + list-style-type: none; +} +.locations:hover > .popover { + display: block; +} + +.amenities:hover > .popover { + display: block; +} + +.popover h2 { + margin-top: 0px; + margin-bottom: 5px; +} + +.locations > .popover > li { + margin-bottom: 30px; + margin-left: 30px; +} +.locations > .popover > li > ul { + padding-left: 20px; +} +.locations > .popover > li > ul > li { + margin-bottom: 10px; +} + +.amenities > .popover > li { + margin-left: 50px; + margin-bottom: 10px; +} diff --git a/web_static/styles/7-places.css b/web_static/styles/7-places.css index 04ede61303e..24c22b26eb9 100644 --- a/web_static/styles/7-places.css +++ b/web_static/styles/7-places.css @@ -1,29 +1,29 @@ -.places { - width: 100%; - border: 0; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; -} - -.places > h1 { - font-size: 30px; - padding-left: 20px; - padding-top: 20px; - margin-bottom: 0px; - flex: 0 1 100%; -} -.places > article { - width: 390px; - padding: 20px 20px 20px 20px; - margin: 20px 20px 20px 20px; - border: 1px solid #FF5A5F; - border-radius: 4px; - display: flex; - justify-content: center; -} - -.places > article > h2 { - font-size: 30px; -} +.places { + width: 100%; + border: 0; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; +} + +.places > h1 { + font-size: 30px; + padding-left: 20px; + padding-top: 20px; + margin-bottom: 0px; + flex: 0 1 100%; +} +.places > article { + width: 390px; + padding: 20px 20px 20px 20px; + margin: 20px 20px 20px 20px; + border: 1px solid #FF5A5F; + border-radius: 4px; + display: flex; + justify-content: center; +} + +.places > article > h2 { + font-size: 30px; +} diff --git a/web_static/styles/8-places.css b/web_static/styles/8-places.css index f0507c9ddc5..a1fd0abbf4e 100644 --- a/web_static/styles/8-places.css +++ b/web_static/styles/8-places.css @@ -1,107 +1,107 @@ -.places { - width: 100%; - border: 0; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; -} - -.places > h1 { - font-size: 30px; - padding-left: 20px; - padding-top: 20px; - margin-bottom: 0px; - flex: 0 1 100%; -} -.places > article { - width: 390px; - padding: 20px 20px 20px 20px; - margin: 20px 20px 20px 20px; - border: 1px solid #FF5A5F; - border-radius: 4px; - display: flex; - flex-direction: column; - justify-content: flex-start; - position: relative; -} - -.places > article > h2 { - font-size: 30px; - margin: 0 0 0 0; - align-self: center; -} - -.price_by_night { - color: #FF5A5F; - border: 4px solid #FF5A5F; - min-width: 60px; - height: 60px; - font-size: 30px; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - margin-left: auto; - position: absolute; - top: 10px; - right: 20px; -} -.price_by_night > p { - margin: 0 0 0 0; -} - -.information { - align-self: center; - height: 80px; - width: 100%; - border-top: 1px solid #DDDDDD; - border-bottom: 1px solid #DDDDDD; - margin-top: 30px; - display: flex; - justify-content: center; - align-items: center; -} - -.max_guest, .number_rooms, .number_bathrooms { - width: 100px; - text-align: center; -} - -.max_guest > p, .number_rooms > p, .number_bathrooms > p{ - margin-top: auto; - margin-bottom: auto; -} - -.guest_image { - margin-left: auto; - margin-right: auto; - height: 50px; - width: 50px; - background: url("../images/icon_group.png") no-repeat center; -} - -.bed_image { - margin-left: auto; - margin-right: auto; - height: 50px; - width: 50px; - background: url("../images/icon_bed.png") no-repeat center; -} - -.bath_image { - margin-left: auto; - margin-right: auto; - height: 50px; - width: 50px; - background: url("../images/icon_bath.png") no-repeat center; -} - -.user > p { - margin-top: 20px; - margin-bottom: 0px; -} -.description > p { - margin-top: 7px; - margin-bottom: 0px; -} +.places { + width: 100%; + border: 0; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; +} + +.places > h1 { + font-size: 30px; + padding-left: 20px; + padding-top: 20px; + margin-bottom: 0px; + flex: 0 1 100%; +} +.places > article { + width: 390px; + padding: 20px 20px 20px 20px; + margin: 20px 20px 20px 20px; + border: 1px solid #FF5A5F; + border-radius: 4px; + display: flex; + flex-direction: column; + justify-content: flex-start; + position: relative; +} + +.places > article > h2 { + font-size: 30px; + margin: 0 0 0 0; + align-self: center; +} + +.price_by_night { + color: #FF5A5F; + border: 4px solid #FF5A5F; + min-width: 60px; + height: 60px; + font-size: 30px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + margin-left: auto; + position: absolute; + top: 10px; + right: 20px; +} +.price_by_night > p { + margin: 0 0 0 0; +} + +.information { + align-self: center; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + margin-top: 30px; + display: flex; + justify-content: center; + align-items: center; +} + +.max_guest, .number_rooms, .number_bathrooms { + width: 100px; + text-align: center; +} + +.max_guest > p, .number_rooms > p, .number_bathrooms > p{ + margin-top: auto; + margin-bottom: auto; +} + +.guest_image { + margin-left: auto; + margin-right: auto; + height: 50px; + width: 50px; + background: url("../images/icon_group.png") no-repeat center; +} + +.bed_image { + margin-left: auto; + margin-right: auto; + height: 50px; + width: 50px; + background: url("../images/icon_bed.png") no-repeat center; +} + +.bath_image { + margin-left: auto; + margin-right: auto; + height: 50px; + width: 50px; + background: url("../images/icon_bath.png") no-repeat center; +} + +.user > p { + margin-top: 20px; + margin-bottom: 0px; +} +.description > p { + margin-top: 7px; + margin-bottom: 0px; +}