diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index f3164ade6..3774feac0 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -134,7 +134,7 @@ auto getTorrents(tr_session* session, tr_variant* args) std::begin(by_id), std::end(by_id), std::back_inserter(torrents), - [&cutoff](auto const* tor) { return tor->has_changed_since(cutoff); }); + [&cutoff](auto const* tor) { return tor != nullptr && tor->has_changed_since(cutoff); }); } else { @@ -148,7 +148,12 @@ auto getTorrents(tr_session* session, tr_variant* args) else // all of them { auto const& by_id = session->torrents().sorted_by_id(); - torrents = std::vector{ std::begin(by_id), std::end(by_id) }; + torrents.reserve(std::size(by_id)); + std::copy_if( + std::begin(by_id), + std::end(by_id), + std::back_inserter(torrents), + [](auto const* tor) { return tor != nullptr; }); } return torrents; diff --git a/tests/libtransmission/rpc-test.cc b/tests/libtransmission/rpc-test.cc index ce4f74c20..387d1de67 100644 --- a/tests/libtransmission/rpc-test.cc +++ b/tests/libtransmission/rpc-test.cc @@ -17,6 +17,7 @@ #include #include "gtest/gtest.h" +#include "libtransmission/quark.h" #include "test-fixtures.h" struct tr_session; @@ -183,4 +184,45 @@ TEST_F(RpcTest, sessionGet) tr_torrentRemove(tor, false, nullptr, nullptr); } +TEST_F(RpcTest, torrentGet) +{ + auto const rpc_response_func = [](tr_session* /*session*/, tr_variant* response, void* setme) noexcept + { + std::swap(*static_cast(setme), *response); + }; + + auto* tor = zeroTorrentInit(ZeroTorrentState::NoFiles); + EXPECT_NE(nullptr, tor); + + tr_variant request; + tr_variantInitDict(&request, 1); + + tr_variantDictAddStrView(&request, TR_KEY_method, "torrent-get"); + + tr_variant* args_in = tr_variantDictAddDict(&request, TR_KEY_arguments, 1); + tr_variant* fields = tr_variantDictAddList(args_in, TR_KEY_fields, 1); + tr_variantListAddStrView(fields, tr_quark_get_string_view(TR_KEY_id)); + + tr_variant response; + tr_rpc_request_exec_json(session_, &request, rpc_response_func, &response); + + EXPECT_TRUE(response.holds_alternative()); + tr_variant* args = nullptr; + EXPECT_TRUE(tr_variantDictFindDict(&response, TR_KEY_arguments, &args)); + + tr_variant* torrents = nullptr; + EXPECT_TRUE(tr_variantDictFindList(args, TR_KEY_torrents, &torrents)); + EXPECT_EQ(1UL, tr_variantListSize(torrents)); + + tr_variant* first_torrent = tr_variantListChild(torrents, 0); + + EXPECT_TRUE(first_torrent->holds_alternative()); + int64_t first_torrent_id = 0; + EXPECT_TRUE(tr_variantDictFindInt(first_torrent, TR_KEY_id, &first_torrent_id)); + EXPECT_EQ(1, first_torrent_id); + + // cleanup + tr_torrentRemove(tor, false, nullptr, nullptr); +} + } // namespace libtransmission::test