def transact(self, request, configfile, waitForDb): self.app = create_app(configfile, waitForDb) self.test_client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() self.test_user_name = 'testuserusers' self.test_user_password = '******' self.ph = PostHelper(self.test_client, self.test_user_name, self.test_user_password) db.create_all() yield db.session.remove() db.drop_all() self.app_context.pop()
class ClientsTests(TestCase): @pytest.fixture(autouse=True) def transact(self, request, configfile, waitForDb): self.app = create_app(configfile, waitForDb) self.test_client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() self.test_user_name = 'testuserusers' self.test_user_password = '******' self.ph = PostHelper(self.test_client, self.test_user_name, self.test_user_password) db.create_all() yield db.session.remove() db.drop_all() self.app_context.pop() def test_create_and_retrieve_client(self): """ Ensure we can create a new Client and then retrieve it """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new client, assert we receive a 201 http code and and assert there's only one Client in the db new_client_name = 'New Client Name' post_res = self.ph.create_client(new_client_name) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) self.assertEqual(Client.query.count(), 1) # check that the returned values in the post response are correct post_res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res_data['name'], new_client_name) # get the new client url, retrieve it and assert the correct values client_url = post_res_data['url'] res = self.test_client.get( client_url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['name'], new_client_name) def test_create_duplicated_client(self): """ Ensure we cannot create a duplicated Client """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new client and assert the respose values new_client_name = 'New Information' post_res = self.ph.create_client(new_client_name) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) self.assertEqual(Client.query.count(), 1) post_res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res_data['name'], new_client_name) # try to assert it again, and assert the status code is an http 400 second_post_res = self.ph.create_client(new_client_name) self.assertEqual(second_post_res.status_code, status.HTTP_400_BAD_REQUEST, "The insertion of a duplicate client didn't return a 400 code") self.assertEqual(Client.query.count(), 1) def test_retrieve_clients_list(self): """ Ensure we can retrieve the clients list """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create 4 clients and assert the response for i in range(1, 5): name = 'Client {}'.format(i) post_res = self.ph.create_client(name) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 4 self.assertEqual(Client.query.count(), 4) # retrieve the complete list of clients, it should return only the 2 we created url = url_for('api.clientlistresource', _external=True) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 4) def test_update_client(self): """ Ensure we can update the name for an existing client """ # create our user so we can authenticate and create the client res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new client and assert the result client_name = 'Client 1' post_res_1 = self.ph.create_client(client_name) self.assertEqual(post_res_1.status_code, status.HTTP_201_CREATED, post_res_1.get_data(as_text=True)) post_res_data_1 = json.loads(post_res_1.get_data(as_text=True)) # create a patch request to update the client name client_url = post_res_data_1['url'] client_name_2 = 'Client 2' data = {'name': client_name_2} patch_response = self.test_client.patch( client_url, headers=self.ph.get_authentication_headers(), data=json.dumps(data)) self.assertEqual(patch_response.status_code, status.HTTP_200_OK, patch_response.get_data(as_text=True)) # retrieve the updated client and validate the name is the same as the updated value res = self.test_client.get( client_url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['name'], client_name_2) def test_create_delete_and_retrieve_client(self): """ Ensure we can create a new Client, delete it and if we retrieve it should not be there """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new client, assert we receive a 201 http code and and assert there's only one Client in the db new_client_name = 'New Client Name' post_res = self.ph.create_client(new_client_name) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) self.assertEqual(Client.query.count(), 1) # check that the returned values in the post response are correct post_res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res_data['name'], new_client_name) # get the new client url and delete it client_url = post_res_data['url'] patch_res = self.test_client.delete( client_url, headers=self.ph.get_authentication_headers()) # retrieve it and assert the correct values self.assertEqual(patch_res.status_code, status.HTTP_204_NO_CONTENT, patch_res.get_data(as_text=True)) res = self.test_client.get( client_url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND, res.get_data(as_text=True))
class FeaturesTests(TestCase): @pytest.fixture(autouse=True) def transact(self, request, configfile, waitForDb): self.app = create_app(configfile, waitForDb) self.test_client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() self.test_user_name = 'testuserusers' self.test_user_password = '******' self.ph = PostHelper(self.test_client, self.test_user_name, self.test_user_password) db.create_all() yield db.session.remove() db.drop_all() self.app_context.pop() def test_create_and_retrieve_feature(self): """ Ensure we can create a new Feature and then retrieve it """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new feature, assert we receive a 201 http code and and assert there's only one Feature in the db title = 'New Feature Title' description = 'Description ' * 10 target_date = date(2018, 6, 15) priority = 1 client = 'Client 1' area = 'Billing' post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) self.assertEqual(Feature.query.count(), 1) # check that the returned values in the post response are correct post_res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res_data['title'], title) self.assertEqual(post_res_data['description'], description) self.assertEqual(post_res_data['target_date'], target_date.isoformat()) self.assertEqual(post_res_data['client_priority'], priority) self.assertEqual(post_res_data['client']['name'], client) self.assertEqual(post_res_data['area']['name'], area) # get the new feature url, retrieve it and assert the correct values feature_url = post_res_data['url'] res = self.test_client.get( feature_url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['title'], title) self.assertEqual(res_data['description'], description) self.assertEqual(res_data['target_date'], target_date.isoformat()) self.assertEqual(res_data['client_priority'], priority) self.assertEqual(res_data['client']['name'], client) self.assertEqual(res_data['area']['name'], area) def test_retrieve_features_list(self): """ Ensure we can retrieve the features list """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create 4 features and assert the response for i in range(1, 5): title = 'New Feature Title {}'.format(i) description = 'Description {}'.format(i) target_date = date(2018, 6, i) priority = i client = "Client" area = "Billing" post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 4 self.assertEqual(Feature.query.count(), 4) # retrieve the complete list of features, it should return only the 4 we created url = url_for('api.featurelistresource', _external=True) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 4) def test_update_feature(self): """ Ensure we can update the name for an existing feature """ # create our user so we can authenticate and create the feature res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create a new feature, assert we receive a 201 http code and and assert there's only one Feature in the db title = 'New Feature Title' description = 'Description ' * 10 target_date = date(2018, 6, 15) priority = 1 client = 'Client 1' area = 'Billing' post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) self.assertEqual(Feature.query.count(), 1) post_res_data = json.loads(post_res.get_data(as_text=True)) # Create a new area and a new client, so we test we can update those too area = "New Area" res = self.ph.create_area(area) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) client = "New Client" res = self.ph.create_client(client) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # Create the patch request with the updated values feature_url = post_res_data['url'] title = 'Updated Title' description = 'Updated Description ' * 10 target_date = date(2018, 5, 19) priority = 15 data = {'title': title, 'description': description, 'target_date': target_date.isoformat(), 'client_priority': priority, 'client': client, 'area': area} patch_response = self.test_client.patch( feature_url, headers=self.ph.get_authentication_headers(), data=json.dumps(data)) self.assertEqual(patch_response.status_code, status.HTTP_200_OK, patch_response.get_data(as_text=True)) # retrieve the updated feature and validate the name is the same as the updated value res = self.test_client.get( feature_url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['title'], title) self.assertEqual(res_data['description'], description) self.assertEqual(res_data['target_date'], target_date.isoformat()) self.assertEqual(res_data['client_priority'], priority) self.assertEqual(res_data['area']['name'], area) self.assertEqual(res_data['client']['name'], client) def test_features_priority_adjustment_when_adding_a_new_feature(self): """ Ensure that when creating a new feature that has the same priority as another one it should adjust the priorities """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create 4 features and assert the response for i in range(10): title = 'Title {}'.format(i+1) description = 'Description {}'.format(i+1) target_date = date(2018, 6, 1) priority = i+1 client = "Client" area = "Billing" post_res = self.ph.create_feature(title, description, target_date, priority, client, area) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 10 features (with priorities from 1 to 10) self.assertEqual(Feature.query.count(), 10) # create a new one with priority 5, so the service must update all the priorities that are higher than 5 title = 'New Feature' description = 'Description' target_date = date(2018, 6, i) priority = 5 client = "Client" area = "Billing" post_res = self.ph.create_feature(title, description, target_date, priority, client, area) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # Query all the priorities and verify they are updated correctly url = url_for('api.featurelistresource', _external=True, page=1, size=11) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 11) # because it's a new db for this test, the id should be the same as the priority before we updated them features = res_data['results'] for i in range(11): id = features[i]['id'] priority = features[i]['client_priority'] if id <= 4: self.assertEqual(priority, id) elif id == 11: self.assertEqual(priority, 5) else: self.assertEqual(priority, id + 1) def test_features_priority_adjustment_when_updating_an_existing_feature(self): """ Ensure that when updating a feature that has the same priority as another one it should adjust the priorities """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create the first feature, that we will update later title = 'Title 1' description = 'Description 1' target_date = date(2018, 6, 1) priority = 1 client = "Client" area = "Billing" post_res = self.ph.create_feature(title, description, target_date, priority, client, area) res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) feature_url = res_data['url'] # create other 9 features and assert the response for i in range(1,10): title = 'Title {}'.format(i+1) description = 'Description {}'.format(i+1) target_date = date(2018, 6, 1) priority = i+1 client = "Client" area = "Billing" post_res = self.ph.create_feature(title, description, target_date, priority, client, area) res_data = json.loads(post_res.get_data(as_text=True)) self.assertEqual(post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 10 features (with priorities from 1 to 10) self.assertEqual(Feature.query.count(), 10) # update a feature with priority 1 to priority 2, so the service must update all the priorities that are higher or equal than 2 priority = 2 data = {'client_priority': priority} patch_response = self.test_client.patch( feature_url, headers=self.ph.get_authentication_headers(), data=json.dumps(data)) self.assertEqual(patch_response.status_code, status.HTTP_200_OK, patch_response.get_data(as_text=True)) # Query all the priorities and verify they are updated correctly url = url_for('api.featurelistresource', _external=True, page=1, size=10) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 10) # because it's a new db for this test, the id should be the same as the priority before we updated them features = res_data['results'] for i in range(10): id = features[i]['id'] priority = features[i]['client_priority'] self.assertEqual(priority, id+1) def test_retrieve_features_list_by_area(self): """ Ensure we can retrieve the features list for an area """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create 4 features and assert the response for i in range(1, 5): title = 'New Feature Title {}'.format(i) description = 'Description {}'.format(i) target_date = date(2018, 6, i) priority = i client = "Client" area = "Billing" post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # create another 4 features but for another area for i in range(1, 5): title = 'New Feature Title {}'.format(i) description = 'Description {}'.format(i) target_date = date(2018, 6, i) priority = i client = "Client" area = "Claims" post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 8 self.assertEqual(Feature.query.count(), 8) # retrieve the complete list of features for the first client, it should return only the 4 we created url = url_for('api.featurelistbyarearesource', id = 1, _external=True) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 4) def test_retrieve_features_list_by_client(self): """ Ensure we can retrieve the features list for a client """ # create our user so we can authenticate res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.get_data(as_text=True)) # create 4 features and assert the response for i in range(1, 5): title = 'New Feature Title {}'.format(i) description = 'Description {}'.format(i) target_date = date(2018, 6, i) priority = i client = "Client" area = "Billing" post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # create another 4 features but for another area for i in range(1, 5): title = 'New Feature Title {}'.format(i) description = 'Description {}'.format(i) target_date = date(2018, 6, i) priority = i client = "Client 2" area = "Billing" post_res = self.ph.create_feature( title, description, target_date, priority, client, area) self.assertEqual( post_res.status_code, status.HTTP_201_CREATED, post_res.get_data(as_text=True)) # assert we only have this 8 self.assertEqual(Feature.query.count(), 8) # retrieve the complete list of features for the first client, it should return only the 4 we created url = url_for('api.featurelistbyclientresource', id = 1, _external=True) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) res_data = json.loads(res.get_data(as_text=True)) self.assertEqual(res.status_code, status.HTTP_200_OK, res.get_data(as_text=True)) self.assertEqual(res_data['count'], 4)
class UsersTests(TestCase): @pytest.fixture(autouse=True) def transact(self, request, configfile, waitForDb): self.app = create_app(configfile, waitForDb) self.test_client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() self.test_user_name = 'testuserusers' self.test_user_password = '******' self.ph = PostHelper(self.test_client, self.test_user_name, self.test_user_password) db.create_all() yield db.session.remove() db.drop_all() self.app_context.pop() def test_retrieve_users_list(self): """ Ensure we can retrieve the users paginated list """ # Insert our first and 6 more res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, json.loads(res.get_data(as_text=True))) for i in range(6): name, password = '******'.format( i), 'Password1!.{}'.format(i) res = self.ph.create_user(name, password) self.assertEqual(res.status_code, status.HTTP_201_CREATED, json.loads(res.get_data(as_text=True))) # Validate we have in total only 7 self.assertEqual(User.query.count(), 7) # Get the first page first_url = url_for('api.userlistresource', _external=True) first_res = self.test_client.get( first_url, headers=self.ph.get_authentication_headers()) first_res_data = json.loads(first_res.get_data(as_text=True)) # Make sure we only get the first 5 elements self.assertEqual(first_res.status_code, status.HTTP_200_OK, json.loads(first_res.get_data(as_text=True))) self.assertEqual(first_res_data['count'], 7) self.assertIsNone(first_res_data['previous']) self.assertEqual(first_res_data['next'], url_for('api.userlistresource', page=2, size=5)) self.assertIsNone(first_res_data['previous']) self.assertIsNotNone(first_res_data['results']) self.assertEqual(len(first_res_data['results']), 5) self.assertEqual(first_res_data['results'][0]['name'], self.test_user_name) # Get the second page, there should be only 2 elements second_url = url_for('api.userlistresource', page=2) second_res = self.test_client.get( second_url, headers=self.ph.get_authentication_headers()) second_res_data = json.loads(second_res.get_data(as_text=True)) self.assertEqual(second_res.status_code, status.HTTP_200_OK, json.loads(first_res.get_data(as_text=True))) self.assertIsNotNone(second_res_data['previous']) self.assertEqual(second_res_data['previous'], url_for('api.userlistresource', page=1, size=5)) self.assertIsNone(second_res_data['next']) self.assertIsNotNone(second_res_data['results']) self.assertEqual(len(second_res_data['results']), 2)
class AuthTests(TestCase): @pytest.fixture(autouse=True) def transact(self, request, configfile, waitForDb): self.app = create_app(configfile, waitForDb) self.test_client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() self.test_user_name = 'testuserusers' self.test_user_password = '******' self.ph = PostHelper(self.test_client, self.test_user_name, self.test_user_password) db.create_all() yield db.session.remove() db.drop_all() self.app_context.pop() def test_request_without_authentication(self): """ Ensure we cannot access a resource that requires authentication without an appropriate authentication header """ res = self.test_client.get( url_for('api.featurelistresource', _external=True), headers=self.ph.get_accept_content_type_headers()) self.assertTrue(res.status_code == status.HTTP_401_UNAUTHORIZED) def test_request_with_authentication(self): """ Ensure we can access a resource that requires authentication with an appropriate authentication header """ user_res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(user_res.status_code, status.HTTP_201_CREATED) res = self.test_client.get( url_for('api.featurelistresource', _external=True), headers=self.ph.get_authentication_headers()) self.assertTrue(res.status_code == status.HTTP_200_OK) def test_login_request_with_authentication(self): """ Ensure we can obtain the user's data if it's logged correctly """ # create a user and assert the response user_res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(user_res.status_code, status.HTTP_201_CREATED) user_res_data = json.loads(user_res.get_data(as_text=True)) self.assertEqual(user_res_data['name'], self.test_user_name) # Get the url for the login resource and query it url = url_for('api.userloginresource', _external=True, name=self.test_user_name) res = self.test_client.get( url, headers=self.ph.get_authentication_headers()) # assert that the resonse is the same as the one that we created before self.assertTrue(res.status_code == status.HTTP_200_OK) res_data = json.loads(res.get_data(as_text=True)) self.assertTrue(res_data['id'], user_res_data['id']) self.assertTrue(res_data['name'], user_res_data['name']) def test_login_request_with_an_incorrect_authentication(self): """ Ensure we can access a resource that requires authentication with an appropriate authentication header """ user_res = self.ph.create_user(self.test_user_name, self.test_user_password) self.assertEqual(user_res.status_code, status.HTTP_201_CREATED) res = self.test_client.get( url_for('api.featurelistresource', _external=True)) self.assertTrue(res.status_code == status.HTTP_401_UNAUTHORIZED)