// SourceAccountId が null のタブに対しては Primary のアカウントを返す
var actual = accounts.GetAccountForTab(tabWithoutAccountId);
- Assert.Equal(new("00000000-0000-4000-8000-000000000000"), actual?.UniqueKey);
+ Assert.IsType<TwitterAccount>(actual);
+ Assert.Equal(new("00000000-0000-4000-8000-000000000000"), actual.UniqueKey);
}
[Fact]
// SourceAccountId が設定されているタブに対しては対応するアカウントを返す
var actual = accounts.GetAccountForTab(tabWithAccountId);
- Assert.Equal(new("00000000-0000-4000-8000-111111111111"), actual?.UniqueKey);
+ Assert.IsType<TwitterAccount>(actual);
+ Assert.Equal(new("00000000-0000-4000-8000-111111111111"), actual.UniqueKey);
}
[Fact]
var tabWithAccountId = new RelatedPostsTabModel("hoge", new("00000000-0000-4000-8000-999999999999"), new());
- // SourceAccountId に存在しない ID が設定されていた場合は null を返す
- Assert.Null(accounts.GetAccountForTab(tabWithAccountId));
+ // SourceAccountId に存在しない ID が設定されていた場合は InvalidAccount を返す
+ var actual = accounts.GetAccountForTab(tabWithAccountId);
+ Assert.IsType<InvalidAccount>(actual);
+ Assert.Equal(new("00000000-0000-4000-8000-999999999999"), actual.UniqueKey);
}
}
}
--- /dev/null
+// 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;
+using System.Threading.Tasks;
+using OpenTween.Connection;
+using Xunit;
+
+namespace OpenTween.SocialProtocol
+{
+ public class InvalidAccountTest
+ {
+ [Fact]
+ public async Task Connection_Test()
+ {
+ using var account = new InvalidAccount(Guid.NewGuid());
+ var requeset = new GetRequest { RequestUri = new("https://example.com/aaa") };
+
+ await Assert.ThrowsAsync<WebApiException>(
+ () => account.Connection.SendAsync(requeset)
+ );
+ }
+
+ [Fact]
+ public async Task Client_Test()
+ {
+ using var account = new InvalidAccount(Guid.NewGuid());
+
+ await Assert.ThrowsAsync<WebApiException>(
+ () => account.Client.VerifyCredentials()
+ );
+ }
+ }
+}
account.Dispose();
}
- public ISocialAccount? GetAccountForTab(TabModel tab)
+ public ISocialAccount GetAccountForTab(TabModel tab)
{
if (tab.SourceAccountId is { } accountId)
{
if (this.accounts.TryGetValue(accountId, out var account))
return account;
- return null;
+ // タブ追加後に設定画面からアカウントの情報を削除した場合
+ return new InvalidAccount(accountId);
}
return this.Primary;
--- /dev/null
+// 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.
+
+#nullable enable
+
+using System;
+using System.Threading.Tasks;
+using OpenTween.Connection;
+using OpenTween.Models;
+
+namespace OpenTween.SocialProtocol
+{
+ public class InvalidAccount : ISocialAccount
+ {
+ public string AccountType
+ => "InvalidAccount";
+
+ public Guid UniqueKey { get; }
+
+ public PersonId UserId
+ => new TwitterUserId("0");
+
+ public string UserName
+ => "(Unknown account)";
+
+ public IApiConnection Connection { get; } = new InvalidAccountConnection();
+
+ public ISocialProtocolClient Client { get; } = new InvalidAccountClient();
+
+ public bool IsDisposed { get; private set; }
+
+ public InvalidAccount(Guid uniqueKey)
+ => this.UniqueKey = uniqueKey;
+
+ public void Initialize(UserAccount accountSettings, SettingCommon settingCommon)
+ {
+ }
+
+ public void Dispose()
+ => this.IsDisposed = true;
+
+ private class InvalidAccountConnection : IApiConnection
+ {
+ public Task<ApiResponse> SendAsync(IHttpRequest request)
+ => throw new WebApiException("Invalid account");
+
+ public void Dispose()
+ {
+ }
+ }
+
+ private class InvalidAccountClient : ISocialProtocolClient
+ {
+ public Task<UserInfo> VerifyCredentials()
+ => throw this.CreateException();
+
+ public Task<PostClass> GetPostById(PostId postId, bool firstLoad)
+ => throw this.CreateException();
+
+ public Task<TimelineResponse> GetHomeTimeline(int count, IQueryCursor? cursor, bool firstLoad)
+ => throw this.CreateException();
+
+ public Task<TimelineResponse> GetSearchTimeline(string query, string lang, int count, IQueryCursor? cursor, bool firstLoad)
+ => throw this.CreateException();
+
+ public Task<PostClass[]> GetRelatedPosts(PostClass targetPost, bool firstLoad)
+ => throw this.CreateException();
+
+ public Task DeletePost(PostId postId)
+ => throw this.CreateException();
+
+ public Task FavoritePost(PostId postId)
+ => throw this.CreateException();
+
+ public Task UnfavoritePost(PostId postId)
+ => throw this.CreateException();
+
+ public Task<PostClass?> RetweetPost(PostId postId)
+ => throw this.CreateException();
+
+ public Task UnretweetPost(PostId postId)
+ => throw this.CreateException();
+
+ private WebApiException CreateException()
+ => new("Invalid account");
+ }
+ }
+}
=> this.accounts.Primary;
public ISocialAccount CurrentTabAccount
- => this.accounts.GetAccountForTab(this.CurrentTab) ?? throw new InvalidOperationException("Account not found");
+ => this.accounts.GetAccountForTab(this.CurrentTab);
// Growl呼び出し部
private readonly GrowlHelper gh = new(ApplicationSettings.ApplicationName);
try
{
var accountForTab = this.accounts.GetAccountForTab(tab);
- if (accountForTab == null)
+ if (accountForTab is InvalidAccount)
return;
this.RefreshTasktrayIcon();
headerPanel = new GeneralTimelineHeaderPanel
{
Dock = DockStyle.Top,
- HeaderText = account != null ? $"@{account.UserName}: Home" : "",
+ HeaderText = $"@{account.UserName}: Home",
};
}
// 検索関連の準備