def test_display_report_stream(test_config): setup_responses( init_response=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} metrics = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ] assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) updated_state = stream.get_updated_state(None, stream_slice) assert updated_state == stream_slice profiles = make_profiles(profile_type="vendor") stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) metrics = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ] # Skip asins record for vendor profiles assert len(metrics) == METRICS_COUNT * (len(stream.metrics_map) - 1)
def test_display_report_stream_slices_full_refresh(test_config): config = AmazonAdsConfig(**test_config) stream = SponsoredDisplayReportStream(config, None, authenticator=mock.MagicMock()) slices = stream.stream_slices(SyncMode.full_refresh, cursor_field=stream.cursor_field) assert slices == [{"reportDate": "20210730"}]
def test_display_report_stream_backoff(mocker, test_config, modifiers, expected): setup_responses(init_response=REPORT_INIT_RESPONSE, metric_response=METRIC_RESPONSE) with freeze_time("2021-01-02 03:04:05") as frozen_time: class StatusCallback: count: int = 0 def __call__(self, request): self.count += 1 response = REPORT_STATUS_RESPONSE.replace( "SUCCESS", "IN_PROGRESS") for index, status, time in modifiers: if index(self.count): if status: response = response.replace("IN_PROGRESS", status) if time: frozen_time.move_to(time) return (200, {}, response) callback = StatusCallback() responses.add_callback( responses.GET, re.compile( r"https://advertising-api.amazon.com/v2/reports/[^/]+$"), callback=callback) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} if isinstance(expected, int): list( stream.read_records(SyncMode.incremental, stream_slice=stream_slice)) assert callback.count == expected elif issubclass(expected, Exception): with pytest.raises(expected): list( stream.read_records(SyncMode.incremental, stream_slice=stream_slice))
def test_display_report_stream_init_failure(mocker, test_config): config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} responses.add( responses.POST, re.compile(r"https://advertising-api.amazon.com/sd/[a-zA-Z]+/report"), json={"error": "some error"}, status=400) with pytest.raises(Exception): [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ]
def test_display_report_stream_init_http_exception(mocker, test_config): mocker.patch("time.sleep", lambda x: None) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} responses.add( responses.POST, re.compile(r"https://advertising-api.amazon.com/sd/[a-zA-Z]+/report"), body=ConnectionError()) with raises(ConnectionError): _ = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ] assert len(responses.calls) == 5
def test_brands_video_report_stream(test_config): setup_responses( init_response_brands=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredBrandsVideoReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} metrics = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ] assert len(metrics) == METRICS_COUNT * len(stream.metrics_map)
def test_display_report_stream_report_generation_failure(test_config): setup_responses( init_response=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE.replace("SUCCESS", "FAILURE"), metric_response=METRIC_RESPONSE, ) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} with pytest.raises(Exception): _ = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ]
def test_display_report_stream_timeout(mocker, test_config): time_mock = mock.MagicMock() mocker.patch("time.sleep", time_mock) setup_responses(init_response=REPORT_INIT_RESPONSE, metric_response=METRIC_RESPONSE) with freeze_time("2021-07-30 04:26:08") as frozen_time: success_cnt = 2 class StatusCallback: count: int = 0 def __call__(self, request): self.count += 1 response = REPORT_STATUS_RESPONSE if self.count > success_cnt: response = REPORT_STATUS_RESPONSE.replace( "SUCCESS", "IN_PROGRESS") if self.count > success_cnt + 1: frozen_time.move_to("2021-07-30 06:26:08") return (200, {}, response) responses.add_callback( responses.GET, re.compile( r"https://advertising-api.amazon.com/v2/reports/[^/]+$"), callback=StatusCallback()) config = AmazonAdsConfig(**test_config) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice = {"reportDate": "20210725"} with pytest.raises(Exception): _ = [ m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice) ] time_mock.assert_called_with(30)
def test_display_report_stream_slices_incremental(test_config): config = AmazonAdsConfig(**test_config) stream = SponsoredDisplayReportStream(config, None, authenticator=mock.MagicMock()) stream_state = {"reportDate": "20210726"} slices = stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state=stream_state) assert slices == [ { "reportDate": "20210723" }, { "reportDate": "20210724" }, { "reportDate": "20210725" }, { "reportDate": "20210726" }, { "reportDate": "20210727" }, { "reportDate": "20210728" }, { "reportDate": "20210729" }, { "reportDate": "20210730" }, ] stream_state = {"reportDate": "20210730"} slices = stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state=stream_state) assert slices == [ { "reportDate": "20210727" }, { "reportDate": "20210728" }, { "reportDate": "20210729" }, { "reportDate": "20210730" }, ] stream_state = {"reportDate": "20210731"} slices = stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state=stream_state) assert slices == [ { "reportDate": "20210728" }, { "reportDate": "20210729" }, { "reportDate": "20210730" }, ] slices = stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state={}) assert slices == [{"reportDate": "20210730"}] slices = stream.stream_slices(SyncMode.incremental, cursor_field=None, stream_state={}) assert slices == [{"reportDate": "20210730"}]