Skip to content

Commit

Permalink
Merge pull request #16035 from brave/sszaloki-26545-check-if-the-user…
Browse files Browse the repository at this point in the history
…-has-a-recipient_id-before-creating-one

Implements `GetRecipientIDGemini`.
  • Loading branch information
szilardszaloki authored Nov 21, 2022
2 parents db541aa + 91669cc commit 975476a
Show file tree
Hide file tree
Showing 10 changed files with 362 additions and 15 deletions.
2 changes: 2 additions & 0 deletions vendor/bat-native-ledger/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ source_set("ledger") {
"src/bat/ledger/internal/endpoint/uphold/uphold_server.h",
"src/bat/ledger/internal/endpoint/uphold/uphold_utils.cc",
"src/bat/ledger/internal/endpoint/uphold/uphold_utils.h",
"src/bat/ledger/internal/endpoints/gemini/get_recipient_id/get_recipient_id_gemini.cc",
"src/bat/ledger/internal/endpoints/gemini/get_recipient_id/get_recipient_id_gemini.h",
"src/bat/ledger/internal/endpoints/get_parameters/get_parameters.cc",
"src/bat/ledger/internal/endpoints/get_parameters/get_parameters.h",
"src/bat/ledger/internal/endpoints/get_parameters/get_parameters_utils.cc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
module ledger.mojom;

enum GetRecipientIDGeminiError {
kFailedToCreateRequest,
kUnexpectedStatusCode, // HTTP xxx
kFailedToParseBody
};

enum GetParametersError {
kFailedToCreateRequest,
kFailedToGetParameters, // HTTP 500
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
#include "bat/ledger/ledger.h"

namespace ledger {
namespace endpoint {
namespace gemini {
namespace endpoints {
inline const char kGeminiRecipientIDLabel[] = "Brave Browser";
}
namespace endpoint::gemini {

std::string GetClientId();

Expand All @@ -26,8 +28,7 @@ std::string GetOauthServerUrl(const std::string& path);

mojom::Result CheckStatusCode(const int status_code);

} // namespace gemini
} // namespace endpoint
} // namespace endpoint::gemini
} // namespace ledger

#endif // BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINT_GEMINI_GEMINI_UTILS_H_
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mojom::Result PostRecipientId::ParseBody(const std::string& body,

std::string PostRecipientId::GeneratePayload() {
base::Value::Dict payload;
payload.Set("label", base::GenerateGUID());
payload.Set("label", endpoints::kGeminiRecipientIDLabel);

std::string json;
base::JSONWriter::Write(payload, &json);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "bat/ledger/internal/endpoints/gemini/get_recipient_id/get_recipient_id_gemini.h"

#include <utility>

#include "base/json/json_reader.h"
#include "bat/ledger/internal/endpoint/gemini/gemini_utils.h"
#include "bat/ledger/internal/ledger_impl.h"
#include "net/http/http_status_code.h"

namespace ledger::endpoints {
using Error = GetRecipientIDGemini::Error;
using Result = GetRecipientIDGemini::Result;

namespace {

Result ParseBody(const std::string& body) {
auto value = base::JSONReader::Read(body);
if (!value || !value->is_list()) {
BLOG(0, "Failed to parse body!");
return base::unexpected(Error::kFailedToParseBody);
}

for (auto& item : value->GetList()) {
auto* pair = item.GetIfDict();
if (!pair) {
BLOG(0, "Failed to parse body!");
return base::unexpected(Error::kFailedToParseBody);
}

auto* label = pair->FindString("label");
auto* recipient_id = pair->FindString("recipient_id");

if (!label || !recipient_id) {
BLOG(0, "Failed to parse body!");
return base::unexpected(Error::kFailedToParseBody);
}

if (*label == kGeminiRecipientIDLabel) {
return std::move(*recipient_id);
}
}

return "";
}

} // namespace

// static
Result GetRecipientIDGemini::ProcessResponse(
const mojom::UrlResponse& response) {
switch (response.status_code) {
case net::HTTP_OK: // HTTP 200
return ParseBody(response.body);
default:
BLOG(0, "Unexpected status code! (HTTP " << response.status_code << ')');
return base::unexpected(Error::kUnexpectedStatusCode);
}
}

GetRecipientIDGemini::GetRecipientIDGemini(LedgerImpl* ledger,
std::string&& token)
: RequestBuilder(ledger), token_(std::move(token)) {}

GetRecipientIDGemini::~GetRecipientIDGemini() = default;

absl::optional<std::string> GetRecipientIDGemini::Url() const {
return endpoint::gemini::GetApiServerUrl("/v1/payments/recipientIds");
}

mojom::UrlMethod GetRecipientIDGemini::Method() const {
return mojom::UrlMethod::GET;
}

absl::optional<std::vector<std::string>> GetRecipientIDGemini::Headers(
const std::string&) const {
return endpoint::gemini::RequestAuthorization(token_);
}

} // namespace ledger::endpoints
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINTS_GEMINI_GET_RECIPIENT_ID_GET_RECIPIENT_ID_GEMINI_H_
#define BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINTS_GEMINI_GET_RECIPIENT_ID_GET_RECIPIENT_ID_GEMINI_H_

#include <string>
#include <vector>

#include "bat/ledger/internal/endpoints/request_builder.h"
#include "bat/ledger/internal/endpoints/response_handler.h"
#include "bat/ledger/internal/endpoints/result_for.h"
#include "brave/vendor/bat-native-ledger/include/bat/ledger/public/interfaces/ledger_endpoints.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

// GET /v1/payments/recipientIds
//
// Request body:
// -
//
// Response body:
// [
// {
// "label": "95eac685-3e3e-4e5d-a32d-5bc18716cb0d",
// "recipient_id": "621609a9-ce36-453f-b892-0d7b42212329"
// }, {
// "label": "de476441-a834-4b93-82e3-3226e5153f73",
// "recipient_id": "621d392c-75b3-b655-94e4-2849a44d38a9"
// }, {
// "label": "Brave Browser",
// "recipient_id": "6378fc55-18db-488a-85a3-1af557767d0a"
// }
// ]

namespace ledger {
class LedgerImpl;

namespace endpoints {

class GetRecipientIDGemini;

template <>
struct ResultFor<GetRecipientIDGemini> {
using Value = std::string; // recipient ID
using Error = mojom::GetRecipientIDGeminiError;
};

class GetRecipientIDGemini final
: public RequestBuilder,
public ResponseHandler<GetRecipientIDGemini> {
public:
static Result ProcessResponse(const mojom::UrlResponse&);

GetRecipientIDGemini(LedgerImpl*, std::string&& token);
~GetRecipientIDGemini() override;

private:
absl::optional<std::string> Url() const override;
mojom::UrlMethod Method() const override;
absl::optional<std::vector<std::string>> Headers(
const std::string& content) const override;

std::string token_;
};

} // namespace endpoints
} // namespace ledger

#endif // BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINTS_GEMINI_GET_RECIPIENT_ID_GET_RECIPIENT_ID_GEMINI_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <string>
#include <tuple>
#include <utility>

#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "bat/ledger/internal/endpoints/gemini/get_recipient_id/get_recipient_id_gemini.h"
#include "bat/ledger/internal/endpoints/request_for.h"
#include "bat/ledger/internal/ledger_client_mock.h"
#include "bat/ledger/internal/ledger_impl_mock.h"
#include "net/http/http_status_code.h"
#include "testing/gtest/include/gtest/gtest.h"

// npm run test -- brave_unit_tests --filter=*GetRecipientIDGemini*

using ::testing::_;
using ::testing::Invoke;
using ::testing::TestParamInfo;
using ::testing::TestWithParam;
using ::testing::Values;

namespace ledger::endpoints::test {
using Error = GetRecipientIDGemini::Error;
using Result = GetRecipientIDGemini::Result;

// clang-format off
using GetRecipientIDGeminiParamType = std::tuple<
std::string, // test name suffix
net::HttpStatusCode, // GET recipient ID Gemini endpoint response status code
std::string, // GET recipient ID Gemini endpoint response body
Result // expected result
>;
// clang-format on

class GetRecipientIDGemini
: public TestWithParam<GetRecipientIDGeminiParamType> {
public:
GetRecipientIDGemini(const GetRecipientIDGemini&) = delete;
GetRecipientIDGemini& operator=(const GetRecipientIDGemini&) = delete;

GetRecipientIDGemini(GetRecipientIDGemini&&) = delete;
GetRecipientIDGemini& operator=(GetRecipientIDGemini&&) = delete;

private:
base::test::TaskEnvironment task_environment_;

protected:
GetRecipientIDGemini()
: mock_ledger_client_(), mock_ledger_impl_(&mock_ledger_client_) {}

MockLedgerClient mock_ledger_client_;
MockLedgerImpl mock_ledger_impl_;
};

TEST_P(GetRecipientIDGemini, Paths) {
const auto& [ignore, status_code, body, expected_result] = GetParam();

ON_CALL(mock_ledger_client_, LoadURL(_, _))
.WillByDefault(Invoke(
[status_code = status_code, body = body](
mojom::UrlRequestPtr, client::LoadURLCallback callback) mutable {
mojom::UrlResponse response;
response.status_code = status_code;
response.body = std::move(body);
std::move(callback).Run(response);
}));

RequestFor<endpoints::GetRecipientIDGemini>(&mock_ledger_impl_, "token")
.Send(base::BindLambdaForTesting(
[expected_result = expected_result](Result&& result) {
EXPECT_EQ(result, expected_result);
}));
}

// clang-format off
INSTANTIATE_TEST_SUITE_P(
Endpoints,
GetRecipientIDGemini,
Values(
GetRecipientIDGeminiParamType{
"HTTP_200_success",
net::HTTP_OK,
R"(
[
{
"label": "de476441-a834-4b93-82e3-3226e5153f73",
"recipient_id": "621d392c-75b3-b655-94e4-2849a44d38a9"
}, {
"label": "Brave Browser",
"recipient_id": "6378fc55-18db-488a-85a3-1af557767d0a"
}
]
)",
"6378fc55-18db-488a-85a3-1af557767d0a"
},
GetRecipientIDGeminiParamType{
"HTTP_200_no_recipient_id_with_brave_browser_label",
net::HTTP_OK,
R"(
[
{
"label": "de476441-a834-4b93-82e3-3226e5153f73",
"recipient_id": "621d392c-75b3-b655-94e4-2849a44d38a9"
}, {
"label": "not Brave Browser",
"recipient_id": "6378fc55-18db-488a-85a3-1af557767d0a"
}
]
)",
""
},
GetRecipientIDGeminiParamType{
"HTTP_200_failed_to_parse_body",
net::HTTP_OK,
R"(
[
{
"label": "de476441-a834-4b93-82e3-3226e5153f73",
"recipient_id": "621d392c-75b3-b655-94e4-2849a44d38a9"
}, {
"label": 42,
"recipient_id": 42
}
]
)",
base::unexpected(Error::kFailedToParseBody)
},
GetRecipientIDGeminiParamType{
"HTTP_503_unexpected_status_code",
net::HTTP_SERVICE_UNAVAILABLE,
"",
base::unexpected(Error::kUnexpectedStatusCode)
}),
[](const auto& info) {
return std::get<0>(info.param);
}
);
// clang-format on

} // namespace ledger::endpoints::test
Loading

0 comments on commit 975476a

Please sign in to comment.