Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
upsilon committed Jan 27, 2024
2 parents 39cbe2a + db3cde3 commit b954c0f
Show file tree
Hide file tree
Showing 49 changed files with 2,546 additions and 136 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
更新履歴

==== Ver 3.13.0(2024/01/27)
* NEW: Cookie使用時のReplyタブの更新に対応(/statuses/mentions_timeline.json 廃止に伴う対応)
* NEW: Cookie使用時のFavoritesタブの更新に対応
* NEW: Cookie使用時のFav追加・削除に対応
* NEW: ステータスバーに各タブの更新回数(起動時からの回数)の表示を追加
* NEW: 設定画面の更新間隔ページに24時間分の取得回数目安の表示を追加
* CHG: 更新間隔の初期設定を変更
* FIX: Cookie使用時にツイート検索の言語指定が効かない不具合を修正
* FIX: ツイート検索のキーワードを後から変更すると検索結果が表示されない不具合を修正
* FIX: Cookie使用時にステータスバーにRecentタブのレートリミットが表示されない不具合を修正
* FIX: 取得したツイートの中身が空だった場合のエラー処理を改善
* FIX: タイムラインの取得結果にレートリミットに関するメッセージが含まれていた場合はエラーとして扱う

==== Ver 3.12.0(2024/01/20)
* NEW: graphqlエンドポイントを使用したホームタイムラインの取得に対応

Expand Down
78 changes: 78 additions & 0 deletions OpenTween.Tests/Api/GraphQL/FavoriteTweetRequestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// OpenTween - Client of Twitter
// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.

using System.Threading.Tasks;
using Moq;
using OpenTween.Connection;
using Xunit;

namespace OpenTween.Api.GraphQL
{
public class FavoriteTweetRequestTest
{
[Fact]
public async Task Send_Test()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/FavoriteTweet.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x =>
x.SendAsync(It.IsAny<IHttpRequest>())
)
.Callback<IHttpRequest>(x =>
{
var request = Assert.IsType<PostJsonRequest>(x);
Assert.Equal(new("https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet"), request.RequestUri);
Assert.Equal("""{"variables":{"tweet_id":"12345"},"queryId":"lI07N6Otwv1PhnEgXILM7A"}""", request.JsonString);
})
.ReturnsAsync(apiResponse);

var request = new FavoriteTweetRequest
{
TweetId = new("12345"),
};

await request.Send(mock.Object);

mock.VerifyAll();
}

[Fact]
public async Task Send_AlreadyFavoritedTest()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/FavoriteTweet_AlreadyFavorited.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x => x.SendAsync(It.IsAny<IHttpRequest>()))
.ReturnsAsync(apiResponse);

var request = new FavoriteTweetRequest
{
TweetId = new("12345"),
};

// 重複によるエラーレスポンスが返っているが例外を発生させない
await request.Send(mock.Object);

mock.VerifyAll();
}
}
}
28 changes: 28 additions & 0 deletions OpenTween.Tests/Api/GraphQL/HomeLatestTimelineRequestTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

using System.Threading.Tasks;
using Moq;
using OpenTween.Api.DataModel;
using OpenTween.Connection;
using Xunit;

Expand Down Expand Up @@ -92,5 +93,32 @@ public async Task Send_RequestCursor_Test()
await request.Send(mock.Object);
mock.VerifyAll();
}

[Fact]
public async Task Send_RateLimitTest()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/HomeLatestTimeline_RateLimit.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x =>
x.SendAsync(It.IsAny<IHttpRequest>())
)
.Callback<IHttpRequest>(x =>
{
var request = Assert.IsType<GetRequest>(x);
Assert.Equal(new("https://twitter.com/i/api/graphql/lAKISuk_McyDUlhS2Zmv4A/HomeLatestTimeline"), request.RequestUri);
})
.ReturnsAsync(apiResponse);

var request = new HomeLatestTimelineRequest();

var ex = await Assert.ThrowsAsync<TwitterApiException>(
() => request.Send(mock.Object)
);
var errorItem = Assert.Single(ex.Errors);
Assert.Equal(TwitterErrorCode.RateLimit, errorItem.Code);

mock.VerifyAll();
}
}
}
95 changes: 95 additions & 0 deletions OpenTween.Tests/Api/GraphQL/LikesRequestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// OpenTween - Client of Twitter
// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.

using System.Threading.Tasks;
using Moq;
using OpenTween.Connection;
using Xunit;

