diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a83174..cc7f084 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,11 @@ set(CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -DDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -march=native -DNDEBUG") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-O1,--sort-common,--as-needed,-z,relro") +if(UNIX) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-O1,--sort-common,--as-needed,-z,relro") +elseif(WIN32 OR APPLE) + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-O1,--sort-common,--as-needed") +endif() if(CMAKE_GENERATOR STREQUAL "Ninja") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -49,28 +53,64 @@ if(ENABLE_CODE_COVERAGE) endif() # Required libraries -find_package(Boost 1.71.0 COMPONENTS unit_test_framework REQUIRED) -find_package(PkgConfig REQUIRED) -find_package(OpenSSL REQUIRED) -if(NOT OPENSSL_FOUND) - message(FATAL_ERROR "Fail to find OpenSSL") # exit +if(ENABLE_TEST) + if(NOT (UNIX OR APPLE)) + message(FAITAL_ERROR "unit test is NOT supported on Windows") + endif() + find_package(Boost 1.71.0 COMPONENTS unit_test_framework REQUIRED) + # Enable CTest + enable_testing() + add_subdirectory(test) +endif() + + +# Search OpenSSL +if(UNIX OR APPLE) + find_package(PkgConfig REQUIRED) + find_package(OpenSSL REQUIRED) + if(NOT OPENSSL_FOUND) + message(FATAL_ERROR "Fail to find OpenSSL") # exit + endif() + set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) +elseif(WIN32) + if(NOT OPENSSL_ROOT_DIR) + message(FATAL_ERROR "Fail to find OpenSSL") # exit + endif() + set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include") + set(OPENSSL_LIBRARIES "${OPENSSL_ROOT_DIR}/lib/libssl.dll.a" "${OPENSSL_ROOT_DIR}/lib/libcrypto.dll.a" ) + file(GLOB DLL ${OPENSSL_ROOT_DIR}/*.dll) + file(COPY ${DLL} DESTINATION ${CMAKE_BINARY_DIR}) endif() message(STATUS "OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}") +message(STATUS "OpenSSL Libraries : ${OPENSSL_LIBRARIES}") include_directories(${OPENSSL_INCLUDE_DIR}) -find_package(CURL REQUIRED) -if(NOT CURL_FOUND) - message(FATAL_ERROR "Fail to find OpenSSL") # exit + +# Search cURL library +if(UNIX OR APPLE) + find_package(CURL REQUIRED) + if(NOT CURL_FOUND) + message(FATAL_ERROR "Fail to find cURL library") # exit + endif() +elseif(WIN32) + if(NOT CURL_ROOT_DIR) + message(FATAL_ERROR "Fail to find cURL library") # exit + endif() + add_definitions(-DCURL_STATICLIB) + set(CURL_INCLUDE_DIRS "${CURL_ROOT_DIR}/include") + set(CURL_LIBRARIES "${CURL_ROOT_DIR}/lib/libcurl.dll.a") + file(GLOB DLL ${CURL_ROOT_DIR}/bin/*.dll) + file(COPY ${DLL} DESTINATION ${CMAKE_BINARY_DIR}) endif() +message(STATUS "CURL_INCLUDE_DIR: ${CURL_INCLUDE_DIRS}") +message(STATUS "CURL_LIBRARIES: ${CURL_LIBRARIES}") include_directories(${CURL_INCLUDE_DIRS}) + include_directories( - ${PROJECT_SOURCE_DIR}/src - ${PROJECT_SOURCE_DIR}/third + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/third ) -# Enable CTest -enable_testing() add_subdirectory(src) -add_subdirectory(test) diff --git a/Jenkinsfile b/Jenkinsfile index b7f1729..db2aef8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -26,7 +26,7 @@ pipeline { sh ''' mkdir -p build cd build - cmake .. -G Ninja + cmake .. -G Ninja -DENABLE_TEST=TRUE ''' } } @@ -47,7 +47,7 @@ pipeline { try{ sh ''' cd build - ctest --output_on_failure + ctest --output-on-failure ''' unittestBadge.setStatus('passing') }catch(Exception error){ diff --git a/README.md b/README.md index 5c06c11..94dc795 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,6 @@ # CocoaTweet This is a library for using Twitter API from C++ -# Dependency -- libcurl -- libssl - # Features you can use these endpoint - statuses/update @@ -17,6 +13,45 @@ you can use these endpoint - favorites/create - favorites/destroy +# Dependency +- libcurl(openssl version) +- libssl + +# Instllation +## Ubuntu +``` +# apt install clang cmake git libboost-dev libboost-test-dev libcurl4-openssl-dev libssl-dev nunja-build +$ git clone https://github.com/koron0902/CocoaTweet +$ cd CocoaTweet +$ mkdir build +$ cd build +$ cmake .. -G Ninja +$ ninja +``` + +## Windows +- Get MinGW32 from [here](https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/)(start download automatically at open link) +- Install `mingw32-base-bin` and `mingw32-gcc-g+-bin` via MinGW32 +- Add PATH in System Environment +- Get libcurl-32bit and OpenSSL-32bit from [here](https://curl.se/windows/) +- Get ninja from [here](https://github.com/ninja-build/ninja/releases) and add PATH(Optional, but build faster) + +and then.... +``` +$ git clone https://github.com/koron0902/CocoaTweet +$ cd CocoaTweet +$ mkdir build +$ cd build + +// if install ninja +$ cmake .. -G Ninja -DOPENSSL_ROOT_DIR= -DCURL_ROOT_DIR= -DCMAKE_CXX_COMPILER=mingw32-g++ -DCMAKE_C_COMPILER=mingw32-gcc -DCMAKE_MAKE_PROGRAM=ninja +$ ninja + +// if NOT install ninja +$ cmake .. -G "MinGW Makefiles" -DOPENSSL_ROOT_DIR= -DCURL_ROOT_DIR= +$ mingw32-make +``` + # How ## API Key Registration ### 1.Write Key into code diff --git a/src/cocoatweet/CMakeLists.txt b/src/cocoatweet/CMakeLists.txt index ef17d9c..c00a05c 100644 --- a/src/cocoatweet/CMakeLists.txt +++ b/src/cocoatweet/CMakeLists.txt @@ -1,11 +1,15 @@ file(GLOB_RECURSE SOURCES ./*.cc) add_library(lib-cocoatweet ${SOURCES}) + + target_link_libraries(lib-cocoatweet PUBLIC - Boost::boost - OpenSSL::SSL - OpenSSL::Crypto + ${OPENSSL_LIBRARIES} ${CURL_LIBRARIES} ) +if(ENABLE_TEST) + target_link_libraries(lib-cocoatweet PUBLIC Boost::boost) +endif() + target_include_directories(lib-cocoatweet PUBLIC ${PROJECT_SOURCE_DIR}/src) set_target_properties(lib-cocoatweet PROPERTIES OUTPUT_NAME cocoatweet) diff --git a/src/cocoatweet/api/favorite/create.cc b/src/cocoatweet/api/favorite/create.cc index ece7181..a181e1a 100644 --- a/src/cocoatweet/api/favorite/create.cc +++ b/src/cocoatweet/api/favorite/create.cc @@ -1,5 +1,6 @@ #include -#include +#include + namespace CocoaTweet::API::Favorites { Create::Create() { contentType_ = "application/x-www-form-urlencoded"; @@ -10,9 +11,13 @@ void Create::id(const std::string& _id) { bodyParam_.insert_or_assign("id", _id); } -void Create::process(std::weak_ptr _oauth) { - HttpPost::process(_oauth, [](const unsigned int _, const std::string& _srv) { - std::cout << _srv << std::endl; - }); +CocoaTweet::API::Model::Tweet Create::process(std::weak_ptr _oauth) { + CocoaTweet::API::Model::Tweet tweet; + HttpPost::process(_oauth, + [&tweet](const unsigned int _responseCode, const std::string& _rcv) { + tweet = CocoaTweet::API::Model::Tweet(_responseCode, _rcv); + }); + + return tweet; } } // namespace CocoaTweet::API::Favorites diff --git a/src/cocoatweet/api/favorite/create.h b/src/cocoatweet/api/favorite/create.h index 9a22f88..58e6c88 100644 --- a/src/cocoatweet/api/favorite/create.h +++ b/src/cocoatweet/api/favorite/create.h @@ -2,13 +2,14 @@ #define COCOATWEET_API_FAVORITE_CREATE_H_ #include +#include namespace CocoaTweet::API::Favorites { class Create : public CocoaTweet::API::Interface::HttpPost { public: Create(); void id(const std::string& _id); - void process(std::weak_ptr _oauth); + CocoaTweet::API::Model::Tweet process(std::weak_ptr _oauth); private: }; diff --git a/src/cocoatweet/api/favorite/destroy.cc b/src/cocoatweet/api/favorite/destroy.cc index dac36fa..126eac6 100644 --- a/src/cocoatweet/api/favorite/destroy.cc +++ b/src/cocoatweet/api/favorite/destroy.cc @@ -1,5 +1,6 @@ #include -#include +#include + namespace CocoaTweet::API::Favorites { Destroy::Destroy() { contentType_ = "application/x-www-form-urlencoded"; @@ -10,9 +11,14 @@ void Destroy::id(const std::string& _id) { bodyParam_.insert_or_assign("id", _id); } -void Destroy::process(std::weak_ptr _oauth) { - HttpPost::process(_oauth, [](const unsigned int _, const std::string& _srv) { - std::cout << _srv << std::endl; - }); +CocoaTweet::API::Model::Tweet Destroy::process( + std::weak_ptr _oauth) { + CocoaTweet::API::Model::Tweet tweet; + HttpPost::process(_oauth, + [&tweet](const unsigned int _responseCode, const std::string& _rcv) { + tweet = CocoaTweet::API::Model::Tweet(_responseCode, _rcv); + }); + + return tweet; } } // namespace CocoaTweet::API::Favorites diff --git a/src/cocoatweet/api/favorite/destroy.h b/src/cocoatweet/api/favorite/destroy.h index 809f4e7..5515375 100644 --- a/src/cocoatweet/api/favorite/destroy.h +++ b/src/cocoatweet/api/favorite/destroy.h @@ -2,13 +2,14 @@ #define COCOATWEET_API_FAVORITE_DESTROY_H_ #include +#include namespace CocoaTweet::API::Favorites { class Destroy : public CocoaTweet::API::Interface::HttpPost { public: Destroy(); void id(const std::string& _id); - void process(std::weak_ptr _oauth); + CocoaTweet::API::Model::Tweet process(std::weak_ptr _oauth); private: }; diff --git a/src/cocoatweet/api/favorite/favorite.cc b/src/cocoatweet/api/favorite/favorite.cc index 6bdb88d..71631ff 100644 --- a/src/cocoatweet/api/favorite/favorite.cc +++ b/src/cocoatweet/api/favorite/favorite.cc @@ -1,5 +1,3 @@ -#include - #include "cocoatweet/api/favorite/favorite.h" #include "cocoatweet/api/favorite/create.h" #include "cocoatweet/api/favorite/destroy.h" @@ -9,15 +7,15 @@ Favorite::Favorite(std::shared_ptr _oauth) { oauth_ = _oauth; } -void Favorite::Create(const std::string& _id) const { +CocoaTweet::API::Model::Tweet Favorite::Create(const std::string& _id) const { CocoaTweet::API::Favorites::Create create; create.id(_id); - create.process(oauth_); + return create.process(oauth_); } -void Favorite::Destroy(const std::string& _id) const { +CocoaTweet::API::Model::Tweet Favorite::Destroy(const std::string& _id) const { CocoaTweet::API::Favorites::Destroy destroy; destroy.id(_id); - destroy.process(oauth_); + return destroy.process(oauth_); } } // namespace CocoaTweet::API::Favorites diff --git a/src/cocoatweet/api/favorite/favorite.h b/src/cocoatweet/api/favorite/favorite.h index eae9ae8..b79544a 100644 --- a/src/cocoatweet/api/favorite/favorite.h +++ b/src/cocoatweet/api/favorite/favorite.h @@ -3,14 +3,15 @@ #include "cocoatweet/api/interface/groupInterface.h" #include "cocoatweet/oauth/oauth.h" +#include namespace CocoaTweet::API::Favorites { class Favorite : public groupInterface { public: Favorite() = default; Favorite(std::shared_ptr _oauth); - void Create(const std::string& _id) const; - void Destroy(const std::string& _id) const; + CocoaTweet::API::Model::Tweet Create(const std::string& _id) const; + CocoaTweet::API::Model::Tweet Destroy(const std::string& _id) const; }; } // namespace CocoaTweet::API::Favorites diff --git a/src/cocoatweet/api/interface/httpPost.cc b/src/cocoatweet/api/interface/httpPost.cc index d320ce3..618d0c4 100644 --- a/src/cocoatweet/api/interface/httpPost.cc +++ b/src/cocoatweet/api/interface/httpPost.cc @@ -4,7 +4,7 @@ #include #include #include -#include +#include extern "C" { #include } @@ -31,7 +31,6 @@ void HttpPost::process(std::weak_ptr _oauth, auto signature = oauth->signature(sigingParam, "POST", url_); // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録 - std::cout << "signature : " << signature["oauth_signature"] << std::endl; oauthParam.merge(signature); // リクエストボディの構築 @@ -43,7 +42,6 @@ void HttpPost::process(std::weak_ptr _oauth, } requestBody = CocoaTweet::Util::join(tmp, "&"); } - std::cout << "request Body -> " << requestBody << std::endl; // ヘッダの構築 std::string oauthHeader = "authorization: OAuth "; @@ -54,7 +52,6 @@ void HttpPost::process(std::weak_ptr _oauth, } oauthHeader += CocoaTweet::Util::join(tmp, ","); } - std::cout << "OAuth Header -> " << oauthHeader << std::endl; // do post CURL* curl; @@ -63,15 +60,17 @@ void HttpPost::process(std::weak_ptr _oauth, long responseCode; curl = curl_easy_init(); url_ = url_; - std::cout << "URL : " << url_ << std::endl; if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestBody.length()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv); +#ifndef NDEBUG curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); +#endif // Headerを保持するcurl_slist*を初期化 struct curl_slist* headers = NULL; // Authorizationをヘッダに追加 @@ -83,7 +82,7 @@ void HttpPost::process(std::weak_ptr _oauth, } if (res != CURLE_OK) { - std::cout << "curl error : " << res << std::endl; + throw std::runtime_error(std::string("INTERNAL ERROR : curl(") + std::to_string(res) + ")"); exit(1); } diff --git a/src/cocoatweet/api/model/tweet.cc b/src/cocoatweet/api/model/tweet.cc index 3ee397e..3bf3fb7 100644 --- a/src/cocoatweet/api/model/tweet.cc +++ b/src/cocoatweet/api/model/tweet.cc @@ -1,10 +1,11 @@ #include #include #include +#include +#include +#include #include "nlohmann/json.hpp" -#include - namespace CocoaTweet::API::Model { Tweet Tweet::parse(const unsigned int _responseCode, const std::string& _json) { auto j = nlohmann::json::parse(_json); @@ -12,13 +13,22 @@ Tweet Tweet::parse(const unsigned int _responseCode, const std::string& _json) { if (_responseCode == 200) { tweet.id(j["id_str"]); + tweet.createdAt(j["created_at"]); + tweet.text(j["text"]); + tweet.source(j["source"]); } else { auto error = j["errors"][0]["code"]; auto message = j["errors"][0]["message"]; if (error.get() == 144) { throw CocoaTweet::Exception::TweetNotFoundException(message.get().c_str()); - }else if(error.get() == 32){ + } else if (error.get() == 32) { throw CocoaTweet::Exception::AuthenticateException(message.get().c_str()); + } else if (error.get() == 187) { + throw CocoaTweet::Exception::TweetDuplicateException(message.get().c_str()); + } else if (error.get() == 88 || error.get() == 185) { + throw CocoaTweet::Exception::RateLimitException(message.get().c_str()); + } else if (error.get() == 186) { + throw CocoaTweet::Exception::TweetTooLongException(message.get().c_str()); } } @@ -29,7 +39,27 @@ void Tweet::id(const std::string _id) { id_ = _id; } +void Tweet::createdAt(const std::string _at) { + createdAt_ = _at; +} + +void Tweet::text(const std::string _text) { + text_ = _text; +} +void Tweet::source(const std::string _source) { + source_ = _source; +} + const std::string Tweet::id() const { return id_; } +const std::string Tweet::createdAt() const { + return createdAt_; +} +const std::string Tweet::text() const { + return text_; +} +const std::string Tweet::source() const { + return source_; +} } // namespace CocoaTweet::API::Model diff --git a/src/cocoatweet/api/model/tweet.h b/src/cocoatweet/api/model/tweet.h index 085362d..ca80b95 100644 --- a/src/cocoatweet/api/model/tweet.h +++ b/src/cocoatweet/api/model/tweet.h @@ -12,10 +12,19 @@ public: : Tweet(Tweet::parse(_responseCode, _json)) {} static Tweet parse(const unsigned int _responseCode, const std::string& _json); void id(const std::string _id); + void createdAt(const std::string _at); + void text(const std::string _text); + void source(const std::string _source); const std::string id() const; + const std::string createdAt() const; + const std::string text() const; + const std::string source() const; private: std::string id_; + std::string createdAt_; + std::string text_; + std::string source_; }; } // namespace CocoaTweet::API::Model diff --git a/src/cocoatweet/api/status/destroy.cc b/src/cocoatweet/api/status/destroy.cc index 257e8fb..bee285e 100644 --- a/src/cocoatweet/api/status/destroy.cc +++ b/src/cocoatweet/api/status/destroy.cc @@ -1,6 +1,6 @@ #include "cocoatweet/api/status/destroy.h" #include -#include + namespace CocoaTweet::API::Statuses { Destroy::Destroy() {} void Destroy::id(const std::string _id) { diff --git a/src/cocoatweet/api/status/status.cc b/src/cocoatweet/api/status/status.cc index 7ea485d..ce9d288 100644 --- a/src/cocoatweet/api/status/status.cc +++ b/src/cocoatweet/api/status/status.cc @@ -1,5 +1,3 @@ -#include - #include "cocoatweet/api/status/status.h" #include "cocoatweet/api/status/update.h" #include "cocoatweet/api/status/destroy.h" diff --git a/src/cocoatweet/api/status/update.cc b/src/cocoatweet/api/status/update.cc index af6e04b..e6e8612 100644 --- a/src/cocoatweet/api/status/update.cc +++ b/src/cocoatweet/api/status/update.cc @@ -1,5 +1,4 @@ #include "cocoatweet/api/status/update.h" -#include namespace CocoaTweet::API::Statuses { Update::Update() { diff --git a/src/cocoatweet/oauth/key.h b/src/cocoatweet/oauth/key.h index 07aba49..71828e4 100644 --- a/src/cocoatweet/oauth/key.h +++ b/src/cocoatweet/oauth/key.h @@ -11,11 +11,7 @@ class Key { const std::string accessTokenSecret_; public: - Key() - : consumerKey_(""), - consumerSecret_(""), - accessToken_(""), - accessTokenSecret_("") {} + Key() : consumerKey_(""), consumerSecret_(""), accessToken_(""), accessTokenSecret_("") {} Key(const std::string& _consumerKey, const std::string& _consumerSecret, const std::string& _accessToken, const std::string& _accessTokenSecret) : consumerKey_(_consumerKey), diff --git a/src/cocoatweet/oauth/oauth.cc b/src/cocoatweet/oauth/oauth.cc index 7895229..8224e68 100644 --- a/src/cocoatweet/oauth/oauth.cc +++ b/src/cocoatweet/oauth/oauth.cc @@ -7,7 +7,6 @@ #include #include #include -#include extern "C" { #include @@ -26,7 +25,6 @@ std::map OAuth1::signature( std::vector tmp; for (const auto& [key, value] : _param) { tmp.push_back(key + "=" + value); - std::cout << (key + "=" + value) << std::endl; } std::string query = CocoaTweet::Util::join(tmp, "&"); @@ -36,10 +34,6 @@ std::map OAuth1::signature( CocoaTweet::Util::urlEncode(query); auto k64Sha1 = hmacSha1(significateKey, significateBase); - std::cout << "significate key : " << significateKey << std::endl; - std::cout << "significate base : " << significateBase << std::endl; - std::cout << "hmac-sha1 : " << k64Sha1 << std::endl; - auto ret = std::map{{"oauth_signature", k64Sha1}}; return ret; } diff --git a/src/main.cc b/src/main.cc index 3646a6c..ad29ed3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -19,7 +19,8 @@ auto main() -> int { // CocoaTweet::API::API api(key); // Now, you can use a twitter api - // api.status().Update("Hello Twitter World from Cocoa Twitter Library"); - // api.favorite().Create("tweet id you want to fav."); - // api.favorite().Destroy("tweet id you want to un_fav."); + // auto status = api.status().Update("Hello Twitter World via Cocoa Twitter Library"); + // api.favorite().Create(status.id()); + // api.favorite().Destroy(status.id()); + // api.status().Destroy(status.id()); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe3c3f1..bdc6ab5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,5 @@ file(GLOB_RECURSE SOURCES ./*.cc) +include_directories(${CMAKE_SOURCE_DIR}/third) foreach(TEST_SOURCE_FILE ${SOURCES}) file(RELATIVE_PATH SRC_RELPATH ${CMAKE_CURRENT_LIST_DIR} ${TEST_SOURCE_FILE}) diff --git a/test/api/model/tweet.cc b/test/api/model/tweet.cc new file mode 100644 index 0000000..c7450c7 --- /dev/null +++ b/test/api/model/tweet.cc @@ -0,0 +1,96 @@ +#define BOOST_TEST_DYN_LINK + +#include + +#include "nlohmann/json.hpp" +#include "cocoatweet/api/model/tweet.h" +#include "cocoatweet/exception/authenticateException.h" +#include "cocoatweet/exception/rateLimitException.h" +#include "cocoatweet/exception/tweetTooLongException.h" +#include "cocoatweet/exception/tweetDuplicateException.h" + +BOOST_AUTO_TEST_SUITE(tweet_object) +BOOST_AUTO_TEST_CASE(test01) { + CocoaTweet::API::Model::Tweet tweet; + + BOOST_TEST(tweet.id() == ""); + BOOST_TEST(tweet.createdAt() == ""); + BOOST_TEST(tweet.text() == ""); + BOOST_TEST(tweet.source() == ""); +} + +BOOST_AUTO_TEST_CASE(test02) { + std::string json = R"({ + "id_str" : "1234567890", + "created_at" : "Thu Mar 04 00:00:00 +0000 2021", + "text" : "tweet", + "source" : "Twitter for Android" + })"; + + CocoaTweet::API::Model::Tweet tweet(200, json); + BOOST_TEST(tweet.id() == "1234567890"); + BOOST_TEST(tweet.createdAt() == "Thu Mar 04 00:00:00 +0000 2021"); + BOOST_TEST(tweet.text() == "tweet"); + BOOST_TEST(tweet.source() == "Twitter for Android"); +} + +BOOST_AUTO_TEST_CASE(test03) { + std::string json = R"({ + "errors" : [{ + "code" : 32, + "message" : "Could not authenticate you." + }] + })"; + + BOOST_CHECK_THROW(CocoaTweet::API::Model::Tweet(401, json), + CocoaTweet::Exception::AuthenticateException); +} + +BOOST_AUTO_TEST_CASE(test04) { + std::string json = R"({ + "errors" : [{ + "code" : 88, + "message" : "Rate limit exceeded." + }] + })"; + + BOOST_CHECK_THROW(CocoaTweet::API::Model::Tweet(429, json), + CocoaTweet::Exception::RateLimitException); +} + +BOOST_AUTO_TEST_CASE(test05) { + std::string json = R"({ + "errors" : [{ + "code" : 185, + "message" : "User is over daily status update limit." + }] + })"; + + BOOST_CHECK_THROW(CocoaTweet::API::Model::Tweet(403, json), + CocoaTweet::Exception::RateLimitException); +} + +BOOST_AUTO_TEST_CASE(test06) { + std::string json = R"({ + "errors" : [{ + "code" : 186, + "message" : "Tweet needs to be a bit shorter." + }] + })"; + + BOOST_CHECK_THROW(CocoaTweet::API::Model::Tweet(403, json), + CocoaTweet::Exception::TweetTooLongException); +} + +BOOST_AUTO_TEST_CASE(test07) { + std::string json = R"({ + "errors" : [{ + "code" : 187, + "message" : "Status is a duplicate." + }] + })"; + + BOOST_CHECK_THROW(CocoaTweet::API::Model::Tweet(403, json), + CocoaTweet::Exception::TweetDuplicateException); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/oauth/key.cc b/test/oauth/key.cc index c5bd0c7..f03b2b8 100644 --- a/test/oauth/key.cc +++ b/test/oauth/key.cc @@ -6,7 +6,7 @@ BOOST_AUTO_TEST_SUITE(oauth_key) BOOST_AUTO_TEST_CASE(test01) { - CocoaTweet::OAuth::Key key; + CocoaTweet::OAuth::Key key; BOOST_TEST(key.consumerKey() == ""); BOOST_TEST(key.consumerSecret() == ""); @@ -15,7 +15,8 @@ BOOST_AUTO_TEST_CASE(test01) { } BOOST_AUTO_TEST_CASE(test02) { - CocoaTweet::OAuth::Key key("consumerKey", "consumerSecret", "accessToken", "accessTokenSecret"); + CocoaTweet::OAuth::Key key("consumerKey", "consumerSecret", "accessToken", + "accessTokenSecret"); BOOST_TEST(key.consumerKey() == "consumerKey"); BOOST_TEST(key.consumerSecret() == "consumerSecret"); @@ -31,5 +32,4 @@ BOOST_AUTO_TEST_CASE(test02) { BOOST_TEST(secret.at("oauth_token") == "accessTokenSecret"); } - BOOST_AUTO_TEST_SUITE_END()