Exemplo n.º 1
0
class TestTargets(unittest.TestCase):

    mock_data = mock_data = (
        '12827,Volunteer Recruitment Tiers,Tier,109957740\n'
        '12827,Volunteer Recruitment Tiers,Tier,109957754')
    mock_result = Table([
        ('12827', 'Volunteer Recruitment Tiers', 'Tier', '109957740'),
        ('12827', 'Volunteer Recruitment Tiers', 'Tier', '109957754')])

    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'], db="MyVoters", raise_for_status=False)

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_targets(self, m):

        # Create response
        json = {u'count': 2, u'items':
                [{u'targetId': 12827,
                  u'type': u'TEST CODE',
                  u'name': u'TEST CODE',
                  u'description': None,
                  u'points': 20,
                  u'areSubgroupsSticky': False,
                  u'status': u'Active',
                  u'subgroups': None,
                  u'markedSubgroup': None}],
                u'nextPageLink': None}

        m.get(self.van.connection.uri + 'targets', json=json)

        # Expected Structure
        expected = ['targetId', 'type', 'name', 'description',
                    'points', 'areSubgroupsSticky', 'status', 'subgroups', 'markedSubgroup']

        # Assert response is expected structure
        self.assertTrue(validate_list(expected, self.van.get_targets()))

        # To Do: Test what happens when it doesn't find any targets

    @requests_mock.Mocker()
    def test_get_target(self, m):

        # Create response
        json = {u'targetId': 15723,
                u'name': u'Mail_VR_Chase',
                u'type': u'Dynamic',
                u'description': None,
                u'points': 15,
                u'areSubgroupsSticky': False,
                u'status': u'Active',
                u'subgroups':
                [{u'targetId': 12827,
                  u'fullName': u'April_VR_Chase Calls',
                  u'name': u'April_Chase_20',
                  u'subgroupId': 46803,
                  u'isAssociatedWithBadges': True}],
                u'markedSubgroup': None}

        m.get(self.van.connection.uri + 'targets/15723', json=json)

        self.assertEqual(json, self.van.get_target(15723))

    @requests_mock.Mocker()
    def test_create_target_export(self, m):

        export_job_id = '{"exportJobId": "455961790"}'
        target_id = 12827

        m.post(self.van.connection.uri + 'targetExportJobs', json=export_job_id, status_code=204)

        # Test that it doesn't throw and error
        r = self.van.create_target_export(target_id, webhook_url=None)

        self.assertEqual(r, export_job_id)

    @requests_mock.Mocker()
    def test_get_target_export(self, m):

        export_job_id = 455961790
        json = [{
            "targetId": 12827,
            "file": {
                "downloadUrl": (
                    "https://ngpvan.blob.core.windows.net/"
                    "target-export-files/TargetExport_455961790.csv"),
                "dateExpired": "null",
                "recordCount": 1016883},
            "webhookUrl": "null",
            "exportJobId": 455961790,
            "jobStatus": "Complete"}]

        download_url = (
            'https://ngpvan.blob.core.windows.net/target-export-files/TargetExport_455961790.csv')

        m.post(self.van.connection.uri + 'targetExportJobs', json=export_job_id, status_code=204)
        m.get(self.van.connection.uri + 'targetExportJobs/455961790', json=json)
        m.get(download_url, text=self.mock_data)
        assert_matching_tables(self.van.get_target_export(export_job_id),
                               self.mock_result)
Exemplo n.º 2
0
# ### CODE

import os  # noqa: E402
import random  # noqa: E402
from parsons import VAN  # noqa: E402
from parsons import logger  # noqa: E402

# Setup

# If variables specified above, sets them as environmental variables
for name, value in config_vars.items():
    if value.strip() != "":
        os.environ[name] = value

van = VAN(db=os.environ["VAN_DB_NAME"])

# Get details on the saved list we're pulling from and the folder we're uploading to
saved_list = van.get_saved_list(os.environ["VAN_SAVED_LIST_ID"])
folder = van.get_folder(os.environ["VAN_FOLDER_ID"])

# If you're receiving errors when trying to call this method related to permissions, you may want to
# reach out to [email protected] to make sure your API key has the correct permissions.
saved_list_download = van.download_saved_list(os.environ["VAN_SAVED_LIST_ID"])

