diff --git a/README.adoc b/README.adoc index fbc5408..29ca70e 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 @@ -392,7 +397,7 @@ strings and you can use unsupported fields in an `Entity` by converting it to * [x] List * [x] Mention * [x] Notification -* [ ] Poll +* [x] Poll * [x] PushSubscription * [x] Relationship * [ ] Report ^(Deprecated)^ 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/types_easy.hpp b/src/easy/types_easy.hpp index f87be58..1591e5d 100644 --- a/src/easy/types_easy.hpp +++ b/src/easy/types_easy.hpp @@ -224,6 +224,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/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); + } + } + } +}