def test_dynamic_price(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks, receiver_privkey: str): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address price_cycle = cycle([1, 2, 3, 4, 5]) url_to_price = {} def price_fn(url: str): if url in url_to_price: price = url_to_price[url] else: price = next(price_cycle) url_to_price[url] = price return price content = PaywalledContent( 'resource_\d', price=price_fn, get_fn=lambda url: (url.split("_")[1], 200), ) proxy.add_content(content) response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 response = requests.get(endpoint_url + '/resource_5') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 2 response = requests.get(endpoint_url + '/resource_2') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 channel = client.get_suitable_channel(headers.receiver_address, 2) wait_for_blocks(6) channel.balance = 2 headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource_5', headers=headers) assert response.status_code == 200 assert response.text.strip() == '"5"' close_channel_cooperatively(channel, receiver_privkey, client.channel_manager_address, 0)
def test_get(empty_proxy: PaywalledProxy, api_endpoint_address: str, channel_manager_address: str, token_address: str, sender_address: str, receiver_address: str, client: Client, wait_for_blocks): """ Test with manual client interaction for isolated server testing. Note: Debug in microraiden.proxy.resources.expensive for most of the server response logic. """ es_mock = ElasticsearchBackend(None) es_mock.search = mock.Mock(return_value=Resource( price=5, content='success', expires_at=time.time() + 30)) server = APIServer(empty_proxy, es=es_mock) api_path = 'http://' + api_endpoint_address # Request price (and cache resource). body = {'query': 'query something'} url = api_path + '/some_index/some_type/_search' response = requests.get(url, json=body) print(response.content) assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert headers.token_address == token_address assert headers.contract_address == channel_manager_address assert headers.receiver_address == receiver_address price = int(headers.price) assert price == 5 assert len(server.resource_cache) == 1 # Perform payment and request same resource again. Include payment information in headers. channel = client.get_suitable_channel(receiver_address, price) # Server requires some confirmations, so mine some blocks. wait_for_blocks(10) channel.create_transfer(price) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = sender_address headers.receiver_address = receiver_address headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(url, headers=headers, json=body) headers = HTTPHeaders.deserialize(response.headers) assert 'nonexisting_channel' not in headers, 'Server should acknowledge the created channel.' assert 'insuf_confs' not in headers, 'Server should acknowledge the created channel.' assert 'invalid_amount' not in headers, 'The correct amount should have been sent.' assert response.status_code == 200 assert response.json() == 'success' assert len(server.resource_cache) == 1 es_mock.search.assert_called_once_with(index='some_index', doc_type='some_type', body={'query': 'query something'})
def test_dynamic_price(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address price_cycle = cycle([1, 2, 3, 4, 5]) url_to_price = {} # type: Dict def price_fn(url: str): if url in url_to_price: price = url_to_price[url] else: price = next(price_cycle) url_to_price[url] = price return price proxy.add_paywalled_resource(DynamicPriceResource, '/resource_<int:res_id>', price_fn) response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 response = requests.get(endpoint_url + '/resource_5') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 2 response = requests.get(endpoint_url + '/resource_2') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 channel = client.get_suitable_channel(headers.receiver_address, 2) wait_for_blocks(6) channel.update_balance(2) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource_5', headers=headers) assert response.status_code == 200 assert response.text.strip() == '5'
def test_static_price( empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks ): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource(StaticPriceResource, '/resource', 3) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 assert response.text.strip() == 'GET' assert_method(requests.post, endpoint_url + '/resource', headers, channel, 'POST') assert_method(requests.put, endpoint_url + '/resource', headers, channel, 'PUT') assert_method(requests.delete, endpoint_url + '/resource', headers, channel, 'DEL')
def test_explicit_json( empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks ): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource(JSONResource, '/resource', 3) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 # If headers don't merge properly, this results in 'application/json,application/json'. assert response.headers['Content-Type'] == 'application/json' assert response.json() == {'GET': 1}
def test_static_price(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks, receiver_privkey: str): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address content = PaywalledContent( 'resource', price=3, get_fn=lambda url: ('SUCCESS', 200), ) proxy.add_content(content) response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel = client.get_suitable_channel(headers.receiver_address, 3) wait_for_blocks(6) channel.balance = 3 headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 assert response.text.strip() == '"SUCCESS"' close_channel_cooperatively(channel, receiver_privkey, client.channel_manager_address, 0)
def test_static_price(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource(StaticPriceResource, '/resource', 3) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 assert response.text.strip() == 'GET' assert_method(requests.post, endpoint_url + '/resource', headers, channel, 'POST') assert_method(requests.put, endpoint_url + '/resource', headers, channel, 'PUT') assert_method(requests.delete, endpoint_url + '/resource', headers, channel, 'DEL')
def test_explicit_json(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource(JSONResource, '/resource', 3) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 # If headers don't merge properly, this results in 'application/json,application/json'. assert response.headers['Content-Type'] == 'application/json' assert response.json() == {'GET': 1}
def test_method_price(empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource(DynamicMethodResource, '/resource', resource_class_args=(42, ), resource_class_kwargs={'bar': 9814072356}) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 channel = client.get_suitable_channel(headers.receiver_address, 1 + 2 + 3 + 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 assert response.text.strip() == 'GET' assert_method(requests.post, endpoint_url + '/resource', headers, channel, 'POST', expected_price=2) assert_method(requests.put, endpoint_url + '/resource', headers, channel, 'PUT', expected_price=3) assert_method(requests.delete, endpoint_url + '/resource', headers, channel, 'DEL', expected_price=4)
def test_method_price( empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks ): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address proxy.add_paywalled_resource( DynamicMethodResource, '/resource', resource_class_args=(42,), resource_class_kwargs={'bar': 9814072356}) # test GET response = requests.get(endpoint_url + '/resource') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 channel = client.get_suitable_channel(headers.receiver_address, 1 + 2 + 3 + 4) wait_for_blocks(6) channel.update_balance(int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource', headers=headers) assert response.status_code == 200 assert response.text.strip() == 'GET' assert_method(requests.post, endpoint_url + '/resource', headers, channel, 'POST', expected_price=2) assert_method(requests.put, endpoint_url + '/resource', headers, channel, 'PUT', expected_price=3) assert_method(requests.delete, endpoint_url + '/resource', headers, channel, 'DEL', expected_price=4)
def assert_method(method, url, headers, channel, expected_reply, expected_price=3): # test POST response = method(url, headers=headers) assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == expected_price channel.update_balance(int(headers.sender_balance) + int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = method(url, headers=headers) assert response.status_code == 200 assert response.text.strip() == expected_reply
def assert_method(method, url, headers, channel, expected_reply): # test POST response = method(url, headers=headers) assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 channel.update_balance(int(headers.sender_balance) + int(headers.price)) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = method(url, headers=headers) assert response.status_code == 200 assert response.text.strip() == expected_reply
def test_dynamic_price( empty_proxy: PaywalledProxy, api_endpoint_address: str, client: Client, wait_for_blocks ): proxy = empty_proxy endpoint_url = "http://" + api_endpoint_address price_cycle = cycle([1, 2, 3, 4, 5]) url_to_price = {} # type: Dict def price_fn(): url = request.path if int(url.split('_')[-1]) == 0: return 0 if url in url_to_price: price = url_to_price[url] else: price = next(price_cycle) url_to_price[url] = price return price proxy.add_paywalled_resource( DynamicPriceResource, '/resource_<int:res_id>', price=price_fn ) response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 response = requests.get(endpoint_url + '/resource_5') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 2 response = requests.get(endpoint_url + '/resource_2') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 3 response = requests.get(endpoint_url + '/resource_3') assert response.status_code == 402 headers = HTTPHeaders.deserialize(response.headers) assert int(headers.price) == 1 response = requests.get(endpoint_url + '/resource_0') assert response.status_code == 200 assert response.text.strip() == '0' channel = client.get_suitable_channel(headers.receiver_address, 2) wait_for_blocks(6) channel.update_balance(2) headers = Munch() headers.balance = str(channel.balance) headers.balance_signature = encode_hex(channel.balance_sig) headers.sender_address = channel.sender headers.open_block = str(channel.block) headers = HTTPHeaders.serialize(headers) response = requests.get(endpoint_url + '/resource_5', headers=headers) assert response.status_code == 200 assert response.text.strip() == '5'