namespace OpenTween.Api.GraphQL
{
public class LikesRequestTest
{
[Fact]
public async Task Send_Test()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/Likes.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x =>
x.SendAsync(It.IsAny<IHttpRequest>())
)
.Callback<IHttpRequest>(x =>
{
var request = Assert.IsType<GetRequest>(x);
Assert.Equal(new("https://twitter.com/i/api/graphql/G_zHbTiwSqLm0TAK_3sNWQ/Likes"), request.RequestUri);
var query = request.Query!;
Assert.Equal(2, query.Count);
Assert.Equal("""{"userId":"12345","count":20,"includePromotedContent":false,"withClientEventToken":false,"withBirdwatchNotes":false,"withVoice":true,"withV2Timeline":true}""", query["variables"]);
Assert.True(query.ContainsKey("features"));
Assert.Equal("Likes", request.EndpointName);
})
.ReturnsAsync(apiResponse);

var request = new LikesRequest
{
UserId = "12345",
Count = 20,
};

var response = await request.Send(mock.Object);
Assert.Single(response.Tweets);
Assert.Equal("DAAHCgABGEs2Ve9AAAELAAIAAAATMTc4OTA3OTU2MDM5NDcxNTMyMggAAwAAAAEAAA", response.CursorTop);
Assert.Equal("DAAHCgABGEs2Ve8___8LAAIAAAATMTc4OTA3OTU2MDM5NDcxNTMyMggAAwAAAAIAAA", response.CursorBottom);

mock.VerifyAll();
}

[Fact]
public async Task Send_RequestCursor_Test()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/Likes.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x =>
x.SendAsync(It.IsAny<IHttpRequest>())
)
.Callback<IHttpRequest>(x =>
{
var request = Assert.IsType<GetRequest>(x);
Assert.Equal(new("https://twitter.com/i/api/graphql/G_zHbTiwSqLm0TAK_3sNWQ/Likes"), request.RequestUri);
var query = request.Query!;
Assert.Equal("""{"userId":"12345","count":20,"includePromotedContent":false,"withClientEventToken":false,"withBirdwatchNotes":false,"withVoice":true,"withV2Timeline":true,"cursor":"aaa"}""", query["variables"]);
})
.ReturnsAsync(apiResponse);

var request = new LikesRequest
{
UserId = "12345",
Count = 20,
Cursor = "aaa",
};

await request.Send(mock.Object);
mock.VerifyAll();
}
}
}
15 changes: 14 additions & 1 deletion OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,24 @@ public void ToStatus_TweetTombstone_Test()
var rootElm = this.LoadResponseDocument("TimelineTweet_TweetTombstone.json");
var timelineTweet = new TimelineTweet(rootElm);

Assert.True(timelineTweet.IsTombstone);
Assert.False(timelineTweet.IsAvailable);
var ex = Assert.Throws<WebApiException>(
() => timelineTweet.ToTwitterStatus()
);
Assert.Equal("This Post is from a suspended account. Learn more", ex.Message);
}

[Fact]
public void ToStatus_EmptyTweet_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_EmptyTweet.json");
var timelineTweet = new TimelineTweet(rootElm);

Assert.False(timelineTweet.IsAvailable);
var ex = Assert.Throws<WebApiException>(
() => timelineTweet.ToTwitterStatus()
);
Assert.Equal("Tweet is not available", ex.Message);
}
}
}
58 changes: 58 additions & 0 deletions OpenTween.Tests/Api/GraphQL/UnfavoriteTweetRequestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// OpenTween - Client of Twitter
// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.

using System.Threading.Tasks;
using Moq;
using OpenTween.Connection;
using Xunit;

namespace OpenTween.Api.GraphQL
{
public class UnfavoriteTweetRequestTest
{
[Fact]
public async Task Send_Test()
{
using var apiResponse = await TestUtils.CreateApiResponse("Resources/Responses/UnfavoriteTweet.json");

var mock = new Mock<IApiConnection>();
mock.Setup(x =>
x.SendAsync(It.IsAny<IHttpRequest>())
)
.Callback<IHttpRequest>(x =>
{
var request = Assert.IsType<PostJsonRequest>(x);
Assert.Equal(new("https://twitter.com/i/api/graphql/ZYKSe-w7KEslx3JhSIk5LA/UnfavoriteTweet"), request.RequestUri);
Assert.Equal("""{"variables":{"tweet_id":"12345"},"queryId":"ZYKSe-w7KEslx3JhSIk5LA"}""", request.JsonString);
})
.ReturnsAsync(apiResponse);

var request = new UnfavoriteTweetRequest
{
TweetId = new("12345"),
};

await request.Send(mock.Object);

mock.VerifyAll();
}
}
}
Loading

0 comments on commit b954c0f

Please sign in to comment.