def test_create_success(self, parent_id): data = self.minimal_data.copy() if parent_id: data["parent_id"] = parent_id self.register_get_comment_response({"thread_id": "test_thread", "id": parent_id}) self.register_post_comment_response( {"id": "test_comment", "username": self.user.username}, thread_id="test_thread", parent_id=parent_id ) saved = self.save_and_reserialize(data) expected_url = ( "/api/v1/comments/{}".format(parent_id) if parent_id else "/api/v1/threads/test_thread/comments" ) self.assertEqual(urlparse(httpretty.last_request().path).path, expected_url) self.assertEqual( httpretty.last_request().parsed_body, { "course_id": [unicode(self.course.id)], "body": ["Test body"], "user_id": [str(self.user.id)], } ) self.assertEqual(saved["id"], "test_comment") self.assertEqual(saved["parent_id"], parent_id)
def test_create_session_with_location_hint(self): httpretty.register_uri( httpretty.POST, u("https://api.opentok.com/session/create"), body=u( '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sessions><Session><session_id>1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg</session_id><partner_id>123456</partner_id><create_dt>Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>' ), status=200, content_type=u("text/xml"), ) session = self.opentok.create_session(location="12.34.56.78") validate_jwt_header(self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to(contain(u("OpenTok-Python-SDK/") + __version__)) # ordering of keys is non-deterministic, must parse the body to see if it is correct body = parse_qs(httpretty.last_request().body) expect(body).to(have_key(b("location"), [b("12.34.56.78")])) expect(body).to(have_key(b("p2p.preference"), [b("enabled")])) expect(session).to(be_a(Session)) expect(session).to( have_property( u("session_id"), u("1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg") ) ) expect(session).to(have_property(u("media_mode"), MediaModes.relayed)) expect(session).to(have_property(u("location"), u("12.34.56.78")))
def test_send_questions(self): httpretty.register_uri( httpretty.POST, "https://api.pushover.net/1/messages.json", status=200 ) test_params = [ "title=PushOverflow%3A+TEST", "priority=0", "url=http%3A%2F%2FTEST.stackexchange.com%2Fquestions%3Fsort" "%3Dnewest", "token=APP_KEY", "user=USER_KEY", "message=2+new+questions+posted", "url_title=Open+TEST.stackexchange.com" ] questions = [{"title": "TITLE 1", "link": "LINK_1"}, {"title": "TITLE 2", "link": "LINK_2"}] del self.test_config["Pushover"]["device"] success = cli.send_questions_to_pushover( self.test_config["Pushover"], "TEST", questions) self.assertTrue(success) self.assertEqual(httpretty.last_request().method, "POST") body = httpretty.last_request().body self.assertEqual(len(body.rsplit(b"&")), 7) for param in test_params: self.assertTrue(param in str(body))
def test_login(self): httpretty.register_uri( httpretty.POST, "http://example.com/api_jsonrpc.php", body=json.dumps({ "jsonrpc": "2.0", "result": "0424bd59b807674191e7d77572075f33", "id": 0 }), ) zapi = ZabbixAPI('http://example.com') zapi.login('mylogin', 'mypass') # Check request self.assertEqual( httpretty.last_request().body, json.dumps({ 'jsonrpc': '2.0', 'method': 'user.login', 'params': {'user': '******', 'password': '******'}, 'id': 0, }) ) self.assertEqual( httpretty.last_request().headers['content-type'], 'application/json-rpc' ) self.assertEqual( httpretty.last_request().headers['user-agent'], 'python/pyzabbix' ) # Check response self.assertEqual(zapi.auth, "0424bd59b807674191e7d77572075f33")
def test_mesos_disk_collector_when_connection_error(self): settings = DiskCollectorSettings( http_api_url=self.agent_api_url, executor_id_json_path=self.executor_id_json_path, disk_usage_json_path=self.disk_usage_json_path, disk_collection_timeout=self.collection_timeout, disk_collection_interval=self.collection_interval ) def exception_callback(request, uri, headers): raise ConnectionError httpretty.register_uri( method=httpretty.GET, uri="http://localhost:5051/containers", body=exception_callback ) collector = MesosDiskCollector(self.sandbox_path, settings) def wait(): collector.sample() if collector._thread is not None: collector._thread.event.wait() self.assertEquals(collector.value, 0) wait() self.assertEquals(collector.value, LOOK_UP_ERROR_VALUE) self.assertEquals(httpretty.last_request().method, "GET") self.assertEquals(httpretty.last_request().path, "/containers")
def test_delete_archive(self): archive_id = u('ARCHIVEID') archive = Archive(self.opentok, { u('createdAt'): 1395183243556, u('duration'): 0, u('id'): archive_id, u('name'): u(''), u('partnerId'): 123456, u('reason'): u(''), u('sessionId'): u('SESSIONID'), u('size'): 0, u('status'): u('available'), u('hasAudio'): True, u('hasVideo'): True, u('outputMode'): OutputModes.composed.value, u('url'): None, }) httpretty.register_uri(httpretty.DELETE, u('https://api.opentok.com/v2/partner/{0}/archive/{1}').format(self.api_key, archive_id), body=u(''), status=204) archive.delete() validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')]) expect(httpretty.last_request().headers[u('user-agent')]).to(contain(u('OpenTok-Python-SDK/')+__version__)) expect(httpretty.last_request().headers[u('content-type')]).to(equal(u('application/json')))
def test_get_from_date_issues(self): """ Test get_from_issues API call """ issue = read_file('data/github_request_from_2016_03_01') httpretty.register_uri(httpretty.GET, GITHUB_ISSUES_URL, body=issue, status=200, forcing_headers={ 'X-RateLimit-Remaining': '20', 'X-RateLimit-Reset': '15' }) from_date = datetime.datetime(2016, 3, 1) client = GitHubClient("zhquan_example", "repo", "aaa", None) raw_issues = [issues for issues in client.get_issues(from_date)] self.assertEqual(len(raw_issues), 1) self.assertEqual(raw_issues[0], issue) # Check requests expected = { 'per_page': ['30'], 'state': ['all'], 'direction': ['asc'], 'since': ['2016-03-01T00:00:00'], 'sort': ['updated'] } self.assertDictEqual(httpretty.last_request().querystring, expected) self.assertEqual(httpretty.last_request().headers["Authorization"], "token aaa")
def test_publishing_succeeds(self): httpretty.enable() httpretty.register_uri(httpretty.POST, self.URL, body='ok') pub.Publisher().publish( version=self.VERSION, databases=[ StubDatabase(b'lorem', 1), StubDatabase(b'ipsum', 2) ], private_key_binary=KeyPair.PRIVATE, target_url=self.URL ) body_binary = httpretty.last_request().body assert self._are_same_dicts( self._build_expected_body_dict(), json.loads(body_binary.decode(self.UTF8_ENCODING)) ) signature_binary = pub.Base64.base64_str_to_binary( httpretty.last_request().headers[self.SIGNATURE_HEADER] ) assert SignatureVerifier.is_valid_signature( KeyPair.PUBLIC, body_binary, signature_binary )
def test_updates(self): """Test updates API call""" setup_http_server() client = TelegramBotClient(TELEGRAM_TOKEN) # Check empty params client.updates() expected = {} req = httpretty.last_request() self.assertEqual(req.method, 'GET') self.assertRegex(req.path, '/bot12345678/getUpdates') self.assertDictEqual(req.querystring, expected) # Check request with offset client.updates(offset=319280321) expected = { 'offset' : ['319280321'] } req = httpretty.last_request() self.assertEqual(req.method, 'GET') self.assertRegex(req.path, '/bot12345678/getUpdates') self.assertDictEqual(req.querystring, expected)
def test_basic(self): self.register_get_user_response(self.user) self.register_thread() self.register_comment() request_data = {"thread_id": "test_thread", "raw_body": "Test body"} expected_response_data = { "id": "test_comment", "thread_id": "test_thread", "parent_id": None, "author": self.user.username, "author_label": None, "created_at": "1970-01-01T00:00:00Z", "updated_at": "1970-01-01T00:00:00Z", "raw_body": "Test body", "rendered_body": "<p>Test body</p>", "endorsed": False, "endorsed_by": None, "endorsed_by_label": None, "endorsed_at": None, "abuse_flagged": False, "voted": False, "vote_count": 0, "children": [], "editable_fields": ["abuse_flagged", "raw_body", "voted"], } response = self.client.post(self.url, json.dumps(request_data), content_type="application/json") self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assertEqual(response_data, expected_response_data) self.assertEqual(urlparse(httpretty.last_request().path).path, "/api/v1/threads/test_thread/comments") self.assertEqual( httpretty.last_request().parsed_body, {"course_id": [unicode(self.course.id)], "body": ["Test body"], "user_id": [str(self.user.id)]}, )
def test_first_submission_is_stored(self): httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/[email protected]', headers=ajax_headers, data={'missed': 'this was important'} ) f = Form.query.first() self.assertEqual(f.email, '*****@*****.**') self.assertEqual(f.confirm_sent, True) self.assertEqual(f.counter, 0) # the counter shows zero submissions self.assertEqual(f.get_monthly_counter(), 0) # monthly submissions also 0 # got a confirmation email self.assertIn('one+step+away', httpretty.last_request().body) # clicking of activation link self.client.get('/confirm/%s' % (f.hash,)) f = Form.query.first() self.assertEqual(f.confirmed, True) self.assertEqual(f.counter, 1) # counter has increased self.assertEqual(f.get_monthly_counter(), 1) # monthly submissions also # got the first (missed) submission self.assertIn('this+was+important', httpretty.last_request().body)
def test_create_routed_session(self): httpretty.register_uri( httpretty.POST, u("https://api.opentok.com/session/create"), body=u( '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sessions><Session><session_id>1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg</session_id><partner_id>123456</partner_id><create_dt>Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>' ), status=200, content_type=u("text/xml"), ) session = self.opentok.create_session(media_mode=MediaModes.routed) expect(httpretty.last_request().headers[u("x-tb-partner-auth")]).to.equal( self.api_key + u(":") + self.api_secret ) expect(httpretty.last_request().headers[u("user-agent")]).to.contain(u("OpenTok-Python-SDK/") + __version__) body = parse_qs(httpretty.last_request().body) expect(body).to.have.key(b("p2p.preference")).being.equal([b("disabled")]) expect(body).to.have.key(b("archiveMode")).being.equal([b("manual")]) expect(session).to.be.a(Session) expect(session).to.have.property(u("session_id")).being.equal( u("1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg") ) expect(session).to.have.property(u("media_mode")).being.equal(MediaModes.routed) expect(session).to.have.property(u("location")).being.equal(None)
def _request_credentials(self, redirection=None, status=200): access_rules = [{'method': 'GET', 'path': '/storage'}] response = { 'validationUrl': 'https://api.runabove.com/login/qdfwb', 'consumerKey': '63C4VMs4MDpwfGDj4KQEnTjbkvjSJCSY', 'state': 'pendingTest' } if not status == 200: response = {'message': 'Error'} register_uri( POST, self.actual_base_url + '/auth/credential', content_type='application/json', status=status, body=json.dumps(response) ) res = self.api.request_credentials(access_rules, redirection) self.assertEqual(self.api.consumer_key, response['consumerKey']) self.assertEqual( httpretty.last_request().headers['content-type'], 'application/json' ) self.assertEqual( httpretty.last_request().headers['X-Ra-Application'], self.application_key ) self.assertEqual( httpretty.last_request().parsed_body['redirection'], redirection ) self.assertEqual( httpretty.last_request().parsed_body['accessRules'], access_rules )
def test_upload(self): """ Test the upload class method """ obj_hash = { '_id': 127, u'foo': u'bar' } url = "http://127.0.0.1:9200/pacifica/ElasticAPI/127" obj = ElasticAPI() obj.id = 127 setattr(obj, 'to_hash', lambda: obj_hash) response_body = { "status": "uploaded!" } httpretty.register_uri(httpretty.PUT, url, body=dumps(response_body), content_type="application/json") ElasticAPI.elastic_upload(obj) self.assertEqual(httpretty.last_request().method, "PUT") sent_body = httpretty.last_request().parsed_body self.assertTrue(isinstance(sent_body, unicode)) sent_body = loads(sent_body) self.assertTrue('_id' not in sent_body) for key, value in sent_body.iteritems(): self.assertEqual(value, obj_hash[key])
def test_get_empty_issues(self): """ Test when issue is empty API call """ issue = read_file('data/github_empty_request') httpretty.register_uri(httpretty.GET, GITHUB_ISSUES_URL, body=issue, status=200, forcing_headers={ 'X-RateLimit-Remaining': '20', 'X-RateLimit-Reset': '15' }) client = GitHubClient("zhquan_example", "repo", "aaa", None) raw_issues = [issues for issues in client.get_issues()] self.assertEqual(raw_issues[0], issue) # Check requests expected = { 'per_page': ['30'], 'state': ['all'], 'direction': ['asc'], 'sort': ['updated'] } self.assertDictEqual(httpretty.last_request().querystring, expected) self.assertEqual(httpretty.last_request().headers["Authorization"], "token aaa")
def test_signal_with_connection_id(self): data = { u('type'): u('type test'), u('data'): u('test data') } connection_id = u('da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf') httpretty.register_uri(httpretty.POST, u('https://api.opentok.com/v2/project/{0}/session/{1}/connection/{2}/signal').format(self.api_key, self.session_id, connection_id), body=textwrap.dedent(u("""\ { "type": "type test", "data": "test data" }""")), status=204, content_type=u('application/json')) self.opentok.signal(self.session_id, data, connection_id) validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')]) expect(httpretty.last_request().headers[u('user-agent')]).to(contain(u('OpenTok-Python-SDK/')+__version__)) expect(httpretty.last_request().headers[u('content-type')]).to(equal(u('application/json'))) # non-deterministic json encoding. have to decode to test it properly if PY2: body = json.loads(httpretty.last_request().body) if PY3: body = json.loads(httpretty.last_request().body.decode('utf-8')) expect(body).to(have_key(u('type'), u('type test'))) expect(body).to(have_key(u('data'), u('test data')))
def test_http_wrong_status(self): """Test if a error is raised when the http status was not 200""" issue = "" httpretty.register_uri(httpretty.GET, GITHUB_ISSUES_URL, body=issue, status=500, forcing_headers={ 'X-RateLimit-Remaining': '20', 'X-RateLimit-Reset': '15' }) client = GitHubClient("zhquan_example", "repo", "aaa", None) with self.assertRaises(requests.exceptions.HTTPError): _ = [issues for issues in client.get_issues()] # Check requests expected = { 'per_page': ['30'], 'state': ['all'], 'direction': ['asc'], 'sort': ['updated'] } self.assertDictEqual(httpretty.last_request().querystring, expected) self.assertEqual(httpretty.last_request().headers["Authorization"], "token aaa")
def test_mesos_disk_collector_unexpected_response_format(self): settings = DiskCollectorSettings( http_api_url=self.agent_api_url, executor_id_json_path=self.executor_id_json_path, disk_usage_json_path=self.disk_usage_json_path, disk_collection_timeout=self.collection_timeout, disk_collection_interval=self.collection_interval) json_body = json.dumps({"status": "bad_request"}) httpretty.register_uri( method=httpretty.GET, uri="http://localhost:5051/containers", body=json_body, content_type='application/json') collector = MesosDiskCollector(self.sandbox_path, settings) def wait(): collector.sample() if collector._thread is not None: collector._thread.event.wait() assert collector.value == 0 wait() assert collector.value == LOOK_UP_ERROR_VALUE self.assertEquals(httpretty.last_request().method, "GET") self.assertEquals(httpretty.last_request().path, "/containers")
def test_rate_limit_error(self): """ Test get_page_issue API call """ issue = read_file('data/github_empty_request') httpretty.register_uri(httpretty.GET, GITHUB_ISSUES_URL, body=issue, status=200, forcing_headers={ 'X-RateLimit-Remaining': '0', 'X-RateLimit-Reset': '0', 'Link': '<'+GITHUB_ISSUES_URL+'/?&page=2>; rel="next", <'+GITHUB_ISSUES_URL+'/?&page=3>; rel="last"' }) client = GitHubClient("zhquan_example", "repo", "aaa", sleep_for_rate=False) with self.assertRaises(RateLimitError): _ = [issues for issues in client.get_issues()] # Check requests expected = { 'per_page': ['30'], 'state': ['all'], 'direction': ['asc'], 'sort': ['updated'] } self.assertDictEqual(httpretty.last_request().querystring, expected) self.assertEqual(httpretty.last_request().headers["Authorization"], "token aaa")
def test_login(self): httpretty.register_uri( httpretty.POST, "http://java.zabbix.dooioo.com/api_jsonrpc.php", body=json.dumps({ "jsonrpc": "2.0", "result": "0424bd59b807674191e7d77572075f33", "id": 0 }), ) zapi = ZabbixClient() zapi.login_in() # Check request self.assertEqual( json.loads(httpretty.last_request().body.decode('utf-8')), { 'jsonrpc': '2.0', 'method': 'user.login', 'params': {'user': '******', 'password': '******'}, 'id': 0, 'auth': '' } ) self.assertEqual( httpretty.last_request().headers['content-type'], 'application/json-rpc' ) self.assertEqual( httpretty.last_request().headers['user-agent'], 'python-zabbix-client' ) # Check response self.assertEqual(zapi.auth, "0424bd59b807674191e7d77572075f33")
def test_scan_list(self): httpretty.register_uri(httpretty.GET, self.get_url("/"), body=INDEX_RESPONSE, content_type="application/json") httpretty.register_uri( httpretty.GET, self.get_url("/version"), body=VERSION_RESPONSE, content_type="application/json" ) httpretty.register_uri( httpretty.GET, self.get_url("/scans/"), body=SCAN_LIST_RESPONSE, content_type="application/json" ) httpretty.register_uri( httpretty.DELETE, self.get_url("/scans/1"), body=SCAN_LIST_RESPONSE, content_type="application/json" ) httpretty.register_uri( httpretty.GET, self.get_url("/scans/0/stop"), body=SCAN_LIST_RESPONSE, content_type="application/json" ) conn = Connection(self.api_url) scans = conn.get_scans() running_scan = scans[0] stopped_scan = scans[1] running_scan.stop() self.assertEqual(httpretty.last_request().path, "/scans/0/stop") stopped_scan.cleanup() self.assertEqual(httpretty.last_request().path, "/scans/1") self.assertEqual(httpretty.last_request().method, "DELETE")
def test_delete_archive_1(self): self.httpretty_enable() archive_id = u('ARCHIVEID') archive = Archive(self.opentok, { u('createdAt'): 1395183243556, u('duration'): 0, u('id'): archive_id, u('name'): u(''), u('partnerId'): 123456, u('reason'): u(''), u('sessionId'): u('SESSIONID'), u('size'): 0, u('status'): u('available'), u('url'): None, }) httpretty.register_uri(httpretty.DELETE, u('https://api.opentok.com/v2/partner/{0}/archive/{1}').format(self.api_key, archive_id), body=u(''), status=204) archive.delete() expect(httpretty.last_request().headers[u('x-tb-partner-auth')]).to.equal(self.api_key+u(':')+self.api_secret) expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__) expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json')) self.httpretty_disable()
def test_with_token_authorization(self, token_baseapi): httpretty.enable() stub_request('https://localhost:8080/pdb/query/v4/nodes') token_baseapi._query('nodes') assert httpretty.last_request().path == '/pdb/query/v4/nodes' assert httpretty.last_request().headers['X-Authentication'] == \ 'tokenstring'
def test_get_folder_info(self): folder_id = 165 body = get_dummy_folder_result() body['id'] = folder_id httpretty.register_uri(httpretty.GET, "https://api.box.com/2.0/folders/%s" % folder_id, body=json.dumps(body), status=200, content_type='text/json') refresh_token = "refresh_token_dummy#!" access_token = "access_token_dummy#!" box = boxv2.BoxSession(self.client_id, self.client_secret, refresh_token, access_token) resp = box.get_folder_info(folder_id) expect(httpretty.last_request()).have.property("querystring").\ should.be.equal({}) expect(httpretty.last_request()).have.property("body").\ should.be.equal('') expect(httpretty.last_request().headers['Authorization']).\ to.equal('Bearer %s' % access_token) (resp).should.be.equal(body)
def test_create_always_archive_mode_session(self): httpretty.register_uri( httpretty.POST, u("https://api.opentok.com/session/create"), body=u( '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sessions><Session><session_id>1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg</session_id><partner_id>123456</partner_id><create_dt>Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>' ), status=200, content_type=u("text/xml"), ) session = self.opentok.create_session(media_mode=MediaModes.routed, archive_mode=ArchiveModes.always) validate_jwt_header(self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to(contain(u("OpenTok-Python-SDK/") + __version__)) body = parse_qs(httpretty.last_request().body) expect(body).to(have_key(b("p2p.preference"), [b("disabled")])) expect(body).to(have_key(b("archiveMode"), [b("always")])) expect(session).to(be_a(Session)) expect(session).to( have_property( u("session_id"), u("1_MX4xMjM0NTZ-fk1vbiBNYXIgMTcgMDA6NDE6MzEgUERUIDIwMTR-MC42ODM3ODk1MzQ0OTQyODA4fg") ) ) expect(session).to(have_property(u("media_mode"), MediaModes.routed)) expect(session).to(have_property(u("archive_mode"), ArchiveModes.always))
def test_objects_with_marker(self): marker = six.text_type("object2") marker_param = "marker=%s" % marker self.stub_url(httpretty.GET, path=[obj.Object.base_path % {"container": self.container_name} + "?" + marker_param], json=self.objects_body) count = 0 for actual, expected in zip(self.proxy.objects(self.container_name, marker=marker), self.returned_objects): # Make sure the marker made it into the actual request. self.assertIn(marker_param, httpretty.last_request().path) self.assertEqual(expected, actual) count += 1 self.assertEqual(len(self.returned_objects), count) # Since we have to make one request beyond the end, because no # limit was provided, make sure the last container appears as # the marker in this last request. self.assertIn(self.returned_objects[-1]["name"], httpretty.last_request().path)
def _test_successful_ecommerce_api_call(self, is_completed=True, utm_tracking_present=False): """ Verifies that the view contacts the E-Commerce API with the correct data and headers. """ with mock.patch('commerce.api.v0.views.audit_log') as mock_audit_log: response = self._post_to_view(include_utm_cookie=utm_tracking_present) # Verify that an audit message was logged self.assertTrue(mock_audit_log.called) # Validate the response content if is_completed: msg = Messages.ORDER_COMPLETED.format(order_number=TEST_ORDER_NUMBER) self.assertResponseMessage(response, msg) else: self.assertResponsePaymentData(response) # Make sure ecommerce API call forwards Sailthru cookie self.assertIn('{}=sailthru id'.format(SAILTHRU_CAMPAIGN_COOKIE), httpretty.last_request().headers['cookie']) # Check that UTM tracking cookie is passed along in request to ecommerce for attribution if utm_tracking_present: cookie_string = '{cookie_name}={cookie_contents}'.format( cookie_name=UTM_COOKIE_NAME, cookie_contents=json.dumps(UTM_COOKIE_CONTENTS)) self.assertIn(cookie_string, httpretty.last_request().headers['cookie'])
def test_success(self, parent_id, mock_emit): if parent_id: self.register_get_comment_response({"id": parent_id, "thread_id": "test_thread"}) self.register_post_comment_response( { "id": "test_comment", "thread_id": "test_thread", "username": self.user.username, "created_at": "2015-05-27T00:00:00Z", "updated_at": "2015-05-27T00:00:00Z", }, thread_id=(None if parent_id else "test_thread"), parent_id=parent_id, ) data = self.minimal_data.copy() if parent_id: data["parent_id"] = parent_id actual = create_comment(self.request, data) expected = { "id": "test_comment", "thread_id": "test_thread", "parent_id": parent_id, "author": self.user.username, "author_label": None, "created_at": "2015-05-27T00:00:00Z", "updated_at": "2015-05-27T00:00:00Z", "raw_body": "Test body", "endorsed": False, "endorsed_by": None, "endorsed_by_label": None, "endorsed_at": None, "abuse_flagged": False, "voted": False, "vote_count": 0, "children": [], } self.assertEqual(actual, expected) expected_url = "/api/v1/comments/{}".format(parent_id) if parent_id else "/api/v1/threads/test_thread/comments" self.assertEqual(urlparse(httpretty.last_request().path).path, expected_url) self.assertEqual( httpretty.last_request().parsed_body, {"course_id": [unicode(self.course.id)], "body": ["Test body"], "user_id": [str(self.user.id)]}, ) expected_event_name = "edx.forum.comment.created" if parent_id else "edx.forum.response.created" expected_event_data = { "discussion": {"id": "test_thread"}, "commentable_id": "test_topic", "options": {"followed": False}, "id": "test_comment", "truncated": False, "body": "Test body", "url": "", "user_forums_roles": [FORUM_ROLE_STUDENT], "user_course_roles": [], } if parent_id: expected_event_data["response"] = {"id": parent_id} actual_event_name, actual_event_data = mock_emit.call_args[0] self.assertEqual(actual_event_name, expected_event_name) self.assertEqual(actual_event_data, expected_event_data)
def test_find_archives_with_offset(self): httpretty.register_uri(httpretty.GET, u('https://api.opentok.com/v2/partner/{0}/archive').format(self.api_key), body=textwrap.dedent(u("""\ { "count" : 6, "items" : [ { "createdAt" : 1395183243000, "duration" : 544, "id" : "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9", "name" : "", "partnerId" : 123456, "reason" : "", "sessionId" : "SESSIONID", "size" : 78499758, "status" : "available", "hasAudio": true, "hasVideo": true, "url" : "http://tokbox.com.archive2.s3.amazonaws.com/123456%2F30b3ebf1-ba36-4f5b-8def-6f70d9986fe9%2Farchive.mp4?Expires=1395188695&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, { "createdAt" : 1394396753000, "duration" : 24, "id" : "b8f64de1-e218-4091-9544-4cbf369fc238", "name" : "showtime again", "partnerId" : 123456, "reason" : "", "sessionId" : "SESSIONID", "size" : 2227849, "status" : "available", "hasAudio": true, "hasVideo": true, "url" : "http://tokbox.com.archive2.s3.amazonaws.com/123456%2Fb8f64de1-e218-4091-9544-4cbf369fc238%2Farchive.mp4?Expires=1395188695&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, { "createdAt" : 1394321113000, "duration" : 1294, "id" : "832641bf-5dbf-41a1-ad94-fea213e59a92", "name" : "showtime", "partnerId" : 123456, "reason" : "", "sessionId" : "SESSIONID", "size" : 42165242, "status" : "available", "hasAudio": true, "hasVideo": true, "url" : "http://tokbox.com.archive2.s3.amazonaws.com/123456%2F832641bf-5dbf-41a1-ad94-fea213e59a92%2Farchive.mp4?Expires=1395188695&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } ] }""")), status=200, content_type=u('application/json')) archive_list = self.opentok.get_archives(offset=3) expect(httpretty.last_request().headers[u('x-tb-partner-auth')]).to.equal(self.api_key+u(':')+self.api_secret) expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__) expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json')) expect(httpretty.last_request()).to.have.property("querystring").being.equal({ u('offset'): [u('3')] }) expect(archive_list).to.be.an(ArchiveList) expect(archive_list).to.have.property(u('count')).being.equal(6) expect(list(archive_list.items)).to.have.length_of(3)
def test_allow_override_of_auth_token(self): fake_url = "/fake-url" fake_token = "fake_token" fake_resp = {"result": True} self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_url("GET", [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT) cl = client.Client( username="******", password="******", tenant_name="exampleproject", auth_url=self.TEST_URL ) self.assertEqual(cl.auth_token, self.TEST_TOKEN) # the token returned from the authentication will be used resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) self.assertEqual(httpretty.last_request().headers.get("X-Auth-Token"), self.TEST_TOKEN) # then override that token and the new token shall be used cl.auth_token = fake_token resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) self.assertEqual(httpretty.last_request().headers.get("X-Auth-Token"), fake_token) # if we clear that overriden token then we fall back to the original del cl.auth_token resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) self.assertEqual(httpretty.last_request().headers.get("X-Auth-Token"), self.TEST_TOKEN)
def test_failed_authentication(self): client = Client(base_url=self.api_url, auth_token='atoken') httpretty.register_uri(httpretty.GET, self.test_url, body='', status=401) self.assertEqual(client.has_resource(self.test_endpoint), False) self.assertEqual(httpretty.last_request().headers['Authorization'], 'Token atoken')
def test_form_creation(self): # register user r = self.client.post('/register', data={ 'email': '*****@*****.**', 'password': '******' }) self.assertEqual(r.status_code, 302) self.assertEqual(r.location.endswith('/dashboard'), True) self.assertEqual(1, User.query.count()) # fail to create form r = self.client.post('/forms', headers={'Content-type': 'application/json'}, data={'email': '*****@*****.**'}) self.assertEqual(r.status_code, 402) self.assertIn('error', json.loads(r.data)) self.assertEqual(0, Form.query.count()) # upgrade user manually user = User.query.filter_by(email='*****@*****.**').first() user.upgraded = True DB.session.add(user) DB.session.commit() # successfully create form r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({'email': '*****@*****.**'})) resp = json.loads(r.data) self.assertEqual(r.status_code, 200) self.assertIn('submission_url', resp) self.assertIn('random_like_string', resp) form_endpoint = resp['random_like_string'] self.assertIn(resp['random_like_string'], resp['submission_url']) self.assertEqual(1, Form.query.count()) self.assertEqual( Form.query.first().id, Form.get_form_by_random_like_string(resp['random_like_string']).id) # post to form httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/' + form_endpoint, headers={'Referer': 'formspree.io'}, data={'name': 'bruce'}) self.assertIn("We've sent a link to your email", r.data) self.assertIn('confirm+your+email', httpretty.last_request().body) self.assertEqual(1, Form.query.count()) # confirm form form = Form.query.first() self.client.get( '/confirm/%s:%s' % (HASH(form.email, str(form.id)), form.get_random_like_string())) self.assertTrue(Form.query.first().confirmed) # send 5 forms (monthly limits should not apply to the upgraded user) self.assertEqual(settings.MONTHLY_SUBMISSIONS_LIMIT, 2) for i in range(5): r = self.client.post('/' + form_endpoint, headers={'Referer': 'formspree.io'}, data={ 'name': 'ana', 'submission': '__%s__' % i }) form = Form.query.first() self.assertEqual(form.counter, 5) self.assertEqual(form.get_monthly_counter(), 5) self.assertIn('ana', httpretty.last_request().body) self.assertIn('__4__', httpretty.last_request().body) self.assertNotIn('You+are+past+our+limit', httpretty.last_request().body) # try (and fail) to submit from a different host r = self.client.post('/' + form_endpoint, headers={'Referer': 'bad.com'}, data={'name': 'usurper'}) self.assertEqual(r.status_code, 403) self.assertIn( 'ana', httpretty.last_request().body) # no more data is sent to sendgrid self.assertIn('__4__', httpretty.last_request().body)
def test_create_volume(self): url = '/volumes' name = 'volume1' cap = '10' pool = 'testpool_0' stgtype = types.DS8K_VOLUME_TYPE_FB captype = 'gib' tp = 'ese' lss = '00' def _verify_request(request, uri, headers): self.assertEqual(uri, self.domain + self.base_url + url) req = RequestParser({ 'name': name, 'cap': cap, 'pool': pool, 'stgtype': stgtype, 'captype': captype, 'lss': lss, 'tp': tp, }) self.assertDictContainsSubset( req.get_request_data().get('request').get('params'), json.loads(request.body).get('request').get('params'), ) return (201, headers, create_volume_response_json) httpretty.register_uri( httpretty.POST, self.domain + self.base_url + url, body=_verify_request, content_type='application/json', ) # Way 1 resp1 = self.system.create_volume(name=name, cap=cap, pool=pool, stgtype=stgtype, captype=captype, lss=lss, tp=tp) self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(resp1[0], Volume) # Way 2 volume = self.system.all(DS8K_VOLUME, rebuild_url=True) new_vol2 = volume.create( name=name, cap=cap, pool=pool, stgtype=stgtype, captype=captype, lss=lss, tp=tp, ) resp2, data2 = new_vol2.posta() self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(data2[0], Volume) self.assertEqual(resp2.status_code, 201) # Way 3 volume = self.system.all(DS8K_VOLUME, rebuild_url=True) new_vol3 = volume.create( name=name, cap=cap, pool=pool, stgtype=stgtype, captype=captype, lss=lss, tp=tp, ) resp3, data3 = new_vol3.save() self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(data3[0], Volume) self.assertEqual(resp3.status_code, 201)
def runtestcase(self, testcase): """Run a single test case.""" tc_name = tc_getattr("", testcase, "name") tc_desc = tc_getattr(tc_name, testcase, "description", None) print("Processing test case: %s: %s" % (tc_name, tc_desc)) httpretty.httpretty.allow_net_connect = False pywbem_request = tc_getattr(tc_name, testcase, "pywbem_request") exp_http_request = tc_getattr(tc_name, testcase, "http_request", None) http_response = tc_getattr(tc_name, testcase, "http_response", None) exp_pywbem_response = tc_getattr(tc_name, testcase, "pywbem_response") # Setup HTTPretty for one WBEM operation if exp_http_request is not None: exp_http_exception = tc_getattr(tc_name, http_response, "exception", None) if exp_http_exception is None: params = { "body": tc_getattr(tc_name, http_response, "data"), "adding_headers": tc_getattr(tc_name, http_response, "headers", None), "status": tc_getattr(tc_name, http_response, "status") } else: callback_name = exp_http_exception try: callback_func = getattr(Callback(), callback_name) except AttributeError: raise ClientTestError("Error in testcase %s: Unknown "\ "exception callback specified: %s"%\ (tc_name, callback_name)) params = {"body": callback_func} method = tc_getattr(tc_name, exp_http_request, "verb") uri = tc_getattr(tc_name, exp_http_request, "url") httpretty.register_uri(method=method, uri=uri, **params) conn = pywbem.WBEMConnection( url=tc_getattr(tc_name, pywbem_request, "url"), creds=tc_getattr(tc_name, pywbem_request, "creds"), default_namespace=tc_getattr(tc_name, pywbem_request, "namespace"), timeout=tc_getattr(tc_name, pywbem_request, "timeout")) conn.debug = tc_getattr(tc_name, pywbem_request, "debug", False) op = tc_getattr(tc_name, pywbem_request, "operation") # Example: # "operation": { # "pywbem_method": "GetInstance", # "InstanceName": { # "pywbem_object": "CIMInstanceName", # "classname": "PyWBEM_Person", # "keybindings": { # "Name": "Fritz" # } # }, # "LocalOnly": False # } op_name = tc_getattr(tc_name, op, "pywbem_method") op_args = {} for arg_name in op: if arg_name == "pywbem_method": continue op_args[arg_name] = obj(op[arg_name], tc_name) try: op_call = getattr(conn, op_name) except AttributeError as exc: raise ClientTestError("Error in definition of testcase %s: "\ "Unknown operation name: %s" %\ (tc_name, op_name)) # Invoke the PyWBEM operation to be tested try: result = op_call(**op_args) raised_exception = None except Exception as exc: raised_exception = exc stringio = six.StringIO() traceback.print_exc(file=stringio) raised_traceback_str = stringio.getvalue() stringio.close() result = None # Validate PyWBEM result and exceptions. # We validate exceptions before validating the HTTP request, because # an exception might have been raised on the way down before the # request was actually made. exp_exception = tc_getattr(tc_name, exp_pywbem_response, "exception", None) exp_cim_status = tc_getattr(tc_name, exp_pywbem_response, "cim_status", 0) # get the expected result. This may be either the the definition # of a value or cimobject or a list of values or cimobjects. exp_result = tc_getattr_list(tc_name, exp_pywbem_response, "result", None) if exp_exception is not None and exp_result is not None: raise ClientTestError("Error in definition of testcase %s: "\ "'result' and 'exception' attributes in "\ "'pywbem_result' are not compatible." %\ tc_name) if exp_cim_status != 0 and exp_result is not None: raise ClientTestError("Error in definition of testcase %s: "\ "'result' and 'cim_status' attributes in "\ "'pywbem_result' are not compatible." %\ tc_name) if exp_cim_status != 0: exp_exception = 'CIMError' if exp_exception is not None: if raised_exception is None: raise AssertionError("Testcase %s: A %s exception was "\ "expected to be raised by PyWBEM "\ "operation %s, but no exception was "\ "actually raised." %\ (tc_name, exp_exception, op_name)) elif raised_exception.__class__.__name__ != exp_exception: raise AssertionError("Testcase %s: A %s exception was "\ "expected to be raised by PyWBEM "\ "operation %s, but a different "\ "exception was actually raised:\n"\ "%s\n" %\ (tc_name, exp_exception, op_name, raised_traceback_str)) else: if raised_exception is not None: raise AssertionError("Testcase %s: No exception was "\ "expected to be raised by PyWBEM "\ "operation %s, but an exception was "\ "actually raised:\n"\ "%s\n" %\ (tc_name, op_name, raised_traceback_str)) # Validate HTTP request produced by PyWBEM if exp_http_request is not None: http_request = httpretty.last_request() self.assertTrue( not isinstance(http_request, HTTPrettyRequestEmpty), "HTTP request is empty") exp_verb = tc_getattr(tc_name, exp_http_request, "verb") self.assertEqual(http_request.method, exp_verb, "verb in HTTP request") exp_headers = tc_getattr(tc_name, exp_http_request, "headers", {}) for header_name in exp_headers: self.assertEqual(http_request.headers[header_name], exp_headers[header_name], "headers in HTTP request") exp_data = tc_getattr(tc_name, exp_http_request, "data", None) self.assertXMLEqual(http_request.body, exp_data, "data in HTTP request") # Continue with validating the result if isinstance(raised_exception, pywbem.CIMError): cim_status = raised_exception.args[0] else: cim_status = 0 self.assertEqual(cim_status, exp_cim_status, "PyWBEM CIM status") if exp_result is not None: exp_result_obj = obj(exp_result, tc_name) # pylint: disable=unidiomatic-typecheck if type(result) != type(exp_result_obj): print("result and expected result type mismatch") print("result type %s" % type(result)) print("expected result type %s" % type(result)) raise AssertionError("PyWBEM CIM result type is not" \ " as expected.") if result != exp_result_obj: print("Details for the following assertion error:") print("- Expected result:") print(" Returned object: %r" % exp_result_obj) if hasattr(exp_result_obj, "properties"): print(" Its properties: %r" % exp_result_obj.properties) print("- Actual result:") print(" Returned object: %r" % result) if hasattr(result, "properties"): print(" Its properties: %r" % result.properties) if conn.debug: print(" HTTP response data: %r" % conn.last_raw_reply) raise AssertionError("PyWBEM CIM result is not as expected.") else: self.assertEqual(result, None, "PyWBEM CIM result")
def test_basic(self): self.register_get_user_response(self.user) cs_thread = make_minimal_cs_thread({ "id": "test_thread", "course_id": unicode(self.course.id), "commentable_id": "original_topic", "username": self.user.username, "user_id": str(self.user.id), "created_at": "2015-05-29T00:00:00Z", "updated_at": "2015-05-29T00:00:00Z", "thread_type": "discussion", "title": "Original Title", "body": "Original body", }) self.register_get_thread_response(cs_thread) self.register_put_thread_response(cs_thread) request_data = {"raw_body": "Edited body"} expected_response_data = { "id": "test_thread", "course_id": unicode(self.course.id), "topic_id": "original_topic", "group_id": None, "group_name": None, "author": self.user.username, "author_label": None, "created_at": "2015-05-29T00:00:00Z", "updated_at": "2015-05-29T00:00:00Z", "type": "discussion", "title": "Original Title", "raw_body": "Edited body", "rendered_body": "<p>Edited body</p>", "pinned": False, "closed": False, "following": False, "abuse_flagged": False, "voted": False, "vote_count": 0, "comment_count": 0, "unread_comment_count": 0, "comment_list_url": "http://testserver/api/discussion/v1/comments/?thread_id=test_thread", "endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None, "editable_fields": [ "abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted" ], "read": False, "has_endorsed": False, "response_count": 0, } response = self.client.patch( # pylint: disable=no-member self.url, json.dumps(request_data), content_type="application/json") self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assertEqual(response_data, expected_response_data) self.assertEqual( httpretty.last_request().parsed_body, { "course_id": [unicode(self.course.id)], "commentable_id": ["original_topic"], "thread_type": ["discussion"], "title": ["Original Title"], "body": ["Edited body"], "user_id": [str(self.user.id)], "anonymous": ["False"], "anonymous_to_peers": ["False"], "closed": ["False"], "pinned": ["False"], })
def testCreateClassification(self): """ Tests client.createClassification(). Asserts the returned object has fields with expected values for both the classifciation name and bitmap. """ # Arrange: mock JSON response from API, mock out the API endpoint we expect # to be called. mockResponseString = getMockApiData("dfw_category.json") httpretty.register_uri( httpretty.POST, "http://api.cortical.io/rest/classify/create_category_filter", body=mockResponseString, content_type="application/json") # Act: create the client object we'll be testing. client = cortipy.CorticalClient(apiKey="fakeKey", verbosity=0, useCache=False, retina="en_synonymous") positives = [ "The truth will set you free. But not until it is finished \ with you.", "You will become way less concerned with what other people \ think of you when you realize how seldom they do." ] negatives = [ "It was the best of times, it was the worst of times, it was \ the age of wisdom, it was the age of foolishness, it was the epoch of \ belief, it was the epoch of incredulity, it was the season of Light, \ it was the season of Darkness, it was the spring of hope, it was the \ winter of despair, we had everything before us, we had nothing before \ us, we were all going direct to Heaven, we were all going direct the \ other way -- in short, the period was so far like the present period, \ that some of its noisiest authorities insisted on its being received, \ for good or for evil, in the superlative degree of comparison only." ] response = client.createClassification("dfw", positives, negatives) # Assert: check the result object. self.assertTrue("positions" in response, "No \'positions\' field in the returned object.") self.assertTrue("categoryName" in response, "No \'categoryName\' field in the returned object.") self.assertEqual(response["categoryName"], "dfw", "The returned category name is incorrect.") self.assertIsInstance( response["positions"], list, "The returned object does not contain a \'positions\' list.") # Assert: get the request sent to the API and check it. request = httpretty.last_request() self.assertEqual(request.method, 'POST', "Incorrect request method.") self.assertEqual(request.headers['content-type'], 'application/json', "Incorrect request headers.") self.assertTrue(hasattr(request, 'querystring'), "The request field \'queryString\' does not exist") self.assertEqual( request.querystring, { "retina_name": ["en_synonymous"], "filter_name": ["dfw"] }, "The request field \'queryString\' does not have the expected values." )
def test_custom_options_as_dictionary(client, texts): options = {'anotherOption': 4711, 'language': 'no'} client.tonality(texts, **options) request_body = json.loads(httpretty.last_request().body) assert request_body['language'] == 'no' assert request_body['anotherOption'] == 4711
def test_custom_options_as_arguments(client, texts): client.tonality(texts, language='sv', myCustomOption='optionally optional') request_body = json.loads(httpretty.last_request().body) assert request_body['language'] == 'sv' assert request_body['myCustomOption'] == 'optionally optional'
def test_input_list_of_strings(client): client.tonality( ['this is a text', 'this is text 2', 'this is the third text']) request_body = json.loads(httpretty.last_request().body) assert request_body['texts'][2]['body'] == 'this is the third text'
def test_default_language(client, texts): client.tonality(texts) request = httpretty.last_request() assert '"language": "en"' in request.body
def __exit__(self, exc_type, exc_val, exc_tb): assert self.expect_called == (httpretty.last_request().headers != {}) httpretty.disable() if self.reset_on_exit: httpretty.reset()
def testAaaUserJsonGET(self): httpretty.register_uri(httpretty.GET, url + '/api/aaaRefresh.json') self.login.GET(format='json') (httpretty.last_request().method).should.equal('GET') (httpretty.last_request().path).should.equal('/api/aaaRefresh.json')
def request_callback(method, uri, headers): reqs.append(httpretty.last_request()) resp = responses[uri].pop(0) return (resp[0], headers, resp[1])
{ "result": {'token': token}, "jsonrpc": "2.0", "id": 1, } ), adding_headers = { 'set-cookie': cookie, }, ) c = kerio.api.Client(url = 'https://1.1.1.1/api') r = c.Session.login(userName = '******', password = '******', application = {'name': "", 'vendor': "", 'version': ""}) body = json.loads(httpretty.last_request().body) expect(body).to(have_key('method', 'Session.login')) expect(body['params']).to(have_key('userName', 'u')) expect(body['params']).to(have_key('password', 'p')) expect(body['params']).to(have_key('application')) result = ':-)' httpretty.register_uri( httpretty.POST, 'https://1.1.1.1/api', body = json.dumps( { "result": result, "jsonrpc": "2.0", "id": 1,
def assert_last_query_params(self, expected_params): """ Assert that the last mock request had the expected query parameters """ self.assert_query_params_equal(httpretty.last_request(), expected_params)
def test_buglist(self): """Test buglist API call""" # Set up a mock HTTP server body = read_file('data/bugzilla/bugzilla_version.xml') httpretty.register_uri(httpretty.GET, BUGZILLA_METADATA_URL, body=body, status=200) body = read_file('data/bugzilla/bugzilla_buglist.csv') httpretty.register_uri(httpretty.GET, BUGZILLA_BUGLIST_URL, body=body, status=200) # Call API without args client = BugzillaClient(BUGZILLA_SERVER_URL) response = client.buglist() self.assertEqual(client.version, '4.2.1+') self.assertEqual(response, body) # Check request params expected = { 'ctype': ['csv'], 'limit': ['10000'], 'order': ['changeddate'], 'chfieldfrom': ['1970-01-01 00:00:00'] } req = httpretty.last_request() self.assertEqual(req.method, 'GET') self.assertRegex(req.path, '/buglist.cgi') self.assertDictEqual(req.querystring, expected) # Call API with from_date response = client.buglist(from_date=datetime.datetime(2015, 1, 1)) self.assertEqual(response, body) # Check request params expected = { 'ctype': ['csv'], 'limit': ['10000'], 'order': ['changeddate'], 'chfieldfrom': ['2015-01-01 00:00:00'] } req = httpretty.last_request() self.assertEqual(req.method, 'GET') self.assertRegex(req.path, '/buglist.cgi') self.assertDictEqual(req.querystring, expected) # Call API having defined max_bugs_cvs parameter client = BugzillaClient(BUGZILLA_SERVER_URL, max_bugs_csv=300) response = client.buglist() # Check request params expected = { 'ctype': ['csv'], 'limit': ['300'], 'order': ['changeddate'], 'chfieldfrom': ['1970-01-01 00:00:00'] } req = httpretty.last_request() self.assertEqual(req.method, 'GET') self.assertRegex(req.path, '/buglist.cgi') self.assertDictEqual(req.querystring, expected)
def test_create_node(self): node_data = { "Status": "ready", "Metadata": { "pool": "tsuru2", "iaas": "ec2", "LastSuccess": "2015-11-16T18:44:36-02:00", }, "Address": "http://127.0.0.3:4243" } url = "http://target/1.2/node" httpretty.register_uri( httpretty.POST, url, body=json.dumps(node_data), status=200, content_type='application/x-json-stream', ) data = { "address": "127.0.0.3:4243", "pool": "tsuru2", "register": "false" } result = self.cl.nodes.create(**data) self.assertListEqual(list(result), [node_data]) self.assertEqual("bearer abc123", httpretty.last_request().headers["authorization"]) self.assertIn("register", httpretty.last_request().body.decode('utf-8')) self.assertIn("false", httpretty.last_request().body.decode('utf-8')) result = self.cl.nodes.create(**data) self.assertListEqual(list(result), [node_data]) self.assertEqual("bearer abc123", httpretty.last_request().headers["authorization"]) self.assertIn("register", httpretty.last_request().body.decode('utf-8')) self.assertIn("false", httpretty.last_request().body.decode('utf-8')) data = { "address": "127.0.0.3:4243", "pool": "tsuru2", "register": "true" } result = self.cl.nodes.create(**data) self.assertListEqual(list(result), [node_data]) self.assertEqual("bearer abc123", httpretty.last_request().headers["authorization"]) self.assertIn("register", httpretty.last_request().body.decode('utf-8')) self.assertIn("true", httpretty.last_request().body.decode('utf-8')) data = { "address": "127.0.0.3:4243", "pool": "tsuru2", "register": "invalid" } result = self.cl.nodes.create(**data) self.assertListEqual(list(result), [node_data]) self.assertEqual("bearer abc123", httpretty.last_request().headers["authorization"]) self.assertIn("register", httpretty.last_request().body.decode('utf-8')) self.assertIn("invalid", httpretty.last_request().body.decode('utf-8'))
def test_send_poll_request(): """Test the sending of a configured poll request.""" # Ensures that non-registered paths fail httpretty.HTTPretty.allow_net_connect = False # Mock the TAXII endpoint enough to send it a request httpretty.register_uri( httpretty.POST, 'http://example.com:80/taxii_endpoint', body=lambda request, uri, headers: (200, {}, 'OK'), ) # Configure a client and make a poll request taxii_client = certau.source.SimpleTaxiiClient( username='******', password='******', begin_ts='2015-12-30T10:13:05.00000+10:00', end_ts='2015-12-30T18:09:43.00000+10:00', hostname='example.com', path='/taxii_endpoint', collection='my_collection', ) # send_poll_request should fail to get a valid poll response # and throw an exception as a result - below ensures this with pytest.raises(Exception) as excinfo: taxii_client.send_poll_request() assert str( excinfo.value) == 'TAXII response not a poll response as expected.' # Capture the client request data request = httpretty.last_request() # Remove non-repeatable headers headers = request.headers.dict del headers['content-length'] # Check we have the correct request headers assert request.headers.dict == { 'x-taxii-accept': 'urn:taxii.mitre.org:message:xml:1.1', 'x-taxii-protocol': 'urn:taxii.mitre.org:protocol:http:1.0', 'accept-encoding': 'identity', 'user-agent': 'libtaxii.httpclient', 'connection': 'close', 'accept': 'application/xml', 'x-taxii-content-type': 'urn:taxii.mitre.org:message:xml:1.1', 'host': 'example.com:80', 'x-taxii-services': 'urn:taxii.mitre.org:services:1.1', 'content-type': 'application/xml', 'authorization': 'Basic dXNlcjpwYXNz' } # Create a dict representation of the body XML dictbody = xmltodict.parse(request.body, dict_constructor=dict) # Remove non-repeatable items del dictbody['taxii_11:Poll_Request']['@message_id'] # Check we have the correct request body assert dictbody == { u'taxii_11:Poll_Request': { u'@xmlns:taxii': u'http://taxii.mitre.org/messages/taxii_xml_binding-1', u'taxii_11:Inclusive_End_Timestamp': u'2015-12-30T18:09:43+10:00', u'@xmlns:taxii_11': u'http://taxii.mitre.org/messages/taxii_xml_binding-1.1', u'@collection_name': u'my_collection', u'@xmlns:tdq': u'http://taxii.mitre.org/query/taxii_default_query-1', u'taxii_11:Poll_Parameters': { u'taxii_11:Response_Type': u'FULL', u'@allow_asynch': u'false' }, u'taxii_11:Exclusive_Begin_Timestamp': u'2015-12-30T10:13:05+10:00' } }
def test_monthly_limits(self): httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') # monthly limit is set to 2 during tests self.assertEqual(settings.MONTHLY_SUBMISSIONS_LIMIT, 2) # manually verify [email protected] r = self.client.post('/[email protected]', headers=http_headers, data={'name': 'luke'}) f = Form.query.first() f.confirm_sent = True f.confirmed = True DB.session.add(f) DB.session.commit() # first submission httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/[email protected]', headers=http_headers, data={'name': 'peter'}) self.assertEqual(r.status_code, 302) self.assertIn('peter', httpretty.last_request().body) # second submission httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/[email protected]', headers=http_headers, data={'name': 'ana'}) self.assertEqual(r.status_code, 302) self.assertIn('ana', httpretty.last_request().body) # third submission, now we're over the limit httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/[email protected]', headers=http_headers, data={'name': 'maria'}) self.assertEqual(r.status_code, 302) # the response to the user is the same # being the form over the limits or not # but the mocked sendgrid should never receive this last form self.assertNotIn('maria', httpretty.last_request().body) self.assertIn('You+are+past+our+limit', httpretty.last_request().body) # all the other variables are ok: self.assertEqual(1, Form.query.count()) f = Form.query.first() self.assertEqual(f.counter, 3) self.assertEqual(f.get_monthly_counter(), 3) # the counters mark 4 # the user pays and becomes upgraded r = self.client.post('/register', data={ 'email': '*****@*****.**', 'password': '******' }) user = User.query.filter_by(email='*****@*****.**').first() user.upgraded = True user.emails = [Email(address='*****@*****.**')] DB.session.add(user) DB.session.commit() # the user should receive form posts again httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/[email protected]', headers=http_headers, data={'name': 'noah'}) self.assertEqual(r.status_code, 302) self.assertIn('noah', httpretty.last_request().body)
def test_form_creation_with_a_registered_email(self): httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') # register user r = self.client.post('/register', data={ 'email': '*****@*****.**', 'password': '******' }) # upgrade user manually user = User.query.filter_by(email='*****@*****.**').first() user.upgraded = True DB.session.add(user) DB.session.commit() httpretty.reset() httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') # create form without providing an url should not send verification email r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({'email': '*****@*****.**'})) self.assertEqual(httpretty.has_request(), False) # create form without a confirmed email should send a verification email r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({ 'email': '*****@*****.**', 'url': 'https://www.testsite.com/contact.html' })) resp = json.loads(r.data) self.assertEqual(resp['confirmed'], False) self.assertEqual(httpretty.has_request(), True) self.assertIn('Confirm+email', httpretty.last_request().body) self.assertIn('www.testsite.com%2Fcontact.html', httpretty.last_request().body) # manually verify an email email = Email() email.address = '*****@*****.**' email.owner_id = user.id DB.session.add(email) DB.session.commit() # create a form with the verified email address r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({ 'email': '*****@*****.**', 'url': 'https://www.testsite.com/about.html' })) resp = json.loads(r.data) self.assertEqual(resp['confirmed'], True) self.assertIn('www.testsite.com%2Fcontact.html', httpretty.last_request().body ) # same as the last, means no new request was made # should have three created forms in the end self.assertEqual(Form.query.count(), 3)
def request_callback(method, uri, headers): body = bodies.pop(0) requests.append(httpretty.last_request()) return (200, headers, body)
def test_sitewide_forms(self): httpretty.register_uri( httpretty.GET, 'http://mysite.com/formspree-verify.txt', body=u'[email protected]\nmyüñìćõð€[email protected]', status=200) httpretty.register_uri(httpretty.GET, 'http://www.naive.com/formspree-verify.txt', body=u'myüñìćõð€[email protected]', status=200) # register user r = self.client.post('/register', data={ 'email': '*****@*****.**', 'password': '******' }) # upgrade user manually user = User.query.filter_by(email='*****@*****.**').first() user.upgraded = True DB.session.add(user) DB.session.commit() # manually verify an email email = Email() email.address = u'myüñìćõð€[email protected]' email.owner_id = user.id DB.session.add(email) DB.session.commit() # create a sitewide form with the verified email address r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({ 'email': u'myüñìćõð€[email protected]', 'url': 'http://mysite.com', 'sitewide': 'true' })) resp = json.loads(r.data) self.assertEqual(httpretty.has_request(), True) self.assertEqual(resp['confirmed'], True) self.assertEqual(1, Form.query.count()) forms = Form.query.all() form = forms[0] self.assertEqual(form.sitewide, True) self.assertEqual(form.host, 'mysite.com') # submit form httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/' + form.hashid, headers={ 'Referer': 'http://www.mysite.com/hipopotamo', 'content-type': 'application/json' }, data=json.dumps({'name': 'alice'})) self.assertIn('alice', httpretty.last_request().body) self.client.post('/' + form.hashid, headers={ 'Referer': 'http://mysite.com/baleia/urso?w=2', 'content-type': 'application/json' }, data=json.dumps({'name': 'maria'})) self.assertIn('maria', httpretty.last_request().body) self.client.post('/' + form.hashid, headers={ 'Referer': 'http://mysite.com/', 'content-type': 'application/json' }, data=json.dumps({'name': 'laura'})) self.assertIn('laura', httpretty.last_request().body) # another form, now with a www prefix that will be stripped r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({ 'email': u'myüñìćõð€[email protected]', 'url': 'http://www.naive.com', 'sitewide': 'true' })) resp = json.loads(r.data) self.assertEqual(httpretty.has_request(), True) self.assertEqual(resp['confirmed'], True) self.assertEqual(2, Form.query.count()) forms = Form.query.all() form = forms[1] self.assertEqual(form.sitewide, True) self.assertEqual(form.host, 'naive.com') # submit form httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json') r = self.client.post('/' + form.hashid, headers={ 'Referer': 'http://naive.com/hipopotamo', 'content-type': 'application/json' }, data=json.dumps({'name': 'alice'})) self.assertIn('alice', httpretty.last_request().body) self.client.post('/' + form.hashid, headers={ 'Referer': 'http://www.naive.com/baleia/urso?w=2', 'content-type': 'application/json' }, data=json.dumps({'name': 'maria'})) self.assertIn('maria', httpretty.last_request().body) self.client.post('/' + form.hashid, headers={ 'Referer': 'http://www.naive.com/', 'content-type': 'application/json' }, data=json.dumps({'name': 'laura'})) self.assertIn('laura', httpretty.last_request().body) # create a different form with the same email address, now using unprefixed url r = self.client.post('/forms', headers={ 'Accept': 'application/json', 'Content-type': 'application/json' }, data=json.dumps({ 'email': u'myüñìćõð€[email protected]', 'url': 'mysite.com', 'sitewide': 'true' })) resp = json.loads(r.data)
def test_create_volumes(self): url = '/volumes' name = 'volume1' quantity = '10' namecol = ['volume{}'.format(i) for i in range(10)] cap = '10' pool = 'testpool_0' stgtype = types.DS8K_VOLUME_TYPE_FB captype = 'gib' tp = 'ese' lss = '00' def _verify_request1(request, uri, headers): self.assertEqual(uri, self.domain + self.base_url + url) resq = RequestParser({ 'name': name, 'cap': cap, 'pool': pool, 'stgtype': stgtype, 'captype': captype, 'lss': lss, 'tp': tp, 'quantity': quantity }) self.assertEqual(json.loads(request.body), resq.get_request_data()) return (201, headers, create_volumes_response_json) def _verify_request2(request, uri, headers): self.assertEqual(uri, self.domain + self.base_url + url) resq = RequestParser({ 'namecol': namecol, 'cap': cap, 'pool': pool, 'stgtype': stgtype, 'name': '', 'quantity': '', 'captype': captype, 'lss': lss, 'tp': tp, }) self.assertEqual(json.loads(request.body), resq.get_request_data()) return (201, headers, create_volumes_response_json) httpretty.register_uri(httpretty.POST, self.domain + self.base_url + url, responses=[ httpretty.Response( body=_verify_request1, content_type='application/json', ), httpretty.Response( body=_verify_request2, content_type='application/json', ), ]) resp1 = self.system.create_volumes_with_same_prefix(name, cap, pool, quantity=quantity, stgtype=stgtype, captype=captype, lss=lss, tp=tp) self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(resp1[0], Volume) resp2 = self.system.create_volumes_without_same_prefix(namecol, cap, pool, stgtype=stgtype, captype=captype, lss=lss, tp=tp) self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(resp2[0], Volume) resp3 = self.system.create_volumes_with_names(namecol, cap, pool, stgtype=stgtype, captype=captype, lss=lss, tp=tp) self.assertEqual(httpretty.POST, httpretty.last_request().method) self.assertIsInstance(resp3[0], Volume)
def _get_query_params(self, index): return httpretty.last_request( ).querystring # already parsed to be dict
def test_delete_success(self): self.prepare_response("DELETE", "/ws/DataStream/test", "", status=200) test_stream = self.dc.streams.get_stream("test").delete() self.assertEqual(httpretty.last_request().command, 'DELETE')
def test_start_broadcast_only_one_rtmp(self): """ Test start_broadcast() method with only one rtmp """ httpretty.register_uri( httpretty.POST, u("https://api.opentok.com/v2/project/{0}/broadcast").format( self.api_key), body=textwrap.dedent( u("""\ { "id": "1748b7070a81464c9759c46ad10d3734", "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4", "projectId": 100, "createdAt": 1437676551000, "updatedAt": 1437676551000, "resolution": "640x480", "status": "started", "broadcastUrls": { "hls" : "http://server/fakepath/playlist.m3u8", "rtmp": { "foo": { "serverUrl": "rtmp://myfooserver/myfooapp", "streamName": "myfoostream" }, "bar": { "serverUrl": "rtmp://mybarserver/mybarapp", "streamName": "mybarstream" } } } } """)), status=200, content_type=u("application/json"), ) options = { "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ", "layout": { "type": "custom", "stylesheet": "the layout stylesheet (only used with type == custom)", }, "maxDuration": 5400, "outputs": { "rtmp": { "id": "my-id", "serverUrl": "rtmp://myserver/myapp", "streamName": "my-stream-name", } }, "resolution": "640x480", } broadcast = self.opentok.start_broadcast(self.session_id, options) validate_jwt_header( self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to( contain(u("OpenTok-Python-SDK/") + __version__)) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json"))) expect(broadcast).to(be_an(Broadcast)) expect(broadcast).to( have_property(u("id"), u("1748b7070a81464c9759c46ad10d3734"))) expect(broadcast).to( have_property(u("sessionId"), u("2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4"))) expect(broadcast).to(have_property(u("projectId"), 100)) expect(broadcast).to(have_property(u("createdAt"), 1437676551000)) expect(broadcast).to(have_property(u("updatedAt"), 1437676551000)) expect(broadcast).to(have_property(u("resolution"), u("640x480"))) expect(broadcast).to(have_property(u("status"), u("started"))) expect(list(broadcast.broadcastUrls)).to(have_length(2)) expect(list(broadcast.broadcastUrls["rtmp"])).to(have_length(2))
def parse_request_xml(self): http_request = httpretty.last_request() self.assertEquals(http_request.method, "POST") self.assertEquals(http_request.headers['Content-type'], 'text/plain') self.request_xml_root = ET.fromstring(http_request.body)
def test_start_broadcast_with_screenshare_type(self): """ Test start_broadcast() method """ httpretty.register_uri( httpretty.POST, u("https://api.opentok.com/v2/project/{0}/broadcast").format( self.api_key), body=textwrap.dedent( u("""\ { "id": "1748b7070a81464c9759c46ad10d3734", "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4", "projectId": 100, "createdAt": 1437676551000, "updatedAt": 1437676551000, "resolution": "640x480", "status": "started", "broadcastUrls": { "hls" : "http://server/fakepath/playlist.m3u8", "rtmp": { "foo": { "serverUrl": "rtmp://myfooserver/myfooapp", "streamName": "myfoostream" }, "bar": { "serverUrl": "rtmp://mybarserver/mybarapp", "streamName": "mybarstream" } } } } """)), status=200, content_type=u("application/json"), ) options = { "layout": { "screenshareType": "verticalPresentation" }, "maxDuration": 5400, "outputs": { "hls": {}, "rtmp": [ { "id": "foo", "serverUrl": "rtmp://myfooserver/myfooapp", "streamName": "myfoostream", }, { "id": "bar", "serverUrl": "rtmp://mybarserver/mybarapp", "streamName": "mybarstream", }, ], }, "resolution": "640x480", } broadcast = self.opentok.start_broadcast(self.session_id, options) validate_jwt_header( self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to( contain(u("OpenTok-Python-SDK/") + __version__)) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json"))) # non-deterministic json encoding. have to decode to test it properly if PY2: body = json.loads(httpretty.last_request().body) if PY3: body = json.loads(httpretty.last_request().body.decode("utf-8")) expect(body).to(have_key("sessionId", self.session_id)) expect(body).to(have_key("layout")) expect(body["layout"]).to(have_key("screenshareType")) expect(body["layout"]["screenshareType"]).to( equal("verticalPresentation")) expect(broadcast).to(be_an(Broadcast)) expect(broadcast).to( have_property(u("id"), u("1748b7070a81464c9759c46ad10d3734"))) expect(broadcast).to( have_property(u("sessionId"), u("2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4"))) expect(broadcast).to(have_property(u("projectId"), 100)) expect(broadcast).to(have_property(u("createdAt"), 1437676551000)) expect(broadcast).to(have_property(u("updatedAt"), 1437676551000)) expect(broadcast).to(have_property(u("resolution"), u("640x480"))) expect(broadcast).to(have_property(u("status"), u("started"))) expect(list(broadcast.broadcastUrls)).to(have_length(2)) expect(list(broadcast.broadcastUrls["rtmp"])).to(have_length(2))
def test_basic(self): self.register_get_user_response(self.user) cs_thread = make_minimal_cs_thread({ "id": self.thread_id, "course_id": unicode(self.course.id), "commentable_id": "test_topic", "username": self.user.username, "user_id": str(self.user.id), "title": "Test Title", "body": "Test body", "created_at": "2015-05-29T00:00:00Z", "updated_at": "2015-05-29T00:00:00Z" }) expected_response_data = { "author": self.user.username, "author_label": None, "created_at": "2015-05-29T00:00:00Z", "updated_at": "2015-05-29T00:00:00Z", "raw_body": "Test body", "rendered_body": "<p>Test body</p>", "abuse_flagged": False, "voted": False, "vote_count": 0, "editable_fields": [ "abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted" ], "course_id": unicode(self.course.id), "topic_id": "test_topic", "group_id": None, "group_name": None, "title": "Test Title", "pinned": False, "closed": False, "following": False, "comment_count": 0, "unread_comment_count": 0, "comment_list_url": "http://testserver/api/discussion/v1/comments/?thread_id=test_thread", "endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None, "read": False, "has_endorsed": False, "id": "test_thread", "type": "discussion", "response_count": 0, } self.register_get_thread_response(cs_thread) response = self.client.get(self.url) self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content), expected_response_data) self.assertEqual(httpretty.last_request().method, "GET")
def test_get_broadcast(self): """ Test get_broadcast() method """ broadcast_id = u("1748b707-0a81-464c-9759-c46ad10d3734") httpretty.register_uri( httpretty.GET, u("https://api.opentok.com/v2/project/{0}/broadcast/{1}").format( self.api_key, broadcast_id), body=textwrap.dedent( u("""\ { "id": "1748b707-0a81-464c-9759-c46ad10d3734", "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4", "projectId": 100, "createdAt": 1437676551000, "updatedAt": 1437676551000, "resolution": "640x480", "broadcastUrls": { "hls" : "http://server/fakepath/playlist.m3u8", "rtmp": { "foo": { "serverUrl": "rtmp://myfooserver/myfooapp", "streamName": "myfoostream", "status": "live" }, "bar": { "serverUrl": "rtmp://mybarserver/mybarapp", "streamName": "mybarstream", "status": "live" } } }, "status": "started" } """)), status=200, content_type=u("application/json"), ) broadcast = self.opentok.get_broadcast(broadcast_id) validate_jwt_header( self, httpretty.last_request().headers[u("x-opentok-auth")]) expect(httpretty.last_request().headers[u("user-agent")]).to( contain(u("OpenTok-Python-SDK/") + __version__)) expect(httpretty.last_request().headers[u("content-type")]).to( equal(u("application/json"))) expect(broadcast).to(be_an(Broadcast)) expect(broadcast).to(have_property(u("id"), broadcast_id)) expect(broadcast).to( have_property(u("sessionId"), u("2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4"))) expect(broadcast).to(have_property(u("projectId"), 100)) expect(broadcast).to(have_property(u("createdAt"), 1437676551000)) expect(broadcast).to(have_property(u("updatedAt"), 1437676551000)) expect(broadcast).to(have_property(u("resolution"), u("640x480"))) expect(broadcast).to(have_property(u("status"), u("started"))) expect(list(broadcast.broadcastUrls)).to(have_length(2)) expect(list(broadcast.broadcastUrls["rtmp"])).to(have_length(2))