From fff263cc3b913547e21a2f06fce809d414040e9c Mon Sep 17 00:00:00 2001 From: Shantanu Dhiman Date: Thu, 28 Sep 2023 13:31:06 +0530 Subject: [PATCH] [TDL-23979] Fix the existing schema and discovery (#28) * Fixed discovery. * Schema changes for accounts stream. * Fixed accounts schema. * Fixed STREAM_CONFIG. * Fixed teams stream. * Added creatorId & updaterId in teams schema. * CHanges: 1. Fixed accounts, calls & teams schema. 2. Added phoneNumberId in STREAM_CONFIGS. * Fixed content categories schema. * Fixed events schema. * Fixed mailboxes schema. * Fixed mailings schema. * Fixed opportunities schema. * Fixed prospects schema. * Fixed sequences schema. * Fixed sequence_templates schema. * Fixed sequence_steps schema. * Fixed sequence_states schema. * Fixed tasks schema. * Fixed review comments. * Changes: 1) Fixed users schema. 2) Changed teams & sequenceTemplates streams to incremental. * Fixed sequence_steps schema and added fixture for tasks & events stream. * Removed redundant tasks stream from skip list. * Changes: 1) Making sequence_templates to full table as updatedAt is not filterable & sortable. * Fixed bookmarking. * Fixed discovery. * Schema changes for accounts stream. * Fixed accounts schema. * Fixed STREAM_CONFIG. * Fixed teams stream. * Added creatorId & updaterId in teams schema. * CHanges: 1. Fixed accounts, calls & teams schema. 2. Added phoneNumberId in STREAM_CONFIGS. * Fixed content categories schema. * Fixed events schema. * Fixed mailboxes schema. * Fixed mailings schema. * Fixed opportunities schema. * Fixed prospects schema. * Fixed sequences schema. * Fixed sequence_templates schema. * Fixed sequence_steps schema. * Fixed sequence_states schema. * Fixed tasks schema. * Fixed review comments. * Changes: 1) Fixed users schema. 2) Changed teams & sequenceTemplates streams to incremental. * Fixed sequence_steps schema and added fixture for tasks & events stream. * Removed redundant tasks stream from skip list. * Changes: 1) Making sequence_templates to full table as updatedAt is not filterable & sortable. * Fixed bookmarking. * Fixed bookmarking logic. * sort the streams while storing in catalog file * Fixed sync_endpoint test by modifying bookmark value. * Changes: 1) Added logger for currently syncing. 2) Fixed formatting for all unit tests. * [TDL-20774] Integration tests (#27) * Added replication keys in catalog during discovery. * Added base test suite & discovery test. * Added new lines at the end of test files. * Changed teams & sequence_templates from full to incremental. * Added automatic and all fields tests. * Fixed MISSING_FIELDS & streams_to_exclude in all fields test. * Fixed MISSING_FIELDS in automatic fields test. * Changes: 1) Added new pagination test. 2) Changed docstring for all fields test. * Added start date test. * Changed sequence_templates stream to full table in base.py * Changes: 1) Added new bookmark test. 2) Fixed a field in automatic fields test. * Added new Sync Canary Test. * Fixed formatting for all integration tests. * Changes: 1) Fixed boomark & start date test. 2) Added new interrupted sync test. * Fixed names for Bookmark & Start date test. * Fixed bookmark & start date tests. * fix bookmark, interrupted sync and start date tests * add integration tests in circle ci config * update tap-tester image version in cicle ci config * Fix integration tests * Fix all fields test and minor fixes * fix bookmark test review --------- Co-authored-by: RushiT0122 --------- Co-authored-by: Sourabh Gandhi Co-authored-by: RushiT0122 --- .circleci/config.yml | 9 +- tap_outreach/discover.py | 6 +- tap_outreach/schemas/accounts.json | 785 ++++++++++++++++++- tap_outreach/schemas/calls.json | 39 +- tap_outreach/schemas/content_categories.json | 14 +- tap_outreach/schemas/events.json | 36 +- tap_outreach/schemas/mailboxes.json | 24 +- tap_outreach/schemas/mailings.json | 25 +- tap_outreach/schemas/opportunities.json | 342 ++++++++ tap_outreach/schemas/prospects.json | 756 +++++++++++++++--- tap_outreach/schemas/sequence_states.json | 20 +- tap_outreach/schemas/sequence_steps.json | 14 +- tap_outreach/schemas/sequence_templates.json | 12 + tap_outreach/schemas/sequences.json | 16 +- tap_outreach/schemas/tasks.json | 12 + tap_outreach/schemas/teams.json | 32 +- tap_outreach/schemas/users.json | 151 +++- tap_outreach/sync.py | 73 +- tests/base.py | 170 ++++ tests/test_all_fields.py | 18 + tests/test_automatic_fields.py | 20 + tests/test_bookmark.py | 55 ++ tests/test_discovery.py | 13 + tests/test_interrupted_sync.py | 35 + tests/test_pagination.py | 17 + tests/test_start_date.py | 26 + tests/test_sync_canary.py | 14 + tests/unittests/test_exception_handling.py | 42 +- tests/unittests/test_request_timeout.py | 61 +- tests/unittests/test_retry_logic.py | 23 +- tests/unittests/test_sync_endpoint.py | 2 +- 31 files changed, 2609 insertions(+), 253 deletions(-) create mode 100644 tests/base.py create mode 100644 tests/test_all_fields.py create mode 100644 tests/test_automatic_fields.py create mode 100644 tests/test_bookmark.py create mode 100644 tests/test_discovery.py create mode 100644 tests/test_interrupted_sync.py create mode 100644 tests/test_pagination.py create mode 100644 tests/test_start_date.py create mode 100644 tests/test_sync_canary.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ca1792..2578f56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ orbs: jobs: build: docker: - - image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:tap-tester-v4 + - image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:stitch-tap-tester steps: - checkout - run: @@ -33,6 +33,13 @@ jobs: nosetests --with-coverage --cover-erase --cover-package=tap_outreach --cover-html-dir=htmlcov tests/unittests coverage html when: always + - run: + name: 'Integration Tests' + command: | + aws s3 cp s3://com-stitchdata-dev-deployment-assets/environments/tap-tester/tap_tester_sandbox dev_env.sh + source dev_env.sh + source /usr/local/share/virtualenvs/tap-tester/bin/activate + run-test --tap=tap-outreach tests - store_test_results: path: test_output/report.xml - store_artifacts: diff --git a/tap_outreach/discover.py b/tap_outreach/discover.py index 4a2fe3a..7ff6a90 100644 --- a/tap_outreach/discover.py +++ b/tap_outreach/discover.py @@ -15,8 +15,8 @@ def get_schemas(): schemas_metadata = {} schemas_path = get_abs_path('schemas') - file_names = [f for f in os.listdir(schemas_path) - if os.path.isfile(os.path.join(schemas_path, f))] + file_names = sorted([f for f in os.listdir(schemas_path) + if os.path.isfile(os.path.join(schemas_path, f))]) for file_name in file_names: stream_name = file_name[:-5] @@ -28,9 +28,11 @@ def get_schemas(): singer.resolve_schema_references(schema, refs) replication = STREAM_CONFIGS[stream_name]['replication'] + replication_key = STREAM_CONFIGS[stream_name].get('filter_field', None) meta = metadata.get_standard_metadata( schema=schema, key_properties=['id'], + valid_replication_keys=[replication_key] if replication_key else [], replication_method='FULL_TABLE' if replication == 'full' else replication.upper() ) diff --git a/tap_outreach/schemas/accounts.json b/tap_outreach/schemas/accounts.json index 94609ff..f13989e 100644 --- a/tap_outreach/schemas/accounts.json +++ b/tap_outreach/schemas/accounts.json @@ -7,20 +7,19 @@ "integer" ] }, - "companyType": { + "buyerIntentScore": { "type": [ "null", - "string" + "number" ] }, - "createdAt": { + "companyType": { "type": [ "null", "string" - ], - "format": "date-time" + ] }, - "updatedAt": { + "createdAt": { "type": [ "null", "string" @@ -231,102 +230,818 @@ "string" ] }, - "customId": { + "custom35": { "type": [ "null", "string" ] }, - "description": { + "custom36": { "type": [ "null", "string" ] }, - "domain": { + "custom37": { "type": [ "null", "string" ] }, - "externalSource": { + "custom38": { "type": [ "null", "string" ] }, - "followers": { + "custom39": { "type": [ "null", - "integer" + "string" ] }, - "foundedAt": { + "custom40": { "type": [ "null", "string" - ], - "format": "date-time" + ] }, - "industry": { + "custom41": { "type": [ "null", "string" ] }, - "linkedInEmployees": { + "custom42": { "type": [ "null", - "integer" + "string" ] }, - "linkedInUrl": { + "custom43": { "type": [ "null", "string" ] }, - "locality": { + "custom44": { "type": [ "null", "string" ] }, - "name": { + "custom45": { "type": [ "null", "string" ] }, - "named": { + "custom46": { "type": [ "null", - "boolean" + "string" ] }, - "naturalName": { + "custom47": { "type": [ "null", "string" ] }, - "numberOfEmployees": { + "custom48": { "type": [ "null", - "integer" + "string" ] }, - "tags": { + "custom49": { "type": [ "null", - "array" - ], - "items": { - "type": [ - "null", - "string" - ] - } + "string" + ] + }, + "custom50": { + "type": [ + "null", + "string" + ] + }, + "custom51": { + "type": [ + "null", + "string" + ] + }, + "custom52": { + "type": [ + "null", + "string" + ] + }, + "custom53": { + "type": [ + "null", + "string" + ] + }, + "custom54": { + "type": [ + "null", + "string" + ] + }, + "custom55": { + "type": [ + "null", + "string" + ] + }, + "custom56": { + "type": [ + "null", + "string" + ] + }, + "custom57": { + "type": [ + "null", + "string" + ] + }, + "custom58": { + "type": [ + "null", + "string" + ] + }, + "custom59": { + "type": [ + "null", + "string" + ] + }, + "custom60": { + "type": [ + "null", + "string" + ] + }, + "custom61": { + "type": [ + "null", + "string" + ] + }, + "custom62": { + "type": [ + "null", + "string" + ] + }, + "custom63": { + "type": [ + "null", + "string" + ] + }, + "custom64": { + "type": [ + "null", + "string" + ] + }, + "custom65": { + "type": [ + "null", + "string" + ] + }, + "custom66": { + "type": [ + "null", + "string" + ] + }, + "custom67": { + "type": [ + "null", + "string" + ] + }, + "custom68": { + "type": [ + "null", + "string" + ] + }, + "custom69": { + "type": [ + "null", + "string" + ] + }, + "custom70": { + "type": [ + "null", + "string" + ] + }, + "custom71": { + "type": [ + "null", + "string" + ] + }, + "custom72": { + "type": [ + "null", + "string" + ] + }, + "custom73": { + "type": [ + "null", + "string" + ] + }, + "custom74": { + "type": [ + "null", + "string" + ] + }, + "custom75": { + "type": [ + "null", + "string" + ] + }, + "custom76": { + "type": [ + "null", + "string" + ] + }, + "custom77": { + "type": [ + "null", + "string" + ] + }, + "custom78": { + "type": [ + "null", + "string" + ] + }, + "custom79": { + "type": [ + "null", + "string" + ] + }, + "custom80": { + "type": [ + "null", + "string" + ] + }, + "custom81": { + "type": [ + "null", + "string" + ] + }, + "custom82": { + "type": [ + "null", + "string" + ] + }, + "custom83": { + "type": [ + "null", + "string" + ] + }, + "custom84": { + "type": [ + "null", + "string" + ] + }, + "custom85": { + "type": [ + "null", + "string" + ] + }, + "custom86": { + "type": [ + "null", + "string" + ] + }, + "custom87": { + "type": [ + "null", + "string" + ] + }, + "custom88": { + "type": [ + "null", + "string" + ] + }, + "custom89": { + "type": [ + "null", + "string" + ] + }, + "custom90": { + "type": [ + "null", + "string" + ] + }, + "custom91": { + "type": [ + "null", + "string" + ] + }, + "custom92": { + "type": [ + "null", + "string" + ] + }, + "custom93": { + "type": [ + "null", + "string" + ] + }, + "custom94": { + "type": [ + "null", + "string" + ] + }, + "custom95": { + "type": [ + "null", + "string" + ] + }, + "custom96": { + "type": [ + "null", + "string" + ] + }, + "custom97": { + "type": [ + "null", + "string" + ] + }, + "custom98": { + "type": [ + "null", + "string" + ] + }, + "custom99": { + "type": [ + "null", + "string" + ] + }, + "custom100": { + "type": [ + "null", + "string" + ] + }, + "custom101": { + "type": [ + "null", + "string" + ] + }, + "custom102": { + "type": [ + "null", + "string" + ] + }, + "custom103": { + "type": [ + "null", + "string" + ] + }, + "custom104": { + "type": [ + "null", + "string" + ] + }, + "custom105": { + "type": [ + "null", + "string" + ] + }, + "custom106": { + "type": [ + "null", + "string" + ] + }, + "custom107": { + "type": [ + "null", + "string" + ] + }, + "custom108": { + "type": [ + "null", + "string" + ] + }, + "custom109": { + "type": [ + "null", + "string" + ] + }, + "custom110": { + "type": [ + "null", + "string" + ] + }, + "custom111": { + "type": [ + "null", + "string" + ] + }, + "custom112": { + "type": [ + "null", + "string" + ] + }, + "custom113": { + "type": [ + "null", + "string" + ] + }, + "custom114": { + "type": [ + "null", + "string" + ] + }, + "custom115": { + "type": [ + "null", + "string" + ] + }, + "custom116": { + "type": [ + "null", + "string" + ] + }, + "custom117": { + "type": [ + "null", + "string" + ] + }, + "custom118": { + "type": [ + "null", + "string" + ] + }, + "custom119": { + "type": [ + "null", + "string" + ] + }, + "custom120": { + "type": [ + "null", + "string" + ] + }, + "custom121": { + "type": [ + "null", + "string" + ] + }, + "custom122": { + "type": [ + "null", + "string" + ] + }, + "custom123": { + "type": [ + "null", + "string" + ] + }, + "custom124": { + "type": [ + "null", + "string" + ] + }, + "custom125": { + "type": [ + "null", + "string" + ] + }, + "custom126": { + "type": [ + "null", + "string" + ] + }, + "custom127": { + "type": [ + "null", + "string" + ] + }, + "custom128": { + "type": [ + "null", + "string" + ] + }, + "custom129": { + "type": [ + "null", + "string" + ] + }, + "custom130": { + "type": [ + "null", + "string" + ] + }, + "custom131": { + "type": [ + "null", + "string" + ] + }, + "custom132": { + "type": [ + "null", + "string" + ] + }, + "custom133": { + "type": [ + "null", + "string" + ] + }, + "custom134": { + "type": [ + "null", + "string" + ] + }, + "custom135": { + "type": [ + "null", + "string" + ] + }, + "custom136": { + "type": [ + "null", + "string" + ] + }, + "custom137": { + "type": [ + "null", + "string" + ] + }, + "custom138": { + "type": [ + "null", + "string" + ] + }, + "custom139": { + "type": [ + "null", + "string" + ] + }, + "custom140": { + "type": [ + "null", + "string" + ] + }, + "custom141": { + "type": [ + "null", + "string" + ] + }, + "custom142": { + "type": [ + "null", + "string" + ] + }, + "custom143": { + "type": [ + "null", + "string" + ] + }, + "custom144": { + "type": [ + "null", + "string" + ] + }, + "custom145": { + "type": [ + "null", + "string" + ] + }, + "custom146": { + "type": [ + "null", + "string" + ] + }, + "custom147": { + "type": [ + "null", + "string" + ] + }, + "custom148": { + "type": [ + "null", + "string" + ] + }, + "custom149": { + "type": [ + "null", + "string" + ] + }, + "custom150": { + "type": [ + "null", + "string" + ] + }, + "customId": { + "type": [ + "null", + "string" + ] + }, + "description": { + "type": [ + "null", + "string" + ] + }, + "domain": { + "type": [ + "null", + "string" + ] + }, + "externalSource": { + "type": [ + "null", + "string" + ] + }, + "followers": { + "type": [ + "null", + "integer" + ] + }, + "foundedAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, + "industry": { + "type": [ + "null", + "string" + ] + }, + "linkedInEmployees": { + "type": [ + "null", + "integer" + ] + }, + "linkedInUrl": { + "type": [ + "null", + "string" + ] + }, + "locality": { + "type": [ + "null", + "string" + ] + }, + "name": { + "type": [ + "null", + "string" + ] + }, + "named": { + "type": [ + "null", + "boolean" + ] + }, + "naturalName": { + "type": [ + "null", + "string" + ] + }, + "numberOfEmployees": { + "type": [ + "null", + "integer" + ] + }, + "sharingTeamId": { + "type": [ + "null", + "string" + ] + }, + "tags": { + "type": [ + "null", + "array" + ], + "items": { + "type": [ + "null", + "string" + ] + } + }, + "touchedAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, + "updatedAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" }, "websiteUrl": { "type": [ diff --git a/tap_outreach/schemas/calls.json b/tap_outreach/schemas/calls.json index 4ab2750..5262475 100644 --- a/tap_outreach/schemas/calls.json +++ b/tap_outreach/schemas/calls.json @@ -28,7 +28,7 @@ ], "format": "date-time" }, - "updatedAt": { + "dialedAt": { "type": [ "null", "string" @@ -41,6 +41,12 @@ "string" ] }, + "externalVendor": { + "type": [ + "null", + "string" + ] + }, "from": { "type": [ "null", @@ -78,6 +84,12 @@ "string" ] }, + "shouldRecordCall": { + "type": [ + "null", + "boolean" + ] + }, "state": { "type": [ "null", @@ -109,12 +121,31 @@ "string" ] }, + "uid": { + "type": [ + "null", + "string" + ] + }, + "updatedAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, "userCallType": { "type": [ "null", "string" ] }, + "vendorCallId": { + "type": [ + "null", + "string" + ] + }, "voicemailRecordingUrl": { "type": [ "null", @@ -139,6 +170,12 @@ "integer" ] }, + "phoneNumberId": { + "type": [ + "null", + "integer" + ] + }, "prospectId": { "type": [ "null", diff --git a/tap_outreach/schemas/content_categories.json b/tap_outreach/schemas/content_categories.json index 0a8ca28..f370409 100644 --- a/tap_outreach/schemas/content_categories.json +++ b/tap_outreach/schemas/content_categories.json @@ -10,22 +10,22 @@ "allowSequences": { "type": [ "null", - "string" + "boolean" ] }, "allowSnippets": { "type": [ "null", - "string" + "boolean" ] }, "allowTemplates": { "type": [ "null", - "string" + "boolean" ] }, - "name": { + "color": { "type": [ "null", "string" @@ -38,6 +38,12 @@ ], "format": "date-time" }, + "name": { + "type": [ + "null", + "string" + ] + }, "updatedAt": { "type": [ "null", diff --git a/tap_outreach/schemas/events.json b/tap_outreach/schemas/events.json index b8353db..bc4acdd 100644 --- a/tap_outreach/schemas/events.json +++ b/tap_outreach/schemas/events.json @@ -33,12 +33,6 @@ "string" ] }, - "mailingId": { - "type": [ - "null", - "integer" - ] - }, "name": { "type": [ "null", @@ -81,12 +75,42 @@ "boolean" ] }, + "accountId": { + "type": [ + "null", + "integer" + ] + }, + "callId": { + "type": [ + "null", + "integer" + ] + }, + "mailingId": { + "type": [ + "null", + "integer" + ] + }, + "opportunityId": { + "type": [ + "null", + "integer" + ] + }, "prospectId": { "type": [ "null", "integer" ] }, + "taskId": { + "type": [ + "null", + "integer" + ] + }, "userId": { "type": [ "null", diff --git a/tap_outreach/schemas/mailboxes.json b/tap_outreach/schemas/mailboxes.json index 3811e97..6503f22 100644 --- a/tap_outreach/schemas/mailboxes.json +++ b/tap_outreach/schemas/mailboxes.json @@ -32,6 +32,12 @@ "string" ] }, + "emailHash": { + "type": [ + "null", + "string" + ] + }, "emailProvider": { "type": [ "null", @@ -190,12 +196,6 @@ "string" ] }, - "smtpHost": { - "type": [ - "null", - "string" - ] - }, "smtpPort": { "type": [ "null", @@ -284,18 +284,6 @@ "string" ] }, - "validateSend": { - "type": [ - "null", - "boolean" - ] - }, - "validateSync": { - "type": [ - "null", - "boolean" - ] - }, "creatorId": { "type": [ "null", diff --git a/tap_outreach/schemas/mailings.json b/tap_outreach/schemas/mailings.json index 1f50649..452e23c 100644 --- a/tap_outreach/schemas/mailings.json +++ b/tap_outreach/schemas/mailings.json @@ -46,13 +46,6 @@ ], "format": "date-time" }, - "updatedAt": { - "type": [ - "null", - "string" - ], - "format": "date-time" - }, "deliveredAt": { "type": [ "null", @@ -151,8 +144,14 @@ "references": { "type": [ "null", - "string" - ] + "array" + ], + "items": { + "type": [ + "null", + "string" + ] + } }, "repliedAt": { "type": [ @@ -232,7 +231,7 @@ ], "format": "date-time" }, - "calendarId": { + "followUpSequenceId": { "type": [ "null", "integer" @@ -285,6 +284,12 @@ "null", "integer" ] + }, + "userId": { + "type": [ + "null", + "integer" + ] } } } \ No newline at end of file diff --git a/tap_outreach/schemas/opportunities.json b/tap_outreach/schemas/opportunities.json index 79dc999..e21c66e 100644 --- a/tap_outreach/schemas/opportunities.json +++ b/tap_outreach/schemas/opportunities.json @@ -27,6 +27,12 @@ ], "format": "date-time" }, + "currencyType": { + "type": [ + "null", + "string" + ] + }, "custom1": { "type": [ "null", @@ -627,6 +633,306 @@ "string" ] }, + "custom101": { + "type": [ + "null", + "string" + ] + }, + "custom102": { + "type": [ + "null", + "string" + ] + }, + "custom103": { + "type": [ + "null", + "string" + ] + }, + "custom104": { + "type": [ + "null", + "string" + ] + }, + "custom105": { + "type": [ + "null", + "string" + ] + }, + "custom106": { + "type": [ + "null", + "string" + ] + }, + "custom107": { + "type": [ + "null", + "string" + ] + }, + "custom108": { + "type": [ + "null", + "string" + ] + }, + "custom109": { + "type": [ + "null", + "string" + ] + }, + "custom110": { + "type": [ + "null", + "string" + ] + }, + "custom111": { + "type": [ + "null", + "string" + ] + }, + "custom112": { + "type": [ + "null", + "string" + ] + }, + "custom113": { + "type": [ + "null", + "string" + ] + }, + "custom114": { + "type": [ + "null", + "string" + ] + }, + "custom115": { + "type": [ + "null", + "string" + ] + }, + "custom116": { + "type": [ + "null", + "string" + ] + }, + "custom117": { + "type": [ + "null", + "string" + ] + }, + "custom118": { + "type": [ + "null", + "string" + ] + }, + "custom119": { + "type": [ + "null", + "string" + ] + }, + "custom120": { + "type": [ + "null", + "string" + ] + }, + "custom121": { + "type": [ + "null", + "string" + ] + }, + "custom122": { + "type": [ + "null", + "string" + ] + }, + "custom123": { + "type": [ + "null", + "string" + ] + }, + "custom124": { + "type": [ + "null", + "string" + ] + }, + "custom125": { + "type": [ + "null", + "string" + ] + }, + "custom126": { + "type": [ + "null", + "string" + ] + }, + "custom127": { + "type": [ + "null", + "string" + ] + }, + "custom128": { + "type": [ + "null", + "string" + ] + }, + "custom129": { + "type": [ + "null", + "string" + ] + }, + "custom130": { + "type": [ + "null", + "string" + ] + }, + "custom131": { + "type": [ + "null", + "string" + ] + }, + "custom132": { + "type": [ + "null", + "string" + ] + }, + "custom133": { + "type": [ + "null", + "string" + ] + }, + "custom134": { + "type": [ + "null", + "string" + ] + }, + "custom135": { + "type": [ + "null", + "string" + ] + }, + "custom136": { + "type": [ + "null", + "string" + ] + }, + "custom137": { + "type": [ + "null", + "string" + ] + }, + "custom138": { + "type": [ + "null", + "string" + ] + }, + "custom139": { + "type": [ + "null", + "string" + ] + }, + "custom140": { + "type": [ + "null", + "string" + ] + }, + "custom141": { + "type": [ + "null", + "string" + ] + }, + "custom142": { + "type": [ + "null", + "string" + ] + }, + "custom143": { + "type": [ + "null", + "string" + ] + }, + "custom144": { + "type": [ + "null", + "string" + ] + }, + "custom145": { + "type": [ + "null", + "string" + ] + }, + "custom146": { + "type": [ + "null", + "string" + ] + }, + "custom147": { + "type": [ + "null", + "string" + ] + }, + "custom148": { + "type": [ + "null", + "string" + ] + }, + "custom149": { + "type": [ + "null", + "string" + ] + }, + "custom150": { + "type": [ + "null", + "string" + ] + }, "description": { "type": [ "null", @@ -640,6 +946,24 @@ ], "format": "date-time" }, + "mapLink": { + "type": [ + "null", + "string" + ] + }, + "mapNextSteps": { + "type": [ + "null", + "string" + ] + }, + "mapStatus": { + "type": [ + "null", + "string" + ] + }, "name": { "type": [ "null", @@ -670,6 +994,12 @@ "string" ] }, + "sharingTeamId": { + "type": [ + "null", + "string" + ] + }, "tags": { "type": [ "null", @@ -719,6 +1049,18 @@ "null", "integer" ] + }, + "stageId": { + "type": [ + "null", + "integer" + ] + }, + "updaterId": { + "type": [ + "null", + "integer" + ] } } } \ No newline at end of file diff --git a/tap_outreach/schemas/prospects.json b/tap_outreach/schemas/prospects.json index 089f747..57f7dcd 100644 --- a/tap_outreach/schemas/prospects.json +++ b/tap_outreach/schemas/prospects.json @@ -94,354 +94,930 @@ "integer" ] }, + "company": { + "type": [ + "null", + "string" + ] + }, "contactHistogram": { "type": [ "null", - "array" - ], - "items": { - "type": [ - "array" - ], - "items": { - "type": [ - "integer" - ] - } - } + "array" + ], + "items": { + "type": [ + "array" + ], + "items": { + "type": [ + "integer" + ] + } + } + }, + "createdAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, + "custom1": { + "type": [ + "null", + "string" + ] + }, + "custom2": { + "type": [ + "null", + "string" + ] + }, + "custom3": { + "type": [ + "null", + "string" + ] + }, + "custom4": { + "type": [ + "null", + "string" + ] + }, + "custom5": { + "type": [ + "null", + "string" + ] + }, + "custom6": { + "type": [ + "null", + "string" + ] + }, + "custom7": { + "type": [ + "null", + "string" + ] + }, + "custom8": { + "type": [ + "null", + "string" + ] + }, + "custom9": { + "type": [ + "null", + "string" + ] + }, + "custom10": { + "type": [ + "null", + "string" + ] + }, + "custom11": { + "type": [ + "null", + "string" + ] + }, + "custom12": { + "type": [ + "null", + "string" + ] + }, + "custom13": { + "type": [ + "null", + "string" + ] + }, + "custom14": { + "type": [ + "null", + "string" + ] + }, + "custom15": { + "type": [ + "null", + "string" + ] + }, + "custom16": { + "type": [ + "null", + "string" + ] + }, + "custom17": { + "type": [ + "null", + "string" + ] + }, + "custom18": { + "type": [ + "null", + "string" + ] + }, + "custom19": { + "type": [ + "null", + "string" + ] + }, + "custom20": { + "type": [ + "null", + "string" + ] + }, + "custom21": { + "type": [ + "null", + "string" + ] + }, + "custom22": { + "type": [ + "null", + "string" + ] + }, + "custom23": { + "type": [ + "null", + "string" + ] + }, + "custom24": { + "type": [ + "null", + "string" + ] + }, + "custom25": { + "type": [ + "null", + "string" + ] + }, + "custom26": { + "type": [ + "null", + "string" + ] + }, + "custom27": { + "type": [ + "null", + "string" + ] + }, + "custom28": { + "type": [ + "null", + "string" + ] + }, + "custom29": { + "type": [ + "null", + "string" + ] + }, + "custom30": { + "type": [ + "null", + "string" + ] + }, + "custom31": { + "type": [ + "null", + "string" + ] + }, + "custom32": { + "type": [ + "null", + "string" + ] + }, + "custom33": { + "type": [ + "null", + "string" + ] + }, + "custom34": { + "type": [ + "null", + "string" + ] + }, + "custom35": { + "type": [ + "null", + "string" + ] + }, + "custom36": { + "type": [ + "null", + "string" + ] + }, + "custom37": { + "type": [ + "null", + "string" + ] + }, + "custom38": { + "type": [ + "null", + "string" + ] + }, + "custom39": { + "type": [ + "null", + "string" + ] + }, + "custom40": { + "type": [ + "null", + "string" + ] + }, + "custom41": { + "type": [ + "null", + "string" + ] + }, + "custom42": { + "type": [ + "null", + "string" + ] + }, + "custom43": { + "type": [ + "null", + "string" + ] + }, + "custom44": { + "type": [ + "null", + "string" + ] + }, + "custom45": { + "type": [ + "null", + "string" + ] + }, + "custom46": { + "type": [ + "null", + "string" + ] + }, + "custom47": { + "type": [ + "null", + "string" + ] + }, + "custom48": { + "type": [ + "null", + "string" + ] + }, + "custom49": { + "type": [ + "null", + "string" + ] + }, + "custom50": { + "type": [ + "null", + "string" + ] + }, + "custom51": { + "type": [ + "null", + "string" + ] + }, + "custom52": { + "type": [ + "null", + "string" + ] + }, + "custom53": { + "type": [ + "null", + "string" + ] + }, + "custom54": { + "type": [ + "null", + "string" + ] + }, + "custom55": { + "type": [ + "null", + "string" + ] + }, + "custom56": { + "type": [ + "null", + "string" + ] + }, + "custom57": { + "type": [ + "null", + "string" + ] + }, + "custom58": { + "type": [ + "null", + "string" + ] + }, + "custom59": { + "type": [ + "null", + "string" + ] + }, + "custom60": { + "type": [ + "null", + "string" + ] + }, + "custom61": { + "type": [ + "null", + "string" + ] + }, + "custom62": { + "type": [ + "null", + "string" + ] + }, + "custom63": { + "type": [ + "null", + "string" + ] + }, + "custom64": { + "type": [ + "null", + "string" + ] + }, + "custom65": { + "type": [ + "null", + "string" + ] }, - "createdAt": { + "custom66": { "type": [ "null", "string" - ], - "format": "date-time" + ] }, - "custom1": { + "custom67": { "type": [ "null", "string" ] }, - "custom2": { + "custom68": { "type": [ "null", "string" ] }, - "custom3": { + "custom69": { "type": [ "null", "string" ] }, - "custom4": { + "custom70": { "type": [ "null", "string" ] }, - "custom5": { + "custom71": { "type": [ "null", "string" ] }, - "custom6": { + "custom72": { "type": [ "null", "string" ] }, - "custom7": { + "custom73": { "type": [ "null", "string" ] }, - "custom8": { + "custom74": { "type": [ "null", "string" ] }, - "custom9": { + "custom75": { "type": [ "null", "string" ] }, - "custom10": { + "custom76": { "type": [ "null", "string" ] }, - "custom11": { + "custom77": { "type": [ "null", "string" ] }, - "custom12": { + "custom78": { "type": [ "null", "string" ] }, - "custom13": { + "custom79": { "type": [ "null", "string" ] }, - "custom14": { + "custom80": { "type": [ "null", "string" ] }, - "custom15": { + "custom81": { "type": [ "null", "string" ] }, - "custom16": { + "custom82": { "type": [ "null", "string" ] }, - "custom17": { + "custom83": { "type": [ "null", "string" ] }, - "custom18": { + "custom84": { "type": [ "null", "string" ] }, - "custom19": { + "custom85": { "type": [ "null", "string" ] }, - "custom20": { + "custom86": { "type": [ "null", "string" ] }, - "custom21": { + "custom87": { "type": [ "null", "string" ] }, - "custom22": { + "custom88": { "type": [ "null", "string" ] }, - "custom23": { + "custom89": { "type": [ "null", "string" ] }, - "custom24": { + "custom90": { "type": [ "null", "string" ] }, - "custom25": { + "custom91": { "type": [ "null", "string" ] }, - "custom26": { + "custom92": { "type": [ "null", "string" ] }, - "custom27": { + "custom93": { "type": [ "null", "string" ] }, - "custom28": { + "custom94": { "type": [ "null", "string" ] }, - "custom29": { + "custom95": { "type": [ "null", "string" ] }, - "custom30": { + "custom96": { "type": [ "null", "string" ] }, - "custom31": { + "custom97": { "type": [ "null", "string" ] }, - "custom32": { + "custom98": { "type": [ "null", "string" ] }, - "custom33": { + "custom99": { "type": [ "null", "string" ] }, - "custom34": { + "custom100": { "type": [ "null", "string" ] }, - "custom35": { + "custom101": { "type": [ "null", "string" ] }, - "custom36": { + "custom102": { "type": [ "null", "string" ] }, - "custom37": { + "custom103": { "type": [ "null", "string" ] }, - "custom38": { + "custom104": { "type": [ "null", "string" ] }, - "custom39": { + "custom105": { "type": [ "null", "string" ] }, - "custom40": { + "custom106": { "type": [ "null", "string" ] }, - "custom41": { + "custom107": { "type": [ "null", "string" ] }, - "custom42": { + "custom108": { "type": [ "null", "string" ] }, - "custom43": { + "custom109": { "type": [ "null", "string" ] }, - "custom44": { + "custom110": { "type": [ "null", "string" ] }, - "custom45": { + "custom111": { "type": [ "null", "string" ] }, - "custom46": { + "custom112": { "type": [ "null", "string" ] }, - "custom47": { + "custom113": { "type": [ "null", "string" ] }, - "custom48": { + "custom114": { "type": [ "null", "string" ] }, - "custom49": { + "custom115": { "type": [ "null", "string" ] }, - "custom50": { + "custom116": { "type": [ "null", "string" ] }, - "custom51": { + "custom117": { "type": [ "null", "string" ] }, - "custom52": { + "custom118": { "type": [ "null", "string" ] }, - "custom53": { + "custom119": { "type": [ "null", "string" ] }, - "custom54": { + "custom120": { "type": [ "null", "string" ] }, - "custom55": { + "custom121": { + "type": [ + "null", + "string" + ] + }, + "custom122": { + "type": [ + "null", + "string" + ] + }, + "custom123": { + "type": [ + "null", + "string" + ] + }, + "custom124": { + "type": [ + "null", + "string" + ] + }, + "custom125": { + "type": [ + "null", + "string" + ] + }, + "custom126": { + "type": [ + "null", + "string" + ] + }, + "custom127": { + "type": [ + "null", + "string" + ] + }, + "custom128": { + "type": [ + "null", + "string" + ] + }, + "custom129": { + "type": [ + "null", + "string" + ] + }, + "custom130": { + "type": [ + "null", + "string" + ] + }, + "custom131": { + "type": [ + "null", + "string" + ] + }, + "custom132": { + "type": [ + "null", + "string" + ] + }, + "custom133": { + "type": [ + "null", + "string" + ] + }, + "custom134": { + "type": [ + "null", + "string" + ] + }, + "custom135": { + "type": [ + "null", + "string" + ] + }, + "custom136": { + "type": [ + "null", + "string" + ] + }, + "custom137": { + "type": [ + "null", + "string" + ] + }, + "custom138": { + "type": [ + "null", + "string" + ] + }, + "custom139": { + "type": [ + "null", + "string" + ] + }, + "custom140": { + "type": [ + "null", + "string" + ] + }, + "custom141": { + "type": [ + "null", + "string" + ] + }, + "custom142": { + "type": [ + "null", + "string" + ] + }, + "custom143": { + "type": [ + "null", + "string" + ] + }, + "custom144": { + "type": [ + "null", + "string" + ] + }, + "custom145": { + "type": [ + "null", + "string" + ] + }, + "custom146": { + "type": [ + "null", + "string" + ] + }, + "custom147": { + "type": [ + "null", + "string" + ] + }, + "custom148": { + "type": [ + "null", + "string" + ] + }, + "custom149": { + "type": [ + "null", + "string" + ] + }, + "custom150": { "type": [ "null", "string" @@ -574,8 +1150,14 @@ "homePhones": { "type": [ "null", - "string" - ] + "array" + ], + "items": { + "type": [ + "null", + "string" + ] + } }, "jobStartDate": { "type": [ @@ -726,26 +1308,13 @@ "score": { "type": [ "null", - "integer" - ] - }, - "smsOptStatus": { - "type": [ - "null", - "string" + "number" ] }, - "smsOptedAt": { + "sharingTeamId": { "type": [ "null", "string" - ], - "format": "date-time" - }, - "smsOptedOut": { - "type": [ - "null", - "boolean" ] }, "source": { @@ -815,6 +1384,13 @@ ], "format": "date-time" }, + "trashedAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, "twitterUrl": { "type": [ "null", @@ -888,12 +1464,6 @@ "integer" ] }, - "defaultPluginMappingId": { - "type": [ - "null", - "integer" - ] - }, "ownerId": { "type": [ "null", diff --git a/tap_outreach/schemas/sequence_states.json b/tap_outreach/schemas/sequence_states.json index a592ca5..9130f32 100644 --- a/tap_outreach/schemas/sequence_states.json +++ b/tap_outreach/schemas/sequence_states.json @@ -64,7 +64,7 @@ "integer" ] }, - "naturalReplyCount": { + "neutralReplyCount": { "type": [ "null", "integer" @@ -145,6 +145,18 @@ "integer" ] }, + "mailboxId": { + "type": [ + "null", + "integer" + ] + }, + "opportunityId": { + "type": [ + "null", + "integer" + ] + }, "prospectId": { "type": [ "null", @@ -156,6 +168,12 @@ "null", "integer" ] + }, + "sequenceStepId": { + "type": [ + "null", + "integer" + ] } } } \ No newline at end of file diff --git a/tap_outreach/schemas/sequence_steps.json b/tap_outreach/schemas/sequence_steps.json index 19d7cde..d1beed9 100644 --- a/tap_outreach/schemas/sequence_steps.json +++ b/tap_outreach/schemas/sequence_steps.json @@ -31,7 +31,7 @@ "null", "string" ], - "format": "date" + "format": "date-time" }, "deliverCount": { "type": [ @@ -130,6 +130,12 @@ ], "format": "date-time" }, + "callPurposeId": { + "type": [ + "null", + "integer" + ] + }, "creatorId": { "type": [ "null", @@ -142,6 +148,12 @@ "integer" ] }, + "taskPriorityId": { + "type": [ + "null", + "integer" + ] + }, "updaterId": { "type": [ "null", diff --git a/tap_outreach/schemas/sequence_templates.json b/tap_outreach/schemas/sequence_templates.json index 954d042..22bcb5f 100644 --- a/tap_outreach/schemas/sequence_templates.json +++ b/tap_outreach/schemas/sequence_templates.json @@ -112,6 +112,18 @@ "integer" ] }, + "sequenceStepId": { + "type": [ + "null", + "integer" + ] + }, + "templateId": { + "type": [ + "null", + "integer" + ] + }, "updaterId": { "type": [ "null", diff --git a/tap_outreach/schemas/sequences.json b/tap_outreach/schemas/sequences.json index 80744f5..0fac373 100644 --- a/tap_outreach/schemas/sequences.json +++ b/tap_outreach/schemas/sequences.json @@ -212,8 +212,14 @@ "tags": { "type": [ "null", - "string" - ] + "array" + ], + "items": { + "type": [ + "null", + "string" + ] + } }, "throttleCapacity": { "type": [ @@ -265,6 +271,12 @@ "integer" ] }, + "rulesetId": { + "type": [ + "null", + "integer" + ] + }, "updaterId": { "type": [ "null", diff --git a/tap_outreach/schemas/tasks.json b/tap_outreach/schemas/tasks.json index f3cab92..96783e7 100644 --- a/tap_outreach/schemas/tasks.json +++ b/tap_outreach/schemas/tasks.json @@ -59,6 +59,12 @@ "string" ] }, + "opportunityAssociation": { + "type": [ + "null", + "string" + ] + }, "scheduledAt": { "type": [ "null", @@ -158,6 +164,12 @@ "integer" ] }, + "sequenceTemplateId": { + "type": [ + "null", + "integer" + ] + }, "subjectId": { "type": [ "null", diff --git a/tap_outreach/schemas/teams.json b/tap_outreach/schemas/teams.json index 7aa7e4f..350f329 100644 --- a/tap_outreach/schemas/teams.json +++ b/tap_outreach/schemas/teams.json @@ -13,25 +13,49 @@ "string" ] }, + "createdAt": { + "type": [ + "null", + "string" + ], + "format": "date-time" + }, "name": { "type": [ "null", "string" ] }, - "createdAt": { + "scimExternalId": { "type": [ "null", "string" - ], - "format": "date-time" + ] }, - "createdAt": { + "scimSource": { + "type": [ + "null", + "string" + ] + }, + "updatedAt": { "type": [ "null", "string" ], "format": "date-time" + }, + "creatorId": { + "type": [ + "null", + "integer" + ] + }, + "updaterId": { + "type": [ + "null", + "integer" + ] } } } \ No newline at end of file diff --git a/tap_outreach/schemas/users.json b/tap_outreach/schemas/users.json index b313e9d..cecf59b 100644 --- a/tap_outreach/schemas/users.json +++ b/tap_outreach/schemas/users.json @@ -7,6 +7,12 @@ "integer" ] }, + "accountsViewId": { + "type": [ + "null", + "integer" + ] + }, "activityNotificationsDisabled": { "type": [ "null", @@ -31,6 +37,12 @@ "string" ] }, + "callsViewId": { + "type": [ + "null", + "integer" + ] + }, "controlledTabDefault": { "type": [ "null", @@ -131,6 +143,12 @@ "boolean" ] }, + "engagementEmailsEnabled": { + "type": [ + "null", + "boolean" + ] + }, "firstName": { "type": [ "null", @@ -155,6 +173,12 @@ "string" ] }, + "inboundPhoneType": { + "type": [ + "null", + "string" + ] + }, "inboundVoicemailCustomMessageText": { "type": [ "null", @@ -167,6 +191,24 @@ "string" ] }, + "inboundVoicemailPromptType": { + "type": [ + "null", + "string" + ] + }, + "kaiaRecordingsViewId": { + "type": [ + "null", + "integer" + ] + }, + "keepBridgePhoneConnected": { + "type": [ + "null", + "boolean" + ] + }, "lastName": { "type": [ "null", @@ -192,6 +234,12 @@ "boolean" ] }, + "meetingEngagementNotificationEnabled": { + "type": [ + "null", + "boolean" + ] + }, "name": { "type": [ "null", @@ -246,12 +294,11 @@ "boolean" ] }, - "onboardedAt": { + "opportunitiesViewId": { "type": [ "null", - "string" - ], - "format": "date-time" + "integer" + ] }, "passwordExpiresAt": { "type": [ @@ -278,18 +325,96 @@ "string" ] }, + "pluginAlertNotificationEnabled": { + "type": [ + "null", + "boolean" + ] + }, + "preferredVoiceRegion": { + "type": [ + "null", + "string" + ] + }, "prefersLocalPresence": { "type": [ "null", "boolean" ] }, + "primaryTimezone": { + "type": [ + "null", + "string" + ] + }, + "prospectsViewId": { + "type": [ + "null", + "integer" + ] + }, + "reportsTeamPerfViewId": { + "type": [ + "null", + "integer" + ] + }, + "reportsViewId": { + "type": [ + "null", + "integer" + ] + }, + "scimExternalId": { + "type": [ + "null", + "string" + ] + }, + "scimSource": { + "type": [ + "null", + "string" + ] + }, + "secondaryTimezone": { + "type": [ + "null", + "string" + ] + }, "senderNotificationsExcluded": { "type": [ "null", "string" ] }, + "tasksViewId": { + "type": [ + "null", + "integer" + ] + }, + "teamsViewId": { + "type": [ + "null", + "integer" + ] + }, + "tertiaryTimezone": { + "type": [ + "null", + "string" + ] + }, + "textingEmailNotifications": { + "type": [ + "null", + "boolean" + ] + }, "title": { "type": [ "null", @@ -309,22 +434,34 @@ ], "format": "date-time" }, + "userGuid": { + "type": [ + "null", + "string" + ] + }, "username": { "type": [ "null", "string" ] }, - "weeklyDigestEmailEnabled": { + "usersViewId": { + "type": [ + "null", + "integer" + ] + }, + "voicemailNotificationEnabled": { "type": [ "null", "boolean" ] }, - "calendarId": { + "weeklyDigestEmailEnabled": { "type": [ "null", - "integer" + "boolean" ] }, "creatorId": { diff --git a/tap_outreach/sync.py b/tap_outreach/sync.py index 84b945c..cc2f15f 100644 --- a/tap_outreach/sync.py +++ b/tap_outreach/sync.py @@ -35,6 +35,7 @@ 'callDispositionId', 'callPurposeId', 'opportunityId', + 'phoneNumberId', 'prospectId', 'sequenceId', 'sequenceStateId', @@ -57,7 +58,15 @@ 'url_path': 'events', 'replication': 'incremental', 'filter_field': 'eventAt', - 'fks': ['prospectId', 'userId'] + 'fks': [ + 'accountId', + 'callId', + 'mailingId', + 'opportunityId', + 'prospectId', + 'taskId', + 'userId' + ] }, 'mailboxes': { 'url_path': 'mailboxes', @@ -70,7 +79,7 @@ 'replication': 'incremental', 'filter_field': 'updatedAt', 'fks': [ - 'calendarId', + 'followUpSequenceId', 'mailboxId', 'opportunityId', 'prospectId', @@ -89,7 +98,9 @@ 'accountId', 'creatorId', 'opportunityStageId', - 'ownerId' + 'ownerId', + 'stageId', + 'updaterId' ] }, 'personas': { @@ -104,40 +115,52 @@ 'fks': [ 'accountId', 'creatorId', - 'defaultPluginMappingId', 'ownerId', 'personaId', 'stageId', 'updaterId' ] }, - 'stages': { - 'url_path': 'stages', - 'replication': 'incremental', - 'filter_field': 'updatedAt', - 'fks': ['creatorId', 'updaterId'] - }, - 'sequences': { - 'url_path': 'sequences', - 'replication': 'incremental', - 'filter_field': 'updatedAt', - 'fks': ['creatorId', 'ownerid', 'updaterId'] - }, 'sequence_states': { 'url_path': 'sequenceStates', 'replication': 'incremental', 'filter_field': 'updatedAt', - 'fks': ['accountid', 'creatorId', 'prospectId', 'sequenceId'] + 'fks': [ + 'accountId', + 'creatorId', + 'mailboxId', + 'opportunityId', + 'prospectId', + 'sequenceId', + 'sequenceStepId' + ] }, 'sequence_steps': { 'url_path': 'sequenceSteps', 'replication': 'incremental', 'filter_field': 'updatedAt', - 'fks': ['creatorId', 'sequenceId', 'updaterId'] + 'fks': [ + 'callPurposeId', + 'creatorId', + 'sequenceId', + 'taskPriorityId', + 'updaterId' + ] }, 'sequence_templates': { 'url_path': 'sequenceTemplates', 'replication': 'full', + 'fks': ['creatorId', 'sequenceStepId', 'templateId', 'updaterId'] + }, + 'sequences': { + 'url_path': 'sequences', + 'replication': 'incremental', + 'filter_field': 'updatedAt', + 'fks': ['creatorId', 'ownerId', 'rulesetId', 'updaterId'] + }, + 'stages': { + 'url_path': 'stages', + 'replication': 'incremental', 'filter_field': 'updatedAt', 'fks': ['creatorId', 'updaterId'] }, @@ -157,15 +180,16 @@ 'sequenceId', 'sequenceStateId', 'sequenceStepId', + 'sequenceTemplateId', 'subjectId', 'taskPriorityId', - 'taskThemeId', 'templateId' ] }, 'teams': { 'url_path': 'teams', - 'replication': 'full', + 'replication': 'incremental', + 'filter_field': 'updatedAt', 'fks': ['creatorId', 'updaterId'] }, 'users': { @@ -173,7 +197,6 @@ 'replication': 'incremental', 'filter_field': 'updatedAt', 'fks': [ - 'calendarId', 'mailboxId', 'profileId', 'roleId', @@ -185,13 +208,13 @@ def get_bookmark(state, stream_name, default): - return state.get('bookmarks', {}).get(stream_name, default) + return state.get('bookmarks', {}).get(stream_name, {}).get(STREAM_CONFIGS[stream_name].get('filter_field'), default) def write_bookmark(state, stream_name, value): if 'bookmarks' not in state: state['bookmarks'] = {} - state['bookmarks'][stream_name] = value + state['bookmarks'][stream_name] = {STREAM_CONFIGS[stream_name]['filter_field']: value} singer.write_state(state) @@ -228,7 +251,7 @@ def process_records(stream, mdata, max_modified, records, filter_field, fks): 'null or `id` field expected for `data` relationship') # potential fix for the issue - https://github.com/singer-io/tap-outreach/issues/20 - if stream.tap_stream_id != "prospects": + if stream.tap_stream_id not in ["prospects", "events"]: if fk_field_name in record_flat: raise Exception('`{}` exists as both an attribute and generated relationship name'.format(fk_field_name)) @@ -319,13 +342,13 @@ def sync_endpoint(client, config, state, start_date, stream, mdata): def update_current_stream(state, stream_name=None): + LOGGER.info("Setting the stream as currently syncing") set_currently_syncing(state, stream_name) singer.write_state(state) def sync(client, config, catalog, state, start_date): selected_streams = catalog.get_selected_streams(state) - selected_streams = sorted(selected_streams, key=lambda x: x.tap_stream_id) for stream in selected_streams: mdata = metadata.to_map(stream.metadata) diff --git a/tests/base.py b/tests/base.py new file mode 100644 index 0000000..5799be2 --- /dev/null +++ b/tests/base.py @@ -0,0 +1,170 @@ +import os + +from tap_tester.base_suite_tests.base_case import BaseCase + + +class OutreachBase(BaseCase): + """ + Setup expectations for test sub classes. + Metadata describing streams. + A bunch of shared methods that are used in tap-tester tests. + Shared tap-specific methods (as needed). + """ + PAGE_SIZE = 100000 + start_date = "2019-01-01T00:00:00Z" + + @staticmethod + def tap_name(): + """The name of the tap""" + return "tap-outreach" + + @staticmethod + def get_type(): + """the expected url route ending""" + return "platform.outreach" + + def get_properties(self, original: bool = True): + """Configuration properties required for the tap.""" + + return_value = { + "start_date": self.start_date, + "redirect_uri": "https://app.stitchdata.test:8080/v2/integrations/platform.outreach/callback", + "client_id": os.getenv("TAP_OUTREACH_CLIENT_ID"), + "client_secret": os.getenv("TAP_OUTREACH_CLIENT_SECRET"), + "refresh_token": os.getenv("TAP_OUTREACH_REFRESH_TOKEN"), + } + + return return_value + + @staticmethod + def get_credentials(): + return { + "client_id": os.getenv("TAP_OUTREACH_CLIENT_ID"), + "client_secret": os.getenv("TAP_OUTREACH_CLIENT_SECRET"), + "refresh_token": os.getenv("TAP_OUTREACH_REFRESH_TOKEN"), + } + + @classmethod + def expected_metadata(self): + """The expected streams and metadata about the streams""" + + return { + "accounts": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "call_dispositions": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "call_purposes": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "calls": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "content_categories": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "duties": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_METHOD: self.FULL_TABLE, + }, + "events": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"eventAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "mailboxes": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "mailings": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "opportunities": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "personas": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "prospects": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "stages": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "sequences": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "sequence_states": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "sequence_steps": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "sequence_templates": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_METHOD: self.FULL_TABLE, + }, + "tasks": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "teams": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + "users": { + self.PRIMARY_KEYS: {"id"}, + self.REPLICATION_KEYS: {"updatedAt"}, + self.REPLICATION_METHOD: self.INCREMENTAL, + }, + } + + @classmethod + def setUpClass(cls): + super().setUpClass(logging="Ensuring environment variables are sourced.") + missing_envs = [ + x + for x in [ + "TAP_OUTREACH_CLIENT_ID", + "TAP_OUTREACH_CLIENT_SECRET", + "TAP_OUTREACH_REFRESH_TOKEN", + ] + if os.getenv(x) is None + ] + + if len(missing_envs) != 0: + raise Exception("Missing environment variables: {}".format(missing_envs)) + + ########################################################################## + ### Tap Specific Methods + ########################################################################## diff --git a/tests/test_all_fields.py b/tests/test_all_fields.py new file mode 100644 index 0000000..442d62f --- /dev/null +++ b/tests/test_all_fields.py @@ -0,0 +1,18 @@ +from tap_tester.base_suite_tests.all_fields_test import AllFieldsTest +from base import OutreachBase + + +class OutreachAllFieldsTest(AllFieldsTest, OutreachBase): + """Standard All Fields Test""" + MISSING_FIELDS = { + "sequence_templates": {"negaitveReplyCount"}, + "tasks": {"taskThemeId"}, + } + + @staticmethod + def name(): + return "tt_outreach_all_fields_test" + + def streams_to_test(self): + streams_to_exclude = {"mailings"} + return self.expected_stream_names().difference(streams_to_exclude) diff --git a/tests/test_automatic_fields.py b/tests/test_automatic_fields.py new file mode 100644 index 0000000..4079f74 --- /dev/null +++ b/tests/test_automatic_fields.py @@ -0,0 +1,20 @@ +from tap_tester.base_suite_tests.automatic_fields_test import MinimumSelectionTest +from base import OutreachBase + + +class OutreachMinimumSelectionTest(MinimumSelectionTest, OutreachBase): + """Standard Automatic Fields Test""" + + @staticmethod + def name(): + return "tt_outreach_auto" + + def streams_to_test(self): + streams_to_exclude = { + "mailings", + "duties", + "users", + "sequence_states", + "sequences", + } + return self.expected_stream_names().difference(streams_to_exclude) diff --git a/tests/test_bookmark.py b/tests/test_bookmark.py new file mode 100644 index 0000000..5d2049e --- /dev/null +++ b/tests/test_bookmark.py @@ -0,0 +1,55 @@ +from tap_tester.base_suite_tests.bookmark_test import BookmarkTest +from base import OutreachBase + +# from debugpy import listen, wait_for_client +# listen(8000) +# wait_for_client() + +class OutreachBookmarkTest(BookmarkTest, OutreachBase): + """Standard Bookmark Test""" + + bookmark_format = "%Y-%m-%dT%H:%M:%S.%fZ" + initial_bookmarks = { + "bookmarks": { + "accounts": {"updatedAt": "2016-07-07T14:22:04.624Z"}, + "call_dispositions": {"updatedAt": "2020-05-06T18:54:08.250Z"}, + "call_purposes": {"updatedAt": "2020-11-06T20:17:17Z"}, + "calls": {"updatedAt": "2018-01-17T13:45:25.125Z"}, + "content_categories": {"updatedAt": "2019-10-10T03:23:15.466Z"}, + "events": {"updatedAt": "2016-07-07T14:22:04.624Z"}, + "mailboxes": {"updatedAt": "2020-05-06T18:54:08.250Z"}, + # "mailings": {"updatedAt": "2020-11-06T20:17:17Z"}, + "opportunities": {"updatedAt": "2018-01-17T13:45:25.125Z"}, + "personas": {"updatedAt": "2019-10-10T03:23:15.466Z"}, + "prospects": {"updatedAt": "2016-07-07T14:22:04.624Z"}, + "stages": {"updatedAt": "2020-05-06T18:54:08.250Z"}, + "sequences": {"updatedAt": "2020-11-06T20:17:17Z"}, + "sequence_states": {"updatedAt": "2018-01-17T13:45:25.125Z"}, + "sequence_steps": {"updatedAt": "2019-10-10T03:23:15.466Z"}, + "tasks": {"updatedAt": "2020-05-06T18:54:08.250Z"}, + "teams": {"updatedAt": "2020-11-06T20:17:17Z"}, + "users": {"updatedAt": "2019-10-10T03:23:15.466Z"}, + } + } + + @property + def start_date(self): + return "2015-03-25T00:00:00Z" + + @staticmethod + def name(): + return "tt_outreach_bookmark_test" + + def streams_to_test(self): + # Skip streams due to lack of test data + streams_to_exclude = {"mailings", "duties", "sequence_templates"} + return self.expected_stream_names().difference(streams_to_exclude) + + def calculate_new_bookmarks(self): + """ + Calculates new bookmarks by looking through sync 1 data to determine a bookmark + that will sync 2 records in sync 2 (plus any necessary look back data) + """ + new_bookmarks = super().calculate_new_bookmarks() + return {key: {k: v.replace(".000000Z", ".000Z") for k, v in value.items()} + for key, value in new_bookmarks.items()} diff --git a/tests/test_discovery.py b/tests/test_discovery.py new file mode 100644 index 0000000..958ca95 --- /dev/null +++ b/tests/test_discovery.py @@ -0,0 +1,13 @@ +from tap_tester.base_suite_tests.discovery_test import DiscoveryTest +from base import OutreachBase + + +class OutreachDiscoveryTest(DiscoveryTest, OutreachBase): + """Standard Discovery Test""" + + @staticmethod + def name(): + return "tt_outreach_discovery" + + def streams_to_test(self): + return self.expected_stream_names() diff --git a/tests/test_interrupted_sync.py b/tests/test_interrupted_sync.py new file mode 100644 index 0000000..704fe67 --- /dev/null +++ b/tests/test_interrupted_sync.py @@ -0,0 +1,35 @@ +from tap_tester.base_suite_tests.interrupted_sync_test import InterruptedSyncTest +from base import OutreachBase + + +class OutreachInterruptedSyncTest(InterruptedSyncTest, OutreachBase): + """Standard Interrupted Sync Test""" + bookmark_format = "%Y-%m-%dT%H:%M:%S.%fZ" + + @staticmethod + def name(): + return "tt_outreach_interrupted_sync_test" + + def streams_to_test(self): + # Skip streams due to lack of test data + # BUG:TDL-24173 - equality assertion fails fails because `passwordExpiresAt` + # in 'users' stream updated after authentication + streams_to_exclude = {"mailings", "duties", "sequence_templates", "users"} + return self.expected_stream_names().difference(streams_to_exclude) + + def manipulate_state(self): + return { + "currently_syncing": "prospects", + "bookmarks": { + "mailboxes": {"updatedAt": "2023-08-31T17:49:56.000Z"}, + "calls": {"updatedAt": "2023-09-13T21:07:04.000Z"}, + "prospects": {"updatedAt": "2023-07-31T18:23:54.000Z"}, + "call_dispositions": {"updatedAt": "2023-09-13T20:38:36.000Z"}, + "call_purposes": {"updatedAt": "2023-09-13T20:50:34.000Z"}, + "content_categories": {"updatedAt": "2023-08-31T14:59:57.000Z"}, + "personas": {"updatedAt": "2023-08-31T18:00:58.000Z"}, + "opportunities": {"updatedAt": "2023-08-31T14:52:57.000Z"}, + "accounts": {"updatedAt": "2023-09-13T20:48:48.000Z"}, + "events": {"eventAt": "2023-09-13T21:07:04.000Z"}, + }, + } diff --git a/tests/test_pagination.py b/tests/test_pagination.py new file mode 100644 index 0000000..0c72f3d --- /dev/null +++ b/tests/test_pagination.py @@ -0,0 +1,17 @@ +from tap_tester.base_suite_tests.pagination_test import PaginationTest +from base import OutreachBase + + +class OutreachPaginationTest(PaginationTest, OutreachBase): + """Standard Pagination Test""" + + @staticmethod + def name(): + return "tt_outreach_pagination_test" + + def expected_page_size(self, stream): + return 1 + + def streams_to_test(self): + streams_to_exclude = {"mailings", "calls"} + return self.expected_stream_names().difference(streams_to_exclude) diff --git a/tests/test_start_date.py b/tests/test_start_date.py new file mode 100644 index 0000000..202ab16 --- /dev/null +++ b/tests/test_start_date.py @@ -0,0 +1,26 @@ +from tap_tester.base_suite_tests.start_date_test import StartDateTest +from base import OutreachBase + + + +class OutreachStartdateTest(StartDateTest, OutreachBase): + """Standard Start date Test""" + + bookmark_format = "%Y-%m-%dT%H:%M:%S.%fZ" + + @staticmethod + def name(): + return "tt_outreach_start_date_test" + + def streams_to_test(self): + # Skip streams due to lack of test data + streams_to_exclude = {"mailings", "prospects", "sequence_states", "duties", "sequence_templates"} + return self.expected_stream_names().difference(streams_to_exclude) + + @property + def start_date_1(self): + return "2015-03-25T00:00:00Z" + + @property + def start_date_2(self): + return "2023-09-01T00:00:00Z" diff --git a/tests/test_sync_canary.py b/tests/test_sync_canary.py new file mode 100644 index 0000000..4771825 --- /dev/null +++ b/tests/test_sync_canary.py @@ -0,0 +1,14 @@ +from tap_tester.base_suite_tests.sync_canary_test import SyncCanaryTest +from base import OutreachBase + + +class OutreachSyncCanaryTest(SyncCanaryTest, OutreachBase): + """Standard Sync Canary Test""" + + @staticmethod + def name(): + return "tt_outreach_sync_canary_test" + + def streams_to_test(self): + streams_to_exclude = {"mailings"} + return self.expected_stream_names().difference(streams_to_exclude) diff --git a/tests/unittests/test_exception_handling.py b/tests/unittests/test_exception_handling.py index ccd2c5b..b57966f 100644 --- a/tests/unittests/test_exception_handling.py +++ b/tests/unittests/test_exception_handling.py @@ -34,7 +34,10 @@ def test_conflict_id(self): "mock_filter_field", "mock_fks", ) - self.assertEqual(e.exception.args[0], 'Error flattening Outeach record - conflict with `id` key') + self.assertEqual( + e.exception.args[0], + "Error flattening Outeach record - conflict with `id` key", + ) def test_conflict_data_links(self): """call `process_records` function and by passing the `mock_id_records` in @@ -42,7 +45,9 @@ def test_conflict_data_links(self): We expect the exception to be raised - `Only `data` or `links` expected in relationships` """ - mock_records = [{"id": 1, "attributes": {}, "relationships": {"prop": {"value": ""}}}] + mock_records = [ + {"id": 1, "attributes": {}, "relationships": {"prop": {"value": ""}}} + ] mock_stream = MockStream() with self.assertRaises(Exception) as e: process_records( @@ -53,7 +58,9 @@ def test_conflict_data_links(self): "mock_filter_field", "mock_fks", ) - self.assertEqual(e.exception.args[0], 'Only `data` or `links` expected in relationships') + self.assertEqual( + e.exception.args[0], "Only `data` or `links` expected in relationships" + ) def test_conflict_data_id(self): """call `process_records` function and by passing the `mock_id_records` in @@ -61,7 +68,13 @@ def test_conflict_data_id(self): We expect the exception to be raised - `null or `id` field expected for `data` relationship` """ - mock_records = [{"id": 1, "attributes": {}, "relationships": {"prop": {"data": "data_value"}}}] + mock_records = [ + { + "id": 1, + "attributes": {}, + "relationships": {"prop": {"data": "data_value"}}, + } + ] mock_stream = MockStream() mock_fks = ["propId"] with self.assertRaises(Exception) as e: @@ -71,9 +84,11 @@ def test_conflict_data_id(self): "mock_max_modified", mock_records, "mock_filter_field", - mock_fks + mock_fks, ) - self.assertEqual(e.exception.args[0], 'null or `id` field expected for `data` relationship') + self.assertEqual( + e.exception.args[0], "null or `id` field expected for `data` relationship" + ) def test_conflict_prospects_attributes(self): """call `process_records` function and by passing the `mock_id_records` in @@ -81,7 +96,13 @@ def test_conflict_prospects_attributes(self): We expect the exception to be raised - ``propId` exists as both an attribute and generated relationship name` """ - mock_records = [{"id": 1, "attributes": {"propId": 456}, "relationships": {"prop": {"data": {"id": 123}}}}] + mock_records = [ + { + "id": 1, + "attributes": {"propId": 456}, + "relationships": {"prop": {"data": {"id": 123}}}, + } + ] mock_stream = MockStream() mock_fks = ["propId"] with self.assertRaises(Exception) as e: @@ -91,6 +112,9 @@ def test_conflict_prospects_attributes(self): "mock_max_modified", mock_records, "mock_filter_field", - mock_fks + mock_fks, ) - self.assertEqual(e.exception.args[0], '`propId` exists as both an attribute and generated relationship name') + self.assertEqual( + e.exception.args[0], + "`propId` exists as both an attribute and generated relationship name", + ) diff --git a/tests/unittests/test_request_timeout.py b/tests/unittests/test_request_timeout.py index 691e0d7..6ffdb11 100644 --- a/tests/unittests/test_request_timeout.py +++ b/tests/unittests/test_request_timeout.py @@ -4,15 +4,24 @@ import requests from parameterized import parameterized + class Mockresponse: - """ Mock response object class.""" + """Mock response object class.""" - def __init__(self, status_code, json, raise_error, headers={'X-RateLimit-Remaining': 1}, text=None, content=None): + def __init__( + self, + status_code, + json, + raise_error, + headers={"X-RateLimit-Remaining": 1}, + text=None, + content=None, + ): self.status_code = status_code self.raise_error = raise_error self.text = json self.headers = headers - self.content = content if content is not None else 'github' + self.content = content if content is not None else "github" def raise_for_status(self): if not self.raise_error: @@ -21,33 +30,39 @@ def raise_for_status(self): raise requests.HTTPError("Sample message") def json(self): - """ Response JSON method.""" + """Response JSON method.""" return self.text + def get_response(status_code, json={}, raise_error=False, content=None): - """ Returns required mock response. """ + """Returns required mock response.""" return Mockresponse(status_code, json, raise_error, content=content) + @mock.patch("tap_outreach.client.requests.Session.request") class TestTimeoutValue(unittest.TestCase): """ - Test case to verify the timeout value is set as expected + Test case to verify the timeout value is set as expected """ - json = {"key": "value"} - @parameterized.expand([ - ["test_int_value", {"request_timeout": 100}, 100.0], - ["test_str_value", {"request_timeout": "100"}, 100.0], - ["test_empty_value", {"request_timeout": ""}, 300.0], - ["test_int_zero_value", {"request_timeout": 0}, 300.0], - ["test_str_zero_value", {"request_timeout": "0"}, 300.0], - ["test_str_float_value", {"request_timeout": "100.1"}, 100.1], - ["test_float_value", {"request_timeout": 100.1}, 100.1], - ["test_none_value", {"request_timeout": None}, 300.0], - ["test_no_value", {"request_timeout": "0"}, REQUEST_TIMEOUT] + json = {"key": "value"} - ]) - def test_timeout_value_in_config(self, mock_request, name, mock_config, expected_value): + @parameterized.expand( + [ + ["test_int_value", {"request_timeout": 100}, 100.0], + ["test_str_value", {"request_timeout": "100"}, 100.0], + ["test_empty_value", {"request_timeout": ""}, 300.0], + ["test_int_zero_value", {"request_timeout": 0}, 300.0], + ["test_str_zero_value", {"request_timeout": "0"}, 300.0], + ["test_str_float_value", {"request_timeout": "100.1"}, 100.1], + ["test_float_value", {"request_timeout": 100.1}, 100.1], + ["test_none_value", {"request_timeout": None}, 300.0], + ["test_no_value", {"request_timeout": "0"}, REQUEST_TIMEOUT], + ] + ) + def test_timeout_value_in_config( + self, mock_request, name, mock_config, expected_value + ): """ Test if timeout value given in config """ @@ -56,9 +71,9 @@ def test_timeout_value_in_config(self, mock_request, name, mock_config, expected test_client = OutreachClient(mock_config) - test_client.request(method='get', url='') + test_client.request(method="get", url="") # verify that the request was called with expected timeout value - mock_request.assert_called_with('get', '', timeout=expected_value, headers={'Authorization': 'Bearer None'}) - - + mock_request.assert_called_with( + "get", "", timeout=expected_value, headers={"Authorization": "Bearer None"} + ) diff --git a/tests/unittests/test_retry_logic.py b/tests/unittests/test_retry_logic.py index 19efe1c..87b657e 100644 --- a/tests/unittests/test_retry_logic.py +++ b/tests/unittests/test_retry_logic.py @@ -4,20 +4,23 @@ from requests.models import Response from tap_outreach import client + class Mockresponse(Response): def __init__(self, status_code): super().__init__() self.status_code = status_code self.headers = {"x-ratelimit-reset": time.time()} - + def raise_for_status(self): pass - + + class TestRetryLogic(unittest.TestCase): """A set of unit tests to ensure that the retry logic work as expected""" + @patch("tap_outreach.client.requests.Session.request") def test_retries_on_5XX(self, mock_session_request): - """`OutreachClient.get()` calls a `request` method,to make a request to the API. + """`OutreachClient.get()` calls a `request` method,to make a request to the API. We set the mock response status code to `500`. We expect the tap to retry this request up to 5 times, which is @@ -32,7 +35,7 @@ def test_retries_on_5XX(self, mock_session_request): "client_secret": "mock_secret", "redirect_uri": "mock_uri", "refresh_token": "mock_token", - "request_timeout": 5 + "request_timeout": 5, } # Initialize the object and call `get()` @@ -45,8 +48,8 @@ def test_retries_on_5XX(self, mock_session_request): @patch("tap_outreach.client.OutreachClient.sleep_for_reset_period") @patch("tap_outreach.client.requests.Session.request") def test_retries_on_429(self, mock_session_request, mock_period): - """`OutreachClient.get()` calls a `request` method,to make a request to the API. - We set the mock response status code to `429`. Checks the execution on reaching + """`OutreachClient.get()` calls a `request` method,to make a request to the API. + We set the mock response status code to `429`. Checks the execution on reaching rate limit. We expect the tap to retry this request up to 5 times, which is @@ -61,7 +64,7 @@ def test_retries_on_429(self, mock_session_request, mock_period): "client_secret": "mock_secret", "redirect_uri": "mock_uri", "refresh_token": "mock_token", - "request_timeout": 5 + "request_timeout": 5, } # Initialize the object and call `get()` @@ -74,8 +77,8 @@ def test_retries_on_429(self, mock_session_request, mock_period): @patch("tap_outreach.client.OutreachClient.sleep_for_reset_period") @patch("tap_outreach.client.requests.Session.request") def test_retries_on_404(self, mock_session_request, mock_period): - """`OutreachClient.get()` calls a `request` method,to make a request to the API. - We set the mock response status code to `404`. Checks the execution on reaching + """`OutreachClient.get()` calls a `request` method,to make a request to the API. + We set the mock response status code to `404`. Checks the execution on reaching rate limit. We expect the tap to retry this request up to 1 times, which is @@ -90,7 +93,7 @@ def test_retries_on_404(self, mock_session_request, mock_period): "client_secret": "mock_secret", "redirect_uri": "mock_uri", "refresh_token": "mock_token", - "request_timeout": 5 + "request_timeout": 5, } # Initialize the object and call `get()` diff --git a/tests/unittests/test_sync_endpoint.py b/tests/unittests/test_sync_endpoint.py index d7be176..122d234 100644 --- a/tests/unittests/test_sync_endpoint.py +++ b/tests/unittests/test_sync_endpoint.py @@ -36,7 +36,7 @@ def test_sync_endpoint(self, mock_process_record, mock_schema): mock_state = { "currently_syncing": None, "bookmarks": { - "accounts": "2023-07-07T05:30:59.000Z", + "accounts": {"updatedAt": "2023-07-07T05:30:59.000Z"}, }, }