def test_ssl_should_be_boolean(self): Config(app_id=u'4', key=u'key', secret=u'secret', ssl=False) Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True) self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=u'secret', ssl=4))
def test_host_behaviour(self): conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True) self.assertEqual(conf.host, u'api.pusherapp.com', u'default host should be correct') conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu') self.assertEqual(conf.host, u'api-eu.pusher.com', u'host should be overriden by cluster setting') conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=u'foo') self.assertEqual(conf.host, u'foo', u'host should be overriden by host setting') conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu', host=u'plah') self.assertEqual(conf.host, u'plah', u'host should be used in preference to cluster')
def test_secret_should_be_text(self): self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=4, ssl=False)) self.assertRaises( TypeError, lambda: Config( app_id=u'4', key=u'key', secret=b'secret', ssl=False))
def test_port_should_be_number(self): Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, port=400) self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, port=u'400'))
def test_port_behaviour(self): conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True) self.assertEqual(conf.port, 443, u'port should be 443 for ssl') conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=False) self.assertEqual(conf.port, 80, u'port should be 80 for non ssl') conf = Config(app_id=u'4', key=u'key', secret=u'secret', ssl=False, port=4000) self.assertEqual(conf.port, 4000, u'the port setting override the default')
def test_host_should_be_text(self): Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=u'foo') self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=b'foo')) self.assertRaises( TypeError, lambda: Config( app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=4))
def test_initialize_from_env(self): with mock.patch.object(os, "environ", new={"PUSHER_URL": "https://*****:*****@somehost/apps/42"}): conf = Config.from_env() self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u"plah") self.assertEqual(conf.secret, u"bob") self.assertEqual(conf.host, u"somehost") self.assertEqual(conf.app_id, u"42") with mock.patch.object(os, "environ", new={"PUSHER_DSN": "https://*****:*****@somehost/apps/42"}): conf = Config.from_env("PUSHER_DSN") self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u"plah") self.assertEqual(conf.secret, u"bob") self.assertEqual(conf.host, u"somehost") self.assertEqual(conf.app_id, u"42")
def test_validate_webhook_bad_types(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') conf.validate_webhook(u'key', u'signature', u'body') # These things are meant to be human readable, so enforcing being text is # sensible. with mock.patch('time.time') as time_mock: self.assertRaises( TypeError, lambda: conf.validate_webhook(4, u'signature', u'body')) self.assertRaises( TypeError, lambda: conf.validate_webhook(b'test', u'signature', u'body')) self.assertRaises( TypeError, lambda: conf.validate_webhook(u'key', 4, u'body')) self.assertRaises( TypeError, lambda: conf.validate_webhook(u'key', b'signature', u'body')) self.assertRaises( TypeError, lambda: conf.validate_webhook(u'key', u'signature', 4)) self.assertRaises( TypeError, lambda: conf.validate_webhook(u'key', u'signature', b'body')) time_mock.assert_not_called()
def test_cluster_should_be_text(self): Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu') self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=b'eu')) self.assertRaises( TypeError, lambda: Config( app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=4) )
def test_validate_webhook_bad_time(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") body = u'{"time_ms": 1000000}' signature = six.text_type(hmac.new(conf.secret.encode("utf8"), body.encode("utf8"), hashlib.sha256).hexdigest()) with mock.patch("time.time", return_value=1301): self.assertEqual(conf.validate_webhook(conf.key, signature, body), None)
def test_initialize_from_url(self): self.assertRaises(TypeError, lambda: Config.from_url(4)) self.assertRaises(TypeError, lambda: Config.from_url(b"http://*****:*****@host/apps/4")) self.assertRaises(Exception, lambda: Config.from_url(u"httpsahsutaeh")) conf = Config.from_url(u"http://*****:*****@host/apps/4") self.assertEqual(conf.ssl, False) self.assertEqual(conf.key, u"foo") self.assertEqual(conf.secret, u"bar") self.assertEqual(conf.host, u"host") self.assertEqual(conf.app_id, u"4") conf = Config.from_url(u"https://*****:*****@host/apps/4") self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u"foo") self.assertEqual(conf.secret, u"bar") self.assertEqual(conf.host, u"host") self.assertEqual(conf.app_id, u"4")
def test_initialize_from_url(self): self.assertRaises(TypeError, lambda: Config.from_url(4)) self.assertRaises( TypeError, lambda: Config.from_url(b'http://*****:*****@host/apps/4')) self.assertRaises(Exception, lambda: Config.from_url(u'httpsahsutaeh')) conf = Config.from_url(u'http://*****:*****@host/apps/4') self.assertEqual(conf.ssl, False) self.assertEqual(conf.key, u'foo') self.assertEqual(conf.secret, u'bar') self.assertEqual(conf.host, u'host') self.assertEqual(conf.app_id, u'4') conf = Config.from_url(u'https://*****:*****@host/apps/4') self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u'foo') self.assertEqual(conf.secret, u'bar') self.assertEqual(conf.host, u'host') self.assertEqual(conf.app_id, u'4')
def test_validate_webhook_bad_signature(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") body = u"some body" signature = u"some signature" with mock.patch("time.time") as time_mock: self.assertEqual(conf.validate_webhook(conf.key, signature, body), None) time_mock.assert_not_called()
def test_validate_webhook_bad_time(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') body = u'{"time_ms": 1000000}' signature = six.text_type( hmac.new(conf.secret.encode('utf8'), body.encode('utf8'), hashlib.sha256).hexdigest()) with mock.patch('time.time', return_value=1301): self.assertEqual(conf.validate_webhook(conf.key, signature, body), None)
def test_authenticate_subscription_for_private_channels(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') expected = { u'auth': u"foo:076740bd063f0299742a73bc5aac88900e5f35cb0185a1facbf45d326b5b204b" } self.assertEqual( conf.authenticate_subscription(u'private-channel', u'34523'), expected)
def test_validate_webhook_bad_signature(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') body = u'some body' signature = u'some signature' with mock.patch('time.time') as time_mock: self.assertEqual(conf.validate_webhook(conf.key, signature, body), None) time_mock.assert_not_called()
def test_validate_webhook_bad_key(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") body = u"some body" signature = six.text_type( hmac.new(conf.secret.encode(u"utf8"), body.encode(u"utf8"), hashlib.sha256).hexdigest() ) with mock.patch("time.time") as time_mock: self.assertEqual(conf.validate_webhook(u"badkey", signature, body), None) time_mock.assert_not_called()
def test_authenticate_subscription_types(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') self.assertRaises( TypeError, lambda: conf.authenticate_subscription(b'plah', u'34554')) self.assertRaises( TypeError, lambda: conf.authenticate_subscription(u'plah', b'324435')) self.assertRaises( ValueError, lambda: conf.authenticate_subscription(u'::', u'345345'))
def test_validate_webhook_bad_key(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') body = u'some body' signature = six.text_type( hmac.new(conf.secret.encode(u'utf8'), body.encode(u'utf8'), hashlib.sha256).hexdigest()) with mock.patch('time.time') as time_mock: self.assertEqual(conf.validate_webhook(u'badkey', signature, body), None) time_mock.assert_not_called()
def test_initialize_from_env(self): with mock.patch.object( os, 'environ', new={'PUSHER_URL': 'https://*****:*****@somehost/apps/42'}): conf = Config.from_env() self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u'plah') self.assertEqual(conf.secret, u'bob') self.assertEqual(conf.host, u'somehost') self.assertEqual(conf.app_id, u'42') with mock.patch.object( os, 'environ', new={'PUSHER_DSN': 'https://*****:*****@somehost/apps/42'}): conf = Config.from_env('PUSHER_DSN') self.assertEqual(conf.ssl, True) self.assertEqual(conf.key, u'plah') self.assertEqual(conf.secret, u'bob') self.assertEqual(conf.host, u'somehost') self.assertEqual(conf.app_id, u'42')
def test_get_signature_generation(self): conf = Config.from_url(u'http://*****:*****@somehost/apps/4') expected = { u'auth_key': u'key', u'auth_signature': u'5c49f04a95eedc9028b1e0e8de7c2c7ad63504a0e3b5c145d2accaef6c14dbac', u'auth_timestamp': u'1000', u'auth_version': u'1.0', u'body_md5': u'd41d8cd98f00b204e9800998ecf8427e', u'foo': u'bar' } with mock.patch('time.time', return_value=1000): req = Request(conf, u'GET', u'/some/obscure/api', {u'foo': u'bar'}) self.assertEqual(req.query_params, expected)
def test_authenticate_subscription_for_presence_channels(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") custom_data = {u"user_id": u"fred", u"user_info": {u"key": u"value"}} expected = { u"auth": u"foo:fbbc6d8acc85fc807bba060e2df45aba33deb8ad44cbee1633675b3ce73f4817", u"channel_data": u'{"user_id":"fred","user_info":{"key":"value"}}', } with mock.patch("json.dumps", return_value=expected[u"channel_data"]) as dumps_mock: actual = conf.authenticate_subscription(u"presence-channel", u"34543245", custom_data) self.assertEqual(actual, expected) dumps_mock.assert_called_once_with(custom_data)
def test_validate_webhook_bad_types(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") conf.validate_webhook(u"key", u"signature", u"body") # These things are meant to be human readable, so enforcing being text is # sensible. with mock.patch("time.time") as time_mock: self.assertRaises(TypeError, lambda: conf.validate_webhook(4, u"signature", u"body")) self.assertRaises(TypeError, lambda: conf.validate_webhook(b"test", u"signature", u"body")) self.assertRaises(TypeError, lambda: conf.validate_webhook(u"key", 4, u"body")) self.assertRaises(TypeError, lambda: conf.validate_webhook(u"key", b"signature", u"body")) self.assertRaises(TypeError, lambda: conf.validate_webhook(u"key", u"signature", 4)) self.assertRaises(TypeError, lambda: conf.validate_webhook(u"key", u"signature", b"body")) time_mock.assert_not_called()
def test_post_signature_generation(self): conf = Config.from_url(u'http://*****:*****@somehost/apps/4') expected = { u'auth_key': u'key', u'auth_signature': u'e05fa4cafee86311746ee3981d5581a5e4e87c27bbab0aeb1059e2df5c90258b', u'auth_timestamp': u'1000', u'auth_version': u'1.0', u'body_md5': u'94232c5b8fc9272f6f73a1e36eb68fcf' } with mock.patch('time.time', return_value=1000): # patching this, because json can be unambiguously parsed, but not # unambiguously generated (think whitespace). with mock.patch('json.dumps', return_value='{"foo": "bar"}') as json_dumps_mock: req = Request(conf, u'POST', u'/some/obscure/api', {u'foo': u'bar'}) self.assertEqual(req.query_params, expected) json_dumps_mock.assert_called_once({u"foo": u"bar"})
def test_authenticate_subscription_for_presence_channels(self): conf = Config.from_url(u'http://*****:*****@host/apps/4') custom_data = {u'user_id': u'fred', u'user_info': {u'key': u'value'}} expected = { u'auth': u"foo:fbbc6d8acc85fc807bba060e2df45aba33deb8ad44cbee1633675b3ce73f4817", u'channel_data': u"{\"user_id\":\"fred\",\"user_info\":{\"key\":\"value\"}}" } with mock.patch('json.dumps', return_value=expected[u'channel_data']) as dumps_mock: actual = conf.authenticate_subscription(u'presence-channel', u'34543245', custom_data) self.assertEqual(actual, expected) dumps_mock.assert_called_once_with(custom_data)
def setUp(self): self.pusher = Pusher(config=Config.from_url(u'http://*****:*****@somehost/apps/4'))
def test_authenticate_subscription_types(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") self.assertRaises(TypeError, lambda: conf.authenticate_subscription(b"plah", u"34554")) self.assertRaises(TypeError, lambda: conf.authenticate_subscription(u"plah", b"324435")) self.assertRaises(ValueError, lambda: conf.authenticate_subscription(u"::", u"345345"))
def test_should_be_constructable(self): Config(app_id=u'4', key=u'key', secret=u'secret', ssl=False)
def test_authenticate_subscription_for_private_channels(self): conf = Config.from_url(u"http://*****:*****@host/apps/4") expected = {u"auth": u"foo:076740bd063f0299742a73bc5aac88900e5f35cb0185a1facbf45d326b5b204b"} self.assertEqual(conf.authenticate_subscription(u"private-channel", u"34523"), expected)
def test_ssl_should_be_required(self): self.assertRaises( TypeError, lambda: Config(app_id=u'4', key=u'key', secret=b'secret'))
def setUp(self): self.pusher = Pusher( config=Config.from_url(u'http://*****:*****@somehost/apps/4'))