def test_running(self, mocker): """ Given: - A timestamp replacer instance When: - executing the 'running' method Then: - Ensure all problematic keys are loaded """ problematic_keys = { 'server_replay_ignore_params': 'query_key1 query_key2', 'server_replay_ignore_payload_params': 'payload_key1 payload_key2', 'keys_to_replace': 'key_to_replace1 key_to_replace2' } mocker.patch('os.path.exists', return_value=True) mocker.patch('builtins.open', mock_open(read_data=json.dumps(problematic_keys))) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.running() assert time_stamp_replacer.query_keys == {'query_key2', 'query_key1'} assert time_stamp_replacer.form_keys == { 'payload_key2', 'payload_key1' } assert time_stamp_replacer.json_keys == { 'key_to_replace2', 'key_to_replace1' }
def test_cleaning_problematic_keys_from_json_keys(self, mocker, flow, time): """ Given: - A timestamp replacer instance When: - digesting a request in playback mode Then: - Ensure the problematic keys passed in json body are replaced with constant value """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'playback' flow.request.method = 'POST' flow.request.set_content( json.dumps({ 'key1': 'value1', 'timestamp_key': time, 'dict1': { 'list': ['test', time] } }).encode()) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.json_keys = ['timestamp_key', 'dict1.list.1'] time_stamp_replacer.request(flow) content = json.loads(flow.request.get_content()) for key, val in content.items(): if key == 'timestamp_key': assert val == time_stamp_replacer.constant elif key == 'dict1': assert time_stamp_replacer.constant in val['list']
def test_finding_problematic_keys_in_json_keys(self, mocker, flow, time): """ Given: - A timestamp replacer instance When: - searching a request for problematic keys that has timestamp values Then: - Ensure the problematic key is loaded into json_keys - Ensure the problematic key is loaded into json_keys even when it's nested - Ensure the valid key is not loaded into json_keys """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'record' flow.request.method = 'POST' flow.request.set_content( json.dumps({ 'key1': 'value1', 'timestamp_key': time, 'dict1': { 'list': ['test', time] } }).encode()) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) assert 'timestamp_key' in time_stamp_replacer.json_keys assert 'dict1.list.1' in time_stamp_replacer.json_keys assert 'key1' not in time_stamp_replacer.json_keys
def test_live_false_when_running_in_playback_state(self, flow): """ Given: - A flow When: - script is in playback mode Then: - Ensure that the request will not go out to the real world """ mitmproxy.ctx.options.script_mode = 'playback' time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) assert flow.live is False
def test_fixed_boundary(self, flow): """ Given: - A multipart/form-data flow with a random boundary Then: - Ensure that the boundary will be replaced to 'fixed_boundary' """ original_boundary = 'original_boundary' flow.request.headers[ 'Content-Type'] = f'multipart/form-data; boundary={original_boundary}' flow.request.content = f'--{original_boundary}\nContent-Disposision: form-data; ' \ f'name="test"\n\nsomething\n--{original_boundary}--'.encode() time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) assert flow.request.content == b'--fixed_boundary\nContent-Disposision: form-data; ' \ b'name="test"\n\nsomething\n--fixed_boundary--'
def test_url_query_is_sorted(self, mocker, flow): """ Given: - A timestamp replacer instance When: - searching a request for problematic keys that has timestamp values in the query params Then: - Ensure that the request query params are sorted """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'clean' flow.request._set_query([('key2', 'value2'), ('key1', 'value1')]) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) updated_request = flow.request._get_query() assert updated_request[0] == ('key1', 'value1') assert updated_request[1] == ('key2', 'value2')
def test_finding_problematic_keys_in_url_query(self, mocker, flow, time): """ Given: - A timestamp replacer instance When: - searching a request for problematic keys that has timestamp values in the query params Then: - Ensure the problematic key is loaded into query_keys - Ensure the valid key is not loaded into query_keys """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'record' flow.request._set_query([('key1', 'value1'), ('timestamp_key', time)]) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) assert 'timestamp_key' in time_stamp_replacer.query_keys assert 'key1' not in time_stamp_replacer.query_keys
def test_loader_defaults(self, mocker): """ Given: - A timestamp replacer instance When: - Loading it's options Then: - Ensure that a call with the expected defaults is called """ master_mock = mocker.MagicMock() time_stamp_replacer = TimestampReplacer() time_stamp_replacer.load(master_mock) python_version = sys.version_info if python_version.major == 3 and python_version.minor == 7: pytest.skip( 'The current mock syntax is supported only in python 3.8+') assert master_mock.add_option.call_count == 4 for call in master_mock.add_option.mock_calls: assert self.DEFAULT_OPTIONS_MAPPING[ call.kwargs['name']] == call.kwargs['default']
def test_cleaning_problematic_keys_from_url_query(self, mocker, flow, time): """ Given: - A timestamp replacer instance When: - digesting a request in playback mode Then: - Ensure the problematic key passed as query param is replaced with constant value """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'playback' flow.request._set_query([('key1', 'value1'), ('timestamp_key', time)]) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.query_keys = ['timestamp_key'] time_stamp_replacer.request(flow) for key, val in flow.request._get_query(): if key == 'timestamp_key': assert val == time_stamp_replacer.constant
def test_json_body_parsing(self, mocker, flow): """ Given: - A timestamp replacer instance When: - Trying to parse json body Then: - Ensure the body is parsed when is't json body - Ensure the body is parsed when it's json body with single quotes """ mocker.patch('builtins.open', mock_open()) mitmproxy.ctx.options.detect_timestamps = True mitmproxy.ctx.options.script_mode = 'record' flow.request.method = 'POST' flow.request.set_content( str({ 'timestamp_key': '2021-01-11T13:18:12+00:00' }).encode()) time_stamp_replacer = TimestampReplacer() time_stamp_replacer.request(flow) assert 'timestamp_key' in time_stamp_replacer.json_keys