Repository: HTTP-APIs/hydrus (python)

Issue:
Add created/updated attributes for Instance model
### I'm submitting a 
- [X] feature request.

### Expected Behaviour:
We shall be able to track creation and updating datetime of the instances for server/client sync reason.

### Solution
Add a `created` and `updated` attributes [here](https://github.com/HTTP-APIs/hydrus/blob/master/hydrus/data/db_models.py#L36) using `default` and `onupdate` SQLAlchemy ` [arguments](http://docs.sqlalchemy.org/en/latest/core/defaults.html):
```
Column('created', DateTime, default=func.now()),
# define 'last_modified' to use the current_timestamp SQL function on update
Column('last_modified', DateTime, onupdate=func.utc_timestamp())
```
There is also a way to pull the default value from a key,value table:
```
# define 'key' to pull its default from the 'keyvalues' table
Column('key', String(20), default=select([keyvalues.c.key]).where(keyvalues.c.type='type1')),
```

Pull request:
Add created and last_modified fields
<!-- Please create/claim an issue before sending a PR -->
<!-- Add issue number (Eg: fixes #123) -->

Fixes #216 

### Checklist
- [x] My branch is up-to-date with upstream/develop branch.
- [x] Everything works and tested for Python 3.5.2 and above.

### Description
<!-- Describe about what this PR does, previous state and new state of the output -->

### Test Logs
```<!-- Please submit test logs to confirm everything is working. -->
========================== test session starts ===========================
platform linux -- Python 3.6.7, pytest-4.0.2, py-1.7.0, pluggy-0.8.0
rootdir: /home/invinciblycool/Documents/Github-projects/hydrus, inifile:
collected 51 items                                                       

hydrus/tests/test_app.py ................                          [ 31%]
hydrus/tests/test_auth.py ..........                               [ 50%]
hydrus/tests/test_crud.py ............                             [ 74%]
hydrus/tests/test_doc_writer.py ....                               [ 82%]
hydrus/tests/test_parser.py .........                              [100%]

======================= 51 passed in 1.15 seconds ========================
```

Patch:
diff --git a/hydrus/data/db_models.py b/hydrus/data/db_models.py
index c341e8f..6484d29 100644
--- a/hydrus/data/db_models.py
+++ b/hydrus/data/db_models.py
@@ -1,6 +1,7 @@
 """Models for Hydra Classes."""
 
 from sqlalchemy import create_engine, ForeignKey
+from sqlalchemy.sql import func
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy import Column, Integer, String, DateTime
 from typing import Any
@@ -46,6 +47,8 @@ class Instance(Base):
         unique=True,
         primary_key=True)
     type_ = Column(String, ForeignKey("classes.id"), nullable=True)
+    created = Column('created', DateTime, default=func.now())
+    last_modified = Column('last_modified', DateTime, onupdate=func.now())
 
 
 class BaseProperty(Base):
diff --git a/hydrus/samples/doc_writer_sample.py b/hydrus/samples/doc_writer_sample.py
index ca377dd..3637dfe 100644
--- a/hydrus/samples/doc_writer_sample.py
+++ b/hydrus/samples/doc_writer_sample.py
@@ -3,12 +3,11 @@
 from hydrus.hydraspec.doc_writer import HydraDoc, HydraClass, HydraClassProp, HydraClassOp
 from typing import Any, Dict, Union
 
-# Creating the HydraDoc object, this is the primary class for the Doc
+"""Creating the HydraDoc object, this is the primary class for the Doc"""
 API_NAME = "api"                # Name of the API, will serve as EntryPoint
 BASE_URL = "https://hydrus.com/"    # The base url at which the API is hosted
 # NOTE: The API will be accessible at BASE_URL + ENTRY_POINT (http://hydrus.com/api/)
 
-# Create ApiDoc Object
 api_doc = HydraDoc(API_NAME,
                    "Title for the API Documentation",
                    "Description for the API Documentation",
@@ -16,30 +15,17 @@ api_doc = HydraDoc(API_NAME,
                    BASE_URL)
 
 
-# Creating classes for the API
+"""Creating classes for the API"""
 class_uri = "dummyClass"      # URI of class for the HydraClass
 class_title = "dummyClass"                      # Title of the Class
 class_description = "A dummyClass for demo"     # Description of the class
-class_ = HydraClass(class_uri, class_title, class_description, endpoint=False)
-
-# Class with single instance
-class_2_uri = "singleClass"
-class_2_title = "singleClass"
-class_2_description = "A non collection class"
-class_2 = HydraClass(class_2_uri, class_2_title, class_2_description, endpoint=True)
 
-# Class not having any methods except put and get
-class_3_uri = "extraClass"
-class_3_title = "extraClass"
-class_3_description = "Class without any explicit methods"
-class_3 = HydraClass(class_3_uri, class_3_title, class_3_description, endpoint=False)
-
-# NOTE: Setting endpoint=True creates an endpoint for the class itself, this is usually for classes
-#       that have single instances.
+class_ = HydraClass(class_uri, class_title, class_description, endpoint=False)
+# NOTE: Setting endpoint=True creates an endpoint for the class itself, this is usually for classes that have single instances.
 #       These classes should not ideally have a Collection, although Hydrus will allow creation of Collections for them
 
 
-# Create new properties for the class
+"""Create new properties for the class"""
 prop1_uri = "http://props.hydrus.com/prop1"   # The URI of the class of the property
 prop1_title = "Prop1"                   # Title of the property
 
@@ -57,7 +43,7 @@ dummyProp2 = HydraClassProp(prop1_uri, prop2_title,
 #       Properties that are write=True are writable
 
 
-# Create operations for the class
+"""Create operations for the class"""
 op_name = "UpdateClass"  # The name of the operation
 op_method = "POST"  # The method of the Operation [GET, POST, PUT, DELETE]
 # URI of the object that is expected for the operation
@@ -72,49 +58,22 @@ op1 = HydraClassOp(op_name,
                    op_returns,
                    op_status)
 
-# Same way add DELETE, PUT and GET operations
-op2_status = [{"statusCode": 200, "description": "dummyClass deleted"}]
-op2 = HydraClassOp("DeleteClass", "DELETE", None, None, op2_status)
-op3_status = [{"statusCode": 201, "description": "dummyClass successfully added"}]
-op3 = HydraClassOp("AddClass", "PUT", "vocab:dummyClass", None, op3_status)
-op4_status = [{"statusCode": 200, "description": "dummyClass returned"}]
-op4 = HydraClassOp("GetClass", "GET", None, "vocab:dummyClass", op4_status)
-
-# Operations for non collection class
-class_2_op1_status = [{"statusCode": 200, "description": "singleClass changed"}]
-class_2_op1 = HydraClassOp("UpdateClass", "POST", "vocab:singleClass", None, class_2_op1_status)
-class_2_op2_status = [{"statusCode": 200, "description": "singleClass deleted"}]
-class_2_op2 = HydraClassOp("DeleteClass", "DELETE", None, None, class_2_op2_status)
-class_2_op3_status = [{"statusCode": 201, "description": "singleClass successfully added"}]
-class_2_op3 = HydraClassOp("AddClass", "PUT", "vocab:singleClass", None, op3_status)
-class_2_op4_status = [{"statusCode": 200, "description": "singleClass returned"}]
-class_2_op4 = HydraClassOp("GetClass", "GET", None, "vocab:singleClass", op4_status)
-
-# Add the properties to the classes
+
+"""Add the operation to the Class"""
 class_.add_supported_prop(dummyProp1)
 class_.add_supported_prop(dummyProp2)
-class_2.add_supported_prop(dummyProp1)
-class_2.add_supported_prop(dummyProp2)
 
-# Add the operations to the classes
+"""Add the properties to the Class"""
 class_.add_supported_op(op1)
-class_.add_supported_op(op2)
-class_.add_supported_op(op3)
-class_.add_supported_op(op4)
-class_2.add_supported_op(class_2_op1)
-class_2.add_supported_op(class_2_op2)
-class_2.add_supported_op(class_2_op3)
-class_2.add_supported_op(class_2_op4)
-
-# Add the classes to the HydraDoc
+
+
+"""Add the classes to the HydraDoc"""
 api_doc.add_supported_class(class_, collection=True, collection_path="DcTest")
-api_doc.add_supported_class(class_3, collection=True, collection_path="EcTest")
-api_doc.add_supported_class(class_2, collection=False)
 # NOTE: Using collection=True creates a HydraCollection for the class.
 #       The name of the Collection is class_.title+"Collection"
 #       The collection inherently supports GET and PUT operations
 
-# Other operations needed for the Doc
+"""Other operations needed for the Doc"""
 api_doc.add_baseResource(
 )      # Creates the base Resource Class and adds it to the API Documentation
 # Creates the base Collection Class and adds it to the API Documentation
@@ -123,7 +82,7 @@ api_doc.add_baseCollection()
 api_doc.gen_EntryPoint()
 
 
-# Generate the complete API Documentation
+"""Generate the complete API Documentation"""
 doc = api_doc.generate(
 )  # type: Union[Dict[str, Any], str]       # Returns the entire API Documentation as a Python dict
 
diff --git a/hydrus/samples/doc_writer_sample_output.py b/hydrus/samples/doc_writer_sample_output.py
index 9bdf3b0..936aba9 100644
--- a/hydrus/samples/doc_writer_sample_output.py
+++ b/hydrus/samples/doc_writer_sample_output.py
@@ -50,92 +50,6 @@ doc = {
     "description": "Description for the API Documentation",
     "possibleStatus": [],
     "supportedClass": [
-        {
-            "@id": "vocab:extraClass",
-            "@type": "hydra:Class",
-            "description": "Class without any explicit methods",
-            "supportedOperation": [],
-            "supportedProperty": [],
-            "title": "extraClass"
-        },
-        {
-            "@id": "vocab:singleClass",
-            "@type": "hydra:Class",
-            "description": "A non collection class",
-            "supportedOperation": [
-                {
-                    "@type": "http://schema.org/DeleteAction",
-                    "expects": "vocab:singleClass",
-                    "method": "DELETE",
-                    "possibleStatus": [
-                        {
-                            "description": "singleClass changed",
-                            "statusCode": 200
-                        }
-                    ],
-                    "returns": "null",
-                    "title": "UpdateClass"
-                },
-                {
-                    "@type": "http://schema.org/DeleteAction",
-                    "expects": "null",
-                    "method": "DELETE",
-                    "possibleStatus": [
-                        {
-                            "description": "singleClass deleted",
-                            "statusCode": 200
-                        }
-                    ],
-                    "returns": "null",
-                    "title": "DeleteClass"
-                },
-                {
-                    "@type": "http://schema.org/AddAction",
-                    "expects": "vocab:singleClass",
-                    "method": "PUT",
-                    "possibleStatus": [
-                        {
-                            "description": "dummyClass successfully added",
-                            "statusCode": 201
-                        }
-                    ],
-                    "returns": "null",
-                    "title": "AddClass"
-                },
-                {
-                    "@type": "http://schema.org/FindAction",
-                    "expects": "null",
-                    "method": "GET",
-                    "possibleStatus": [
-                        {
-                            "description": "dummyClass returned",
-                            "statusCode": 200
-                        }
-                    ],
-                    "returns": "vocab:singleClass",
-                    "title": "GetClass"
-                }
-            ],
-            "supportedProperty": [
-                {
-                    "@type": "SupportedProperty",
-                    "property": "http://props.hydrus.com/prop1",
-                    "readonly": "false",
-                    "required": "false",
-                    "title": "Prop1",
-                    "writeonly": "true"
-                },
-                {
-                    "@type": "SupportedProperty",
-                    "property": "http://props.hydrus.com/prop1",
-                    "readonly": "false",
-                    "required": "false",
-                    "title": "Prop2",
-                    "writeonly": "true"
-                }
-            ],
-            "title": "singleClass"
-        },
         {
             "@id": "vocab:dummyClass",
             "@type": "hydra:Class",
@@ -153,45 +67,6 @@ doc = {
                     ],
                     "returns": "null",
                     "title": "UpdateClass"
-                },
-                {
-                    "@type": "http://schema.org/DeleteAction",
-                    "expects": "null",
-                    "method": "DELETE",
-                    "possibleStatus": [
-                        {
-                            "description": "dummyClass deleted",
-                            "statusCode": 200
-                        }
-                    ],
-                    "returns": "null",
-                    "title": "DeleteClass"
-                },
-                {
-                    "@type": "http://schema.org/AddAction",
-                    "expects": "vocab:dummyClass",
-                    "method": "PUT",
-                    "possibleStatus": [
-                        {
-                            "description": "dummyClass successfully added",
-                            "statusCode": 201
-                        }
-                    ],
-                    "returns": "null",
-                    "title": "AddClass"
-                },
-                {
-                    "@type": "http://schema.org/FindAction",
-                    "expects": "null",
-                    "method": "GET",
-                    "possibleStatus": [
-                        {
-                            "description": "dummyClass returned",
-                            "statusCode": 200
-                        }
-                    ],
-                    "returns": "vocab:dummyClass",
-                    "title": "GetClass"
                 }
             ],
             "supportedProperty": [
@@ -282,49 +157,6 @@ doc = {
             ],
             "title": "dummyClassCollection"
         },
-        {
-            "@id": "vocab:extraClassCollection",
-            "@type": "hydra:Class",
-            "description": "A collection of extraclass",
-            "subClassOf": "http://www.w3.org/ns/hydra/core#Collection",
-            "supportedOperation": [
-                {
-                    "@id": "_:extraclass_collection_retrieve",
-                    "@type": "http://schema.org/FindAction",
-                    "description": "Retrieves all extraClass entities",
-                    "expects": "null",
-                    "method": "GET",
-                    "returns": "vocab:extraClassCollection",
-                    "statusCodes": []
-                },
-                {
-                    "@id": "_:extraclass_create",
-                    "@type": "http://schema.org/AddAction",
-                    "description": "Create new extraClass entitity",
-                    "expects": "vocab:extraClass",
-                    "method": "PUT",
-                    "returns": "vocab:extraClass",
-                    "statusCodes": [
-                        {
-                            "description": "If the extraClass entity was created successfully.",
-                            "statusCode": 201
-                        }
-                    ]
-                }
-            ],
-            "supportedProperty": [
-                {
-                    "@type": "SupportedProperty",
-                    "description": "The extraclass",
-                    "property": "http://www.w3.org/ns/hydra/core#member",
-                    "readonly": "false",
-                    "required": "false",
-                    "title": "members",
-                    "writeonly": "false"
-                }
-            ],
-            "title": "extraClassCollection"
-        },
         {
             "@id": "vocab:EntryPoint",
             "@type": "hydra:Class",
@@ -341,83 +173,6 @@ doc = {
                 }
             ],
             "supportedProperty": [
-                {
-                    "hydra:description": "The singleClass Class",
-                    "hydra:title": "singleclass",
-                    "property": {
-                        "@id": "vocab:EntryPoint/singleClass",
-                        "@type": "hydra:Link",
-                        "description": "A non collection class",
-                        "domain": "vocab:EntryPoint",
-                        "label": "singleClass",
-                        "range": "vocab:singleClass",
-                        "supportedOperation": [
-                            {
-                                "@id": "updateclass",
-                                "@type": "http://schema.org/DeleteAction",
-                                "description": "null",
-                                "expects": "vocab:singleClass",
-                                "label": "UpdateClass",
-                                "method": "DELETE",
-                                "returns": "null",
-                                "statusCodes": [
-                                    {
-                                        "description": "singleClass changed",
-                                        "statusCode": 200
-                                    }
-                                ]
-                            },
-                            {
-                                "@id": "deleteclass",
-                                "@type": "http://schema.org/DeleteAction",
-                                "description": "null",
-                                "expects": "null",
-                                "label": "DeleteClass",
-                                "method": "DELETE",
-                                "returns": "null",
-                                "statusCodes": [
-                                    {
-                                        "description": "singleClass deleted",
-                                        "statusCode": 200
-                                    }
-                                ]
-                            },
-                            {
-                                "@id": "addclass",
-                                "@type": "http://schema.org/AddAction",
-                                "description": "null",
-                                "expects": "vocab:singleClass",
-                                "label": "AddClass",
-                                "method": "PUT",
-                                "returns": "null",
-                                "statusCodes": [
-                                    {
-                                        "description": "dummyClass successfully added",
-                                        "statusCode": 201
-                                    }
-                                ]
-                            },
-                            {
-                                "@id": "getclass",
-                                "@type": "http://schema.org/FindAction",
-                                "description": "null",
-                                "expects": "null",
-                                "label": "GetClass",
-                                "method": "GET",
-                                "returns": "vocab:singleClass",
-                                "statusCodes": [
-                                    {
-                                        "description": "dummyClass returned",
-                                        "statusCode": 200
-                                    }
-                                ]
-                            }
-                        ]
-                    },
-                    "readonly": "true",
-                    "required": "null",
-                    "writeonly": "false"
-                },
                 {
                     "hydra:description": "The dummyClassCollection collection",
                     "hydra:title": "dummyclasscollection",
@@ -457,46 +212,6 @@ doc = {
                     "readonly": "true",
                     "required": "null",
                     "writeonly": "false"
-                },
-                {
-                    "hydra:description": "The extraClassCollection collection",
-                    "hydra:title": "extraclasscollection",
-                    "property": {
-                        "@id": "vocab:EntryPoint/EcTest",
-                        "@type": "hydra:Link",
-                        "description": "The extraClassCollection collection",
-                        "domain": "vocab:EntryPoint",
-                        "label": "extraClassCollection",
-                        "range": "vocab:extraClassCollection",
-                        "supportedOperation": [
-                            {
-                                "@id": "_:extraclass_collection_retrieve",
-                                "@type": "http://schema.org/FindAction",
-                                "description": "Retrieves all extraClass entities",
-                                "expects": "null",
-                                "method": "GET",
-                                "returns": "vocab:extraClassCollection",
-                                "statusCodes": []
-                            },
-                            {
-                                "@id": "_:extraclass_create",
-                                "@type": "http://schema.org/AddAction",
-                                "description": "Create new extraClass entitity",
-                                "expects": "vocab:extraClass",
-                                "method": "PUT",
-                                "returns": "vocab:extraClass",
-                                "statusCodes": [
-                                    {
-                                        "description": "If the extraClass entity was created successfully.",
-                                        "statusCode": 201
-                                    }
-                                ]
-                            }
-                        ]
-                    },
-                    "readonly": "true",
-                    "required": "null",
-                    "writeonly": "false"
                 }
             ],
             "title": "EntryPoint"


Test patch:
diff --git a/hydrus/tests/test_app.py b/hydrus/tests/test_app.py
index a632d2d..54fba8a 100644
--- a/hydrus/tests/test_app.py
+++ b/hydrus/tests/test_app.py
@@ -6,10 +6,9 @@ import random
 import string
 import json
 import re
-import uuid
 from hydrus.app import app_factory
 from hydrus.utils import set_session, set_doc, set_api_name
-from hydrus.data import doc_parse, crud
+from hydrus.data import doc_parse
 from hydrus.hydraspec import doc_maker
 from hydrus.samples import doc_writer_sample
 from sqlalchemy import create_engine
@@ -85,12 +84,6 @@ class ViewsTestCase(unittest.TestCase):
         self.api_name_util.__exit__(None, None, None)
         self.session.close()
 
-    def setUp(self):
-        for class_ in self.doc.parsed_classes:
-            if class_ not in self.doc.collections:
-                dummy_obj = gen_dummy_object(class_, self.doc)
-                crud.insert(dummy_obj, id_=str(uuid.uuid4()), session=self.session)
-
     def test_Index(self):
         """Test for the index."""
         response_get = self.client.get("/" + self.API_NAME)
@@ -150,9 +143,7 @@ class ViewsTestCase(unittest.TestCase):
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
         for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
-            if collection_name in self.doc.collections:
+            if endpoint in self.doc.collections:
                 response_get = self.client.get(endpoints[endpoint])
                 # pdb.set_trace()
                 assert response_get.status_code == 200
@@ -168,15 +159,13 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 dummy_object = gen_dummy_object(
                     collection.class_.title, self.doc)
                 good_response_put = self.client.put(
-                    endpoints[endpoint], data=json.dumps(dummy_object))
+                    endpoints[collection_name], data=json.dumps(dummy_object))
                 assert good_response_put.status_code == 201
 
     def test_object_POST(self):
@@ -184,9 +173,7 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 class_ = self.doc.parsed_classes[collection.class_.title]["class"]
@@ -194,11 +181,11 @@ class ViewsTestCase(unittest.TestCase):
                 dummy_object = gen_dummy_object(
                     collection.class_.title, self.doc)
                 initial_put_response = self.client.put(
-                    endpoints[endpoint], data=json.dumps(dummy_object))
+                    endpoints[collection_name], data=json.dumps(dummy_object))
                 assert initial_put_response.status_code == 201
                 response = json.loads(
                     initial_put_response.data.decode('utf-8'))
-                regex = r'(.*)ID (.{36})* (.*)'
+                regex = r'(.*)ID (\d)* (.*)'
                 matchObj = re.match(regex, response["message"])
                 assert matchObj is not None
                 id_ = matchObj.group(2)
@@ -206,7 +193,7 @@ class ViewsTestCase(unittest.TestCase):
                     dummy_object = gen_dummy_object(
                         collection.class_.title, self.doc)
                     post_replace_response = self.client.post(
-                        endpoints[endpoint] + '/' + id_, data=json.dumps(dummy_object))
+                        endpoints[collection_name] + '/' + id_, data=json.dumps(dummy_object))
                     assert post_replace_response.status_code == 200
 
     def test_object_DELETE(self):
@@ -214,9 +201,7 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 class_ = self.doc.parsed_classes[collection.class_.title]["class"]
@@ -224,17 +209,17 @@ class ViewsTestCase(unittest.TestCase):
                 dummy_object = gen_dummy_object(
                     collection.class_.title, self.doc)
                 initial_put_response = self.client.put(
-                    endpoints[endpoint], data=json.dumps(dummy_object))
+                    endpoints[collection_name], data=json.dumps(dummy_object))
                 assert initial_put_response.status_code == 201
                 response = json.loads(
                     initial_put_response.data.decode('utf-8'))
-                regex = r'(.*)ID (.{36})* (.*)'
+                regex = r'(.*)ID (\d)* (.*)'
                 matchObj = re.match(regex, response["message"])
                 assert matchObj is not None
                 id_ = matchObj.group(2)
                 if "DELETE" in class_methods:
                     delete_response = self.client.delete(
-                        endpoints[endpoint] + '/' + id_)
+                        endpoints[collection_name] + '/' + id_)
                     assert delete_response.status_code == 200
 
     def test_object_PUT_at_id(self):
