mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add tests for subscribe/unsubscribe error cases:
Fixes: RIPD-1417 Fix incorrect error case messages. Fix crash in NetworkOps instance when exiting with remaining RPC subscriptions. Add code to remove URL subscription when requested.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
#include <test/jtx/WSClient.h>
|
||||
#include <test/jtx/envconfig.h>
|
||||
#include <test/jtx.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
@@ -382,6 +383,259 @@ public:
|
||||
BEAST_EXPECT(jv[jss::status] == "success");
|
||||
}
|
||||
|
||||
void
|
||||
testSubByUrl()
|
||||
{
|
||||
using namespace jtx;
|
||||
testcase("Subscribe by url");
|
||||
Env env {*this};
|
||||
|
||||
Json::Value jv;
|
||||
jv[jss::url] = "http://localhost/events";
|
||||
jv[jss::url_username] = "admin";
|
||||
jv[jss::url_password] = "password";
|
||||
jv[jss::streams] = Json::arrayValue;
|
||||
jv[jss::streams][0u] = "validations";
|
||||
auto jr = env.rpc("json", "subscribe", to_string(jv)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
|
||||
jv[jss::streams][0u] = "ledger";
|
||||
jr = env.rpc("json", "subscribe", to_string(jv)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
|
||||
jr = env.rpc("json", "unsubscribe", to_string(jv)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
|
||||
jv[jss::streams][0u] = "validations";
|
||||
jr = env.rpc("json", "unsubscribe", to_string(jv)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
}
|
||||
|
||||
void
|
||||
testSubErrors(bool subscribe)
|
||||
{
|
||||
using namespace jtx;
|
||||
auto const method = subscribe ? "subscribe" : "unsubscribe";
|
||||
testcase << "Error cases for " << method;
|
||||
|
||||
Env env {*this};
|
||||
auto wsc = makeWSClient(env.app().config());
|
||||
|
||||
{
|
||||
auto jr = env.rpc("json", method, "{}") [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::url] = "not-a-url";
|
||||
jv[jss::username] = "admin";
|
||||
jv[jss::password] = "password";
|
||||
auto jr = env.rpc("json", method, to_string(jv)) [jss::result];
|
||||
if (subscribe)
|
||||
{
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Failed to parse url.");
|
||||
}
|
||||
// else TODO: why isn't this an error for unsubscribe ?
|
||||
// (findRpcSub returns null)
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::url] = "ftp://scheme.not.supported.tld";
|
||||
auto jr = env.rpc("json", method, to_string(jv)) [jss::result];
|
||||
if (subscribe)
|
||||
{
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Only http and https is supported.");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Env env_nonadmin {*this, no_admin(envconfig(port_increment, 2))};
|
||||
Json::Value jv;
|
||||
jv[jss::url] = "no-url";
|
||||
auto jr = env_nonadmin.rpc("json", method, to_string(jv)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "noPermission");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "You don't have permission for this command.");
|
||||
}
|
||||
|
||||
for (auto const& f : {jss::accounts_proposed, jss::accounts})
|
||||
{
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[f] = "";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[f] = Json::arrayValue;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "actMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Account malformed.");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = "";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = 1;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_gets] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Json::objectValue;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "srcCurMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Source currency is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_gets] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays][jss::currency] = "ZZZZ";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "srcCurMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Source currency is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_gets] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays][jss::currency] = "USD";
|
||||
jv[jss::books][0u][jss::taker_pays][jss::issuer] = 1;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "srcIsrMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Source issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_gets] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays][jss::currency] = "USD";
|
||||
jv[jss::books][0u][jss::taker_pays][jss::issuer] = Account{"gateway"}.human() + "DEAD";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "srcIsrMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Source issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
jv[jss::books][0u][jss::taker_gets] = Json::objectValue;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
// NOTE: this error is slightly incongruous with the
|
||||
// equivalent source currency error
|
||||
BEAST_EXPECT(jr[jss::error] == "dstAmtMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Destination amount/currency/issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
jv[jss::books][0u][jss::taker_gets][jss::currency] = "ZZZZ";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
// NOTE: this error is slightly incongruous with the
|
||||
// equivalent source currency error
|
||||
BEAST_EXPECT(jr[jss::error] == "dstAmtMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Destination amount/currency/issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
jv[jss::books][0u][jss::taker_gets][jss::currency] = "USD";
|
||||
jv[jss::books][0u][jss::taker_gets][jss::issuer] = 1;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "dstIsrMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Destination issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
jv[jss::books][0u][jss::taker_gets][jss::currency] = "USD";
|
||||
jv[jss::books][0u][jss::taker_gets][jss::issuer] = Account{"gateway"}.human() + "DEAD";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "dstIsrMalformed");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Destination issuer is malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::books] = Json::arrayValue;
|
||||
jv[jss::books][0u] = Json::objectValue;
|
||||
jv[jss::books][0u][jss::taker_pays] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
jv[jss::books][0u][jss::taker_gets] = Account{"gateway"}["USD"](1).value().getJson(1);
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "badMarket");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "No such market.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::streams] = "";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::streams] = Json::arrayValue;
|
||||
jv[jss::streams][0u] = 1;
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "malformedStream");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Stream malformed.");
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::streams] = Json::arrayValue;
|
||||
jv[jss::streams][0u] = "not_a_stream";
|
||||
auto jr = wsc->invoke(method, jv) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::error] == "malformedStream");
|
||||
BEAST_EXPECT(jr[jss::error_message] == "Stream malformed.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testServer();
|
||||
@@ -389,6 +643,9 @@ public:
|
||||
testTransactions();
|
||||
testManifests();
|
||||
testValidations();
|
||||
testSubErrors(true);
|
||||
testSubErrors(false);
|
||||
testSubByUrl();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user