зеркало из
				https://github.com/viginum-datalab/twscrape.git
				synced 2025-10-30 21:46:13 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			116 строки
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			116 строки
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import httpx
 | |
| from pytest_httpx import HTTPXMock
 | |
| 
 | |
| from twscrape.accounts_pool import AccountsPool
 | |
| from twscrape.logger import set_log_level
 | |
| from twscrape.queue_client import QueueClient
 | |
| 
 | |
| set_log_level("ERROR")
 | |
| 
 | |
| DB_FILE = "/tmp/twscrape_test_queue_client.db"
 | |
| URL = "https://example.com/api"
 | |
| CF = tuple[AccountsPool, QueueClient]
 | |
| 
 | |
| 
 | |
| async def get_locked(pool: AccountsPool) -> set[str]:
 | |
|     rep = await pool.get_all()
 | |
|     return set([x.username for x in rep if x.locks.get("SearchTimeline", None) is not None])
 | |
| 
 | |
| 
 | |
| async def test_lock_account_when_used(httpx_mock: HTTPXMock, client_fixture):
 | |
|     pool, client = client_fixture
 | |
| 
 | |
|     locked = await get_locked(pool)
 | |
|     assert len(locked) == 0
 | |
| 
 | |
|     # should lock account on getting it
 | |
|     await client.__aenter__()
 | |
|     locked = await get_locked(pool)
 | |
|     assert len(locked) == 1
 | |
|     assert "user1" in locked
 | |
| 
 | |
|     # keep locked on request
 | |
|     httpx_mock.add_response(url=URL, json={"foo": "bar"}, status_code=200)
 | |
|     assert (await client.get(URL)).json() == {"foo": "bar"}
 | |
| 
 | |
|     locked = await get_locked(pool)
 | |
|     assert len(locked) == 1
 | |
|     assert "user1" in locked
 | |
| 
 | |
|     # unlock on exit
 | |
|     await client.__aexit__(None, None, None)
 | |
|     locked = await get_locked(pool)
 | |
|     assert len(locked) == 0
 | |
| 
 | |
| 
 | |
| async def test_do_not_switch_account_on_200(httpx_mock: HTTPXMock, client_fixture: CF):
 | |
|     pool, client = client_fixture
 | |
| 
 | |
|     # get account and lock it
 | |
|     await client.__aenter__()
 | |
|     locked1 = await get_locked(pool)
 | |
|     assert len(locked1) == 1
 | |
| 
 | |
|     # make several requests with status=200
 | |
|     for x in range(1):
 | |
|         httpx_mock.add_response(url=URL, json={"foo": x}, status_code=200)
 | |
|         rep = await client.get(URL)
 | |
|         assert rep.json() == {"foo": x}
 | |
| 
 | |
|     # account should not be switched
 | |
|     locked2 = await get_locked(pool)
 | |
|     assert locked1 == locked2
 | |
| 
 | |
|     # unlock on exit
 | |
|     await client.__aexit__(None, None, None)
 | |
|     locked3 = await get_locked(pool)
 | |
|     assert len(locked3) == 0
 | |
| 
 | |
| 
 | |
| async def test_switch_acc_on_http_error(httpx_mock: HTTPXMock, client_fixture: CF):
 | |
|     pool, client = client_fixture
 | |
| 
 | |
|     # locked account on enter
 | |
|     await client.__aenter__()
 | |
|     locked1 = await get_locked(pool)
 | |
|     assert len(locked1) == 1
 | |
| 
 | |
|     # fail one request, account should be switched
 | |
|     httpx_mock.add_response(url=URL, json={"foo": "1"}, status_code=403)
 | |
|     httpx_mock.add_response(url=URL, json={"foo": "2"}, status_code=200)
 | |
| 
 | |
|     rep = await client.get(URL)
 | |
|     assert rep.json() == {"foo": "2"}
 | |
| 
 | |
|     locked2 = await get_locked(pool)
 | |
|     assert len(locked2) == 2
 | |
| 
 | |
|     # unlock on exit (failed account still should locked)
 | |
|     await client.__aexit__(None, None, None)
 | |
|     locked3 = await get_locked(pool)
 | |
|     assert len(locked3) == 1
 | |
|     assert locked1 == locked3  # failed account locked
 | |
| 
 | |
| 
 | |
| async def test_retry_with_same_acc_on_network_error(httpx_mock: HTTPXMock, client_fixture):
 | |
|     pool, client = client_fixture
 | |
| 
 | |
|     # locked account on enter
 | |
|     await client.__aenter__()
 | |
|     locked1 = await get_locked(pool)
 | |
|     assert len(locked1) == 1
 | |
| 
 | |
|     # timeout on first request, account should not be switched
 | |
|     httpx_mock.add_exception(httpx.ReadTimeout("Unable to read within timeout"))
 | |
|     httpx_mock.add_response(url=URL, json={"foo": "2"}, status_code=200)
 | |
| 
 | |
|     rep = await client.get(URL)
 | |
|     assert rep.json() == {"foo": "2"}
 | |
| 
 | |
|     locked2 = await get_locked(pool)
 | |
|     assert locked2 == locked1
 | |
| 
 | |
|     # check username added to request obj (for logging)
 | |
|     username = getattr(rep, "__username", None)
 | |
|     assert username is not None
 | 
