OSDN Git Service

UserInfoDialogからAPIを呼び出す箇所をTwitterApiクラスに移行
authorKimura Youichi <kim.upsilon@bucyou.net>
Thu, 28 Apr 2016 01:42:35 +0000 (10:42 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Thu, 28 Apr 2016 14:55:18 +0000 (23:55 +0900)
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween/Api/TwitterApi.cs
OpenTween/Tween.cs
OpenTween/UserInfoDialog.cs

index df1c608..720344d 100644 (file)
@@ -107,6 +107,51 @@ namespace OpenTween.Api
         }
 
         [Fact]
+        public async Task UsersShow_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.GetAsync<TwitterUser>(
+                        new Uri("users/show.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "screen_name", "twitterapi" }, { "include_entities", "true" } })
+                )
+                .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.UsersShow(screenName: "twitterapi")
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task UsersReportSpam_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterUser>(
+                        new Uri("users/report_spam.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.UsersReportSpam(screenName: "twitterapi")
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
         public async Task FavoritesCreate_Test()
         {
             using (var twitterApi = new TwitterApi())
@@ -151,5 +196,151 @@ namespace OpenTween.Api
                 mock.VerifyAll();
             }
         }
+
+        [Fact]
+        public async Task FriendshipsShow_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.GetAsync<TwitterFriendship>(
+                        new Uri("friendships/show.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } })
+                )
+                .ReturnsAsync(new TwitterFriendship());
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task FriendshipsCreate_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterFriendship>(
+                        new Uri("friendships/create.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.FriendshipsCreate(screenName: "twitterapi")
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task BlocksCreate_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterUser>(
+                        new Uri("blocks/create.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterUser()));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.BlocksCreate(screenName: "twitterapi")
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task BlocksDestroy_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterUser>(
+                        new Uri("blocks/destroy.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterUser()));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.BlocksDestroy(screenName: "twitterapi")
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task AccountUpdateProfile_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterUser>(
+                        new Uri("account/update_profile.json", UriKind.Relative),
+                        new Dictionary<string, string> {
+                            { "include_entities", "true" },
+                            { "name", "Name" },
+                            { "url", "http://example.com/" },
+                            { "location", "Location" },
+                            { "description", "&lt;script&gt;alert(1)&lt;/script&gt;" },
+                        })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterUser()));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
+        public async Task AccountUpdateProfileImage_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            using (var image = TestUtils.CreateDummyImage())
+            using (var media = new MemoryImageMediaItem(image))
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.PostLazyAsync<TwitterUser>(
+                        new Uri("account/update_profile_image.json", UriKind.Relative),
+                        new Dictionary<string, string> { { "include_entities", "true" } },
+                        new Dictionary<string, IMediaItem> { { "image", media } })
+                )
+                .ReturnsAsync(LazyJson.Create(new TwitterUser()));
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.AccountUpdateProfileImage(media)
+                    .IgnoreResponse()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
     }
 }
index cfeda43..b4fd3a5 100644 (file)
@@ -59,6 +59,29 @@ namespace OpenTween.Api
             return this.apiConnection.GetAsync<TwitterStatus>(endpoint, param);
         }
 
+        public Task<TwitterUser> UsersShow(string screenName)
+        {
+            var endpoint = new Uri("users/show.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+                ["include_entities"] = "true",
+            };
+
+            return this.apiConnection.GetAsync<TwitterUser>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterUser>> UsersReportSpam(string screenName)
+        {
+            var endpoint = new Uri("users/report_spam.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+        }
+
         public Task<LazyJson<TwitterStatus>> FavoritesCreate(long statusId)
         {
             var endpoint = new Uri("favorites/create.json", UriKind.Relative);
@@ -81,6 +104,103 @@ namespace OpenTween.Api
             return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
         }
 
+        public Task<TwitterFriendship> FriendshipsShow(string sourceScreenName, string targetScreenName)
+        {
+            var endpoint = new Uri("friendships/show.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["source_screen_name"] = sourceScreenName,
+                ["target_screen_name"] = targetScreenName,
+            };
+
+            return this.apiConnection.GetAsync<TwitterFriendship>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterFriendship>> FriendshipsCreate(string screenName)
+        {
+            var endpoint = new Uri("friendships/create.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterFriendship>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterFriendship>> FriendshipsDestroy(string screenName)
+        {
+            var endpoint = new Uri("friendships/destroy.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterFriendship>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterUser>> BlocksCreate(string screenName)
+        {
+            var endpoint = new Uri("blocks/create.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterUser>> BlocksDestroy(string screenName)
+        {
+            var endpoint = new Uri("blocks/destroy.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["screen_name"] = screenName,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterUser>> AccountUpdateProfile(string name, string url, string location, string description)
+        {
+            var endpoint = new Uri("account/update_profile.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["include_entities"] = "true",
+            };
+
+            if (name != null)
+                param["name"] = name;
+            if (url != null)
+                param["url"] = url;
+            if (location != null)
+                param["location"] = location;
+
+            if (description != null)
+            {
+                // name, location, description に含まれる < > " の文字はTwitter側で除去されるが、
+                // twitter.com の挙動では description でのみ &lt; 等の文字参照を使って表示することができる
+                var escapedDescription = description.Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;");
+                param["description"] = escapedDescription;
+            }
+
+            return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+        }
+
+        public Task<LazyJson<TwitterUser>> AccountUpdateProfileImage(IMediaItem image)
+        {
+            var endpoint = new Uri("account/update_profile_image.json", UriKind.Relative);
+            var param = new Dictionary<string, string>
+            {
+                ["include_entities"] = "true",
+            };
+            var paramMedia = new Dictionary<string, IMediaItem>
+            {
+                ["image"] = image,
+            };
+
+            return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param, paramMedia);
+        }
+
         public void Dispose()
         {
             this.apiConnection?.Dispose();
index 4f9a89d..93d981d 100644 (file)
@@ -12335,7 +12335,7 @@ namespace OpenTween
 
                 try
                 {
-                    var task = Task.Run(() => this.tw.GetUserInfo(id));
+                    var task = this.twitterApi.UsersShow(id);
                     user = await dialog.WaitForAsync(this, task);
                 }
                 catch (WebApiException ex)
@@ -12354,7 +12354,7 @@ namespace OpenTween
 
         private async Task doShowUserStatus(TwitterUser user)
         {
-            using (var userDialog = new UserInfoDialog(this, this.tw))
+            using (var userDialog = new UserInfoDialog(this, this.twitterApi))
             {
                 var showUserTask = userDialog.ShowUserAsync(user);
                 userDialog.ShowDialog(this);
index 54ca69f..d95e808 100644 (file)
@@ -38,6 +38,7 @@ using System.Text.RegularExpressions;
 using System.Web;
 using System.IO;
 using System.Net;
+using OpenTween.Api;
 using OpenTween.Api.DataModel;
 using OpenTween.Connection;
 using System.Diagnostics.CodeAnalysis;
@@ -50,12 +51,12 @@ namespace OpenTween
         private CancellationTokenSource cancellationTokenSource = null;
 
         private readonly TweenMain mainForm;
-        private readonly Twitter twitter;
+        private readonly TwitterApi twitterApi;
 
-        public UserInfoDialog(TweenMain mainForm, Twitter twitter)
+        public UserInfoDialog(TweenMain mainForm, TwitterApi twitterApi)
         {
             this.mainForm = mainForm;
-            this.twitter = twitter;
+            this.twitterApi = twitterApi;
 
             InitializeComponent();
 
@@ -132,7 +133,7 @@ namespace OpenTween
             this.LinkLabelTweet.Tag = profileUrl;
             this.ToolTip1.SetToolTip(this.LinkLabelTweet, profileUrl);
 
-            if (this.twitter.UserId == user.Id)
+            if (this.twitterApi.CurrentUserId == user.Id)
             {
                 this.ButtonEdit.Enabled = true;
                 this.ChangeIconToolStripMenuItem.Enabled = true;
@@ -269,13 +270,13 @@ namespace OpenTween
             this.ButtonFollow.Enabled = false;
             this.ButtonUnFollow.Enabled = false;
 
-            if (this.twitter.Username == screenName)
+            if (this.twitterApi.CurrentScreenName == screenName)
                 return;
 
             TwitterFriendship friendship;
             try
             {
-                friendship = await Task.Run(() => this.twitter.GetFriendshipInfo(screenName));
+                friendship = await this.twitterApi.FriendshipsShow(this.twitterApi.CurrentScreenName, screenName);
             }
             catch (WebApiException)
             {
@@ -342,16 +343,20 @@ namespace OpenTween
             await this.mainForm.OpenUriInBrowserAsync(linkUrl);
         }
 
-        private void ButtonFollow_Click(object sender, EventArgs e)
+        private async void ButtonFollow_Click(object sender, EventArgs e)
         {
-            try
-            {
-                this.twitter.PostFollowCommand(this._displayUser.ScreenName);
-            }
-            catch (WebApiException ex)
+            using (ControlTransaction.Disabled(this.ButtonFollow))
             {
-                MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
-                return;
+                try
+                {
+                    await this.twitterApi.FriendshipsCreate(this._displayUser.ScreenName)
+                        .IgnoreResponse();
+                }
+                catch (WebApiException ex)
+                {
+                    MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
+                    return;
+                }
             }
 
             MessageBox.Show(Properties.Resources.FRMessage3);
@@ -360,20 +365,24 @@ namespace OpenTween
             ButtonUnFollow.Enabled = true;
         }
 
-        private void ButtonUnFollow_Click(object sender, EventArgs e)
+        private async void ButtonUnFollow_Click(object sender, EventArgs e)
         {
             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonUnFollow_ClickText1,
                                Properties.Resources.ButtonUnFollow_ClickText2,
                                MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
             {
-                try
+                using (ControlTransaction.Disabled(this.ButtonUnFollow))
                 {
-                    this.twitter.PostRemoveCommand(this._displayUser.ScreenName);
-                }
-                catch (WebApiException ex)
-                {
-                    MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
-                    return;
+                    try
+                    {
+                        await this.twitterApi.FriendshipsDestroy(this._displayUser.ScreenName)
+                            .IgnoreResponse();
+                    }
+                    catch (WebApiException ex)
+                    {
+                        MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
+                        return;
+                    }
                 }
 
                 MessageBox.Show(Properties.Resources.FRMessage3);
@@ -466,7 +475,7 @@ namespace OpenTween
         private async void ButtonEdit_Click(object sender, EventArgs e)
         {
             // 自分以外のプロフィールは変更できない
-            if (this.twitter.UserId != this._displayUser.Id)
+            if (this.twitterApi.CurrentUserId != this._displayUser.Id)
                 return;
 
             using (ControlTransaction.Disabled(this.ButtonEdit))
@@ -512,13 +521,13 @@ namespace OpenTween
                     {
                         try
                         {
-                            var user = await Task.Run(() =>
-                                this.twitter.PostUpdateProfile(
-                                    this.TextBoxName.Text,
-                                    this.TextBoxWeb.Text,
-                                    this.TextBoxLocation.Text,
-                                    this.TextBoxDescription.Text));
+                            var response = await this.twitterApi.AccountUpdateProfile(
+                                this.TextBoxName.Text,
+                                this.TextBoxWeb.Text,
+                                this.TextBoxLocation.Text,
+                                this.TextBoxDescription.Text);
 
+                            var user = await response.LoadJsonAsync();
                             showUserTask = this.ShowUserAsync(user);
                         }
                         catch (WebApiException ex)
@@ -558,11 +567,13 @@ namespace OpenTween
         {
             try
             {
-                await Task.Run(() => this.twitter.PostUpdateProfileImage(filename));
+                var mediaItem = new FileMediaItem(filename);
+
+                await this.twitterApi.AccountUpdateProfileImage(mediaItem)
+                    .IgnoreResponse();
             }
             catch (WebApiException ex)
             {
-                // "Err:"が付いたエラーメッセージが返ってくる
                 MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ChangeIconToolStripMenuItem_ClickText4);
                 return;
             }
@@ -571,7 +582,7 @@ namespace OpenTween
 
             try
             {
-                var user = await Task.Run(() => this.twitter.GetUserInfo(this._displayUser.ScreenName));
+                var user = await this.twitterApi.UsersShow(this._displayUser.ScreenName);
 
                 if (user != null)
                     await this.ShowUserAsync(user);
@@ -606,63 +617,75 @@ namespace OpenTween
             }
         }
 
-        private void ButtonBlock_Click(object sender, EventArgs e)
+        private async void ButtonBlock_Click(object sender, EventArgs e)
         {
             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonBlock_ClickText1,
                                 Properties.Resources.ButtonBlock_ClickText2,
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
             {
-                try
+                using (ControlTransaction.Disabled(this.ButtonBlock))
                 {
-                    this.twitter.PostCreateBlock(this._displayUser.ScreenName);
-                }
-                catch (WebApiException ex)
-                {
-                    MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonBlock_ClickText3);
-                    return;
-                }
+                    try
+                    {
+                        await this.twitterApi.BlocksCreate(this._displayUser.ScreenName)
+                            .IgnoreResponse();
+                    }
+                    catch (WebApiException ex)
+                    {
+                        MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonBlock_ClickText3);
+                        return;
+                    }
 
-                MessageBox.Show(Properties.Resources.ButtonBlock_ClickText4);
+                    MessageBox.Show(Properties.Resources.ButtonBlock_ClickText4);
+                }
             }
         }
 
-        private void ButtonReportSpam_Click(object sender, EventArgs e)
+        private async void ButtonReportSpam_Click(object sender, EventArgs e)
         {
             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonReportSpam_ClickText1,
                                 Properties.Resources.ButtonReportSpam_ClickText2,
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
             {
-                try
+                using (ControlTransaction.Disabled(this.ButtonReportSpam))
                 {
-                    this.twitter.PostReportSpam(this._displayUser.ScreenName);
-                }
-                catch (WebApiException ex)
-                {
-                    MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonReportSpam_ClickText3);
-                    return;
-                }
+                    try
+                    {
+                        await this.twitterApi.UsersReportSpam(this._displayUser.ScreenName)
+                            .IgnoreResponse();
+                    }
+                    catch (WebApiException ex)
+                    {
+                        MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonReportSpam_ClickText3);
+                        return;
+                    }
 
-                MessageBox.Show(Properties.Resources.ButtonReportSpam_ClickText4);
+                    MessageBox.Show(Properties.Resources.ButtonReportSpam_ClickText4);
+                }
             }
         }
 
-        private void ButtonBlockDestroy_Click(object sender, EventArgs e)
+        private async void ButtonBlockDestroy_Click(object sender, EventArgs e)
         {
             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonBlockDestroy_ClickText1,
                                 Properties.Resources.ButtonBlockDestroy_ClickText2,
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
             {
-                try
-                {
-                    this.twitter.PostDestroyBlock(this._displayUser.ScreenName);
-                }
-                catch (WebApiException ex)
+                using (ControlTransaction.Disabled(this.ButtonBlockDestroy))
                 {
-                    MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonBlockDestroy_ClickText3);
-                    return;
-                }
+                    try
+                    {
+                        await this.twitterApi.BlocksDestroy(this._displayUser.ScreenName)
+                            .IgnoreResponse();
+                    }
+                    catch (WebApiException ex)
+                    {
+                        MessageBox.Show(ex.Message + Environment.NewLine + Properties.Resources.ButtonBlockDestroy_ClickText3);
+                        return;
+                    }
 
-                MessageBox.Show(Properties.Resources.ButtonBlockDestroy_ClickText4);
+                    MessageBox.Show(Properties.Resources.ButtonBlockDestroy_ClickText4);
+                }
             }
         }