def publish(self, name, data, timeout=None): """Publishes a message on this channel. :Parameters: - `name`: the name for this message - `data`: the data for this message """ message = Message(name, data) if self.encrypted: message.encrypt(self.__cipher) if self.ably.options.use_text_protocol: request_body = message.as_json() else: request_body = message.as_thrift() path = '/channels/%s/publish' % self.__name headers = HttpUtils.default_post_headers(not self.ably.options.use_text_protocol) return self.ably.http.post( path, headers=headers, body=request_body, timeout=timeout ).json()
def test_encode(self): for item in self.items: # need to reset iv self.cipher_params = CipherParams(**self.params) self.cipher = get_cipher(self.cipher_params) data = self.get_encoded(item['encoded']) expected = item['encrypted'] message = Message(item['encoded']['name'], data) message.encrypt(self.cipher) as_dict = message.as_dict() assert as_dict['data'] == expected['data'] assert as_dict['encoding'] == expected['encoding']
def test_encode(self): for item in self.items: # need to reset iv self.cipher_params = CipherParams(**self.params) self.cipher = get_cipher(self.cipher_params) data = self.get_encoded(item["encoded"]) expected = item["encrypted"] message = Message(item["encoded"]["name"], data) message.encrypt(self.cipher) as_dict = message.as_dict() self.assertEqual(as_dict["data"], expected["data"]) self.assertEqual(as_dict["encoding"], expected["encoding"])
def test_decode(self): for item in self.items: assert item['encoded']['name'] == item['encrypted']['name'] message = Message.from_encoded(item['encrypted'], self.cipher) assert message.encoding == '' expected_data = self.get_encoded(item['encoded']) assert expected_data == message.data
def test_decode(self): for item in self.items: self.assertEqual(item["encoded"]["name"], item["encrypted"]["name"]) message = Message.from_dict(item["encrypted"], self.cipher) self.assertEqual(message.encoding, "") expected_data = self.get_encoded(item["encoded"]) self.assertEqual(expected_data, message.data)
def test_decode_array(self): items_encrypted = [item['encrypted'] for item in self.items] messages = Message.from_encoded_array(items_encrypted, self.cipher) for i, message in enumerate(messages): assert message.encoding == '' expected_data = self.get_encoded(self.items[i]['encoded']) assert expected_data == message.data
def test_interoperability(self): name = self.get_channel_name('persisted:interoperability_channel') channel = self.ably.channels[name] url = 'https://%s/channels/%s/messages' % (test_vars["host"], name) key = test_vars['keys'][0] auth = (key['key_name'], key['key_secret']) type_mapping = { 'string': six.text_type, 'jsonObject': dict, 'jsonArray': list, 'binary': bytearray, } root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) path = os.path.join(root_dir, 'submodules', 'test-resources', 'messages-encoding.json') with open(path) as f: data = json.load(f) for input_msg in data['messages']: data = input_msg['data'] encoding = input_msg['encoding'] expected_type = input_msg['expectedType'] if expected_type == 'binary': expected_value = input_msg.get('expectedHexValue') expected_value = expected_value.encode('ascii') expected_value = binascii.a2b_hex(expected_value) else: expected_value = input_msg.get('expectedValue') # 1) channel.publish(data=expected_value) r = requests.get(url, auth=auth) item = r.json()[0] assert item.get('encoding') == encoding if encoding == 'json': assert json.loads(item['data']) == json.loads(data) else: assert item['data'] == data # 2) channel.publish( messages=[Message(data=data, encoding=encoding)]) history = channel.history() message = history.items[0] assert message.data == expected_value assert type(message.data) == type_mapping[expected_type]
def __publish_request_body(self, name=None, data=None, client_id=None, extras=None, messages=None): """ Helper private method, separated from publish() to test RSL1j """ if not messages: messages = [Message(name, data, client_id, extras=extras)] # Idempotent publishing if self.ably.options.idempotent_rest_publishing: # RSL1k1 if all(message.id is None for message in messages): base_id = base64.b64encode(os.urandom(12)).decode() for serial, message in enumerate(messages): message.id = u'{}:{}'.format(base_id, serial) request_body_list = [] for m in messages: if m.client_id == '*': raise IncompatibleClientIdException( 'Wildcard client_id is reserved and cannot be used when publishing messages', 400, 40012) elif m.client_id is not None and not self.ably.auth.can_assume_client_id( m.client_id): raise IncompatibleClientIdException( 'Cannot publish with client_id \'{}\' as it is incompatible with the ' 'current configured client_id \'{}\''.format( m.client_id, self.ably.auth.client_id), 400, 40012) if self.cipher: m.encrypt(self.__cipher) request_body_list.append(m) request_body = [ message.as_dict(binary=self.ably.options.use_binary_protocol) for message in request_body_list ] if len(request_body) == 1: request_body = request_body[0] return request_body
def test_publish_message_list(self): channel = self.ably.channels[self.get_channel_name( 'persisted:message_list_channel')] expected_messages = [ Message("name-{}".format(i), str(i)) for i in range(3) ] channel.publish(messages=expected_messages) # Get the history for this channel history = channel.history() messages = history.items assert messages is not None, "Expected non-None messages" assert len(messages) == len(expected_messages), "Expected 3 messages" for m, expected_m in zip(messages, reversed(expected_messages)): assert m.name == expected_m.name assert m.data == expected_m.data
async def test_message_attr(self): publish0 = self.ably.channels[self.get_channel_name( 'persisted:publish_message_attr')] messages = [ Message('publish', {"test": "This is a JSONObject message payload"}, client_id='client_id') ] await publish0.publish(messages=messages) # Get the history for this channel history = await publish0.history() message = history.items[0] assert isinstance(message, Message) assert message.id assert message.name assert message.data == {'test': 'This is a JSONObject message payload'} assert message.encoding == '' assert message.client_id == 'client_id' assert isinstance(message.timestamp, int)
async def test_message_list_generate_one_request(self): channel = self.ably.channels[self.get_channel_name( 'persisted:message_list_channel_one_request')] expected_messages = [ Message("name-{}".format(i), str(i)) for i in range(3) ] with mock.patch('ably.rest.rest.Http.post', wraps=channel.ably.http.post) as post_mock: await channel.publish(messages=expected_messages) assert post_mock.call_count == 1 if self.use_binary_protocol: messages = msgpack.unpackb(post_mock.call_args[1]['body']) else: messages = json.loads(post_mock.call_args[1]['body']) for i, message in enumerate(messages): assert message['name'] == 'name-' + str(i) assert message['data'] == str(i)
def test_publish_message_list(self): channel = self.ably.channels[self.protocol_channel_name( 'persisted:message_list_channel')] expected_messages = [ Message("name-{}".format(i), str(i)) for i in range(3) ] channel.publish(messages=expected_messages) # Get the history for this channel history = channel.history() messages = history.items self.assertIsNotNone(messages, msg="Expected non-None messages") self.assertEqual(len(messages), len(expected_messages), msg="Expected 3 messages") for m, expected_m in zip(messages, reversed(expected_messages)): self.assertEqual(m.name, expected_m.name) self.assertEqual(m.data, expected_m.data)
def test_message_list_generate_one_request(self): channel = self.ably.channels[self.protocol_channel_name( 'persisted:message_list_channel_one_request')] expected_messages = [ Message("name-{}".format(i), six.text_type(i)) for i in range(3) ] with mock.patch('ably.rest.rest.Http.post', wraps=channel.ably.http.post) as post_mock: channel.publish(messages=expected_messages) self.assertEqual(post_mock.call_count, 1) if self.use_binary_protocol: messages = msgpack.unpackb(post_mock.call_args[1]['body'], encoding='utf-8') else: messages = json.loads(post_mock.call_args[1]['body']) for i, message in enumerate(messages): self.assertEqual(message['name'], 'name-' + str(i)) self.assertEqual(message['data'], six.text_type(i))
def test_message_attr(self): publish0 = self.ably.channels[self.protocol_channel_name( 'persisted:publish_message_attr')] messages = [ Message('publish', {"test": "This is a JSONObject message payload"}, client_id='client_id') ] publish0.publish("publish", messages=messages) # Get the history for this channel history = publish0.history() message = history.items[0] self.assertIsInstance(message, Message) self.assertTrue(message.id) self.assertTrue(message.name) self.assertEqual( message.data, {six.u('test'): six.u('This is a JSONObject message payload')}) self.assertEqual(message.encoding, '') self.assertEqual(message.client_id, 'client_id') self.assertIsInstance(message.timestamp, int)
def test_decode_with_invalid_encoding(self): data = six.u('foó') encoded = base64.b64encode(data.encode('utf-8')) decoded_data = Message.decode(encoded, 'foo/bar/utf-8/base64') self.assertEqual(decoded_data['data'], data) self.assertEqual(decoded_data['encoding'], 'foo/bar')
def test_decode_with_invalid_encoding(self): data = 'foó' encoded = base64.b64encode(data.encode('utf-8')) decoded_data = Message.decode(encoded, 'foo/bar/utf-8/base64') assert decoded_data['data'] == data assert decoded_data['encoding'] == 'foo/bar'