def test_session(self): c = Configuration('1.7.2') c.login_url = os.environ.get("RETS_LOGIN_URL") c.username = os.environ.get("RETS_USERNAME") c.password = os.environ.get("RETS_PASSWORD") s = Session(c) self.assertIsNotNone(s) s.login() system = s.get_system_metadata() self.assertIsNotNone(system) resources = s.get_resources_metadata() self.assertIsNotNone(resources) r_classes = {} for r, v in resources.items(): r_classes[r] = s.get_classes_metadata(r) self.assertIsNotNone(r_classes) objects = s.get_object(resource='Property', r_type='Photo', content_ids='2228878', object_ids='*', location=0) self.assertIsNotNone(objects) fields = s.get_table_metadata(resource_id='Property', class_id='RES') self.assertIsNotNone(fields) search_res = s.search(resource_id='Property', class_id='RES', dqml_query='(ListPrice=150000+)', optional_parameters={'Limit': 3}) self.assertIsNotNone(search_res)
class SessionTester(unittest.TestCase): def setUp(self): super(SessionTester, self).setUp() with open('tests/rets_responses/Login.xml') as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/Login.ashx', body=contents, status=200, headers={ 'Set-Cookie': 'ASP.NET_SessionId=zacqcc1gjhkmazjznjmyrinq;' }) self.session = Session( login_url='http://server.rets.com/rets/Login.ashx', username='******', version='RETS/1.7.2', session_id_cookie_name='ASP.NET_SessionId') self.session.login() def test_system_metadata(self): with open('tests/rets_responses/COMPACT-DECODED/GetMetadata_system.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) sys_metadata = self.session.get_system_metadata() self.assertEqual(sys_metadata['version'], '1.11.76001') self.assertEqual(sys_metadata['system_id'], 'MLS-RETS') def test_logout(self): with open('tests/rets_responses/Logout.html') as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/Logout.ashx', body=contents, status=200) self.assertTrue(self.session.logout()) def test_resource_metadata(self): with open( 'tests/rets_responses/COMPACT-DECODED/GetMetadata_resources.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) resource = self.session.get_resource_metadata() self.assertEqual(len(resource), 6) def test_get_object(self): with open('tests/rets_responses/GetObject.byte', 'rb') as f: single = f.read() with open('tests/rets_responses/GetObject_multipart.byte', 'rb') as f: multiple = f.read() multi_headers = { 'Content-Type': 'multipart/parallel; boundary="24cbd0e0afd2589bb9dcb1f34cf19862"; charset=utf-8', 'Connection': 'keep-alive', 'RETS-Version': 'RETS/1.7.2', 'MIME-Version': '1.0, 1.0' } single_headers = { 'MIME-Version': '1.0, 1.0', 'Object-ID': '0', 'Content-ID': '2144466', 'Content-Type': 'image/jpeg', 'Connection': 'keep-alive', 'RETS-Version': 'RETS/1.7.2' } with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetObject.ashx', body=single, status=200, headers=single_headers) objs = self.session.get_object(resource='Property', object_type='Photo', content_ids='1', object_ids='1') self.assertEqual(len(objs), 1) self.assertEqual(objs[0]['content_md5'], '396106a133a23e10f6926a82d219edbc') resps.add(resps.POST, 'http://server.rets.com/rets/GetObject.ashx', body=multiple, status=200, headers=multi_headers) objs1 = self.session.get_object(resource='Property', object_type='Photo', content_ids='1') self.assertEqual(len(objs1), 9) def test_get_object_location1(self): with open('tests/rets_responses/GetObject_multipart_Location1.byte', 'rb') as f: multiple = f.read() multi_headers = { 'Content-Type': 'multipart/parallel; ' 'boundary="FLEXLIAsmcpmiKpZ3uhewHnpQUlQNYzuNzPeUi0PIqCAxzgSRkpypX"; ' 'charset=utf-8', 'Connection': 'keep-alive', 'RETS-Version': 'RETS/1.7.2', 'MIME-Version': '1.0, 1.0' } with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetObject.ashx', body=multiple, status=200, headers=multi_headers) objs1 = self.session.get_object(resource='Property', object_type='Photo', content_ids='1', location='1') self.assertEqual(len(objs1), 41) def test_preferred_object(self): with open('tests/rets_responses/GetObject_multipart.byte', 'rb') as f: multiple = f.read() multi_headers = { 'Content-Type': 'multipart/parallel; boundary="24cbd0e0afd2589bb9dcb1f34cf19862"; charset=utf-8', 'Connection': 'keep-alive', 'RETS-Version': 'RETS/1.7.2', 'MIME-Version': '1.0, 1.0' } with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetObject.ashx', body=multiple, status=200, headers=multi_headers) obj = self.session.get_preferred_object(resource='Property', object_type='Photo', content_id=1) self.assertTrue(obj) resps.add(resps.POST, 'http://server.rets.com/rets/GetObject.ashx', body=multiple, status=200) resource = dict() resource['ResourceID'] = 'Agent' obj1 = self.session.get_preferred_object(resource=resource, object_type='Photo', content_id=1) self.assertTrue(obj1) def test_class_metadata(self): with open( 'tests/rets_responses/COMPACT-DECODED/GetMetadata_classes.xml' ) as f: contents = ''.join(f.readlines()) with open( 'tests/rets_responses/COMPACT-DECODED/GetMetadata_classes_single.xml' ) as f: single_contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) resource_classes = self.session.get_class_metadata( resource='Agent') self.assertEqual(len(resource_classes), 6) resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=single_contents, status=200) resource_classes_single = self.session.get_class_metadata( resource='Property') self.assertEqual(len(resource_classes_single), 1) def test_search(self): with open('tests/rets_responses/COMPACT-DECODED/Search.xml') as f: search_contents = ''.join(f.readlines()) with open('tests/rets_responses/Errors/Error_InvalidFormat.xml') as f: invalid_contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/Search.ashx', body=search_contents, status=200, stream=True) results = self.session.search( resource='Property', resource_class='RES', search_filter={'ListingPrice': 200000}) self.assertEqual(len(results), 3) resps.add(resps.POST, 'http://server.rets.com/rets/Search.ashx', body=search_contents, status=200, stream=True) results1 = self.session.search( resource='Property', resource_class='RES', limit=3, dmql_query='ListingPrice=200000', optional_parameters={'RestrictedIndicator': '!!!!'}) self.assertEqual(len(results1), 3) resps.add(resps.POST, 'http://server.rets.com/rets/Search.ashx', body=invalid_contents, status=200, stream=True) with self.assertRaises(RETSException): r = self.session.search( resource='Property', resource_class='RES', dmql_query='ListingPrice=200000', optional_parameters={'Format': "Somecrazyformat"}) print(r) def test_auto_offset(self): with open('tests/rets_responses/COMPACT-DECODED/Search_1of2.xml') as f: search1_contents = ''.join(f.readlines()) with open('tests/rets_responses/COMPACT-DECODED/Search_2of2.xml') as f: search2_contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/Search.ashx', body=search1_contents, status=200, stream=True) resps.add(resps.POST, 'http://server.rets.com/rets/Search.ashx', body=search2_contents, status=200, stream=True) results = self.session.search( resource='Property', resource_class='RES', search_filter={'ListingPrice': 200000}) self.assertEqual(len(results), 6) def test_cache_metadata(self): with open('tests/rets_responses/COMPACT-DECODED/GetMetadata_table.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) self.session.get_table_metadata(resource='Property', resource_class='RES') self.assertIn('METADATA-TABLE:Property:RES', list(self.session.metadata_responses.keys())) # Subsequent call without RequestMock should fail unless we get the saved response from metadata_responses table = self.session.get_table_metadata(resource='Property', resource_class='RES') self.assertEqual(len(table), 208) def test_table_metadata(self): with open('tests/rets_responses/COMPACT-DECODED/GetMetadata_table.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) table = self.session.get_table_metadata(resource='Property', resource_class='RES') self.assertEqual(len(table), 208) def test_lookup_type_metadata(self): with open('tests/rets_responses/COMPACT-DECODED/GetMetadata_lookup.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) lookup_values = self.session.get_lookup_values( resource='Agent', lookup_name='Broker') self.assertEqual(len(lookup_values), 61) def test_object_metadata(self): with open( 'tests/rets_responses/COMPACT-DECODED/GetMetadata_objects.xml' ) as f: contents = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=contents, status=200) object_metadata = self.session.get_object_metadata( resource='Agent') self.assertEqual(len(object_metadata), 3) def test_agent_digest_hash(self): self.session.user_agent_password = "******" self.assertIsNotNone(self.session._user_agent_digest_hash()) def test_session_cookie_name(self): self.assertEqual(self.session.session_id, 'zacqcc1gjhkmazjznjmyrinq') def test_change_parser_automatically(self): self.assertEqual(self.session.metadata_format, 'COMPACT-DECODED') with open('tests/rets_responses/Errors/20514.xml') as f: dtd_error = ''.join(f.readlines()) with open('tests/rets_responses/STANDARD-XML/GetMetadata_system.xml' ) as f: content = ''.join(f.readlines()) with responses.RequestsMock() as resps: resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=dtd_error, status=200) resps.add(resps.POST, 'http://server.rets.com/rets/GetMetadata.ashx', body=content, status=200) self.session.get_system_metadata() self.assertEqual(self.session.metadata_format, 'STANDARD-XML')
class SessionTester(unittest.TestCase): def setUp(self): super(SessionTester, self).setUp() with open("tests/rets_responses/Login.xml") as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/Login.ashx", body=contents, status=200, headers={ "Set-Cookie": "ASP.NET_SessionId=zacqcc1gjhkmazjznjmyrinq;" }, ) self.session = Session( login_url="http://server.rets.com/rets/Login.ashx", username="******", version="RETS/1.7.2", session_id_cookie_name="ASP.NET_SessionId", ) self.session.login() def test_system_metadata(self): with open("tests/rets_responses/COMPACT-DECODED/GetMetadata_system.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) sys_metadata = self.session.get_system_metadata() self.assertEqual(sys_metadata["version"], "1.11.76001") self.assertEqual(sys_metadata["system_id"], "MLS-RETS") def test_logout(self): with open("tests/rets_responses/Logout.html") as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/Logout.ashx", body=contents, status=200, ) self.assertTrue(self.session.logout()) def test_resource_metadata(self): with open( "tests/rets_responses/COMPACT-DECODED/GetMetadata_resources.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) resource = self.session.get_resource_metadata() self.assertEqual(len(list(resource)), 6) def test_get_object(self): with open("tests/rets_responses/GetObject.byte", "rb") as f: single = f.read() with open("tests/rets_responses/GetObject_multipart.byte", "rb") as f: multiple = f.read() multi_headers = { "Content-Type": 'multipart/parallel; boundary="24cbd0e0afd2589bb9dcb1f34cf19862"; charset=utf-8', "Connection": "keep-alive", "RETS-Version": "RETS/1.7.2", "MIME-Version": "1.0, 1.0", } single_headers = { "MIME-Version": "1.0, 1.0", "Object-ID": "0", "Content-ID": "2144466", "Content-Type": "image/jpeg", "Connection": "keep-alive", "RETS-Version": "RETS/1.7.2", } with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetObject.ashx", body=single, status=200, headers=single_headers, ) objs = self.session.get_object( resource="Property", object_type="Photo", content_ids="1", object_ids="1", ) obj_l = list(objs) self.assertEqual(len(obj_l), 1) self.assertEqual(obj_l[0]["content_md5"], "396106a133a23e10f6926a82d219edbc") resps.add( resps.POST, "http://server.rets.com/rets/GetObject.ashx", body=multiple, status=200, headers=multi_headers, ) objs1 = self.session.get_object(resource="Property", object_type="Photo", content_ids="1") self.assertEqual(len(list(objs1)), 9) def test_get_object_location1(self): with open("tests/rets_responses/GetObject_multipart_Location1.byte", "rb") as f: multiple = f.read() multi_headers = { "Content-Type": "multipart/parallel; " 'boundary="FLEXLIAsmcpmiKpZ3uhewHnpQUlQNYzuNzPeUi0PIqCAxzgSRkpypX"; ' "charset=utf-8", "Connection": "keep-alive", "RETS-Version": "RETS/1.7.2", "MIME-Version": "1.0, 1.0", } with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetObject.ashx", body=multiple, status=200, headers=multi_headers, ) objs1 = self.session.get_object(resource="Property", object_type="Photo", content_ids="1", location="1") self.assertEqual(len(list(objs1)), 41) def test_preferred_object(self): with open("tests/rets_responses/GetObject_multipart.byte", "rb") as f: multiple = f.read() multi_headers = { "Content-Type": 'multipart/parallel; boundary="24cbd0e0afd2589bb9dcb1f34cf19862"; charset=utf-8', "Connection": "keep-alive", "RETS-Version": "RETS/1.7.2", "MIME-Version": "1.0, 1.0", } with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetObject.ashx", body=multiple, status=200, headers=multi_headers, ) obj = self.session.get_preferred_object(resource="Property", object_type="Photo", content_id=1) self.assertTrue(obj) resps.add( resps.POST, "http://server.rets.com/rets/GetObject.ashx", body=multiple, status=200, ) resource = dict() resource["ResourceID"] = "Agent" obj1 = self.session.get_preferred_object(resource=resource, object_type="Photo", content_id=1) self.assertTrue(obj1) def test_class_metadata(self): with open( "tests/rets_responses/COMPACT-DECODED/GetMetadata_classes.xml" ) as f: contents = "".join(f.readlines()) with open( "tests/rets_responses/COMPACT-DECODED/GetMetadata_classes_single.xml" ) as f: single_contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) resource_classes = self.session.get_class_metadata( resource="Agent") self.assertEqual(len(list(resource_classes)), 6) resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=single_contents, status=200, ) resource_classes_single = self.session.get_class_metadata( resource="Property") self.assertEqual(len(list(resource_classes_single)), 1) def test_search(self): with open("tests/rets_responses/COMPACT-DECODED/Search.xml") as f: search_contents = "".join(f.readlines()) with open("tests/rets_responses/CREA-STANDARD-XML/Search.xml") as f: custom_search_contents = "".join(f.readlines()) with open("tests/rets_responses/Errors/Error_InvalidFormat.xml") as f: invalid_contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=search_contents, status=200, stream=True, ) results_gen = self.session.search( resource="Property", resource_class="RES", search_filter={"ListingPrice": 200000}, ) results = list(results_gen) self.assertEqual(len(results), 3) resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=search_contents, status=200, stream=True, ) results1_gen = self.session.search( resource="Property", resource_class="RES", limit=3, dmql_query="ListingPrice=200000", optional_parameters={"RestrictedIndicator": "!!!!"}, ) results1 = list(results1_gen) self.assertEqual(len(results1), 3) resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=custom_search_contents, status=200, stream=True, ) self.session.search_parser = CreaStandardXParser() results2_gen = self.session.search( resource="Property", resource_class="Property", limit=1, response_format="STANDARD-XML", dmql_query="(ID=20270724)", ) results2 = list(results2_gen) self.assertEqual(len(results2), 1) self.session.search_parser = None resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=invalid_contents, status=200, stream=True, ) with self.assertRaises(RETSException): r = self.session.search( resource="Property", resource_class="RES", dmql_query="ListingPrice=200000", optional_parameters={"Format": "Somecrazyformat"}, ) print(list(r)) def test_auto_offset(self): with open("tests/rets_responses/COMPACT-DECODED/Search_1of2.xml") as f: search1_contents = "".join(f.readlines()) with open("tests/rets_responses/COMPACT-DECODED/Search_2of2.xml") as f: search2_contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=search1_contents, status=200, stream=True, ) resps.add( resps.POST, "http://server.rets.com/rets/Search.ashx", body=search2_contents, status=200, stream=True, ) results_gen = self.session.search( resource="Property", resource_class="RES", search_filter={"ListingPrice": 200000}, ) results = list(results_gen) self.assertEqual(len(results), 6) def test_cache_metadata(self): with open("tests/rets_responses/COMPACT-DECODED/GetMetadata_table.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) self.session.get_table_metadata(resource="Property", resource_class="RES") self.assertIn("METADATA-TABLE:Property:RES", list(self.session.metadata_responses.keys())) # Subsequent call without RequestMock should fail unless we get the saved response from metadata_responses table = self.session.get_table_metadata(resource="Property", resource_class="RES") self.assertEqual(len(list(table)), 208) def test_table_metadata(self): with open("tests/rets_responses/COMPACT-DECODED/GetMetadata_table.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) table = self.session.get_table_metadata(resource="Property", resource_class="RES") self.assertEqual(len(list(table)), 208) def test_lookup_type_metadata(self): with open("tests/rets_responses/COMPACT-DECODED/GetMetadata_lookup.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) lookup_values = self.session.get_lookup_values( resource="Agent", lookup_name="Broker") self.assertEqual(len(list(lookup_values)), 61) def test_object_metadata(self): with open( "tests/rets_responses/COMPACT-DECODED/GetMetadata_objects.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) object_metadata = self.session.get_object_metadata( resource="Agent") self.assertEqual(len(list(object_metadata)), 3) def test_agent_digest_hash(self): self.session.user_agent_password = "******" self.assertIsNotNone(self.session._user_agent_digest_hash()) def test_session_cookie_name(self): self.assertEqual(self.session.session_id, "zacqcc1gjhkmazjznjmyrinq") def test_change_parser_automatically(self): self.assertEqual(self.session.metadata_format, "COMPACT-DECODED") with open("tests/rets_responses/Errors/20514.xml") as f: dtd_error = "".join(f.readlines()) with open("tests/rets_responses/STANDARD-XML/GetMetadata_system.xml" ) as f: content = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=dtd_error, status=200, ) resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=content, status=200, ) self.session.get_system_metadata() self.assertEqual(self.session.metadata_format, "STANDARD-XML") def test_wildcard_lookups(self): with open("tests/rets_responses/STANDARD-XML/GetMetadata_wildcard.xml" ) as f: contents = "".join(f.readlines()) with responses.RequestsMock() as resps: resps.add( resps.POST, "http://server.rets.com/rets/GetMetadata.ashx", body=contents, status=200, ) format_hold = self.session.metadata_format try: self.session.metadata_format = "STANDARD-XML" lookup_values = self.session.get_lookup_values( resource="Property", lookup_name="*") finally: self.session.metadata_format = format_hold self.assertEqual(len(lookup_values), 40)