Exemplo n.º 1
0
def test_good_message_publish_unknown_error(app, mock_pubsub_calls,
                                            mock_set_env_webhook_signature_key):
    """ tests good message that raises unknown exception when published to topic; ensures we
        send a non-200 response
    """
    base_url = "functions.googlecloud.com"
    function_name = "/test_handle_webhook_valid"
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(content, sort_keys=True)
    signature = base64.b64encode(hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json=content,
                                  headers={'X-Square-Signature': signature}):
        mock_pubsub_calls.return_value.publish.return_value.result.side_effect = Exception
        with pytest.raises(InternalServerError):
            main.handle_webhook(flask.request)

        assert mock_pubsub_calls.return_value.publish.call_count == 1
Exemplo n.º 2
0
def test_handle_webhook_publish_timeout(app, mocker, mock_setup):
    """ test that if the publish call to pubsub times out, we send a non-200 response """
    base_url = "functions.googlecloud.com"
    function_name = "/" + os.environ["FUNCTION_NAME"]
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(
        content, sort_keys=True)
    signature = base64.b64encode(
        hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path=path,
                                  base_url=base_url,
                                  json=content,
                                  headers={"X-Square-Signature": signature}):
        with pytest.raises(InternalServerError):
            mocker.patch.object(pubsub_v1.publisher.futures.Future,
                                "result",
                                side_effect=exceptions.TimeoutError())
            main.handle_webhook(flask.request)
Exemplo n.º 3
0
def test_handle_webhook_valid_json_no_signature(app, mock_set_env_webhook_signature_key):
    """ Ensures that if there is JSON content but no signature, the message is rejected """
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    with app.test_request_context(method='POST', json=content):
        with pytest.raises(KeyError):
            main.handle_webhook(flask.request)
Exemplo n.º 4
0
def test_handle_webhook_invalid_signature(app, mock_set_env_webhook_signature_key):
    """ Ensures that if the signature is not correct, the message is rejected """
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json={
                                      "merchant_id": "merchant",
                                      "location_id": "location",
                                      "event_type": "event",
                                      "entity_id": "entity"},
                                  headers={"X-Square-Signature": "NOT_A_VALID_SIGNATURE"}):
        with pytest.raises(BadRequest):
            main.handle_webhook(flask.request)
Exemplo n.º 5
0
def test_handle_webhook_valid(app, mock_setup):
    """ tests that a valid message is successfully processed by the function """
    base_url = "functions.googlecloud.com"
    function_name = "/" + os.environ["FUNCTION_NAME"]
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(
        content, sort_keys=True)
    signature = base64.b64encode(
        hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path=path,
                                  base_url=base_url,
                                  json=content,
                                  headers={"X-Square-Signature": signature}):
        res = main.handle_webhook(flask.request)
        assert res.status == '200 OK'

        response = mock_setup.pull(request={
            "subscription": SUBSCRIPTION_PATH,
            "max_messages": 1
        })
        # ensure that what we sent over the webhook is what we got over pubsub
        assert json.loads(
            response.received_messages[0].message.data) == content
Exemplo n.º 6
0
def test_good_message_retry(app, mock_pubsub_calls, mock_set_env_webhook_signature_key):
    """ tests complete path sent as retry with only pubsub mocked out"""
    base_url = "functions.googlecloud.com"
    function_name = "/test_handle_webhook_valid"
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(content, sort_keys=True)
    signature = base64.b64encode(hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json=content,
                                  headers={
                                      'X-Square-Signature': signature,
                                      'Square-Initial-Delivery-Timestamp':
                                          datetime.datetime.utcnow().isoformat("T") + "Z",
                                      'Square-Retry-Number': 1,
                                      'Square-Retry-Reason': "500 Internal Server Error",
                                  }):
        response = main.handle_webhook(flask.request)

    assert response.status_code == 200
    assert response.data == b'message_id'
    assert mock_pubsub_calls.return_value.publish.call_count == 1
Exemplo n.º 7
0
def test_handle_webhook_empty_webhook_key(app, monkeypatch):
    """ Ensures that if the webhook key is not available to the function, the function fails. """
    monkeypatch.delenv("SQUARE_WEBHOOK_SIGNATURE_KEY", raising=False)

    base_url = "functions.googlecloud.com"
    function_name = "/test_handle_webhook_valid"
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(content, sort_keys=True)
    signature = base64.b64encode(hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json=content,
                                  headers={'X-Square-Signature': signature}):
        with pytest.raises(KeyError):
            main.handle_webhook(flask.request)
Exemplo n.º 8
0
def test_insufficient_json_fields(app, mock_pubsub_calls, mock_set_env_webhook_signature_key):
    """ tests invalid message that is missing a required field in JSON but has a valid signature;
        ensures we return a non-200 response
    """
    base_url = "functions.googlecloud.com"
    function_name = "/test_handle_webhook_valid"
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(content, sort_keys=True)
    signature = base64.b64encode(hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json=content,
                                  headers={'X-Square-Signature': signature}):
        mock_pubsub_calls.return_value.publish.return_value.result.side_effect = Exception
        with pytest.raises(BadRequest):
            main.handle_webhook(flask.request)

        assert mock_pubsub_calls.return_value.publish.call_count == 0
Exemplo n.º 9
0
def test_good_message(app, mock_pubsub_calls, mock_set_env_webhook_signature_key):
    """ tests complete path with only pubsub mocked out"""
    base_url = "functions.googlecloud.com"
    function_name = "/test_handle_webhook_valid"
    path = "/test_handle_webhook_valid"
    content = {
        "merchant_id": "merchant",
        "location_id": "location",
        "event_type": "event",
        "entity_id": "entity"
    }
    to_sign = "://" + base_url + function_name + path + json.dumps(content, sort_keys=True)
    signature = base64.b64encode(hmac.new(KEY.encode(), to_sign.encode(), sha1).digest())
    with app.test_request_context(method='POST',
                                  path="/test_handle_webhook_valid",
                                  base_url="functions.googlecloud.com",
                                  json=content,
                                  headers={'X-Square-Signature': signature}):
        response = main.handle_webhook(flask.request)

    assert response.status_code == 200
    assert response.data == b'message_id'
    assert mock_pubsub_calls.return_value.publish.call_count == 1
Exemplo n.º 10
0
def test_handle_webhook_send_non_json(app):
    """ Ensures that if there is content but it is not JSON, the message is rejected """
    with app.test_request_context(method='POST', content_type='text/plain', data='abc123'):
        with pytest.raises(UnsupportedMediaType):
            main.handle_webhook(flask.request)
Exemplo n.º 11
0
def test_handle_webhook_empty_json(app):
    """ Ensures that if there is no content, the message is rejected """
    with app.test_request_context(method='POST', content_type='application/json'):
        with pytest.raises(BadRequest):
            main.handle_webhook(flask.request)
Exemplo n.º 12
0
def test_handle_webhook_invalid_method(method, app, mock_set_env_webhook_signature_key):
    """ Ensures that if the webhook only responds to POST requests. """
    with app.test_request_context(method=method):
        with pytest.raises(MethodNotAllowed):
            main.handle_webhook(flask.request)