From 241c47f23fbb770ad770166610299a7fe0ac7c5b Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Thu, 20 Aug 2020 08:41:23 +0200 Subject: [PATCH] Adds payment server handler Resolves https://github.com/brave/brave-browser/issues/11284 --- components/brave_rewards/test/BUILD.gn | 44 ++-- vendor/bat-native-ledger/BUILD.gn | 6 + .../endpoint/payment/payment_server.cc | 26 +++ .../endpoint/payment/payment_server.h | 36 +++ .../internal/endpoint/payment/payment_util.cc | 39 ++++ .../internal/endpoint/payment/payment_util.h | 21 ++ .../endpoint/payment/payment_util_unittest.cc | 41 ++++ .../endpoint/payment/post_order/post_order.cc | 205 +++++++++++++++++ .../endpoint/payment/post_order/post_order.h | 104 +++++++++ .../payment/post_order/post_order_unittest.cc | 215 ++++++++++++++++++ .../ledger/internal/request/request_sku.cc | 4 - .../bat/ledger/internal/request/request_sku.h | 2 - .../ledger/internal/response/response_sku.cc | 144 ------------ .../ledger/internal/response/response_sku.h | 4 - .../src/bat/ledger/internal/sku/sku_order.cc | 41 +--- .../src/bat/ledger/internal/sku/sku_order.h | 7 +- 16 files changed, 729 insertions(+), 210 deletions(-) create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util_unittest.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order_unittest.cc diff --git a/components/brave_rewards/test/BUILD.gn b/components/brave_rewards/test/BUILD.gn index 38a5e2058b7c2..0cf536bef335e 100644 --- a/components/brave_rewards/test/BUILD.gn +++ b/components/brave_rewards/test/BUILD.gn @@ -17,8 +17,6 @@ source_set("brave_rewards_unit_tests") { "//brave/components/brave_rewards/browser/rewards_service_impl_unittest.cc", "//brave/components/l10n/browser/locale_helper_mock.cc", "//brave/components/l10n/browser/locale_helper_mock.h", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/bat_helper_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/bat_util_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_monthly_util_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/credentials/credentials_util_unittest.cc", @@ -28,27 +26,10 @@ source_set("brave_rewards_unit_tests") { "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_mock.h", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_publisher_prefix_list_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_util_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_client_mock.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_client_mock.h", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/client_state_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/publisher_settings_state_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/report_balance_state_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/wallet_info_state_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/logging/logging_util_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/github_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/reddit_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/vimeo_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/publisher/prefix_list_reader_unittest.cc", - "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/publisher/publisher_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/api/api_util_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/get_available/get_available_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/get_captcha/get_captcha_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/get_recover_wallet/get_recover_wallet_unittest.cc", @@ -68,6 +49,27 @@ source_set("brave_rewards_unit_tests") { "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/put_captcha/put_captcha_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/put_devicecheck/put_devicecheck_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/put_safetynet/put_safetynet_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_client_mock.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_client_mock.h", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/bat_helper_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/bat_util_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/client_state_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/publisher_settings_state_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/report_balance_state_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/legacy/wallet_info_state_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/logging/logging_util_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/github_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/reddit_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/vimeo_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/publisher/prefix_list_reader_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/publisher/publisher_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_util_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet_util_unittest.cc", diff --git a/vendor/bat-native-ledger/BUILD.gn b/vendor/bat-native-ledger/BUILD.gn index ef7fadb4af1f9..410b559744575 100644 --- a/vendor/bat-native-ledger/BUILD.gn +++ b/vendor/bat-native-ledger/BUILD.gn @@ -324,6 +324,12 @@ source_set("ledger") { "src/bat/ledger/internal/endpoint/api/api_util.h", "src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters.cc", "src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters.h", + "src/bat/ledger/internal/endpoint/payment/payment_server.cc", + "src/bat/ledger/internal/endpoint/payment/payment_server.h", + "src/bat/ledger/internal/endpoint/payment/payment_util.cc", + "src/bat/ledger/internal/endpoint/payment/payment_util.h", + "src/bat/ledger/internal/endpoint/payment/post_order/post_order.cc", + "src/bat/ledger/internal/endpoint/payment/post_order/post_order.h", "src/bat/ledger/internal/endpoint/promotion/get_available/get_available.cc", "src/bat/ledger/internal/endpoint/promotion/get_available/get_available.h", "src/bat/ledger/internal/endpoint/promotion/get_captcha/get_captcha.cc", diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.cc new file mode 100644 index 0000000000000..ec89217ed67d1 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.cc @@ -0,0 +1,26 @@ +/* Copyright (c) 2020 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/endpoint/payment/payment_server.h" + +#include "bat/ledger/internal/ledger_impl.h" + +namespace ledger { +namespace endpoint { + +PaymentServer::PaymentServer(bat_ledger::LedgerImpl* ledger): + ledger_(ledger), + post_order_(new payment::PostOrder(ledger)) { + DCHECK(ledger_); +} + +PaymentServer::~PaymentServer() = default; + +payment::PostOrder* PaymentServer::post_order() const { + return post_order_.get(); +} + +} // namespace endpoint +} // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.h b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.h new file mode 100644 index 0000000000000..5ea112503aa1f --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_server.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2020 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 BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_SERVER_H_ +#define BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_SERVER_H_ + +#include + +#include "bat/ledger/ledger.h" +#include "bat/ledger/internal/endpoint/payment/post_order/post_order.h" + +namespace bat_ledger { +class LedgerImpl; +} + +namespace ledger { +namespace endpoint { + +class PaymentServer { + public: + explicit PaymentServer(bat_ledger::LedgerImpl* ledger); + ~PaymentServer(); + + payment::PostOrder* post_order() const; + + private: + bat_ledger::LedgerImpl* ledger_; // NOT OWNED + std::unique_ptr post_order_; +}; + +} // namespace endpoint +} // namespace ledger + +#endif // BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_SERVER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.cc new file mode 100644 index 0000000000000..eec7343dfc326 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.cc @@ -0,0 +1,39 @@ +/* Copyright (c) 2020 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/endpoint/payment/payment_util.h" + +#include "bat/ledger/ledger.h" + +namespace ledger { +namespace endpoint { +namespace payment { + +const char kDevelopment[] = "https://payment.rewards.brave.software"; +const char kStaging[] = "http://payment.rewards.bravesoftware.com"; +const char kProduction[] = "http://payment.rewards.brave.com"; + +std::string GetServerUrl(const std::string& path) { + DCHECK(!path.empty()); + + std::string url; + switch (ledger::_environment) { + case ledger::Environment::DEVELOPMENT: + url = kDevelopment; + break; + case ledger::Environment::STAGING: + url = kStaging; + break; + case ledger::Environment::PRODUCTION: + url = kProduction; + break; + } + + return url + path; +} + +} // namespace payment +} // namespace endpoint +} // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.h b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.h new file mode 100644 index 0000000000000..84106d0d7c057 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2020 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 BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_UTIL_H_ +#define BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_UTIL_H_ + +#include + +namespace ledger { +namespace endpoint { +namespace payment { + +std::string GetServerUrl(const std::string& path); + +} // namespace payment +} // namespace endpoint +} // namespace ledger + +#endif // BRAVELEDGER_ENDPOINT_PAYMENT_PAYMENT_UTIL_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util_unittest.cc new file mode 100644 index 0000000000000..544a8bda9bca4 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/payment_util_unittest.cc @@ -0,0 +1,41 @@ +/* Copyright (c) 2020 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/global_constants.h" +#include "bat/ledger/internal/endpoint/payment/payment_util.h" +#include "bat/ledger/ledger.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=PaymentUtilTest.* + +namespace ledger { +namespace endpoint { +namespace payment { + +class PaymentUtilTest : public testing::Test { +}; + +TEST(PaymentUtilTest, GetServerUrlDevelopment) { + ledger::_environment = ledger::Environment::DEVELOPMENT; + const std::string url = GetServerUrl("/test"); + const std::string expected_url = ""; + ASSERT_EQ(url, "https://payment.rewards.brave.software/test"); +} + +TEST(PaymentUtilTest, GetServerUrlStaging) { + ledger::_environment = ledger::Environment::STAGING; + const std::string url = GetServerUrl("/test"); + ASSERT_EQ(url, "https://payment.rewards.bravesoftware.com/test"); +} + +TEST(PaymentUtilTest, GetServerUrlProduction) { + ledger::_environment = ledger::Environment::PRODUCTION; + const std::string url = GetServerUrl("/test"); + ASSERT_EQ(url, "https://payment.rewards.brave.com/test"); +} + +} // namespace payment +} // namespace endpoint +} // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.cc new file mode 100644 index 0000000000000..54f0609de7989 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.cc @@ -0,0 +1,205 @@ +/* Copyright (c) 2020 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/endpoint/payment/post_order/post_order.h" + +#include + +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "bat/ledger/internal/endpoint/payment/payment_util.h" +#include "bat/ledger/internal/ledger_impl.h" +#include "net/http/http_status_code.h" + +using std::placeholders::_1; + +namespace ledger { +namespace endpoint { +namespace payment { + +PostOrder::PostOrder(bat_ledger::LedgerImpl* ledger): + ledger_(ledger) { + DCHECK(ledger_); +} + +PostOrder::~PostOrder() = default; + +std::string PostOrder::GetUrl() { + return GetServerUrl("/v1//orders"); +} + +std::string PostOrder::GeneratePayload( + const std::vector& items) { + base::Value order_items(base::Value::Type::LIST); + for (const auto& item : items) { + base::Value order_item(base::Value::Type::DICTIONARY); + order_item.SetStringKey("sku", item.sku); + order_item.SetIntKey("quantity", item.quantity); + order_items.Append(std::move(order_item)); + } + + base::Value body(base::Value::Type::DICTIONARY); + body.SetKey("items", std::move(order_items)); + + std::string json; + base::JSONWriter::Write(body, &json); + + return json; +} + +ledger::Result PostOrder::CheckStatusCode(const int status_code) { + if (status_code == net::HTTP_BAD_REQUEST) { + BLOG(0, "Invalid request"); + return ledger::Result::RETRY_SHORT; + } + + if (status_code == net::HTTP_INTERNAL_SERVER_ERROR) { + BLOG(0, "Internal server error"); + return ledger::Result::RETRY_SHORT; + } + + if (status_code != net::HTTP_CREATED) { + return ledger::Result::LEDGER_ERROR; + } + + return ledger::Result::LEDGER_OK; +} + +ledger::Result PostOrder::ParseBody( + const std::string& body, + const std::vector& order_items, + ledger::SKUOrder* order) { + DCHECK(order); + + base::Optional dictionary = base::JSONReader::Read(body); + if (!dictionary || !dictionary->is_dict()) { + BLOG(0, "Invalid JSON"); + return ledger::Result::LEDGER_ERROR; + } + + const auto* id = dictionary->FindStringKey("id"); + if (id) { + order->order_id = *id; + } + + if (order->order_id.empty()) { + BLOG(0, "Order id empty"); + return ledger::Result::LEDGER_ERROR; + } + + const auto* total_amount = dictionary->FindStringKey("totalPrice"); + if (total_amount) { + const bool success = + base::StringToDouble(*total_amount, &order->total_amount); + if (!success) { + order->total_amount = 0.0; + } + } + + const auto* merchant_id = dictionary->FindStringKey("merchantId"); + if (merchant_id) { + order->merchant_id = *merchant_id; + } + + const auto* location = dictionary->FindStringKey("location"); + if (location) { + order->location = *location; + } + + order->status = ledger::SKUOrderStatus::PENDING; + + auto* items = dictionary->FindListKey("items"); + if (!items) { + return ledger::Result::LEDGER_OK; + } + + if (items->GetList().size() != order_items.size()) { + BLOG(0, "Invalid JSON"); + return ledger::Result::LEDGER_ERROR; + } + + int count = 0; + for (auto& item : items->GetList()) { + auto order_item = ledger::SKUOrderItem::New(); + order_item->order_id = order->order_id; + order_item->sku = order_items[count].sku; + order_item->type = order_items[count].type; + + const auto* id = item.FindStringKey("id"); + if (id) { + order_item->order_item_id = *id; + } + + const auto quantity = item.FindIntKey("quantity"); + if (quantity) { + order_item->quantity = *quantity; + } + + const auto* price = item.FindStringKey("price"); + if (price) { + const bool success = base::StringToDouble(*price, &order_item->price); + if (!success) { + order_item->price = 0.0; + } + } + + const auto* name = item.FindStringKey("name"); + if (name) { + order_item->name = *name; + } + + const auto* description = item.FindStringKey("description"); + if (description) { + order_item->description = *description; + } + + order->items.push_back(std::move(order_item)); + + count++; + } + + return ledger::Result::LEDGER_OK; +} + +void PostOrder::Request( + const std::vector& items, + PostOrderCallback callback) { + auto url_callback = std::bind(&PostOrder::OnRequest, + this, + _1, + items, + callback); + ledger_->LoadURL( + GetUrl(), + {}, + GeneratePayload(items), + "application/json; charset=utf-8", + ledger::UrlMethod::POST, + url_callback); +} + +void PostOrder::OnRequest( + const ledger::UrlResponse& response, + const std::vector& items, + PostOrderCallback callback) { + ledger::LogUrlResponse(__func__, response); + + ledger::Result result = CheckStatusCode(response.status_code); + + if (result != ledger::Result::LEDGER_OK) { + callback(result, nullptr); + return; + } + + auto order = ledger::SKUOrder::New(); + result = ParseBody(response.body, items, order.get()); + callback(result, std::move(order)); +} + +} // namespace payment +} // namespace endpoint +} // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.h b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.h new file mode 100644 index 0000000000000..ff5061cbd95d3 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2020 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 BRAVELEDGER_ENDPOINT_PAYMENT_POST_ORDER_POST_ORDER_H_ +#define BRAVELEDGER_ENDPOINT_PAYMENT_POST_ORDER_POST_ORDER_H_ + +#include +#include + +#include "bat/ledger/ledger.h" + +// POST /v1/orders +// +// Request body: +// { +// "items": [ +// { +// "sku": "okasofkasofdkasofkoasdkf", +// "quantity": 5 +// } +// ] +// } +// +// Success code: +// HTTP_CREATED (201) +// +// Error codes: +// HTTP_BAD_REQUEST (400) +// HTTP_INTERNAL_SERVER_ERROR (500) +// +// Response body: +// { +// "id": "f2e6494e-fb21-44d1-90e9-b5408799acd8", +// "createdAt": "2020-06-10T18:58:21.378752Z", +// "currency": "BAT", +// "updatedAt": "2020-06-10T18:58:21.378752Z", +// "totalPrice": "1", +// "location": "brave.com", +// "status": "pending", +// "items": [ +// { +// "id": "9c9aed7f-b349-452e-80a8-95faf2b1600d", +// "orderId": "f2e6494e-fb21-44d1-90e9-b5408799acd8", +// "sku": "user-wallet-vote", +// "createdAt": "2020-06-10T18:58:21.378752Z", +// "updatedAt": "2020-06-10T18:58:21.378752Z", +// "currency": "BAT", +// "quantity": 4, +// "price": "0.25", +// "subtotal": "1", +// "location": "brave.com", +// "description": "" +// } +// ] +// } + +namespace bat_ledger { +class LedgerImpl; +} + +namespace ledger { +namespace endpoint { +namespace payment { + +using PostOrderCallback = std::function; + +class PostOrder { + public: + explicit PostOrder(bat_ledger::LedgerImpl* ledger); + ~PostOrder(); + + void Request( + const std::vector& items, + PostOrderCallback callback); + + private: + std::string GetUrl(); + + std::string GeneratePayload(const std::vector& items); + + ledger::Result CheckStatusCode(const int status_code); + + ledger::Result ParseBody( + const std::string& body, + const std::vector& order_items, + ledger::SKUOrder* order); + + void OnRequest( + const ledger::UrlResponse& response, + const std::vector& items, + PostOrderCallback callback); + + bat_ledger::LedgerImpl* ledger_; // NOT OWNED +}; + +} // namespace payment +} // namespace endpoint +} // namespace ledger + +#endif // BRAVELEDGER_ENDPOINT_PAYMENT_POST_ORDER_POST_ORDER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order_unittest.cc new file mode 100644 index 0000000000000..5cce611c7f767 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/payment/post_order/post_order_unittest.cc @@ -0,0 +1,215 @@ +/* Copyright (c) 2020 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 +#include +#include +#include + +#include "base/test/task_environment.h" +#include "bat/ledger/internal/ledger_client_mock.h" +#include "bat/ledger/internal/ledger_impl_mock.h" +#include "bat/ledger/internal/endpoint/payment/post_order/post_order.h" +#include "bat/ledger/ledger.h" +#include "net/http/http_status_code.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=PostOrderTest.* + +using ::testing::_; +using ::testing::Invoke; + +namespace ledger { +namespace endpoint { +namespace payment { + +class PostOrderTest : public testing::Test { + private: + base::test::TaskEnvironment scoped_task_environment_; + + protected: + std::unique_ptr mock_ledger_client_; + std::unique_ptr mock_ledger_impl_; + std::unique_ptr order_; + + PostOrderTest() { + mock_ledger_client_ = std::make_unique(); + mock_ledger_impl_ = + std::make_unique(mock_ledger_client_.get()); + order_ = std::make_unique(mock_ledger_impl_.get()); + } +}; + +TEST_F(PostOrderTest, ServerOK) { + ON_CALL(*mock_ledger_client_, LoadURL(_, _, _, _, _, _)) + .WillByDefault( + Invoke([]( + const std::string& url, + const std::vector& headers, + const std::string& content, + const std::string& contentType, + const ledger::UrlMethod method, + ledger::LoadURLCallback callback) { + ledger::UrlResponse response; + response.status_code = 201; + response.url = url; + response.body = R"({ + "id": "f2e6494e-fb21-44d1-90e9-b5408799acd8", + "createdAt": "2020-06-10T18:58:21.378752Z", + "currency": "BAT", + "updatedAt": "2020-06-10T18:58:21.378752Z", + "totalPrice": "1", + "merchantId": "", + "location": "brave.com", + "status": "pending", + "items": [ + { + "id": "9c9aed7f-b349-452e-80a8-95faf2b1600d", + "orderId": "f2e6494e-fb21-44d1-90e9-b5408799acd8", + "sku": "user-wallet-vote", + "createdAt": "2020-06-10T18:58:21.378752Z", + "updatedAt": "2020-06-10T18:58:21.378752Z", + "currency": "BAT", + "quantity": 4, + "price": "0.25", + "subtotal": "1", + "location": "brave.com", + "description": "" + } + ] + })"; + callback(response); + })); + + ledger::SKUOrderItem item; + item.quantity = 4; + item.sku = "asdfasfasfdsdf"; + item.type = ledger::SKUOrderItemType::SINGLE_USE; + std::vector items; + items.push_back(item); + + order_->Request( + items, + [](const ledger::Result result, ledger::SKUOrderPtr order) { + auto expected_order_item = ledger::SKUOrderItem::New(); + expected_order_item->order_id = "f2e6494e-fb21-44d1-90e9-b5408799acd8"; + expected_order_item->sku = "asdfasfasfdsdf"; + expected_order_item->type = ledger::SKUOrderItemType::SINGLE_USE; + expected_order_item->order_item_id = + "9c9aed7f-b349-452e-80a8-95faf2b1600d"; + expected_order_item->quantity = 4; + expected_order_item->price = 0.25; + + ledger::SKUOrder expected_order; + expected_order.order_id = "f2e6494e-fb21-44d1-90e9-b5408799acd8"; + expected_order.total_amount = 1; + expected_order.location = "brave.com"; + expected_order.status = ledger::SKUOrderStatus::PENDING; + expected_order.items.push_back(std::move(expected_order_item)); + + EXPECT_EQ(result, ledger::Result::LEDGER_OK); + EXPECT_TRUE(expected_order.Equals(*order)); + }); +} + +TEST_F(PostOrderTest, ServerError400) { + ON_CALL(*mock_ledger_client_, LoadURL(_, _, _, _, _, _)) + .WillByDefault( + Invoke([]( + const std::string& url, + const std::vector& headers, + const std::string& content, + const std::string& contentType, + const ledger::UrlMethod method, + ledger::LoadURLCallback callback) { + ledger::UrlResponse response; + response.status_code = 400; + response.url = url; + response.body = ""; + callback(response); + })); + + ledger::SKUOrderItem item; + item.quantity = 4; + item.sku = "asdfasfasfdsdf"; + item.type = ledger::SKUOrderItemType::SINGLE_USE; + std::vector items; + items.push_back(item); + + order_->Request( + items, + [](const ledger::Result result, ledger::SKUOrderPtr order) { + EXPECT_EQ(result, ledger::Result::RETRY_SHORT); + EXPECT_TRUE(!order); + }); +} + +TEST_F(PostOrderTest, ServerError500) { + ON_CALL(*mock_ledger_client_, LoadURL(_, _, _, _, _, _)) + .WillByDefault( + Invoke([]( + const std::string& url, + const std::vector& headers, + const std::string& content, + const std::string& contentType, + const ledger::UrlMethod method, + ledger::LoadURLCallback callback) { + ledger::UrlResponse response; + response.status_code = 500; + response.url = url; + response.body = ""; + callback(response); + })); + + ledger::SKUOrderItem item; + item.quantity = 4; + item.sku = "asdfasfasfdsdf"; + item.type = ledger::SKUOrderItemType::SINGLE_USE; + std::vector items; + items.push_back(item); + + order_->Request( + items, + [](const ledger::Result result, ledger::SKUOrderPtr order) { + EXPECT_EQ(result, ledger::Result::RETRY_SHORT); + EXPECT_TRUE(!order); + }); +} + +TEST_F(PostOrderTest, ServerErrorRandom) { + ON_CALL(*mock_ledger_client_, LoadURL(_, _, _, _, _, _)) + .WillByDefault( + Invoke([]( + const std::string& url, + const std::vector& headers, + const std::string& content, + const std::string& contentType, + const ledger::UrlMethod method, + ledger::LoadURLCallback callback) { + ledger::UrlResponse response; + response.status_code = 453; + response.url = url; + response.body = ""; + callback(response); + })); + + ledger::SKUOrderItem item; + item.quantity = 4; + item.sku = "asdfasfasfdsdf"; + item.type = ledger::SKUOrderItemType::SINGLE_USE; + std::vector items; + items.push_back(item); + + order_->Request( + items, + [](const ledger::Result result, ledger::SKUOrderPtr order) { + EXPECT_EQ(result, ledger::Result::LEDGER_ERROR); + EXPECT_TRUE(!order); + }); +} + +} // namespace payment +} // namespace endpoint +} // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.cc index dc7704d9aa8b5..7d2000240399e 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.cc @@ -29,10 +29,6 @@ std::string GetTransactionSuffix(const ledger::SKUTransactionType type) { namespace braveledger_request_util { -std::string GetCreateOrderURL() { - return BuildUrl("/orders", PREFIX_V1, ServerTypes::kPayments); -} - std::string GetOrderCredentialsURL( const std::string& order_id, const std::string& item_id) { diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.h b/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.h index 7232535594e99..28d8dd29ec69e 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/request/request_sku.h @@ -12,8 +12,6 @@ namespace braveledger_request_util { -std::string GetCreateOrderURL(); - std::string GetOrderCredentialsURL( const std::string& order_id, const std::string& item_id = ""); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.cc index 87174f049adbd..396133c3f8121 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.cc @@ -68,150 +68,6 @@ ledger::Result CheckSendExternalTransaction( return ledger::Result::LEDGER_OK; } -// Request Url: -// POST /v1/orders -// -// Success: -// Created (201) -// -// Response Format: -// { -// "id": "f2e6494e-fb21-44d1-90e9-b5408799acd8", -// "createdAt": "2020-06-10T18:58:21.378752Z", -// "currency": "BAT", -// "updatedAt": "2020-06-10T18:58:21.378752Z", -// "totalPrice": "1", -// "location": "brave.com", -// "status": "pending", -// "items": [ -// { -// "id": "9c9aed7f-b349-452e-80a8-95faf2b1600d", -// "orderId": "f2e6494e-fb21-44d1-90e9-b5408799acd8", -// "sku": "user-wallet-vote", -// "createdAt": "2020-06-10T18:58:21.378752Z", -// "updatedAt": "2020-06-10T18:58:21.378752Z", -// "currency": "BAT", -// "quantity": 4, -// "price": "0.25", -// "subtotal": "1", -// "location": "brave.com", -// "description": "" -// } -// ] -// } - -ledger::SKUOrderPtr ParseOrderCreate( - const ledger::UrlResponse& response, - const std::vector& order_items) { - // Bad Request (400) - if (response.status_code == net::HTTP_BAD_REQUEST) { - BLOG(0, "Invalid request"); - return nullptr; - } - - // Internal Server Error (500) - if (response.status_code == net::HTTP_INTERNAL_SERVER_ERROR) { - BLOG(0, "Internal server error"); - return nullptr; - } - - // Created (201) - if (response.status_code != net::HTTP_CREATED) { - return nullptr; - } - - base::Optional dictionary = - base::JSONReader::Read(response.body); - if (!dictionary || !dictionary->is_dict()) { - BLOG(0, "Invalid JSON"); - return nullptr; - } - - auto order = ledger::SKUOrder::New(); - - const auto* id = dictionary->FindStringKey("id"); - if (id) { - order->order_id = *id; - } - - if (order->order_id.empty()) { - return nullptr; - } - - const auto* total_amount = dictionary->FindStringKey("totalPrice"); - if (total_amount) { - const bool success = - base::StringToDouble(*total_amount, &order->total_amount); - if (!success) { - order->total_amount = 0.0; - } - } - - const auto* merchant_id = dictionary->FindStringKey("merchantId"); - if (merchant_id) { - order->merchant_id = *merchant_id; - } - - const auto* location = dictionary->FindStringKey("location"); - if (location) { - order->location = *location; - } - - order->status = ledger::SKUOrderStatus::PENDING; - - auto* items = dictionary->FindListKey("items"); - if (!items) { - return order; - } - - if (items->GetList().size() != order_items.size()) { - BLOG(0, "Invalid JSON"); - return nullptr; - } - - int count = 0; - for (auto& item : items->GetList()) { - auto order_item = ledger::SKUOrderItem::New(); - order_item->order_id = order->order_id; - order_item->sku = order_items[count].sku; - order_item->type = order_items[count].type; - - const auto* id = item.FindStringKey("id"); - if (id) { - order_item->order_item_id = *id; - } - - const auto quantity = item.FindIntKey("quantity"); - if (quantity) { - order_item->quantity = *quantity; - } - - const auto* price = item.FindStringKey("price"); - if (price) { - const bool success = base::StringToDouble(*price, &order_item->price); - if (!success) { - order_item->price = 0.0; - } - } - - const auto* name = item.FindStringKey("name"); - if (name) { - order_item->name = *name; - } - - const auto* description = item.FindStringKey("description"); - if (description) { - order_item->description = *description; - } - - order->items.push_back(std::move(order_item)); - - count++; - } - - return order; -} - // Request Url: // POST /v1/orders/{order_id}/credentials // POST /v1/orders/{order_id}/credentials/{item_id} diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.h b/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.h index 4a7d4f56a3fbd..ac06b88899c85 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/response/response_sku.h @@ -15,10 +15,6 @@ namespace braveledger_response_util { ledger::Result CheckSendExternalTransaction( const ledger::UrlResponse& response); -ledger::SKUOrderPtr ParseOrderCreate( - const ledger::UrlResponse& response, - const std::vector& order_items); - ledger::Result CheckClaimSKUCreds(const ledger::UrlResponse& response); ledger::Result CheckRedeemSKUTokens( diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.cc index 16b7eb4c787ae..bd65bf6ad823b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.cc @@ -19,7 +19,9 @@ using std::placeholders::_3; namespace braveledger_sku { -SKUOrder::SKUOrder(bat_ledger::LedgerImpl* ledger) : ledger_(ledger) { +SKUOrder::SKUOrder(bat_ledger::LedgerImpl* ledger) : + ledger_(ledger), + payment_server_(new ledger::endpoint::PaymentServer(ledger)) { DCHECK(ledger_); } @@ -34,47 +36,20 @@ void SKUOrder::Create( return; } - base::Value order_items(base::Value::Type::LIST); - for (const auto& item : items) { - base::Value order_item(base::Value::Type::DICTIONARY); - order_item.SetStringKey("sku", item.sku); - order_item.SetIntKey("quantity", item.quantity); - order_items.Append(std::move(order_item)); - } - - base::Value body(base::Value::Type::DICTIONARY); - body.SetKey("items", std::move(order_items)); - - std::string json; - base::JSONWriter::Write(body, &json); - auto url_callback = std::bind(&SKUOrder::OnCreate, this, _1, - items, + _2, callback); - const std::string url = braveledger_request_util::GetCreateOrderURL(); - - ledger_->LoadURL( - url, - {}, - json, - "application/json; charset=utf-8", - ledger::UrlMethod::POST, - url_callback); + payment_server_->post_order()->Request(items, url_callback); } void SKUOrder::OnCreate( - const ledger::UrlResponse& response, - const std::vector& order_items, + const ledger::Result result, + ledger::SKUOrderPtr order, ledger::SKUOrderCallback callback) { - BLOG(6, ledger::UrlResponseToString(__func__, response)); - - auto order = - braveledger_response_util::ParseOrderCreate(response, order_items); - - if (!order) { + if (result != ledger::Result::LEDGER_OK) { BLOG(0, "Order response could not be parsed"); callback(ledger::Result::LEDGER_ERROR, ""); return; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.h b/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.h index a7f9a9b1c20bc..1b04d35627c36 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/sku/sku_order.h @@ -7,9 +7,11 @@ #define BRAVELEDGER_SKU_ORDER_H_ #include +#include #include #include +#include "bat/ledger/internal/endpoint/payment/payment_server.h" #include "bat/ledger/ledger.h" namespace bat_ledger { @@ -29,8 +31,8 @@ class SKUOrder { private: void OnCreate( - const ledger::UrlResponse& response, - const std::vector& order_items, + const ledger::Result result, + ledger::SKUOrderPtr order, ledger::SKUOrderCallback callback); void OnCreateSave( @@ -39,6 +41,7 @@ class SKUOrder { ledger::SKUOrderCallback callback); bat_ledger::LedgerImpl* ledger_; // NOT OWNED + std::unique_ptr payment_server_; }; } // namespace braveledger_sku