def setUp(self):
        self.client = OTIAPIClient()
        self.url = reverse('gtfsfeed-list', {})
        self.file_directory = os.path.dirname(os.path.abspath(__file__))
        self.test_gtfs_fh = open(self.file_directory + '/tests/test-gtfs.zip',
                                 'rb')

        # Some tasks such as GTFS imports require an oti-admin user (with a token) to exist
        self.admin = OTIUser.objects.create_user('oti-admin',
                                                 password='******',
                                                 email='*****@*****.**')
        Token.objects.get_or_create(user=self.admin)
Exemple #2
0
class ResetPasswordTest(TestCase):
    """Tests for password reset endpoint"""
    def setUp(self):
        self.client = OTIAPIClient()

    def test_reset_password(self):
        """Tests that only admin user can reset password"""

        api_user = self.client.api_user
        api_admin = self.client.api_admin
        reset_api_user_url = reverse('users-reset-password',
                                     args=(api_user.pk, ))
        admin_reset_response = self.client.post(reset_api_user_url)

        self.assertEqual(admin_reset_response.status_code, status.HTTP_200_OK)
        new_password = admin_reset_response.data['password']
        self.assertNotEqual(new_password, '123')

        self.client.authenticate(admin=False)

        reset_admin_user_url_forbidden = reverse('users-reset-password',
                                                 args=(api_admin.pk, ))
        reset_admin_user_response = self.client.post(
            reset_admin_user_url_forbidden)

        self.assertEqual(reset_admin_user_response.status_code,
                         status.HTTP_403_FORBIDDEN)

    def test_change_password(self):
        """Tests that users can only change their own password"""

        api_user = self.client.api_user
        api_admin = self.client.api_admin
        change_api_admin_url = reverse('users-reset-password',
                                       args=(api_admin.pk, ))
        change_api_admin_response = self.client.post(change_api_admin_url,
                                                     data={'password': '******'})

        self.assertEqual(change_api_admin_response.status_code,
                         status.HTTP_200_OK)

        # verify admin user can change api user's password
        change_api_user_url = reverse('users-reset-password',
                                      args=(api_user.pk, ))
        change_api_user_response = self.client.post(change_api_user_url,
                                                    data={'password': '******'})

        self.assertEqual(change_api_user_response.status_code,
                         status.HTTP_200_OK)

        # verify regular user cannot change admin user's password
        self.client.authenticate(admin=False)
        forbidden_change_api_admin_response = self.client.post(
            change_api_admin_url, data={'password': '******'})
        self.assertEqual(forbidden_change_api_admin_response.status_code,
                         status.HTTP_403_FORBIDDEN)
Exemple #3
0
 def setUp(self):
     self.client = OTIAPIClient()
     self.list_url = reverse('users-list', {})
     self.data = {
         'username': '******',
         'password': '******',
         'email': '*****@*****.**',
         'first_name': '',
         'last_name': '',
         'is_staff': False,
         'is_active': True,
         'is_superuser': False
     }
     # Password and is_superuser not returned by response
     self.response_data = {
         key: self.data[key]
         for key in self.data if key not in ['is_superuser', 'password']
     }
class ResetPasswordTest(TestCase):
    """Tests for password reset endpoint"""

    def setUp(self):
        self.client = OTIAPIClient()

    def test_reset_password(self):
        """Tests that only admin user can reset password"""

        api_user = self.client.api_user
        api_admin = self.client.api_admin
        reset_api_user_url = reverse('users-reset-password', args=(api_user.pk,))
        admin_reset_response = self.client.post(reset_api_user_url)

        self.assertEqual(admin_reset_response.status_code, status.HTTP_200_OK)
        new_password = admin_reset_response.data['password']
        self.assertNotEqual(new_password, '123')

        self.client.authenticate(admin=False)

        reset_admin_user_url_forbidden = reverse('users-reset-password', args=(api_admin.pk,))
        reset_admin_user_response = self.client.post(reset_admin_user_url_forbidden)

        self.assertEqual(reset_admin_user_response.status_code, status.HTTP_403_FORBIDDEN)

    def test_change_password(self):
        """Tests that users can only change their own password"""

        api_user = self.client.api_user
        api_admin = self.client.api_admin
        change_api_admin_url = reverse('users-reset-password', args=(api_admin.pk,))
        change_api_admin_response = self.client.post(change_api_admin_url, data={'password': '******'})

        self.assertEqual(change_api_admin_response.status_code, status.HTTP_200_OK)

        # verify admin user can change api user's password
        change_api_user_url = reverse('users-reset-password', args=(api_user.pk,))
        change_api_user_response = self.client.post(change_api_user_url, data={'password': '******'})

        self.assertEqual(change_api_user_response.status_code, status.HTTP_200_OK)

        # verify regular user cannot change admin user's password
        self.client.authenticate(admin=False)
        forbidden_change_api_admin_response = self.client.post(change_api_admin_url, data={'password': '******'})
        self.assertEqual(forbidden_change_api_admin_response.status_code, status.HTTP_403_FORBIDDEN)