# Generate a random sample of VAN IDs from the list
saved_list_sample_ids = random.sample(
    saved_list_download["VanID"],
    int(os.environ["VAN_SAMPLE_LIST_SIZE"]),
)
Exemplo n.º 3
0
class TestActivistCodes(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_activist_codes(self, m):

        # Create response
        json = {
            u'count':
            43,
            u'items': [{
                u'status': u'Active',
                u'scriptQuestion': None,
                u'name': u'TEST CODE',
                u'mediumName': u'TEST CODE',
                u'activistCodeId': 4388538,
                u'shortName': u'TC',
                u'type': u'Action',
                u'description': None
            }],
            u'nextPageLink':
            None
        }

        m.get(self.van.connection.uri + 'activistCodes', json=json)

        # Expected Structure
        expected = [
            'status', 'scriptQuestion', 'name', 'mediumName', 'activistCodeId',
            'shortName', 'type', 'description'
        ]

        # Assert response is expected structure
        self.assertTrue(validate_list(expected, self.van.get_activist_codes()))

        # To Do: Test what happens when it doesn't find any ACs

    @requests_mock.Mocker()
    def test_get_activist_code(self, m):

        # Create response
        json = {
            "status": "Active",
            "scriptQuestion": "null",
            "name": "Anti-Choice",
            "mediumName": "Anti",
            "activistCodeId": 4135099,
            "shortName": "AC",
            "type": "Constituency",
            "description": "A person who has been flagged as anti-choice."
        }

        m.get(self.van.connection.uri + 'activistCodes/4388538', json=json)

        self.assertEqual(json, self.van.get_activist_code(4388538))

    @requests_mock.Mocker()
    def test_toggle_activist_code(self, m):

        # Test apply activist code
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.assertTrue(
            self.van.toggle_activist_code(2335282, 4429154, 'apply'), 204)

        # Test remove activist code
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.assertTrue(
            self.van.toggle_activist_code(2335282, 4429154, 'remove'), 204)

    @requests_mock.Mocker()
    def test_apply_activist_code(self, m):

        # Test apply activist code
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.assertEqual(self.van.apply_activist_code(2335282, 4429154), 204)

    @requests_mock.Mocker()
    def test_remove_activist_code(self, m):

        # Test remove activist code
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.assertEqual(self.van.remove_activist_code(2335282, 4429154), 204)
Exemplo n.º 4
0
class TestSavedLists(unittest.TestCase):

    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'], db="MyVoters", raise_for_status=False)

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_saved_lists(self, m):

        json = {'count': 1, 'items': [
            {"savedListId": 517612,
             "listCount": 974656,
             "name": "LikelyParents(16andunder)_DWID_S... - MN",
             "doorCount": 520709,
             "description": "null"
             }
        ], 'nextPageLink': None}

        m.get(self.van.connection.uri + 'savedLists', json=json)

        expected = ['savedListId', 'listCount', 'name', 'doorCount', 'description']

        self.assertTrue(validate_list(expected, self.van.get_saved_lists()))

    @requests_mock.Mocker()
    def test_get_saved_list(self, m):

        saved_list_id = 517612

        json = {"savedListId": 517612,
                "listCount": 974656,
                "name": "LikelyParents(16andunder)_DWID_S... - MN",
                "doorCount": 520709,
                "description": "null"
                }

        m.get(self.van.connection.uri + f'savedLists/{saved_list_id}', json=json)

        # expected = ['savedListId', 'listCount', 'name', 'doorCount', 'description']

        self.assertEqual(self.van.get_saved_list(saved_list_id), json)

    def test_upload_saved_list(self):

        cloud_storage.post_file = mock.MagicMock()
        cloud_storage.post_file.return_value = 'https://box.com/my_file.zip'

        self.van.connection._soap_client = mock.MagicMock()
        self.van.get_folders = mock.MagicMock()
        self.van.get_folders.return_value = [{'folderId': 1}]

        tbl = Table([['VANID'], ['1'], ['2'], ['3']])
        self.van.upload_saved_list(
            tbl, 'GOTV List', 1, replace=True, url_type='S3', bucket='tmc-scratch')
        assert self.van.connection._soap_client.service.CreateAndStoreSavedList.called

        @requests_mock.Mocker()
        def test_upload_saved_list_rest(self):

            cloud_storage.post_file = mock.MagicMock()
            cloud_storage.post_file.return_value = 'https://box.com/my_file.zip'
            self.van.get_folders = mock.MagicMock()
            self.van.get_folders.return_value = [{'folderId': 1}]

            tbl = Table([['VANID'], ['1'], ['2'], ['3']])
            response = self.van.upload_saved_list_rest(
                tbl=tbl, url_type="S3",
                folder_id=1, list_name="GOTV List", description="parsons test list",
                callback_url="https://webhook.site/69ab58c3-a3a7-4ed8-828c-1ea850cb4160",
                columns=["VANID"], id_column="VANID",
                bucket="tmc-scratch",
                overwrite=517612
                )
            self.assertIn("jobId", response)

    @requests_mock.Mocker()
    def test_get_folders(self, m):

        json = {u'count': 2,
                u'items': [
                    {
                        u'folderId': 5046,
                        u'name': u'#2018_MN_active_universe'
                    },
                    {u'folderId': 2168,
                     u'name': u'API Generated Lists'
                     }
                ], u'nextPageLink': None}

        m.get(self.van.connection.uri + 'folders', json=json)

        expected = ['folderId', 'name']

        self.assertTrue(validate_list(expected, self.van.get_folders()))

    @requests_mock.Mocker()
    def test_get_folder(self, m):

        folder_id = 5046

        json = {"folderId": 5046, "name": "#2018_MN_active_universe"}

        m.get(self.van.connection.uri + f'folders/{folder_id}', json=json)

        self.assertEqual(json, self.van.get_folder(folder_id))

    @requests_mock.Mocker()
    def test_export_job_types(self, m):

        json = {u'count': 1, u'items':
                [{u'exportJobTypeId': 4, u'name': u'SavedListExport'}],
                u'nextPageLink': None}

        m.get(self.van.connection.uri + 'exportJobTypes', json=json)

        expected = ['exportJobTypeId', 'name']

        self.assertTrue(validate_list(expected, self.van.get_export_job_types()))

    @requests_mock.Mocker()
    def test_export_job_create(self, m):

        saved_list_id = 517612

        json = {"status": "Completed",
                "errorCode": "null",
                "exportJobGuid": "bf4d1297-1c77-3fb2-03bd-f0acda122d37",
                "activistCodes": "null",
                "canvassFileRequestId": 448,
                "dateExpired": "2018-09-08T16:04:00Z",
                "surveyQuestions": "null",
                "webhookUrl": "https://www.nothing.com/",
                "downloadUrl": "https://ngpvan.blob.core.windows.net/canvass-files-savedlistexport/bf4d1297-1c77-3fb2-03bd-f0acda122d37_2018-09-08T13:03:27.7191831-04:00.csv",  # noqa: E501
                "savedListId": 517612,
                "districtFields": "null",
                "canvassFileRequestGuid": "bf4d1297-1c77-3fb2-03bd-f0acda122d37",
                "customFields": "null",
                "type": 4,
                "exportJobId": 448}

        m.post(self.van.connection.uri + 'exportJobs', json=json, status_code=201)

        # expected = [
        #     'status',
        #     'errorCode',
        #     'exportJobGuid',
        #     'activistCodes',
        #     'canvassFileRequestId',
        #     'dateExpired',
        #     'surveyQuestions',
        #     'webhookUrl',
        #     'downloadUrl',
        #     'savedListId',
        #     'districtFields',
        #     'canvassFileRequestGuid',
        #     'customFields',
        #     'type',
        #     'exportJobId']

        self.assertEqual(json, self.van.export_job_create(saved_list_id))

    @requests_mock.Mocker()
    def test_get_export_job(self, m):

        export_job_id = 448

        json = {"status": "Completed",
                "errorCode": "null",
                "exportJobGuid": "bf4d1297-1c77-3fb2-03bd-f0acda122d37",
                "activistCodes": "null",
                "canvassFileRequestId": 448,
                "dateExpired": "2018-09-08T16:04:00Z",
                "surveyQuestions": "null",
                "webhookUrl": "https://www.nothing.com/",
                "downloadUrl": "https://ngpvan.blob.core.windows.net/canvass-files-savedlistexport/bf4d1297-1c77-3fb2-03bd-f0acda122d37_2018-09-08T13:03:27.7191831-04:00.csv",  # noqa: E501
                "savedListId": 517612,
                "districtFields": "null",
                "canvassFileRequestGuid": "bf4d1297-1c77-3fb2-03bd-f0acda122d37",
                "customFields": "null",
                "type": 4,
                "exportJobId": 448}

        # expected = [
        #     'status',
        #     'errorCode',
        #     'exportJobGuid',
        #     'activistCodes',
        #     'canvassFileRequestId',
        #     'dateExpired',
        #     'surveyQuestions',
        #     'webhookUrl',
        #     'downloadUrl',
        #     'savedListId',
        #     'districtFields',
        #     'canvassFileRequestGuid',
        #     'customFields',
        #     'type',
        #     'exportJobId']

        m.get(self.van.connection.uri + f'exportJobs/{export_job_id}', json=json)

        self.assertEqual(json, self.van.get_export_job(export_job_id))
Exemplo n.º 5
0
class TestNGPVAN(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)

    @requests_mock.Mocker()
    def test_find_person(self, m):

        m.post(self.van.connection.uri + 'people/find',
               json=find_people_response,
               status_code=200)

        person = self.van.find_person(first_name='Bob',
                                      last_name='Smith',
                                      phone=4142020792)

        self.assertEqual(person, find_people_response)

    @requests_mock.Mocker()
    def test_find_person_json(self, m):

        json = {
            "firstName": "Bob",
            "lastName": "Smith",
            "phones": [{
                "phoneNumber": 4142020792
            }]
        }

        m.post(self.van.connection.uri + 'people/find',
               json=find_people_response,
               status_code=200)

        person = self.van.find_person_json(match_json=json)

        self.assertEqual(person, find_people_response)

    def test_upsert_person(self):

        pass

    def test_upsert_person_json(self):

        pass

    def test_update_person(self):

        pass

    def test_update_person_json(self):

        pass

    def test_people_search(self):

        # Already tested as part of upsert and find person methods
        pass

    def test_valid_search(self):

        # Fails with FN / LN Only
        self.assertRaises(ValueError, self.van._valid_search, 'Barack',
                          'Obama', None, None, None, None, None)

        # Fails with only Zip
        self.assertRaises(ValueError, self.van._valid_search, 'Barack',
                          'Obama', None, None, None, None, 60622)

        # Fails with no street number
        self.assertRaises(ValueError, self.van._valid_search, 'Barack',
                          'Obama', None, None, None, 'Pennsylvania Ave', None)

        # Successful with FN/LN/Email
        self.van._valid_search('Barack', 'Obama', '*****@*****.**', None,
                               None, None, None)

        # Successful with FN/LN/DOB/ZIP
        self.van._valid_search('Barack', 'Obama', '*****@*****.**', None,
                               '2000-01-01', None, 20009)

        # Successful with FN/LN/Phone
        self.van._valid_search('Barack', 'Obama', None, 2024291000, None, None,
                               None)

    @requests_mock.Mocker()
    def test_get_person(self, m):

        json = get_person_response

        # Test works with external ID
        m.get(self.van.connection.uri + 'people/DWID:15406767', json=json)
        person = self.van.get_person('15406767', id_type='DWID')
        self.assertEqual(get_person_response, person)

        # Test works with vanid
        m.get(self.van.connection.uri + 'people/19722445', json=json)
        person = self.van.get_person('19722445')
        self.assertEqual(get_person_response, person)

    @requests_mock.Mocker()
    def test_apply_canvass_result(self, m):

        # Test a valid attempt
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.van.apply_canvass_result(2335282, 18)

        # Test a bad result code
        json = {
            'errors': [{
                'code': 'INVALID_PARAMETER',
                'text':
                "'resultCodeId' must be a valid result code in the current context.",
                'properties': ['resultCodeId']
            }]
        }
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               json=json,
               status_code=400)
        self.assertRaises(HTTPError, self.van.apply_canvass_result, 2335282, 0)

        # Test a bad vanid
        json = {
            'errors': [{
                'code': 'INTERNAL_SERVER_ERROR',
                'text': 'An unknown error occurred',
                'referenceCode': '88A111-E2FF8'
            }]
        }
        m.post(self.van.connection.uri + 'people/0/canvassResponses',
               json=json,
               status_code=400)
        self.assertRaises(HTTPError, self.van.apply_canvass_result, 0, 18)

        # Test a good dwid
        m.post(self.van.connection.uri +
               'people/DWID:2335282/canvassResponses',
               status_code=204)
        self.van.apply_canvass_result(2335282, 18, id_type='DWID')

    @requests_mock.Mocker()
    def test_apply_survey_question(self, m):

        # Test valid survey question
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=204)
        self.van.apply_survey_response(2335282, 351006, 1443891)

        # Test bad survey response id
        # json = {
        #     'errors': [{
        #         'code': 'INVALID_PARAMETER',
        #         'text': ("'surveyResponseId' must be a valid Response to the given "
        #                  "Survey Question."),
        #         'properties': ['responses[0].surveyResponseId']
        #     }]
        # }
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=400)
        self.assertRaises(HTTPError, self.van.apply_survey_response, 2335282,
                          0, 1443891)

        # Test bad survey question id
        # json = {
        #     'errors': [{
        #         'code': 'INVALID_PARAMETER',
        #         'text': ("'surveyQuestionId' must be a valid Survey Question that is "
        #                 "available in the current context."),
        #         'properties': ['responses[0].surveyQuestionId']
        #     }]
        # }
        m.post(self.van.connection.uri + 'people/2335282/canvassResponses',
               status_code=400)
        self.assertRaises(HTTPError, self.van.apply_survey_response, 2335282,
                          351006, 0)

    def test_toggle_volunteer_action(self):

        pass

    def test_apply_response(self):

        pass

    @requests_mock.Mocker()
    def test_create_relationship(self, m):

        relationship_id = 12
        bad_vanid_1 = 99999
        good_vanid_1 = 12345
        vanid_2 = 54321

        # Bad request
        m.post(self.van.connection.uri +
               "people/{}/relationships".format(bad_vanid_1),
               status_code=404)

        # Good request
        m.post(self.van.connection.uri +
               "people/{}/relationships".format(good_vanid_1),
               status_code=204)

        # Test bad input
        self.assertRaises(HTTPError, self.van.create_relationship, bad_vanid_1,
                          vanid_2, relationship_id)
        self.assertRaises(HTTPError, self.van.create_relationship, bad_vanid_1,
                          vanid_2, relationship_id)

        self.van.create_relationship(good_vanid_1, vanid_2, relationship_id)

    @requests_mock.Mocker()
    def test_apply_person_code(self, m):

        vanid = 999
        code_id = 888

        # Test good request
        m.post(self.van.connection.uri + f"people/{vanid}/codes",
               status_code=204)
        self.van.apply_person_code(vanid, code_id)

        # Test bad request
        m.post(self.van.connection.uri + f"people/{vanid}/codes",
               status_code=404)
        self.assertRaises(HTTPError, self.van.apply_person_code, vanid,
                          code_id)