@@ -242,9 +227,7 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 class_ = self.doc.parsed_classes[collection.class_.title]["class"]
@@ -255,17 +238,16 @@ class ViewsTestCase(unittest.TestCase):
                     dummy_object = gen_dummy_object(
                         collection.class_.title, self.doc)
                     put_response = self.client.put(
-                        endpoints[endpoint] + '/' + str(
-                            uuid.uuid4()), data=json.dumps(dummy_object))
+                        endpoints[collection_name] + '/' + str(
+                            random.randint(
+                                100, 1000)), data=json.dumps(dummy_object))
                     assert put_response.status_code == 201
 
     def test_object_PUT_at_ids(self):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 class_ = self.doc.parsed_classes[collection.class_.title]["class"]
@@ -278,15 +260,15 @@ class ViewsTestCase(unittest.TestCase):
                 for index in range(3):
                     objects.append(gen_dummy_object(
                         collection.class_.title, self.doc))
-                    ids += str(uuid.uuid4())
+                    ids += str(random.randint(100, 1000))
                     ids += ','
                 data_["data"] = objects
                 if "PUT" in class_methods:
                     put_response = self.client.put(
-                        endpoints[endpoint] + '/add/' + ids,
+                        endpoints[collection_name] + '/' + ids,
                         data=json.dumps(
-                            data_))
-                    assert put_response.status_code == 201
+                            data_["data"]))
+                assert put_response.status_code == 201
 
     def test_endpointClass_PUT(self):
         """Check non collection Class PUT."""
