// OpenTween - Client of Twitter
// Copyright (c) 2023 kim_upsilon (@kim_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 , or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using OpenTween.Models;
using Xunit;
namespace OpenTween.Api.GraphQL
{
public class TimelineTweetTest
{
private XElement LoadResponseDocument(string filename)
{
using var stream = File.OpenRead($"Resources/Responses/{filename}");
using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
return XElement.Load(jsonReader);
}
private TabInformations CreateTabInfo()
{
var tabinfo = new TabInformations();
tabinfo.AddDefaultTabs();
return tabinfo;
}
[Fact]
public void ExtractTimelineTweets_Single_Test()
{
var rootElm = this.LoadResponseDocument("ListLatestTweetsTimeline_SimpleTweet.json");
var timelineTweets = TimelineTweet.ExtractTimelineTweets(rootElm);
Assert.Single(timelineTweets);
}
[Fact]
public void ExtractTimelineTweets_Conversation_Test()
{
var rootElm = this.LoadResponseDocument("ListLatestTweetsTimeline_Conversation.json");
var timelineTweets = TimelineTweet.ExtractTimelineTweets(rootElm);
Assert.Equal(3, timelineTweets.Length);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_SimpleTweet_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_SimpleTweet.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1613784711020826626", post.StatusId.Id);
Assert.Equal(40480664L, post.UserId);
Assert.False(post.IsPromoted);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_TweetWithMedia_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_TweetWithMedia.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1614587968567783424", post.StatusId.Id);
Assert.Equal(40480664L, post.UserId);
Assert.Equal(2, post.Media.Count);
Assert.Equal("https://pbs.twimg.com/media/FmgrJiEaAAEU42G.png", post.Media[0].Url);
Assert.Equal("OpenTweenで @opentween のツイート一覧を表示しているスクショ", post.Media[0].AltText);
Assert.Equal("https://pbs.twimg.com/media/FmgrJiXaMAEu873.jpg", post.Media[1].Url);
Assert.Equal("OpenTweenの新しい画像投稿画面を動かしている様子のスクショ", post.Media[1].AltText);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_RetweetedTweet_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_RetweetedTweet.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1617128268548964354", post.StatusId.Id);
Assert.Equal(40480664L, post.RetweetedByUserId);
Assert.Equal("1617126084138659840", post.RetweetedId!.Id);
Assert.Equal(514241801L, post.UserId);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_TweetWithVisibility.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1602775353088524288", post.StatusId.Id);
Assert.Equal(357750891L, post.UserId);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_SelfThread_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_SelfThread.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1511751702684499968", post.StatusId.Id);
Assert.Equal(40480664L, post.UserId);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_QuotedTweet_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_QuotedTweet.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1588614645866147840", post.StatusId.Id);
var quotedPostId = Assert.Single(post.QuoteStatusIds);
Assert.Equal("1583108196868116480", quotedPostId.Id);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_QuotedTweet_Tombstone_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_QuotedTweet_Tombstone.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1614653321310253057", post.StatusId.Id);
var quotedPostId = Assert.Single(post.QuoteStatusIds);
Assert.Equal("1614650279194136576", quotedPostId.Id);
}
[Fact]
public void ToStatus_WithTwitterPostFactory_PromotedTweet_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_PromotedTweet.json");
var timelineTweet = new TimelineTweet(rootElm);
var status = timelineTweet.ToTwitterStatus();
var postFactory = new TwitterPostFactory(this.CreateTabInfo());
var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet());
Assert.Equal("1674737917363888129", post.StatusId.Id);
Assert.Equal(2941313791L, post.UserId);
Assert.True(post.IsPromoted);
Assert.Matches(new Regex(@"^\[Promoted\]\n"), post.TextFromApi);
}
[Fact]
public void ToStatus_TweetTombstone_Test()
{
var rootElm = this.LoadResponseDocument("TimelineTweet_TweetTombstone.json");
var timelineTweet = new TimelineTweet(rootElm);
Assert.False(timelineTweet.IsAvailable);
var ex = Assert.Throws(
() => 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(
() => timelineTweet.ToTwitterStatus()
);
Assert.Equal("Tweet is not available", ex.Message);
}
}
}