Exemplo n.º 6
0
class TestNGPVAN(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'], db="MyVoters")

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_events(self, m):

        json = {
            'count':
            6,
            'items': [{
                "eventId": 1062,
                "startDate": "2010-05-25T11:00:00-05:00",
                "codes": "null",
                "endDate": "2010-05-25T15:00:00-05:00",
                "name": "Sample",
                "roles": "null",
                "isOnlyEditableByCreatingUser": "******",
                "ticketCategories": "null",
                "eventType": {
                    "eventTypeId": 29166,
                    "name": "Confirmation Calls"
                },
                "notes": "null",
                "districtFieldValue": "null",
                "locations": "null",
                "shifts": "null",
                "voterRegistrationBatches": "null",
                "createdDate": "2010-05-25T11:55:00Z",
                "financialProgram": "null",
                "shortName": "Sample",
                "isPubliclyViewable": "null",
                "isActive": "true",
                "description": "This is a sample"
            }],
            'nextPageLink':
            None
        }

        m.get(self.van.connection.uri + 'events', json=json)

        # Expected Structure
        expected = [
            'eventId', 'startDate', 'codes', 'endDate', 'name', 'roles',
            'isOnlyEditableByCreatingUser', 'ticketCategories', 'eventType',
            'notes', 'districtFieldValue', 'locations', 'shifts',
            'voterRegistrationBatches', 'createdDate', 'financialProgram',
            'shortName', 'isPubliclyViewable', 'isActive', 'description'
        ]

        self.assertTrue(validate_list(expected, self.van.get_events()))

    @requests_mock.Mocker()
    def test_get_event(self, m):

        event_id = 1062

        json = {
            "eventId": 1062,
            "startDate": "2010-05-25T11:00:00-05:00",
            "codes": "null",
            "endDate": "2010-05-25T15:00:00-05:00",
            "name": "Sample",
            "roles": "null",
            "isOnlyEditableByCreatingUser": "******",
            "ticketCategories": "null",
            "eventType": {
                "eventTypeId": 29166,
                "name": "Confirmation Calls"
            },
            "notes": "null",
            "districtFieldValue": "null",
            "locations": "null",
            "shifts": "null",
            "voterRegistrationBatches": "null",
            "createdDate": "2010-05-25T11:55:00Z",
            "financialProgram": "null",
            "shortName": "Sample",
            "isPubliclyViewable": "null",
            "isActive": "true",
            "description": "This is a sample"
        }

        m.get(self.van.connection.uri + 'events/{}'.format(event_id),
              json=json)

        self.assertEqual(json, self.van.get_event(event_id))

    @requests_mock.Mocker()
    def test_create_event(self, m):

        m.post(self.van.connection.uri + 'events',
               json=750000984,
               status_code=204)

        # Test that it doesn't throw and error
        r = self.van.create_event('Canvass 01',
                                  'Can01',
                                  '2016-06-01',
                                  '2016-06-02',
                                  296199, [259236],
                                  publicly_viewable='True',
                                  editable=False)

        self.assertEqual(r, 750000984)

    @requests_mock.Mocker()
    def test_get_event_types(self, m):

        json = [{
            'eventTypeId':
            296199,
            'name':
            'Block Party',
            'canHaveMultipleShifts':
            False,
            'canHaveMultipleLocations':
            False,
            'canHaveGoals':
            False,
            'canHaveRoleMaximums':
            False,
            'canHaveRoleMinimums':
            False,
            'canBeRepeatable':
            False,
            'roles': [{
                'roleId': 259236,
                'name': 'Attendee',
                'isEventLead': False
            }, {
                'roleId': 259235,
                'name': 'Supporter',
                'isEventLead': False
            }, {
                'roleId': 259234,
                'name': 'Volunteer',
                'isEventLead': False
            }],
            'statuses': [{
                'statusId': 4,
                'name': 'Invited'
            }, {
                'statusId': 18,
                'name': 'Left Msg'
            }, {
                'statusId': 14,
                'name': 'Tentative'
            }, {
                'statusId': 3,
                'name': 'Declined'
            }, {
                'statusId': 11,
                'name': 'Confirmed'
            }, {
                'statusId': 23,
                'name': 'Conf Twice'
            }, {
                'statusId': 2,
                'name': 'Completed'
            }, {
                'statusId': 15,
                'name': 'Walk In'
            }, {
                'statusId': 6,
                'name': 'No Show'
            }, {
                'statusId': 29,
                'name': 'Texted'
            }],
            'color':
            '#7F7F7F',
            'isAtLeastOneLocationRequired':
            False,
            'defaultLocation':
            None,
            'isSharedWithMasterCommitteeByDefault':
            False,
            'isSharedWithChildCommitteesByDefault':
            False,
            'isOnlineActionsAvailable':
            False
        }]

        m.get(self.van.connection.uri + 'events/types', json=json)

        expected = [
            'eventTypeId', 'name', 'canHaveMultipleShifts',
            'canHaveMultipleLocations', 'canHaveGoals', 'canHaveRoleMaximums',
            'canHaveRoleMinimums', 'canBeRepeatable', 'roles', 'statuses',
            'color', 'isAtLeastOneLocationRequired', 'defaultLocation',
            'isSharedWithMasterCommitteeByDefault',
            'isSharedWithChildCommitteesByDefault', 'isOnlineActionsAvailable'
        ]

        self.assertTrue(validate_list(expected, self.van.get_event_types()))
Exemplo n.º 7
0
class TestNGPVAN(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)

    @requests_mock.Mocker()
    def test_get_changed_entity_resources(self, m):

        json = [
            'ActivistCodes', 'ContactHistory', 'Contacts',
            'ContactsActivistCodes'
        ]
        m.get(self.van.connection.uri + 'changedEntityExportJobs/resources',
              json=json)
        self.assertEqual(json, self.van.get_changed_entity_resources())

    @requests_mock.Mocker()
    def test_get_changed_entity_resource_fields(self, m):

        json = [{
            'fieldName': 'ActivistCodeID',
            'fieldType': 'N',
            'maxTextboxCharacters': None,
            'isCoreField': True,
            'availableValues': None
        }, {
            'fieldName': 'ActivistCodeType',
            'fieldType': 'T',
            'maxTextboxCharacters': 20,
            'isCoreField': True,
            'availableValues': None
        }, {
            'fieldName': 'Campaign',
            'fieldType': 'T',
            'maxTextboxCharacters': 150,
            'isCoreField': True,
            'availableValues': None
        }]

        m.get(self.van.connection.uri +
              'changedEntityExportJobs/fields/ActivistCodes',
              json=json)
        assert_matching_tables(
            Table(json),
            self.van.get_changed_entity_resource_fields('ActivistCodes'))

    @requests_mock.Mocker()
    def test_get_changed_entities(self, m):

        json = {
            "dateChangedFrom": "2021-10-10T00:00:00-04:00",
            "dateChangedTo": "2021-10-11T00:00:00-04:00",
            "files": [],
            "message": "Created export job",
            "code": None,
            "exportedRecordCount": 0,
            "exportJobId": 2170181229,
            "jobStatus": "Pending"
        }

        json2 = {
            "dateChangedFrom":
            "2021-10-10T00:00:00-04:00",
            "dateChangedTo":
            "2021-10-11T00:00:00-04:00",
            "files": [{
                "downloadUrl": "https://box.com/file.csv",
                "dateExpired": "2021-11-03T15:27:01.8687339-04:00"
            }],
            "message":
            "Finished processing export job",
            "code":
            None,
            "exportedRecordCount":
            6110,
            "exportJobId":
            2170181229,
            "jobStatus":
            "Complete"
        }

        tbl = Table([{'a': 1, 'b': 2}])

        m.post(self.van.connection.uri + 'changedEntityExportJobs', json=json)
        m.get(self.van.connection.uri + 'changedEntityExportJobs/2170181229',
              json=json2)

        Table.from_csv = mock.MagicMock()
        Table.from_csv.return_value = tbl

        out_tbl = self.van.get_changed_entities('ContactHistory', '2021-10-10')

        assert_matching_tables(out_tbl, tbl)
Exemplo n.º 8
0
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'], db="MyVoters")
Exemplo n.º 9
0
for name, value in config_vars.items(
):  # sets variables if provided in this script
    if value.strip() != "":
        os.environ[name] = value

rs = Redshift(
)  # just create Redshift() - VAN connector is created dynamically below

# Create dictionary of VAN states and API keys from multiline Civis credential

myv_states = {
    x.split(",")[0]: x.split(",")[1]
    for x in os.environ['VAN_PASSWORD'].split("\r\n")
}
myv_keys = {
    k: VAN(api_key=v, db=os.environ['VAN_DB_NAME'])
    for k, v in myv_states.items()
}

# Create simple set of states for insertion into SQL
states = "','".join([s for s in myv_keys])

# SQL to pull those needing Activist Code
sql = f"""
SELECT vb_smartvan_id
    , vb_vf_source_state
    , hash
    , activist_code_id
FROM schema.table
WHERE vb_vf_source_state IN ({states}) 
"""
Exemplo n.º 10
0
class TestSignups(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="EveryAction",
                       raise_for_status=False)

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_signup_statuses(self, m):

        m.get(self.van.connection.uri + 'signups/statuses', json=signup_status)

        # Test events lookup
        self.assertTrue(
            validate_list(['statusId', 'name'],
                          self.van.get_signups_statuses(event_id=750000849)))

        # Test event type lookup
        self.assertTrue(
            validate_list(
                ['statusId', 'name'],
                self.van.get_signups_statuses(event_type_id=750000849)))

    @requests_mock.Mocker()
    def test_get_signups(self, m):

        json = {'items': [signup], 'nextPageLink': None, 'count': 1}

        m.get(self.van.connection.uri + 'signups', json=json)

        self.assertTrue(
            validate_list(signup_expected,
                          self.van.get_event_signups(event_id=750001004)))

        self.assertTrue(
            validate_list(signup_expected,
                          self.van.get_person_signups(vanid=750000849)))

    @requests_mock.Mocker()
    def test_get_signup(self, m):

        event_signup_id = 14285

        m.get(self.van.connection.uri + f'signups/{event_signup_id}'.format(),
              json=signup)

        self.assertEqual(signup, self.van.get_signup(event_signup_id))

    @requests_mock.Mocker()
    def test_create_signup(self, m):

        m.post(self.van.connection.uri + 'signups',
               json=14285,
               status_code=201)

        self.assertEqual(
            self.van.create_signup(100349920, 750001004, 19076, 263920, 11, 3),
            14285)

    @requests_mock.Mocker()
    def test_update_signup(self, m):

        # This is two part. It makes a call to get the object and then it updates it

        event_signup_id = 14285

        # Get object route
        m.get(self.van.connection.uri + f'signups/{event_signup_id}',
              json=signup)

        # Update object
        m.put(self.van.connection.uri + f'signups/{event_signup_id}',
              status_code=204)

        self.van.update_signup(event_signup_id, status_id=6)
Exemplo n.º 11
0
class TestCodes(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'], db="MyVoters")

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_codes(self, m):

        json = {
            'items': [{
                'codeId': 1004916,
                'parentCodeId': None,
                'name': 'Data Entry',
                'description': 'for test.',
                'codePath': 'Data Entry',
                'createdByName': '',
                'dateCreated': '2018-07-13T15:16:00Z',
                'supportedEntities': None,
                'codeType': 'Tag',
                'campaign': None,
                'contactType': None
            }],
            'nextPageLink':
            None,
            'count':
            8
        }

        m.get(self.van.connection.uri + 'codes', json=json)
        assert_matching_tables(json['items'], self.van.get_codes())

    @requests_mock.Mocker()
    def test_get_code_types(self, m):

        json = ['Tag', 'SourceCode']
        m.get(self.van.connection.uri + 'codeTypes', json=json)
        self.assertEqual(json, self.van.get_code_types())

    @requests_mock.Mocker()
    def test_create_code(self, m):

        m.post(self.van.connection.uri + 'codes',
               json=1004960,
               status_code=201)

        # Test that it doesn't throw and error
        r = self.van.create_code('Test Code',
                                 supported_entities=[{
                                     'name': 'Events',
                                     'is_searchable': True,
                                     'is_applicable': True
                                 }])

        self.assertEqual(r, 1004960)

    @requests_mock.Mocker()
    def test_update_code(self, m):

        # Test a good input
        m.put(self.van.connection.uri + 'codes/1004960', status_code=204)
        self.van.update_code(1004960, name='Test')

        # Test a bad input
        m.put(self.van.connection.uri + 'codes/100496Q', status_code=404)
        self.assertRaises(HTTPError, self.van.update_code, '100496Q')

    @requests_mock.Mocker()
    def test_delete_code(self, m):

        # Test a good input
        m.delete(self.van.connection.uri + 'codes/1004960', status_code=204)
        self.van.delete_code(1004960)

        # Test a bad input
        m.delete(self.van.connection.uri + 'codes/100496Q', status_code=404)
        self.assertRaises(HTTPError, self.van.delete_code, '100496Q')

    @requests_mock.Mocker()
    def test_get_code_supported_entities(self, m):

        json = ['Contacts', 'Events', 'Locations']
        m.get(self.van.connection.uri + 'codes/supportedEntities', json=json)
        self.assertEqual(json, self.van.get_code_supported_entities())
Exemplo n.º 12
0
set_env_var('AWS_SECRET_ACCESS_KEY', os.environ['AWS_SECRET_ACCESS_KEY'])
s3 = S3()

# Logging

logger = logging.getLogger(__name__)
_handler = logging.StreamHandler()
_formatter = logging.Formatter('%(levelname)s %(message)s')
_handler.setFormatter(_formatter)
logger.addHandler(_handler)
logger.setLevel('INFO')

# Create dictionary of VAN states and API keys from multiline Civis credential

myv_states = {x.split(",")[0]: x.split(",")[1] for x in os.environ['VAN_PASSWORD'].split("\r\n")}
myv_keys = {k: VAN(api_key=v, db='MyVoters') for k,v in myv_states.items()}

# Create simple set of states for insertion into SQL
states = "','".join([s for s in myv_keys])

# SQL to pull those needing Activist Code
sql = f"""
SELECT vb_smartvan_id
    , vb_vf_source_state
    , hash
    , activist_code_id
FROM schema.table
WHERE vb_vf_source_state IN ({states}) 
"""

records = rs.query(sql)
Exemplo n.º 13
0
class TestBulkImport(unittest.TestCase):

    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters", raise_for_status=False)

    @requests_mock.Mocker()
    def test_get_bulk_import_resources(self, m):

        json = ['Contacts', 'Contributions',
                'ActivistCodes', 'ContactsActivistCodes']

        m.get(self.van.connection.uri + 'bulkImportJobs/resources', json=json)

        self.assertEqual(self.van.get_bulk_import_resources(), json)

    @requests_mock.Mocker()
    def test_get_bulk_import_job(self, m):

        m.get(self.van.connection.uri +
              'bulkImportJobs/53407', json=bulk_import_job)

        self.assertEqual(self.van.get_bulk_import_job(53407), bulk_import_job)

    @requests_mock.Mocker()
    def test_get_bulk_import_job_results(self, m):

        results_tbl = Table([['BulkUploadDataID', 'ULFileID', 'PrimaryKey',
                              'PrimaryKeyType', 'MailingAddress_3581'],
                             ['1', '1983', '101596008', 'VanID', 'Processed']])

        bulk_import_job = {'id': 92,
                           'status': 'Completed',
                           'resourceType': 'Contacts',
                           'webhookUrl': None,
                           'resultFileSizeLimitKb': 5000,
                           'errors': [],
                           'resultFiles': [{
                               'url': Table.to_csv(results_tbl),
                               'dateExpired': '2020-09-04T22:07:04.0770295-04:00'
                           }]
                           }

        m.get(self.van.connection.uri +
              'bulkImportJobs/53407', json=bulk_import_job)
        assert_matching_tables(
            self.van.get_bulk_import_job_results(53407), results_tbl)

    @requests_mock.Mocker()
    def test_get_bulk_import_mapping_types(self, m):

        m.get(self.van.connection.uri +
              'bulkImportMappingTypes', json=mapping_type)

        assert_matching_tables(
            self.van.get_bulk_import_mapping_types(), Table(mapping_type))

    @requests_mock.Mocker()
    def test_get_bulk_import_mapping_type(self, m):

        m.get(self.van.connection.uri +
              'bulkImportMappingTypes/ActivistCode', json=mapping_type)

        self.assertEqual(self.van.get_bulk_import_mapping_type(
            'ActivistCode'), mapping_type)

    @requests_mock.Mocker()
    def get_bulk_import_mapping_type_fields(self, m):

        json = [{'name': 'Unsubscribed', 'id': '0', 'parents': None},
                {'name': 'Not Subscribed', 'id': '1', 'parents': None},
                {'name': 'Subscribed', 'id': '2', 'parents': None}]
        m.get(self.van.connection.uri +
              'bulkImportMappingTypes/Email/EmailSubscriptionStatusId/values')

        r = self.van.get_bulk_import_mapping_type_fields(
            'Email', 'EmailSubscriptionStatusId')
        self.assertEqual(json, r)

    @requests_mock.Mocker()
    def test_post_bulk_import(self, m):

        # Mock Cloud Storage
        cloud_storage.post_file = mock.MagicMock()
        cloud_storage.post_file.return_value = 'https://s3.com/my_file.zip'

        tbl = Table([['Vanid', 'ActivistCodeID'], [1234, 345345]])

        m.post(self.van.connection.uri +
               'bulkImportJobs', json={'jobId': 54679})

        r = self.van.post_bulk_import(tbl,
                                      'S3',
                                      'ContactsActivistCodes',
                                      [{"name": "ActivistCode"}],
                                      'Activist Code Upload',
                                      bucket='my-bucket')

        self.assertEqual(r, 54679)

    @requests_mock.Mocker()
    def test_bulk_apply_activist_codes(self, m):

        # Mock Cloud Storage
        cloud_storage.post_file = mock.MagicMock()
        cloud_storage.post_file.return_value = 'https://s3.com/my_file.zip'

        tbl = Table([['Vanid', 'ActivistCodeID'], [1234, 345345]])

        m.post(self.van.connection.uri +
               'bulkImportJobs', json={'jobId': 54679})

        job_id = self.van.bulk_apply_activist_codes(
            tbl, url_type="S3", bucket='my-bucket')

        self.assertEqual(job_id, 54679)

    @requests_mock.Mocker()
    def test_bulk_upsert_contacts(self, m):

        # Mock Cloud Storage
        cloud_storage.post_file = mock.MagicMock()
        cloud_storage.post_file.return_value = 'https://s3.com/my_file.zip'

        tbl = Table([['Vanid', 'email'], [1234, '*****@*****.**']])

        m.post(self.van.connection.uri +
               'bulkImportJobs', json={'jobId': 54679})

        job_id = self.van.bulk_upsert_contacts(
            tbl, url_type="S3", bucket='my-bucket')

        self.assertEqual(job_id, 54679)
Exemplo n.º 14
0
# ### CODE

# Setup

import os  # noqa: E402
from parsons import VAN, Zoom  # noqa: E402

# if variables specified above, sets them as environmental variables
for name, value in config_vars.items():
    if value.strip() != "":
        os.environ[name] = value

# Code

zoom = Zoom()
van = VAN(db=VAN_DB)

# Gets participants from Zoom meeting
participants = zoom.get_past_meeting_participants(ZOOM_MEETING_ID)
filtered_participants = participants.select_rows(lambda row: row.duration > MINIMUM_DURATION)

# Coalesce the columns into something VAN expects
column_map = {"first_name": ["fn", "first", "firstname", "first name"],
              "last_name": ["ln", "last", "lastname", "last name"],
              "date_of_birth": ["dob", "date of birth", "birthday"],
              "email": ["email address", "email_address"],
              "street_number": ["street number", "street no.", "street no", "street #"],
              "street_name": ["street name", "street"],
              "phone": ["phone_number", "phone #", "phone_#", "phone no.", "phone no"],
              "zip": ["zip5", "zipcode", "zip code"]}
filtered_participants.map_and_coalesce_columns(column_map)
Exemplo n.º 15
0
class TestScores(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)

    @requests_mock.Mocker()
    def test_get_scores(self, m):

        json = {
            u'count':
            2,
            u'items': [{
                u'origin': None,
                u'scoreId': 2716,
                u'name': u'Democratic Party Support',
                u'maxValue': 100.0,
                u'minValue': 1.0,
                u'state': None,
                u'shortName': u'Dem Support',
                u'description': None
            }],
            u'nextPageLink':
            None
        }

        m.get(self.van.connection.uri + 'scores', json=json)

        expected = [
            'origin', 'scoreId', 'name', 'maxValue', 'minValue', 'state',
            'shortName', 'description'
        ]

        self.assertTrue(validate_list(expected, self.van.get_scores()))

    @requests_mock.Mocker()
    def test_get_score(self, m):

        score_id = 2716

        json = {
            u'origin': None,
            u'scoreId': 2716,
            u'name': u'Democratic Party Support',
            u'maxValue': 100.0,
            u'minValue': 1.0,
            u'state': None,
            u'shortName': u'Dem Support',
            u'description': None
        }

        m.get(self.van.connection.uri + 'scores/{}'.format(score_id),
              json=json)
        self.assertEqual(json, self.van.get_score(score_id))

    @requests_mock.Mocker()
    def test_get_score_updates(self, m):

        json = {
            'items': [{
                'scoreUpdateId': 58319,
                'score': {
                    'scoreId': 29817,
                    'name': 'TargetSmart Gun Ownership',
                    'shortName': None,
                    'description': None,
                    'minValue': 0.0,
                    'maxValue': 100.0,
                    'state': 'MT',
                    'origin': None
                },
                'updateStatistics': {
                    'totalRows': 856644,
                    'duplicateRows': 0,
                    'matchedRows': 856644,
                    'matchPercent': 100.0,
                    'increasedBy': 441264,
                    'decreasedBy': 280588,
                    'nulledOut': 3649,
                    'added': 115129,
                    'outOfRange': 0,
                    'badValues': 0,
                    'maxValue': 95.9,
                    'minValue': 11.2,
                    'averageValue': 72.3338,
                    'medianValue': 76.3
                },
                'loadStatus': 'Completed',
                'dateProcessed': '2019-09-10T02:07:00Z'
            }],
            'nextPageLink':
            None,
            'count':
            306
        }

        m.get(self.van.connection.uri + 'scoreUpdates', json=json)

        expected = [
            'scoreUpdateId', 'loadStatus', 'dateProcessed', 'added',
            'averageValue', 'badValues', 'decreasedBy', 'duplicateRows',
            'increasedBy', 'matchPercent', 'matchedRows', 'maxValue',
            'medianValue', 'minValue', 'nulledOut', 'outOfRange', 'totalRows',
            'description', 'maxValue', 'minValue', 'name', 'origin', 'scoreId',
            'shortName', 'state'
        ]

        self.assertTrue(validate_list(expected, self.van.get_score_updates()))

    @requests_mock.Mocker()
    def test_get_score_update(self, m):

        score_update_id = 27892

        json = {
            "loadStatus": "Canceled",
            "updateStatistics": {
                "increasedBy": 1,
                "nulledOut": 1,
                "added": 0,
                "matchedRows": 4,
                "matchPercent": 100.0,
                "outOfRange": 0,
                "badValues": 1,
                "totalRows": 4,
                "maxValue": 30.0,
                "medianValue": 15.0,
                "minValue": 10.0,
                "duplicateRows": "null",
                "averageValue": 20.0,
                "decreasedBy": 2
            },
            "score": {
                "origin": "null",
                "scoreId": 2716,
                "name": "Democratic Party Support",
                "maxValue": 100.0,
                "minValue": 1.0,
                "state": "null",
                "shortName": "null",
                "description": "null"
            },
            "dateProcessed": "null",
            "scoreUpdateId": 27892
        }

        m.get(self.van.connection.uri + f'scoreUpdates/{score_update_id}',
              json=json)

        # expected = ['loadStatus', 'updateStatistics', 'score', 'dateProcessed', 'scoreUpdateId']

        self.assertEqual(json, self.van.get_score_update(score_update_id))

    @requests_mock.Mocker()
    def test_update_score_status(self, m):

        score_update_id = 27892

        m.patch(self.van.connection.uri +
                'scoreUpdates/{}'.format(score_update_id),
                status_code=204)

        # Test bad input
        self.assertRaises(ValueError, self.van.update_score_status,
                          score_update_id, 'not a thing.')

        # Test good input
        self.assertTrue(
            self.van.update_score_status(score_update_id, 'approved'))

    @requests_mock.Mocker()
    def test_upload_scores(self, m):

        # Mock Cloud Storage
        cloud_storage.post_file = mock.MagicMock()
        cloud_storage.post_file.return_value = 'https://box.com/my_file.zip'

        # Test uploading a job
        tbl = Table([['vanid', 'col'], ['1', '.5']])
        json = {'jobId': 9749}
        m.post(self.van.connection.uri + 'FileLoadingJobs',
               json=json,
               status_code=201)
        self.van.upload_scores(tbl, [{
            'score_id': 9999,
            'score_column': 'col'
        }],
                               url_type='S3')

    @requests_mock.Mocker()
    def test_create_file_load(self, m):

        file_name = 'test_scores.csv'
        file_url_good = 'http://tmc.org/test_scores.zip'
        # file_url_bad = 'http://tmc.org/test_scores'
        columns = ['vanid', 'score']
        id_column = 'vanid'
        id_type = 'VANID'
        score_id = 2716
        score_column = 'score'
        bad_delimiter = '*'

        json = {'jobId': 9749}

        m.post(self.van.connection.uri + 'FileLoadingJobs',
               json=json,
               status_code=201)

        # Test bad delimiter
        self.assertRaises(ValueError,
                          self.van.create_file_load,
                          file_name,
                          file_url_good,
                          columns,
                          id_column,
                          id_type,
                          score_id,
                          score_column,
                          delimiter=bad_delimiter)

        # Test good request
        self.assertEqual(
            json['jobId'],
            self.van.create_file_load(file_name, file_url_good, columns,
                                      id_column, id_type, score_id,
                                      score_column))
Exemplo n.º 16
0
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="EveryAction",
                       raise_for_status=False)
Exemplo n.º 17
0
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)
Exemplo n.º 18
0
class TestNGPVAN(unittest.TestCase):
    def setUp(self):

        self.van = VAN(os.environ['VAN_API_KEY'],
                       db="MyVoters",
                       raise_for_status=False)

    def tearDown(self):

        pass

    @requests_mock.Mocker()
    def test_get_canvass_responses_contact_types(self, m):

        json = {
            "name": "Auto Dial",
            "contactTypeId": 19,
            "channelTypeName": "Phone"
        }

        m.get(self.van.connection.uri + 'canvassResponses/contactTypes',
              json=json)

        assert_matching_tables(Table(json),
                               self.van.get_canvass_responses_contact_types())

    @requests_mock.Mocker()
    def test_get_canvass_responses_input_types(self, m):

        json = {"inputTypeId": 11, "name": "API"}
        m.get(self.van.connection.uri + 'canvassResponses/inputTypes',
              json=json)
        assert_matching_tables(Table(json),
                               self.van.get_canvass_responses_input_types())

    @requests_mock.Mocker()
    def test_get_canvass_responses_result_codes(self, m):

        json = {
            "shortName": "BZ",
            "resultCodeId": 18,
            "name": "Busy",
            "mediumName": "Busy"
        }

        m.get(self.van.connection.uri + 'canvassResponses/resultCodes',
              json=json)
        assert_matching_tables(Table(json),
                               self.van.get_canvass_responses_result_codes())

    @requests_mock.Mocker()
    def test_get_survey_questions(self, m):

        json = {
            u'count':
            67,
            u'items': [{
                "status":
                "Active",
                "responses": [{
                    "shortName": "1",
                    "surveyResponseId": 1288926,
                    "name": "1-Strong Walz",
                    "mediumName": "1"
                }, {
                    "shortName": "2",
                    "surveyResponseId": 1288928,
                    "name": "2-Lean Walz",
                    "mediumName": "2"
                }],
                "scriptQuestion":
                "Who do you support for Governor?",
                "name":
                "MN Governor Gen",
                "surveyQuestionId":
                311838,
                "mediumName":
                "MNGovG",
                "shortName":
                "MGG",
                "type":
                "Candidate",
                "cycle":
                2018
            }],
            u'nextPageLink':
            None
        }

        m.get(self.van.connection.uri + 'surveyQuestions', json=json)

        expected = [
            'status', 'responses', 'scriptQuestion', 'name',
            'surveyQuestionId', 'mediumName', 'shortName', 'type', 'cycle'
        ]

        self.assertTrue(
            validate_list(expected, self.van.get_survey_questions()))

    @requests_mock.Mocker()
    def test_get_supporter_groups(self, m):

        json = {
            "items": [
                {
                    "id": 12,
                    "name": "tmc",
                    "description": "A fun group."
                },
                {
                    "id": 13,
                    "name": "tmc",
                    "description": "A fun group."
                },
            ],
            "nextPageLink":
            None,
            "count":
            3
        }

        m.get(self.van.connection.uri + 'supporterGroups', json=json)

        ['id', 'name', 'description']

        self.van.get_supporter_groups()

    @requests_mock.Mocker()
    def test_get_supporter_group(self, m):

        json = {"id": 12, "name": "tmc", "description": "A fun group."}
        m.get(self.van.connection.uri + 'supporterGroups/12', json=json)

        # Test that columns are expected columns
        self.assertEqual(self.van.get_supporter_group(12), json)

    @requests_mock.Mocker()
    def test_delete_supporter_group(self, m):

        # Test good input
        good_supporter_group_id = 5
        good_ep = f'supporterGroups/{good_supporter_group_id}'
        m.delete(self.van.connection.uri + good_ep, status_code=204)
        self.van.delete_supporter_group(good_supporter_group_id)

        # Test bad input raises
        bad_supporter_group_id = 999
        # bad_vanid = 99999
        bad_ep = f'supporterGroups/{bad_supporter_group_id}'
        m.delete(self.van.connection.uri + bad_ep, status_code=404)
        self.assertRaises(HTTPError, self.van.delete_supporter_group,
                          bad_supporter_group_id)

    @requests_mock.Mocker()
    def test_add_person_supporter_group(self, m):

        # Test good input
        good_supporter_group_id = 5
        good_vanid = 12345
        good_uri = f'supporterGroups/{good_vanid}/people/{good_supporter_group_id}'
        m.put(self.van.connection.uri + good_uri, status_code=204)
        self.van.add_person_supporter_group(good_vanid,
                                            good_supporter_group_id)

        # Test bad input
        bad_supporter_group_id = 999
        bad_vanid = 99999
        bad_uri = f'supporterGroups/{bad_vanid}/people/{bad_supporter_group_id}'
        m.put(self.van.connection.uri + bad_uri, status_code=404)
        self.assertRaises(HTTPError, self.van.add_person_supporter_group,
                          bad_vanid, bad_supporter_group_id)

    @requests_mock.Mocker()
    def test_delete_person_supporter_group(self, m):

        # Test good input
        good_supporter_group_id = 5
        good_vanid = 12345
        good_ep = f'supporterGroups/{good_vanid}/people/{good_supporter_group_id}'
        m.delete(self.van.connection.uri + good_ep, status_code=204)
        self.van.delete_person_supporter_group(good_vanid,
                                               good_supporter_group_id)

        # Test bad input raises
        bad_supporter_group_id = 999
        bad_vanid = 99999
        bad_ep = f'supporterGroups/{bad_vanid}/people/{bad_supporter_group_id}'
        m.delete(self.van.connection.uri + bad_ep, status_code=404)
        self.assertRaises(HTTPError, self.van.delete_person_supporter_group,
                          bad_vanid, bad_supporter_group_id)