@@ -322,9 +304,9 @@ class ViewsTestCase(unittest.TestCase):
                         x.method for x in class_.supportedOperation]
                     if "POST" in class_methods:
                         dummy_object = gen_dummy_object(class_.title, self.doc)
-                        post_response = self.client.post(
+                        put_response = self.client.post(
                             endpoints[class_name], data=json.dumps(dummy_object))
-                        assert post_response.status_code == 200
+                        assert put_response.status_code == 201
 
     def test_endpointClass_DELETE(self):
         """Check non collection Class DELETE."""
@@ -340,9 +322,9 @@ class ViewsTestCase(unittest.TestCase):
                     class_methods = [
                         x.method for x in class_.supportedOperation]
                     if "DELETE" in class_methods:
-                        delete_response = self.client.delete(
+                        put_response = self.client.delete(
                             endpoints[class_name])
-                        assert delete_response.status_code == 200
+                        assert put_response.status_code == 200
 
     def test_endpointClass_GET(self):
         """Check non collection Class GET."""
@@ -359,24 +341,23 @@ class ViewsTestCase(unittest.TestCase):
                         x.method for x in class_.supportedOperation]
                     if "GET" in class_methods:
                         response_get = self.client.get(endpoints[class_name])
-                        assert response_get.status_code == 200
-                        response_get_data = json.loads(
-                            response_get.data.decode('utf-8'))
-                        assert "@context" in response_get_data
-                        assert "@id" in response_get_data
-                        assert "@type" in response_get_data
+                        assert response_get.status_code in [200, 404]
+                        if response_get.status_code == 200:
+                            response_get_data = json.loads(
+                                response_get.data.decode('utf-8'))
+                            assert "@context" in response_get_data
+                            assert "@id" in response_get_data
+                            assert "@type" in response_get_data
 
     def test_bad_objects(self):
         """Checks if bad objects are added or not."""
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 bad_response_put = self.client.put(
-                    endpoints[endpoint],
+                    endpoints[collection_name],
                     data=json.dumps(
                         dict(
                             foo='bar')))
@@ -387,9 +368,7 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
                 collection = self.doc.collections[collection_name]["collection"]
                 class_ = self.doc.parsed_classes[collection.class_.title]["class"]
@@ -397,11 +376,11 @@ class ViewsTestCase(unittest.TestCase):
                 dummy_object = gen_dummy_object(
                     collection.class_.title, self.doc)
                 initial_put_response = self.client.put(
-                    endpoints[endpoint], data=json.dumps(dummy_object))
+                    endpoints[collection_name], data=json.dumps(dummy_object))
                 assert initial_put_response.status_code == 201
                 response = json.loads(
                     initial_put_response.data.decode('utf-8'))
