diff --git a/README.adoc b/README.adoc index fbc5408..4bc1b69 100644 --- a/README.adoc +++ b/README.adoc @@ -97,7 +97,12 @@ Not included in this list are entities. * `Mastodon::Easy::alert_type`, used for push subscriptions. * `Mastodon::Easy::time_type`: Type for time, can be converted to `time_point` and `string`. -* `Mastodon::Easy::Account::account_field_type`: Type for fields in accounts. +* `Mastodon::Easy::account_field_type`: Type for fields in accounts. +* `Mastodon::Easy::urls_type`: Type for URLs returned by `Instance::urls()`. +* `Mastodon::Easy::stats_type`: Type for statistics returned by + `Instance::stats()`. +* `Mastodon::Easy::poll_options_type`: Type for poll options returned by + `Poll::options()`. === Error codes @@ -338,10 +343,9 @@ strings and you can use unsupported fields in an `Entity` by converting it to ** [x] PUT /api/v1/push/subscription ** [x] DELETE /api/v1/push/subscription * Polls - ** [ ] GET /api/v1/polls/:id - ** [ ] POST /api/v1/polls/:id/votes + ** [x] GET /api/v1/polls/:id + ** [x] POST /api/v1/polls/:id/votes * Reports - ** [x] GET /api/v1/reports ^(Deprecated)^ ** [x] POST /api/v1/reports * Scheduled Statuses ** [ ] GET /api/v1/scheduled_statuses @@ -349,7 +353,6 @@ strings and you can use unsupported fields in an `Entity` by converting it to ** [ ] PUT /api/v1/scheduled_statuses/:id ** [ ] DELETE /api/v1/scheduled_statuses/:id * Search - ** [x] GET /api/v1/search ^(Deprecated)^ ** [x] GET /api/v2/search * Statuses ** [x] GET /api/v1/statuses/:id @@ -365,18 +368,19 @@ strings and you can use unsupported fields in an `Entity` by converting it to ** [x] POST /api/v1/statuses/:id/unpin * Timelines ** [x] GET /api/v1/timelines/home - ** [ ] GET /api/v1/conversations + ** [x] GET /api/v1/conversations ** [x] GET /api/v1/timelines/public ** [x] GET /api/v1/timelines/tag/:hashtag ** [x] GET /api/v1/timelines/list/:list_id * Streaming API + ** [x] GET /api/v1/streaming/health ** [x] GET /api/v1/streaming/user ** [x] GET /api/v1/streaming/public ** [x] GET /api/v1/streaming/public/local ** [x] GET /api/v1/streaming/hashtag - ** [ ] GET /api/v1/streaming/hashtag/local + ** [x] GET /api/v1/streaming/hashtag/local ** [x] GET /api/v1/streaming/list - ** [ ] GET /api/v1/streaming/direct + ** [x] GET /api/v1/streaming/direct ==== Entities @@ -385,17 +389,16 @@ strings and you can use unsupported fields in an `Entity` by converting it to * [x] Attachment * [x] Card * [x] Context -* [ ] Conversation +* [x] Conversation * [x] Emoji * [x] Filter * [x] Instance * [x] List * [x] Mention * [x] Notification -* [ ] Poll +* [x] Poll * [x] PushSubscription * [x] Relationship -* [ ] Report ^(Deprecated)^ * [x] Results * [x] Status * [ ] ScheduledStatus diff --git a/src/api/get.cpp b/src/api/get.cpp index 5ce5fed..2b6defa 100644 --- a/src/api/get.cpp +++ b/src/api/get.cpp @@ -86,11 +86,6 @@ const return_call API::get(const Mastodon::API::v1 &call, strcall = "/api/v1/notifications"; break; } - case v1::reports: - { - strcall = "/api/v1/reports"; - break; - } case v1::timelines_home: { strcall = "/api/v1/timelines/home"; @@ -151,11 +146,6 @@ const return_call API::get(const Mastodon::API::v1 &call, strcall = "/api/v1/notifications/" + strid; break; } - case v1::search: - { - strcall = "/api/v1/search"; - break; - } case v1::statuses_id: { strcall = "/api/v1/statuses/" + strid; @@ -236,6 +226,21 @@ const return_call API::get(const Mastodon::API::v1 &call, strcall = "/api/v1/suggestions"; break; } + case v1::polls_id: + { + strcall = "/api/v1/polls/" + strid; + break; + } + case v1::conversations: + { + strcall = "/api/v1/conversations"; + break; + } + case v1::streaming_health: + { + strcall = "/api/v1/streaming/health"; + break; + } default: { ttdebug << "ERROR: Invalid argument.\n"; diff --git a/src/api/get_stream.cpp b/src/api/get_stream.cpp index 29e6b3e..69bd7ea 100644 --- a/src/api/get_stream.cpp +++ b/src/api/get_stream.cpp @@ -51,11 +51,21 @@ void API::get_stream(const Mastodon::API::v1 &call, strcall = "/api/v1/streaming/hashtag"; break; } + case v1::streaming_hashtag_local: + { + strcall = "/api/v1/streaming/hashtag/local"; + break; + } case v1::streaming_list: { strcall = "/api/v1/streaming/list"; break; } + case v1::streaming_direct: + { + strcall = "/api/v1/streaming/direct"; + break; + } default: { const uint8_t err = static_cast(error::INVALID_ARGUMENT); diff --git a/src/api/post.cpp b/src/api/post.cpp index fed3d55..576f708 100644 --- a/src/api/post.cpp +++ b/src/api/post.cpp @@ -195,6 +195,11 @@ return_call API::post(const Mastodon::API::v1 &call, strcall = "/api/v1/filters"; break; } + case v1::polls_id_votes: + { + strcall = "/api/v1/polls/" + strid + "/votes"; + break; + } default: { ttdebug << "ERROR: Invalid argument.\n"; diff --git a/src/easy/all.hpp b/src/easy/all.hpp index 47e931d..12e7a29 100644 --- a/src/easy/all.hpp +++ b/src/easy/all.hpp @@ -29,12 +29,13 @@ #include "entities/mention.hpp" #include "entities/notification.hpp" #include "entities/relationship.hpp" -#include "entities/report.hpp" #include "entities/results.hpp" #include "entities/status.hpp" #include "entities/tag.hpp" #include "entities/token.hpp" #include "entities/pushsubscription.hpp" #include "entities/filter.hpp" +#include "entities/poll.hpp" +#include "entities/conversation.hpp" #endif // MASTODON_CPP_EASY_ALL_HPP diff --git a/src/easy/easy.cpp b/src/easy/easy.cpp index 0f26690..f583e77 100644 --- a/src/easy/easy.cpp +++ b/src/easy/easy.cpp @@ -53,7 +53,8 @@ const vector Easy::parse_stream( const std::string &streamdata) { string stream = streamdata; - std::regex reevent("event: (update|notification|delete|ERROR)\ndata: (.*)\n"); + std::regex reevent("event: (update|notification|delete|filters_changed" + "|ERROR)\ndata: (.*)\n"); std::smatch match; std::vector vec = {}; @@ -63,14 +64,16 @@ const vector Easy::parse_stream( const string &data = match[2].str(); event_type type = event_type::Undefined; - if (event.compare("update") == 0) + if (event == "update") type = event_type::Update; - else if (event.compare("notification") == 0) + else if (event == "notification") type = event_type::Notification; - else if (event.compare("delete") == 0) + else if (event == "delete") type = event_type::Delete; - else if (event.compare("ERROR") == 0) + else if (event == "ERROR") type = event_type::Error; + else if (event == "filters_changed") + type = event_type::Filters_changed; vec.push_back({ type, data }); stream = match.suffix().str(); diff --git a/src/easy/entities/conversation.cpp b/src/easy/entities/conversation.cpp new file mode 100644 index 0000000..4a81c51 --- /dev/null +++ b/src/easy/entities/conversation.cpp @@ -0,0 +1,68 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2018, 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include "conversation.hpp" +#include "debug.hpp" + +using namespace Mastodon; +using Conversation = Easy::Conversation; + +bool Conversation::valid() const +{ + return Entity::check_valid( + { + "id", + "accounts", + "unread" + }); +} + +const string Conversation::id() const +{ + return get_string("id"); +} + +const std::vector Conversation::accounts() const +{ + const Json::Value node = get("accounts"); + if (node.isArray()) + { + std::vector vec; + std::transform(node.begin(), node.end(), std::back_inserter(vec), + [](const Json::Value &value) + { return Easy::Account(value); }); + return vec; + } + + return {}; +} + +const Easy::Status Conversation::last_status() const +{ + const Json::Value &node = get("last_status"); + if (!node.isNull()) + { + return Easy::Status(node); + } + + return {}; +} + +bool Conversation::unread() const +{ + return get_bool("unread"); +} diff --git a/src/easy/entities/report.hpp b/src/easy/entities/conversation.hpp similarity index 57% rename from src/easy/entities/report.hpp rename to src/easy/entities/conversation.hpp index d91a466..19906d5 100644 --- a/src/easy/entities/report.hpp +++ b/src/easy/entities/conversation.hpp @@ -14,14 +14,16 @@ * along with this program. If not, see . */ -#ifndef MASTODON_CPP_EASY_REPORT_HPP -#define MASTODON_CPP_EASY_REPORT_HPP +#ifndef MASTODON_CPP_EASY_CONVERSATION_HPP +#define MASTODON_CPP_EASY_CONVERSATION_HPP #include -#include +#include #include "../../mastodon-cpp.hpp" #include "../entity.hpp" +#include "account.hpp" +#include "status.hpp" using std::string; @@ -30,11 +32,11 @@ namespace Mastodon namespace Easy { /*! - * @brief Class to hold reports + * @brief Class to hold conversations. * - * before 0.11.0 + * @since 0.107.0 */ - class Report : public Entity + class Conversation : public Entity { public: using Entity::Entity; @@ -42,21 +44,34 @@ namespace Easy virtual bool valid() const override; /*! - * @brief Returns true if an action was taken in response to the - * report + * @brief Returns the id of the conversation. * - * @since before 0.11.0 - */ - bool action_taken() const; - - /*! - * @brief Returns the ID of the report - * - * @since before 0.11.0 + * @since 0.107.0 */ const string id() const; + + /*! + * @brief Returns the participating accounts. + * + * @since 0.107.0 + */ + const std::vector accounts() const; + + /*! + * @brief Returns the last status. + * + * @since 0.107.0 + */ + const Status last_status() const; + + /*! + * @brief Returns true if unread. + * + * @since 0.107.0 + */ + bool unread() const; }; } } -#endif // MASTODON_CPP_EASY_REPORT_HPP +#endif // MASTODON_CPP_EASY_CONVERSATION_HPP diff --git a/src/easy/entities/poll.cpp b/src/easy/entities/poll.cpp new file mode 100644 index 0000000..3b18a68 --- /dev/null +++ b/src/easy/entities/poll.cpp @@ -0,0 +1,86 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "poll.hpp" +#include "debug.hpp" + +using namespace Mastodon; +using Poll = Easy::Poll; + +bool Poll::valid() const +{ + return Entity::check_valid( + { + "id", + "expired", + "expired", + "multiple", + "votes_count", + "options" + }); +} + +const string Poll::id() const +{ + return get_string("id"); +} + +const Easy::time_type Poll::expires_at() const +{ + return get_time("expires_at"); +} + +bool Poll::expired() const +{ + return get_bool("expired"); +} + +bool Poll::multiple() const +{ + return get_bool("multiple"); +} + +uint64_t Poll::votes_count() const +{ + return get_uint64("votes_count"); +} + +const vector Poll::options() const +{ + const Json::Value &node = get("options"); + + if (node.isArray()) + { + vector vec_options; + std::transform(node.begin(), node.end(), std::back_inserter(vec_options), + [](const Json::Value &value) + { + return Easy::poll_options_type( + { + value["title"].asString(), + value["votes_count"].asUInt64() + }); + }); + return vec_options; + } + + return {}; +} + +bool Poll::voted() const +{ + return get_bool("voted"); +} diff --git a/src/easy/entities/poll.hpp b/src/easy/entities/poll.hpp new file mode 100644 index 0000000..61b2558 --- /dev/null +++ b/src/easy/entities/poll.hpp @@ -0,0 +1,98 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef MASTODON_CPP_EASY_POLL_HPP +#define MASTODON_CPP_EASY_POLL_HPP + +#include +#include +#include + +#include "../../mastodon-cpp.hpp" +#include "../entity.hpp" + +using std::string; +using std::uint64_t; + +namespace Mastodon +{ +namespace Easy +{ + /*! + * @brief Class to hold polls. + * + * @since 0.107.0 + */ + class Poll : public Entity + { + public: + using Entity::Entity; + + virtual bool valid() const override; + + /*! + * @brief Returns poll ID. + * + * @since 0.107.0 + */ + const string id() const; + + /*! + * @brief Returns time when the poll expires. + * + * @since 0.107.0 + */ + const Easy::time_type expires_at() const; + + /*! + * @brief Returns true if poll has expired. + * + * @since 0.107.0 + */ + bool expired() const; + + /*! + * @brief Returns true or false. + * + * @since 0.107.0 + */ + bool multiple() const; + + /*! + * @brief Returns the number of votes. + * + * @since 0.107.0 + */ + uint64_t votes_count() const; + + /*! + * @brief Returns poll options and their votes count. + * + * @since 0.107.0 + */ + const vector options() const; + + /*! + * @brief Returns whether you voted or not. + * + * @since 0.107.0 + */ + bool voted() const; + }; +} +} + +#endif // MASTODON_CPP_EASY_POLL_HPP diff --git a/src/easy/entities/report.cpp b/src/easy/entities/report.cpp deleted file mode 100644 index 6b134c2..0000000 --- a/src/easy/entities/report.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of mastodon-cpp. - * Copyright © 2018, 2019 tastytea - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include "report.hpp" - -using namespace Mastodon; -using Report = Easy::Report; - -bool Report::valid() const -{ - return Entity::check_valid( - { - "id", - "action_taken" - }); -} - -bool Report::action_taken() const -{ - return get_bool("action_taken"); -} - -const string Report::id() const -{ - return get_string("id"); -} diff --git a/src/easy/return_types_easy.cpp b/src/easy/return_types_easy.cpp index 8204e36..6da8a6a 100644 --- a/src/easy/return_types_easy.cpp +++ b/src/easy/return_types_easy.cpp @@ -26,13 +26,14 @@ #include "easy/entities/mention.hpp" #include "easy/entities/notification.hpp" #include "easy/entities/relationship.hpp" -#include "easy/entities/report.hpp" #include "easy/entities/results.hpp" #include "easy/entities/status.hpp" #include "easy/entities/tag.hpp" #include "easy/entities/token.hpp" #include "easy/entities/pushsubscription.hpp" #include "easy/entities/filter.hpp" +#include "easy/entities/poll.hpp" +#include "easy/entities/conversation.hpp" using namespace Mastodon; @@ -85,13 +86,14 @@ template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; -template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; template struct Easy::return_entity; +template struct Easy::return_entity; +template struct Easy::return_entity; template @@ -130,10 +132,11 @@ template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; -template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; template struct Easy::return_entity_vector; +template struct Easy::return_entity_vector; +template struct Easy::return_entity_vector; diff --git a/src/easy/types_easy.hpp b/src/easy/types_easy.hpp index f87be58..cb2c5cc 100644 --- a/src/easy/types_easy.hpp +++ b/src/easy/types_easy.hpp @@ -41,6 +41,7 @@ namespace Easy Notification, Delete, Error, + Filters_changed, Undefined }; @@ -224,6 +225,15 @@ namespace Easy uint64_t status_count = 0; uint64_t domain_count = 0; } stats_type; + + /*! + * @brief Poll options returned by Poll::options(). + */ + typedef struct poll_options_type + { + string title; + uint64_t votes_count = 0; + } poll_options_type; } } #endif // MASTODON_CPP_EASY_TYPES_EASY_HPP diff --git a/src/mastodon-cpp.hpp b/src/mastodon-cpp.hpp index 6e06235..98c0b37 100644 --- a/src/mastodon-cpp.hpp +++ b/src/mastodon-cpp.hpp @@ -226,8 +226,8 @@ namespace Mastodon lists, accounts_id_lists, - lists_id, lists_id_accounts, + lists_id, media, media_id, @@ -244,37 +244,39 @@ namespace Mastodon notifications_dismiss, push_subscription, + polls_id, + polls_id_votes, + reports, // scheduled_statuses, // scheduled_statuses_id, - search, - - statuses, statuses_id, statuses_id_context, statuses_id_card, statuses_id_reblogged_by, statuses_id_favourited_by, + statuses, statuses_id_reblog, statuses_id_unreblog, statuses_id_pin, statuses_id_unpin, timelines_home, - // timelines_conversations, + conversations, timelines_public, timelines_tag_hashtag, timelines_list_list_id, + streaming_health, streaming_user, streaming_public, streaming_public_local, streaming_hashtag, - // streaming_hashtag_local, + streaming_hashtag_local, streaming_list, - // streaming_direct, + streaming_direct, // Glitch-Soc bookmarks, diff --git a/tests/api/test_api_v1_conversations.cpp b/tests/api/test_api_v1_conversations.cpp new file mode 100644 index 0000000..69a728a --- /dev/null +++ b/tests/api/test_api_v1_conversations.cpp @@ -0,0 +1,74 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "mastodon-cpp.hpp" +#include "easy/easy.hpp" +#include "easy/entities/conversation.hpp" +#include "../environment_variables.hpp" + +using namespace Mastodon; + +SCENARIO ("/api/v1/conversations can be called successfully", + "[api][auth][mastodon][glitch-soc]") +{ + REQUIRE (access_token != nullptr); + + GIVEN ("instance = " + instance) + { + Mastodon::Easy::API masto(instance, access_token); + return_call ret; + Easy::Conversation conversation; + bool exception = false; + + WHEN ("GET /api/v1/conversations is called") + { + try + { + ret = masto.get(API::v1::conversations, {{ "limit", { "2" }}}); + if (ret.answer == "[]") + { + WARN("No Conversations found."); + } + else + { + conversation.from_string( + Easy::json_array_to_vector(ret.answer).front()); + } + } + catch (const std::exception &e) + { + exception = true; + WARN(e.what()); + } + + THEN("No exception is thrown") + AND_THEN ("No error is returned") + AND_THEN ("Answer is valid") + { + REQUIRE_FALSE(exception); + + REQUIRE(ret.error_code == 0); + REQUIRE(ret.http_error_code == 200); + REQUIRE(conversation.valid()); + REQUIRE(conversation.id() != ""); + } + } + } +} + diff --git a/tests/api/test_api_v1_polls_id.cpp b/tests/api/test_api_v1_polls_id.cpp new file mode 100644 index 0000000..908cb98 --- /dev/null +++ b/tests/api/test_api_v1_polls_id.cpp @@ -0,0 +1,76 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "mastodon-cpp.hpp" +#include "easy/easy.hpp" +#include "easy/entities/poll.hpp" +#include "../environment_variables.hpp" + +using namespace Mastodon; + +SCENARIO ("/api/v1/polls/:id can be called successfully", + "[api][auth][mastodon][pleroma][glitch-soc]") +{ + REQUIRE (access_token != nullptr); + + GIVEN ("instance = " + instance) + { + Mastodon::Easy::API masto(instance, access_token); + return_call ret; + Easy::Poll poll; + bool exception = false; + + WHEN ("GET /api/v1/polls/:id is called") + { + try + { + ret = masto.get(API::v1::polls_id, + {{ "id", { "4823515" } }}); + if (ret.answer == "[]") + { + WARN("Poll not found."); + } + else + { + poll.from_string(ret.answer); + } + } + catch (const std::exception &e) + { + exception = true; + WARN(e.what()); + } + + THEN("No exception is thrown") + AND_THEN ("No errors are returned") + AND_THEN ("Answer is valid") + AND_THEN ("The answer makes sense") + { + REQUIRE_FALSE(exception); + + REQUIRE(ret.error_code == 0); + REQUIRE(ret.http_error_code == 200); + REQUIRE(poll.valid()); + + REQUIRE(poll.id() != ""); + } + } + } +} + diff --git a/tests/api/test_api_v1_polls_id_votes.cpp b/tests/api/test_api_v1_polls_id_votes.cpp new file mode 100644 index 0000000..12b3de1 --- /dev/null +++ b/tests/api/test_api_v1_polls_id_votes.cpp @@ -0,0 +1,80 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "mastodon-cpp.hpp" +#include "easy/easy.hpp" +#include "easy/entities/poll.hpp" +#include "../environment_variables.hpp" + +using namespace Mastodon; + +SCENARIO ("/api/v1/polls/:id/votes can be called successfully", + "[api][auth][mastodon][pleroma][glitch-soc]") +{ + REQUIRE (access_token != nullptr); + + GIVEN ("instance = " + instance) + { + Mastodon::Easy::API masto(instance, access_token); + return_call ret; + Easy::Poll poll; + bool exception = false; + + WHEN ("POST /api/v1/polls/:id/votes is called") + { + try + { + ret = masto.post(API::v1::polls_id_votes, + { + { "id", { "4823515" } }, + // TODO: Check if this is the right format. + { "choices", { "false", "false", "true", + "false", "false" } } + }); + if (ret.answer == "[]") + { + WARN("Poll not found."); + } + else + { + poll.from_string(ret.answer); + } + } + catch (const std::exception &e) + { + exception = true; + WARN(e.what()); + } + + THEN("No exception is thrown") + AND_THEN ("An error is returned") + AND_THEN ("Answer is invalid") + { + REQUIRE_FALSE(exception); + + REQUIRE(ret.error_code == 12); + REQUIRE(ret.http_error_code != 200); // Pleroma returns 422. + REQUIRE_FALSE(poll.valid()); + REQUIRE(poll.id() == ""); + REQUIRE(poll.error() == "Poll's author can't vote"); + } + } + } +} + diff --git a/tests/entities/conversation.cpp b/tests/entities/conversation.cpp new file mode 100644 index 0000000..0ea547b --- /dev/null +++ b/tests/entities/conversation.cpp @@ -0,0 +1,89 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "easy/entities/conversation.hpp" +#include "easy/easy.hpp" + +using std::string; +using std::chrono::system_clock; + +using namespace Mastodon; + +SCENARIO ("Easy::Conversation works as intended", "[entity]") +{ + GIVEN ("An Easy::Conversation object") + { + Easy::Conversation conversation; + bool exception = false; + + WHEN ("It is initialized with valid conversation data") + { + const string data = + "\"id\":\"1234567\"," + "\"accounts\":[" + "{\"id\":\"98765\"}," + "{\"id\":\"56789\"}]," + "\"last_status\":null," + "\"unread\":false}"; + + try + { + conversation.from_string(data); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("Conversation is valid") + AND_THEN ("The attributes are set to the right values") + { + REQUIRE_FALSE(exception); + REQUIRE(conversation.valid()); + REQUIRE(conversation.id() == "1234567"); + REQUIRE(conversation.accounts().size() == 2); + REQUIRE(conversation.unread() == false); + } + } + + WHEN ("It is initialized with an empty string") + { + try + { + conversation.from_string(""); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("It is not valid") + AND_THEN ("id is empty") + { + REQUIRE_FALSE(exception); + REQUIRE_FALSE(conversation.valid()); + REQUIRE(conversation.id() == ""); + REQUIRE(conversation.accounts().size() == 0); + } + } + } +} diff --git a/tests/entities/test_poll.cpp b/tests/entities/test_poll.cpp new file mode 100644 index 0000000..620b792 --- /dev/null +++ b/tests/entities/test_poll.cpp @@ -0,0 +1,94 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "easy/entities/poll.hpp" +#include "easy/easy.hpp" + +using std::string; +using std::chrono::system_clock; + +using namespace Mastodon; + +SCENARIO ("Easy::Poll works as intended", "[entity]") +{ + GIVEN ("An Easy::Poll object") + { + Easy::Poll poll; + bool exception = false; + + WHEN ("It is initialized with valid poll data") + { + const string data = + "{\"emojis\":[]," + "\"expired\":false," + "\"expires_at\":\"2019-09-22T12:48:19.000Z\"," + "\"id\":\"1234567\"," + "\"multiple\":false," + "\"options\":[" + "{\"title\":\"Yes\"," "\"votes_count\":12}," + "{\"title\":\"No\",\"votes_count\":13}]," + "\"voted\":false," + "\"votes_count\":25}"; + + try + { + poll.from_string(data); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("Poll is valid") + AND_THEN ("The attributes are set to the right values") + { + REQUIRE_FALSE(exception); + REQUIRE(poll.valid()); + REQUIRE(poll.id() == "1234567"); + REQUIRE(poll.expired() == false); + REQUIRE(poll.options().size() == 2); + REQUIRE(poll.options()[1].votes_count == 13); + } + } + + WHEN ("It is initialized with an empty string") + { + try + { + poll.from_string(""); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("It is not valid") + AND_THEN ("id is empty") + { + REQUIRE_FALSE(exception); + REQUIRE_FALSE(poll.valid()); + REQUIRE(poll.id() == ""); + REQUIRE(poll.options().size() == 0); + } + } + } +}