class RealTimeTestCase(TestCase):
    def setUp(self):
        self.client = OTIAPIClient()
        self.url = reverse('real-time-list', {})
        self.file_directory = os.path.dirname(os.path.abspath(__file__))
        self.test_realtime_fh = open(self.file_directory +
                                     '/tests/stop_times_test.txt_new')

    def tearDown(self):
        self.test_realtime_fh.close()

    def test_txt_new_validation(self):
        self.client.authenticate(admin=True)

        temp_dir = tempfile.mkdtemp()
        badfile_path = temp_dir + '/badfile.txt'
        goodfile_path = temp_dir + '/goodfile.txt_new'

        with open(badfile_path, 'w') as badfile:
            badfile.write("No useful data here.")

        with open(goodfile_path, 'w') as goodfile:
            goodfile.write("Useful data here.")

        with open(badfile_path, 'r') as badfile:
            # Test that uploading a file with an extension other than .txt_new
            # fails
            response = self.client.post(self.url, {'source_file': badfile})
            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST,
                             response.content)

        rmtree(temp_dir)

    def test_realtime_upload(self):
        response = self.client.post(
            self.url, {
                'source_file': self.test_realtime_fh,
                'city_name': settings.OTI_CITY_NAME
            })
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
 def setUp(self):
     self.client = OTIAPIClient()
     self.list_url = reverse('users-list', {})
     self.data = {'username': '******',
                  'password': '******',
                  'email': '*****@*****.**',
                  'first_name': '',
                  'last_name': '',
                  'is_staff': False,
                  'is_active': True,
                  'is_superuser': False}
     # Password and is_superuser not returned by response
     self.response_data = {key: self.data[key] for key in self.data
                           if key not in ['is_superuser','password']}
class RealTimeTestCase(TestCase):

    def setUp(self):
        self.client = OTIAPIClient()
        self.url = reverse('real-time-list', {})
        self.file_directory = os.path.dirname(os.path.abspath(__file__))
        self.test_realtime_fh = open(self.file_directory + '/tests/stop_times_test.txt_new')

    def tearDown(self):
        self.test_realtime_fh.close()

    def test_txt_new_validation(self):
        self.client.authenticate(admin=True)

        temp_dir = tempfile.mkdtemp()
        badfile_path = temp_dir + '/badfile.txt'
        goodfile_path = temp_dir + '/goodfile.txt_new'

        with open(badfile_path, 'w') as badfile:
            badfile.write("No useful data here.")

        with open(goodfile_path, 'w') as goodfile:
            goodfile.write("Useful data here.")

        with open(badfile_path, 'r') as badfile:
            # Test that uploading a file with an extension other than .txt_new
            # fails
            response = self.client.post(self.url, {'source_file': badfile})
            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST,
                             response.content)

        rmtree(temp_dir)

    def test_realtime_upload(self):
        response = self.client.post(self.url, {'source_file': self.test_realtime_fh,
                                               'city_name': settings.OTI_CITY_NAME})
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
Exemple #8
0
class OTIUserTestCase(TestCase):
    """ Tests behavior of OTIUser model."""
    def setUp(self):
        self.client = OTIAPIClient()
        self.list_url = reverse('users-list', {})
        self.data = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**',
            'first_name': '',
            'last_name': '',
            'is_staff': False,
            'is_active': True,
            'is_superuser': False
        }
        # Password and is_superuser not returned by response
        self.response_data = {
            key: self.data[key]
            for key in self.data if key not in ['is_superuser', 'password']
        }

    def test_users_crud(self):
        """Test admin user CRUD operations on OTIUser

        Admin user should have full read/write permissions

        """
        self.client.authenticate(admin=True)
        num_users = OTIUser.objects.count()

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertDictContainsSubset(self.response_data, response.data)
        user_id = response.data['id']
        detail_url = reverse('users-detail', [user_id])

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertDictContainsSubset(self.response_data, response.data)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(new_first_name, response.data['first_name'])

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertEqual(0, OTIUser.objects.filter(id=user_id).count())

    def test_permissions(self):
        """Test CRUD operation permissions on OTIUser

        Standard user should only have read permissions
        Anonymous user should have no permissions

        """
        test_user = OTIUser.objects.create_user('test-1',
                                                password='******',
                                                email='*****@*****.**')
        user_id = test_user.id
        detail_url = reverse('users-detail', [user_id])

        # Standard User
        self.client.authenticate(admin=False)

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertDictContainsSubset(self.response_data, response.data)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # Anonymous user
        self.client.force_authenticate(user=None)

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
Exemple #9
0
 def setUp(self):
     self.client = OTIAPIClient()
 def setUp(self):
     self.client = OTIAPIClient()
     self.url = reverse('real-time-list', {})
     self.file_directory = os.path.dirname(os.path.abspath(__file__))
     self.test_realtime_fh = open(self.file_directory + '/tests/stop_times_test.txt_new')
 def setUp(self):
     self.client = OTIAPIClient()
     self.url = reverse('gtfsfeed-list', {})
     self.file_directory = os.path.dirname(os.path.abspath(__file__))
     self.test_gtfs_fh = open(self.file_directory + '/tests/test-gtfs.zip', 'rb')