-                regex = r'(.*)ID (.{36})* (.*)'
+                regex = r'(.*)ID (\d)* (.*)'
                 matchObj = re.match(regex, response["message"])
                 assert matchObj is not None
                 id_ = matchObj.group(2)
@@ -409,11 +388,11 @@ class ViewsTestCase(unittest.TestCase):
                     dummy_object = gen_dummy_object(
                         collection.class_.title, self.doc)
                     post_replace_response = self.client.post(
-                        endpoints[endpoint] + '/' + id_, data=json.dumps(dummy_object))
+                        endpoints[collection_name] + '/' + id_, data=json.dumps(dummy_object))
                     assert post_replace_response.status_code == 405
                 if "DELETE" not in class_methods:
                     delete_response = self.client.delete(
-                        endpoints[endpoint] + '/' + id_)
+                        endpoints[collection_name] + '/' + id_)
                     assert delete_response.status_code == 405
 
     def test_Endpoints_Contexts(self):
@@ -421,11 +400,9 @@ class ViewsTestCase(unittest.TestCase):
         index = self.client.get("/" + self.API_NAME)
         assert index.status_code == 200
         endpoints = json.loads(index.data.decode('utf-8'))
-        for endpoint in endpoints:
-            collection_name = "/".join(endpoints[endpoint].split(
-                "/" + self.API_NAME + "/")[1:])
+        for collection_name in endpoints:
             if collection_name in self.doc.collections:
-                response_get = self.client.get(endpoints[endpoint])
+                response_get = self.client.get(endpoints[collection_name])
                 assert response_get.status_code == 200
                 context = json.loads(
                     response_get.data.decode('utf-8'))["@context"]