diff --git a/castle/api/approve_device.py b/castle/api/approve_device.py index 5f2b2d2..47946c4 100644 --- a/castle/api/approve_device.py +++ b/castle/api/approve_device.py @@ -5,4 +5,4 @@ class APIApproveDevice(object): @staticmethod def call(device_token): - return APIRequest().call(CommandsApproveDevice.build(device_token)) + return APIRequest().call(CommandsApproveDevice.call(device_token)) diff --git a/castle/api/get_device.py b/castle/api/get_device.py index 37f118d..895e62e 100644 --- a/castle/api/get_device.py +++ b/castle/api/get_device.py @@ -5,4 +5,4 @@ class APIGetDevice(object): @staticmethod def call(device_token): - return APIRequest().call(CommandsGetDevice.build(device_token)) + return APIRequest().call(CommandsGetDevice.call(device_token)) diff --git a/castle/api/get_devices_for_user.py b/castle/api/get_devices_for_user.py index 67b507c..a8ffb4d 100644 --- a/castle/api/get_devices_for_user.py +++ b/castle/api/get_devices_for_user.py @@ -5,4 +5,4 @@ class APIGetDevicesForUser(object): @staticmethod def call(user_id): - return APIRequest().call(CommandsGetDevicesForUser.build(user_id)) + return APIRequest().call(CommandsGetDevicesForUser.call(user_id)) diff --git a/castle/api/report_device.py b/castle/api/report_device.py index c6b4e21..886d771 100644 --- a/castle/api/report_device.py +++ b/castle/api/report_device.py @@ -5,4 +5,4 @@ class APIReportDevice(object): @staticmethod def call(device_token): - return APIRequest().call(CommandsReportDevice.build(device_token)) + return APIRequest().call(CommandsReportDevice.call(device_token)) diff --git a/castle/api/review.py b/castle/api/review.py index 31d3caa..f8315bb 100644 --- a/castle/api/review.py +++ b/castle/api/review.py @@ -5,4 +5,4 @@ class APIReview(object): @staticmethod def call(review_id): - return APIRequest().call(CommandsReview.build(review_id)) + return APIRequest().call(CommandsReview.call(review_id)) diff --git a/castle/client.py b/castle/client.py index 7855638..8201ecd 100644 --- a/castle/client.py +++ b/castle/client.py @@ -5,7 +5,8 @@ from castle.context.merge import ContextMerge from castle.commands.authenticate import CommandsAuthenticate from castle.commands.identify import CommandsIdentify -from castle.commands.impersonate import CommandsImpersonate +from castle.commands.start_impersonation import CommandsStartImpersonation +from castle.commands.end_impersonation import CommandsEndImpersonation from castle.commands.track import CommandsTrack from castle.errors import InternalServerError, RequestError, ImpersonationFailed from castle.failover.prepare_response import FailoverPrepareResponse @@ -65,7 +66,7 @@ def _add_timestamp_if_necessary(self, options): def authenticate(self, options): if self.tracked(): self._add_timestamp_if_necessary(options) - command = CommandsAuthenticate(self.context).build(options) + command = CommandsAuthenticate(self.context).call(options) try: response = self.api.call(command) response.update(failover=False, failover_reason=None) @@ -83,11 +84,18 @@ def identify(self, options): if not self.tracked(): return None self._add_timestamp_if_necessary(options) - return self.api.call(CommandsIdentify(self.context).build(options)) + return self.api.call(CommandsIdentify(self.context).call(options)) - def impersonate(self, options): + def start_impersonation(self, options): self._add_timestamp_if_necessary(options) - response = self.api.call(CommandsImpersonate(self.context).build(options)) + response = self.api.call(CommandsStartImpersonation(self.context).call(options)) + if not response.get('success'): + raise ImpersonationFailed + return response + + def end_impersonation(self, options): + self._add_timestamp_if_necessary(options) + response = self.api.call(CommandsEndImpersonation(self.context).call(options)) if not response.get('success'): raise ImpersonationFailed return response @@ -96,7 +104,7 @@ def track(self, options): if not self.tracked(): return None self._add_timestamp_if_necessary(options) - return self.api.call(CommandsTrack(self.context).build(options)) + return self.api.call(CommandsTrack(self.context).call(options)) def disable_tracking(self): self.do_not_track = True diff --git a/castle/commands/approve_device.py b/castle/commands/approve_device.py index ea77533..b0aca25 100644 --- a/castle/commands/approve_device.py +++ b/castle/commands/approve_device.py @@ -5,7 +5,7 @@ class CommandsApproveDevice(object): @staticmethod - def build(device_token): + def call(device_token): ValidatorsPresent.call({'device_token': device_token}, 'device_token') return Command( diff --git a/castle/commands/authenticate.py b/castle/commands/authenticate.py index b997613..92cb67d 100644 --- a/castle/commands/authenticate.py +++ b/castle/commands/authenticate.py @@ -9,7 +9,7 @@ class CommandsAuthenticate(object): def __init__(self, context): self.context = context - def build(self, options): + def call(self, options): ValidatorsPresent.call(options, 'event') context = ContextMerge.call(self.context, options.get('context')) context = ContextSanitize.call(context) diff --git a/castle/commands/end_impersonation.py b/castle/commands/end_impersonation.py new file mode 100644 index 0000000..4bed078 --- /dev/null +++ b/castle/commands/end_impersonation.py @@ -0,0 +1,23 @@ +from castle.command import Command +from castle.utils.timestamp import UtilsTimestamp as generate_timestamp +from castle.context.merge import ContextMerge +from castle.context.sanitize import ContextSanitize +from castle.validators.present import ValidatorsPresent + + +class CommandsEndImpersonation(object): + def __init__(self, context): + self.context = context + + def call(self, options): + ValidatorsPresent.call(options, 'user_id') + + context = ContextMerge.call(self.context, options.get('context')) + context = ContextSanitize.call(context) + ValidatorsPresent.call(context, 'user_agent', 'ip') + + if context: + options.update({'context': context}) + options.update({'sent_at': generate_timestamp.call()}) + + return Command(method='delete', path='impersonate', data=options) diff --git a/castle/commands/get_device.py b/castle/commands/get_device.py index 783bd77..ad635bf 100644 --- a/castle/commands/get_device.py +++ b/castle/commands/get_device.py @@ -5,7 +5,7 @@ class CommandsGetDevice(object): @staticmethod - def build(device_token): + def call(device_token): ValidatorsPresent.call({'device_token': device_token}, 'device_token') return Command( diff --git a/castle/commands/get_devices_for_user.py b/castle/commands/get_devices_for_user.py index ed38d0c..8b297db 100644 --- a/castle/commands/get_devices_for_user.py +++ b/castle/commands/get_devices_for_user.py @@ -5,7 +5,7 @@ class CommandsGetDevicesForUser(object): @staticmethod - def build(user_id): + def call(user_id): ValidatorsPresent.call({'user_id': user_id}, 'user_id') return Command( diff --git a/castle/commands/identify.py b/castle/commands/identify.py index 370b5f6..43ba523 100644 --- a/castle/commands/identify.py +++ b/castle/commands/identify.py @@ -9,7 +9,7 @@ class CommandsIdentify(object): def __init__(self, context): self.context = context - def build(self, options): + def call(self, options): ValidatorsNotSupported.call(options, 'properties') context = ContextMerge.call(self.context, options.get('context')) context = ContextSanitize.call(context) diff --git a/castle/commands/report_device.py b/castle/commands/report_device.py index 208a25a..cf5a2c7 100644 --- a/castle/commands/report_device.py +++ b/castle/commands/report_device.py @@ -5,7 +5,7 @@ class CommandsReportDevice(object): @staticmethod - def build(device_token): + def call(device_token): ValidatorsPresent.call({'device_token': device_token}, 'device_token') return Command( diff --git a/castle/commands/review.py b/castle/commands/review.py index 651f1e9..d90c7b0 100644 --- a/castle/commands/review.py +++ b/castle/commands/review.py @@ -5,7 +5,7 @@ class CommandsReview(object): @staticmethod - def build(review_id): + def call(review_id): ValidatorsPresent.call({'review_id': review_id}, 'review_id') return Command( diff --git a/castle/commands/impersonate.py b/castle/commands/start_impersonation.py similarity index 77% rename from castle/commands/impersonate.py rename to castle/commands/start_impersonation.py index f8662db..83001e5 100644 --- a/castle/commands/impersonate.py +++ b/castle/commands/start_impersonation.py @@ -5,11 +5,11 @@ from castle.validators.present import ValidatorsPresent -class CommandsImpersonate(object): +class CommandsStartImpersonation(object): def __init__(self, context): self.context = context - def build(self, options): + def call(self, options): ValidatorsPresent.call(options, 'user_id') context = ContextMerge.call(self.context, options.get('context')) @@ -20,6 +20,4 @@ def build(self, options): options.update({'context': context}) options.update({'sent_at': generate_timestamp.call()}) - method = ('delete' if options.get('reset', False) else 'post') - - return Command(method=method, path='impersonate', data=options) + return Command(method='post', path='impersonate', data=options) diff --git a/castle/commands/track.py b/castle/commands/track.py index 5bbcf21..8c125ae 100644 --- a/castle/commands/track.py +++ b/castle/commands/track.py @@ -9,7 +9,7 @@ class CommandsTrack(object): def __init__(self, context): self.context = context - def build(self, options): + def call(self, options): ValidatorsPresent.call(options, 'event') context = ContextMerge.call(self.context, options.get('context')) context = ContextSanitize.call(context) diff --git a/castle/test/__init__.py b/castle/test/__init__.py index ddb00eb..b90ecb5 100644 --- a/castle/test/__init__.py +++ b/castle/test/__init__.py @@ -16,12 +16,13 @@ 'castle.test.command_test', 'castle.test.commands.approve_device_test', 'castle.test.commands.authenticate_test', + 'castle.test.commands.end_impersonation_test', 'castle.test.commands.get_device_test', 'castle.test.commands.get_devices_for_user_test', 'castle.test.commands.identify_test', - 'castle.test.commands.impersonate_test', 'castle.test.commands.report_device_test', 'castle.test.commands.review_test', + 'castle.test.commands.start_impersonation_test', 'castle.test.commands.track_test', 'castle.test.configuration_test', 'castle.test.context.get_default_test', diff --git a/castle/test/client_test.py b/castle/test/client_test.py index 1038199..0c2802c 100644 --- a/castle/test/client_test.py +++ b/castle/test/client_test.py @@ -52,7 +52,7 @@ def test_init(self): self.assertIsInstance(client.api, APIRequest) @responses.activate - def test_impersonate(self): + def test_start_impersonation(self): response_text = {'success': True} responses.add( responses.POST, @@ -62,10 +62,23 @@ def test_impersonate(self): ) client = Client.from_request(request(), {}) options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'} - self.assertEqual(client.impersonate(options), response_text) + self.assertEqual(client.start_impersonation(options), response_text) @responses.activate - def test_impersonate_failed(self): + def test_end_impersonation(self): + response_text = {'success': True} + responses.add( + responses.DELETE, + 'https://api.castle.io/v1/impersonate', + json=response_text, + status=200 + ) + client = Client.from_request(request(), {}) + options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'} + self.assertEqual(client.end_impersonation(options), response_text) + + @responses.activate + def test_start_impersonation_failed(self): response_text = {} responses.add( responses.POST, @@ -76,7 +89,21 @@ def test_impersonate_failed(self): client = Client.from_request(request(), {}) options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'} with self.assertRaises(ImpersonationFailed): - client.impersonate(options) + client.start_impersonation(options) + + @responses.activate + def test_end_impersonation_failed(self): + response_text = {} + responses.add( + responses.DELETE, + 'https://api.castle.io/v1/impersonate', + json=response_text, + status=200 + ) + client = Client.from_request(request(), {}) + options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'} + with self.assertRaises(ImpersonationFailed): + client.end_impersonation(options) @responses.activate def test_identify_tracked_true(self): diff --git a/castle/test/commands/approve_device_test.py b/castle/test/commands/approve_device_test.py index 2fddef3..74a93cd 100644 --- a/castle/test/commands/approve_device_test.py +++ b/castle/test/commands/approve_device_test.py @@ -9,12 +9,12 @@ def device_token(): class CommandsApproveDeviceTestCase(unittest.TestCase): - def test_build_no_device_token(self): + def test_call_no_device_token(self): with self.assertRaises(InvalidParametersError): - CommandsApproveDevice.build('') + CommandsApproveDevice.call('') - def test_build(self): - command = CommandsApproveDevice.build(device_token()) + def test_call(self): + command = CommandsApproveDevice.call(device_token()) self.assertIsInstance(command, Command) self.assertEqual(command.method, 'put') self.assertEqual(command.path, 'devices/1234/approve') diff --git a/castle/test/commands/authenticate_test.py b/castle/test/commands/authenticate_test.py index f7ca7ec..36a0f93 100644 --- a/castle/test/commands/authenticate_test.py +++ b/castle/test/commands/authenticate_test.py @@ -41,7 +41,7 @@ def test_init(self): obj = CommandsAuthenticate(context) self.assertEqual(obj.context, context) - def test_build(self): + def test_call(self): context = {'test': '1'} options = default_options_plus(context={'spam': True}) @@ -51,26 +51,26 @@ def test_build(self): expected = default_command_with_data(**expected_data) self.assertEqual(CommandsAuthenticate( - context).build(options), expected) + context).call(options), expected) - def test_build_no_event(self): + def test_call_no_event(self): context = {} options = default_options() options.pop('event') with self.assertRaises(InvalidParametersError): - CommandsAuthenticate(context).build(options) + CommandsAuthenticate(context).call(options) - def test_build_no_user_id(self): + def test_call_no_user_id(self): context = {} options = default_options() options.pop('user_id') expected = default_command_with_data(**options) - self.assertEqual(CommandsAuthenticate(context).build(options), expected) + self.assertEqual(CommandsAuthenticate(context).call(options), expected) - def test_build_properties_allowed(self): + def test_call_properties_allowed(self): context = {} options = default_options_plus(properties={'test': '1'}) options.update({'context': context}) @@ -78,9 +78,9 @@ def test_build_properties_allowed(self): expected = default_command_with_data(**options) self.assertEqual(CommandsAuthenticate( - context).build(options), expected) + context).call(options), expected) - def test_build_user_traits_allowed(self): + def test_call_user_traits_allowed(self): context = {} options = default_options_plus(user_traits={'email': 'a@b.com'}) options.update({'context': context}) @@ -88,9 +88,9 @@ def test_build_user_traits_allowed(self): expected = default_command_with_data(**options) self.assertEqual(CommandsAuthenticate( - context).build(options), expected) + context).call(options), expected) - def test_build_risk_policy_allowed(self): + def test_call_risk_policy_allowed(self): context = {} risk_policy = { 'id': 'q-rbeMzBTdW2Fd09sbz55A', @@ -102,4 +102,4 @@ def test_build_risk_policy_allowed(self): options = default_options_plus(risk_policy=risk_policy) expected = default_command_with_data(**options) self.assertEqual(CommandsAuthenticate( - context).build(options), expected) + context).call(options), expected) diff --git a/castle/test/commands/impersonate_test.py b/castle/test/commands/end_impersonation_test.py similarity index 57% rename from castle/test/commands/impersonate_test.py rename to castle/test/commands/end_impersonation_test.py index 570132c..0594fb4 100644 --- a/castle/test/commands/impersonate_test.py +++ b/castle/test/commands/end_impersonation_test.py @@ -1,6 +1,6 @@ from castle.test import mock, unittest from castle.command import Command -from castle.commands.impersonate import CommandsImpersonate +from castle.commands.end_impersonation import CommandsEndImpersonation from castle.errors import InvalidParametersError from castle.utils.clone import UtilsClone @@ -19,15 +19,6 @@ def default_options_plus(**extra): def default_command_with_data(**data): - """What we expect the impersonate command to look like.""" - return Command( - method='post', - path='impersonate', - data=dict(sent_at=mock.sentinel.timestamp, **data) - ) - - -def default_reset_command_with_data(**data): """What we expect the impersonate command to look like.""" return Command( method='delete', @@ -36,20 +27,21 @@ def default_reset_command_with_data(**data): ) -class CommandsImpersonateTestCase(unittest.TestCase): +class CommandsEndImpersonationTestCase(unittest.TestCase): def setUp(self): # patch timestamp to return a known value - timestamp_patcher = mock.patch('castle.commands.impersonate.generate_timestamp.call') + timestamp_patcher = mock.patch( + 'castle.commands.end_impersonation.generate_timestamp.call') self.mock_timestamp = timestamp_patcher.start() self.mock_timestamp.return_value = mock.sentinel.timestamp self.addCleanup(timestamp_patcher.stop) def test_init(self): context = mock.sentinel.test_init_context - obj = CommandsImpersonate(context) + obj = CommandsEndImpersonation(context) self.assertEqual(obj.context, context) - def test_build(self): + def test_call(self): context = {'lang': 'es'} options = default_options_plus( context={'local time': '8:53pm', 'ip': '127.0.0.1', 'user_agent': 'Chrome'} @@ -63,46 +55,28 @@ def test_build(self): ) expected = default_command_with_data(**expected_data) - self.assertEqual(CommandsImpersonate(context).build(options), expected) - - def test_reset_build(self): - context = {'lang': 'es'} - options = default_options_plus( - reset=True, - context={'lang': 'es', 'local time': '8:53pm', - 'ip': '127.0.0.1', 'user_agent': 'Chrome'} - ) - - # expect the original context to have been merged with the context specified in the options - expected_data = UtilsClone.call(options) - expected_data.update( - context={'lang': 'es', 'local time': '8:53pm', - 'ip': '127.0.0.1', 'user_agent': 'Chrome'} - ) - expected = default_reset_command_with_data(**expected_data) - - self.assertEqual(CommandsImpersonate(context).build(options), expected) + self.assertEqual(CommandsEndImpersonation(context).call(options), expected) - def test_build_no_event(self): + def test_call_no_event(self): context = {} options = default_options() options.pop('user_id') with self.assertRaises(InvalidParametersError): - CommandsImpersonate(context).build(options) + CommandsEndImpersonation(context).call(options) - def test_build_no_context_ip(self): + def test_call_no_context_ip(self): context = {} options = default_options() options['context'].pop('ip') with self.assertRaises(InvalidParametersError): - CommandsImpersonate(context).build(options) + CommandsEndImpersonation(context).call(options) - def test_build_no_context_user_agent(self): + def test_call_no_context_user_agent(self): context = {} options = default_options() options['context'].pop('user_agent') with self.assertRaises(InvalidParametersError): - CommandsImpersonate(context).build(options) + CommandsEndImpersonation(context).call(options) diff --git a/castle/test/commands/get_device_test.py b/castle/test/commands/get_device_test.py index 80b87f5..d8457e7 100644 --- a/castle/test/commands/get_device_test.py +++ b/castle/test/commands/get_device_test.py @@ -9,12 +9,12 @@ def device_token(): class CommandsGetDeviceTestCase(unittest.TestCase): - def test_build_no_device_token(self): + def test_call_no_device_token(self): with self.assertRaises(InvalidParametersError): - CommandsGetDevice.build('') + CommandsGetDevice.call('') - def test_build(self): - command = CommandsGetDevice.build(device_token()) + def test_call(self): + command = CommandsGetDevice.call(device_token()) self.assertIsInstance(command, Command) self.assertEqual(command.method, 'get') self.assertEqual(command.path, 'devices/1234') diff --git a/castle/test/commands/get_devices_for_user_test.py b/castle/test/commands/get_devices_for_user_test.py index f339aa8..70e462e 100644 --- a/castle/test/commands/get_devices_for_user_test.py +++ b/castle/test/commands/get_devices_for_user_test.py @@ -9,12 +9,12 @@ def user_id(): class CommandsGetDevicesForUserTestCase(unittest.TestCase): - def test_build_no_user_id(self): + def test_call_no_user_id(self): with self.assertRaises(InvalidParametersError): - CommandsGetDevicesForUser.build('') + CommandsGetDevicesForUser.call('') - def test_build(self): - command = CommandsGetDevicesForUser.build(user_id()) + def test_call(self): + command = CommandsGetDevicesForUser.call(user_id()) self.assertIsInstance(command, Command) self.assertEqual(command.method, 'get') self.assertEqual(command.path, 'users/1234/devices') diff --git a/castle/test/commands/identify_test.py b/castle/test/commands/identify_test.py index 30b585c..5c29489 100644 --- a/castle/test/commands/identify_test.py +++ b/castle/test/commands/identify_test.py @@ -39,7 +39,7 @@ def test_init(self): obj = CommandsIdentify(context) self.assertEqual(obj.context, context) - def test_build(self): + def test_call(self): context = {'test': '1'} options = default_options_plus(context={'color': 'blue'}) @@ -48,29 +48,29 @@ def test_build(self): expected_data.update(context={'test': '1', 'color': 'blue'}) expected = default_command_with_data(**expected_data) - self.assertEqual(CommandsIdentify(context).build(options), expected) + self.assertEqual(CommandsIdentify(context).call(options), expected) - def test_build_no_user_id(self): + def test_call_no_user_id(self): context = {} options = default_options() options.pop('user_id') expected = default_command_with_data(**options) - self.assertEqual(CommandsIdentify(context).build(options), expected) + self.assertEqual(CommandsIdentify(context).call(options), expected) - def test_build_properties_not_allowed(self): + def test_call_properties_not_allowed(self): context = {'test': '1'} options = default_options_plus(properties={'hair': 'blonde'}) with self.assertRaises(InvalidParametersError): - CommandsIdentify(context).build(options) + CommandsIdentify(context).call(options) - def test_build_user_traits_allowed(self): + def test_call_user_traits_allowed(self): context = {} options = default_options_plus(user_traits={'email': 'identity@its.me.com'}) options.update({'context': context}) expected = default_command_with_data(**options) - self.assertEqual(CommandsIdentify(context).build(options), expected) + self.assertEqual(CommandsIdentify(context).call(options), expected) diff --git a/castle/test/commands/report_device_test.py b/castle/test/commands/report_device_test.py index a11f298..9cda582 100644 --- a/castle/test/commands/report_device_test.py +++ b/castle/test/commands/report_device_test.py @@ -9,12 +9,12 @@ def device_token(): class CommandsReportDeviceTestCase(unittest.TestCase): - def test_build_no_device_token(self): + def test_call_no_device_token(self): with self.assertRaises(InvalidParametersError): - CommandsReportDevice.build('') + CommandsReportDevice.call('') - def test_build(self): - command = CommandsReportDevice.build(device_token()) + def test_call(self): + command = CommandsReportDevice.call(device_token()) self.assertIsInstance(command, Command) self.assertEqual(command.method, 'put') self.assertEqual(command.path, 'devices/1234/report') diff --git a/castle/test/commands/review_test.py b/castle/test/commands/review_test.py index 8efd872..bb4b5b2 100644 --- a/castle/test/commands/review_test.py +++ b/castle/test/commands/review_test.py @@ -9,12 +9,12 @@ def review_id(): class CommandsReviewTestCase(unittest.TestCase): - def test_build_no_review_id(self): + def test_call_no_review_id(self): with self.assertRaises(InvalidParametersError): - CommandsReview.build('') + CommandsReview.call('') - def test_build(self): - command = CommandsReview.build(review_id()) + def test_call(self): + command = CommandsReview.call(review_id()) self.assertIsInstance(command, Command) self.assertEqual(command.method, 'get') self.assertEqual(command.path, "reviews/1234") diff --git a/castle/test/commands/start_impersonation_test.py b/castle/test/commands/start_impersonation_test.py new file mode 100644 index 0000000..9730756 --- /dev/null +++ b/castle/test/commands/start_impersonation_test.py @@ -0,0 +1,82 @@ +from castle.test import mock, unittest +from castle.command import Command +from castle.commands.start_impersonation import CommandsStartImpersonation +from castle.errors import InvalidParametersError +from castle.utils.clone import UtilsClone + + +def default_options(): + """Default options include all required fields.""" + return {'properties': {'impersonator': 'admin'}, 'user_id': '1234', + 'context': {'ip': '127.0.0.1', 'user_agent': 'Chrome'}} + + +def default_options_plus(**extra): + """Default options plus the given extra fields.""" + options = default_options() + options.update(extra) + return options + + +def default_command_with_data(**data): + """What we expect the impersonate command to look like.""" + return Command( + method='post', + path='impersonate', + data=dict(sent_at=mock.sentinel.timestamp, **data) + ) + + +class CommandsStartImpersonationTestCase(unittest.TestCase): + def setUp(self): + # patch timestamp to return a known value + timestamp_patcher = mock.patch( + 'castle.commands.start_impersonation.generate_timestamp.call') + self.mock_timestamp = timestamp_patcher.start() + self.mock_timestamp.return_value = mock.sentinel.timestamp + self.addCleanup(timestamp_patcher.stop) + + def test_init(self): + context = mock.sentinel.test_init_context + obj = CommandsStartImpersonation(context) + self.assertEqual(obj.context, context) + + def test_call(self): + context = {'lang': 'es'} + options = default_options_plus( + context={'local time': '8:53pm', 'ip': '127.0.0.1', 'user_agent': 'Chrome'} + ) + + # expect the original context to have been merged with the context specified in the options + expected_data = UtilsClone.call(options) + expected_data.update( + context={'lang': 'es', 'local time': '8:53pm', + 'ip': '127.0.0.1', 'user_agent': 'Chrome'} + ) + expected = default_command_with_data(**expected_data) + + self.assertEqual(CommandsStartImpersonation(context).call(options), expected) + + def test_call_no_event(self): + context = {} + options = default_options() + options.pop('user_id') + + with self.assertRaises(InvalidParametersError): + CommandsStartImpersonation(context).call(options) + + def test_call_no_context_ip(self): + context = {} + options = default_options() + options['context'].pop('ip') + + with self.assertRaises(InvalidParametersError): + CommandsStartImpersonation(context).call(options) + + def test_call_no_context_user_agent(self): + context = {} + options = default_options() + options['context'].pop('user_agent') + + with self.assertRaises(InvalidParametersError): + CommandsStartImpersonation(context).call(options) diff --git a/castle/test/commands/track_test.py b/castle/test/commands/track_test.py index 3acc633..6e7f812 100644 --- a/castle/test/commands/track_test.py +++ b/castle/test/commands/track_test.py @@ -39,7 +39,7 @@ def test_init(self): obj = CommandsTrack(context) self.assertEqual(obj.context, context) - def test_build(self): + def test_call(self): context = {'lang': 'es'} options = default_options_plus(context={'local time': '8:53pm'}) @@ -48,26 +48,26 @@ def test_build(self): expected_data.update(context={'lang': 'es', 'local time': '8:53pm'}) expected = default_command_with_data(**expected_data) - self.assertEqual(CommandsTrack(context).build(options), expected) + self.assertEqual(CommandsTrack(context).call(options), expected) - def test_build_no_event(self): + def test_call_no_event(self): context = {} options = default_options() options.pop('event') with self.assertRaises(InvalidParametersError): - CommandsTrack(context).build(options) + CommandsTrack(context).call(options) - def test_build_properties_allowed(self): + def test_call_properties_allowed(self): context = {} options = default_options_plus(properties={'face': 'handsome'}) options.update({'context': context}) expected = default_command_with_data(**options) - self.assertEqual(CommandsTrack(context).build(options), expected) + self.assertEqual(CommandsTrack(context).call(options), expected) - def test_build_user_traits_allowed(self): + def test_call_user_traits_allowed(self): context = {} options = default_options_plus( user_traits={'email': 'track@all.the.things.com'}) @@ -75,4 +75,4 @@ def test_build_user_traits_allowed(self): expected = default_command_with_data(**options) - self.assertEqual(CommandsTrack(context).build(options), expected) + self.assertEqual(CommandsTrack(context).call(options), expected)