class GTFSFeedTestCase(TestCase):
    """Tests behavior of GTFSFeed models. """

    def setUp(self):
        self.client = OTIAPIClient()
        self.url = reverse('gtfsfeed-list', {})
        self.file_directory = os.path.dirname(os.path.abspath(__file__))
        self.test_gtfs_fh = open(self.file_directory + '/tests/test-gtfs.zip', 'rb')

    def tearDown(self):
        self.test_gtfs_fh.close()

    def test_zip_extension_validation(self):
        """Test that uploaded files are correctly checked for .zip extensions and validated."""
        self.client.authenticate(admin=True)
        temp_dir = tempfile.mkdtemp()
        badfile_path = temp_dir + '/badfile.jpg'
        goodfile_path = temp_dir + '/goodfile.zip'

        with open(badfile_path, 'w') as badfile:
            badfile.write("No useful data here.")

        with open(goodfile_path, 'w') as goodfile:
            goodfile.write("Useful data here.")

        with open(badfile_path, 'r') as badfile:
            # Test that uploading a file with an extension other than .zip
            # fails
            response = self.client.post(self.url, {'source_file': badfile})
            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST,
                             response.content)

        rmtree(temp_dir)

    def test_gtfs_validation(self):
        """Test that verifies GTFS validation works correctly"""
        self.client.authenticate(admin=True)
        response = self.client.post(self.url, {'source_file': self.test_gtfs_fh})
        sleep(2) # give time for celery to do job
        problem_count = GTFSFeedProblem.objects.filter(gtfsfeed_id=response.data['id']).count()
        self.assertEqual(problem_count, 2, 'There should have been two problems for uploaded data')

    def test_gtfs_validation_no_shapes(self):
        """Test that verifies GTFS validation works correctly"""
        self.client.authenticate(admin=True)
        with open(self.file_directory + '/tests/patco.zip', 'rb') as patco:
            response = self.client.post(self.url, {'source_file': patco})
        sleep(2) # give time for celery to do job
        problem_count = GTFSFeedProblem.objects.filter(gtfsfeed_id=response.data['id']).count()
        self.assertEqual(problem_count, 2, 'There should have been two problems for uploaded data')

    def test_gtfs_upload_requires_admin(self):
        """Test that verifies GTFS upload requires an admin user"""
        # UNAUTHORIZED if no credentials
        self.client.force_authenticate(user=None)
        response = self.client.post(self.url, {'source_file': self.test_gtfs_fh})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # FORBIDDEN if user is not superuser
        self.client.authenticate(admin=False)
        response = self.client.post(self.url, {'source_file': self.test_gtfs_fh})
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
class OTIUserTestCase(TestCase):
    """ Tests behavior of OTIUser model."""
    def setUp(self):
        self.client = OTIAPIClient()
        self.list_url = reverse('users-list', {})
        self.data = {'username': '******',
                     'password': '******',
                     'email': '*****@*****.**',
                     'first_name': '',
                     'last_name': '',
                     'is_staff': False,
                     'is_active': True,
                     'is_superuser': False}
        # Password and is_superuser not returned by response
        self.response_data = {key: self.data[key] for key in self.data
                              if key not in ['is_superuser','password']}

    def test_users_crud(self):
        """Test admin user CRUD operations on OTIUser

        Admin user should have full read/write permissions

        """
        self.client.authenticate(admin=True)
        num_users = OTIUser.objects.count()

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertDictContainsSubset(self.response_data, response.data)
        user_id = response.data['id']
        detail_url = reverse('users-detail', [user_id])

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertDictContainsSubset(self.response_data, response.data)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(new_first_name, response.data['first_name'])

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertEqual(0, OTIUser.objects.filter(id=user_id).count())

    def test_permissions(self):
        """Test CRUD operation permissions on OTIUser

        Standard user should only have read permissions
        Anonymous user should have no permissions

        """
        test_user = OTIUser.objects.create_user('test-1', password='******', email='*****@*****.**')
        user_id = test_user.id
        detail_url = reverse('users-detail', [user_id])

        # Standard User
        self.client.authenticate(admin=False)

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertDictContainsSubset(self.response_data, response.data)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # Anonymous user
        self.client.force_authenticate(user=None)

        # CREATE
        response = self.client.post(self.list_url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # READ
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # UPDATE
        new_first_name = 'Jerry'
        patch_data = dict(first_name=new_first_name)
        response = self.client.patch(detail_url, patch_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # DELETE
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
 def setUp(self):
     self.client = OTIAPIClient()
class GTFSFeedTestCase(TestCase):
    """Tests behavior of GTFSFeed models. """
    def setUp(self):
        self.client = OTIAPIClient()
        self.url = reverse('gtfsfeed-list', {})
        self.file_directory = os.path.dirname(os.path.abspath(__file__))
        self.test_gtfs_fh = open(self.file_directory + '/tests/test-gtfs.zip',
                                 'rb')

        # Some tasks such as GTFS imports require an oti-admin user (with a token) to exist
        self.admin = OTIUser.objects.create_user('oti-admin',
                                                 password='******',
                                                 email='*****@*****.**')
        Token.objects.get_or_create(user=self.admin)

    def tearDown(self):
        self.test_gtfs_fh.close()

    def test_zip_extension_validation(self):
        """Test that uploaded files are correctly checked for .zip extensions and validated."""
        self.client.authenticate(admin=True)
        temp_dir = tempfile.mkdtemp()
        badfile_path = temp_dir + '/badfile.jpg'
        goodfile_path = temp_dir + '/goodfile.zip'

        with open(badfile_path, 'w') as badfile:
            badfile.write("No useful data here.")

        with open(goodfile_path, 'w') as goodfile:
            goodfile.write("Useful data here.")

        with open(badfile_path, 'r') as badfile:
            # Test that uploading a file with an extension other than .zip
            # fails
            response = self.client.post(self.url, {'source_file': badfile})
            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST,
                             response.content)

        rmtree(temp_dir)

    def test_gtfs_validation(self):
        """Test that verifies GTFS validation works correctly"""
        self.client.authenticate(admin=True)
        response = self.client.post(self.url,
                                    {'source_file': self.test_gtfs_fh})
        sleep(2)  # give time for celery to do job
        problem_count = GTFSFeedProblem.objects.filter(
            gtfsfeed_id=response.data['id']).count()
        self.assertGreater(
            problem_count, 0,
            'There should have been problems for uploaded data')

    def test_gtfs_validation_no_shapes(self):
        """Test that verifies GTFS validation works correctly"""
        self.client.authenticate(admin=True)
        with open(self.file_directory + '/tests/patco.zip', 'rb') as patco:
            response = self.client.post(self.url, {'source_file': patco})
        sleep(2)  # give time for celery to do job
        problem_count = GTFSFeedProblem.objects.filter(
            gtfsfeed_id=response.data['id']).count()
        self.assertGreater(
            problem_count, 0,
            'There should have been problems for uploaded data')

    def test_gtfs_upload_requires_admin(self):
        """Test that verifies GTFS upload requires an admin user"""
        # UNAUTHORIZED if no credentials
        self.client.force_authenticate(user=None)
        response = self.client.post(self.url,
                                    {'source_file': self.test_gtfs_fh})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # FORBIDDEN if user is not superuser
        self.client.authenticate(admin=False)
        response = self.client.post(self.url,
                                    {'source_file': self.test_gtfs_fh})
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 def setUp(self):
     self.client = OTIAPIClient()
     self.url = reverse('real-time-list', {})
     self.file_directory = os.path.dirname(os.path.abspath(__file__))
     self.test_realtime_fh = open(self.file_directory +
                                  '/tests/stop_times_test.txt_new')