public void OldestUnreadId_Test() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.UnreadManage = true; // 未読なし Assert.Equal(-1L, tab.OldestUnreadId); tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(100L, tab.OldestUnreadId); tab.AddPostToInnerStorage(new PostClass { StatusId = 50L, IsRead = true, // 既読 }); tab.AddSubmit(); Assert.Equal(100L, tab.OldestUnreadId); }
public void NextUnreadId_DisabledTest() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; // 未読表示無効 tab.UnreadManage = false; tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(-1L, tab.NextUnreadId); }
public void SetReadState_MarkAsUnreadTest() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.UnreadManage = true; tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = true, // 既読 }); tab.AddSubmit(); Assert.Equal(0, tab.UnreadCount); tab.SetReadState(100L, false); // 未読にする Assert.Equal(1, tab.UnreadCount); }
public void OldestUnreadIndex_DisabledTest() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; // 未読表示無効 tab.UnreadManage = false; tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); tab.SortMode = ComparerMode.Id; tab.SortOrder = SortOrder.Ascending; tab.Sort(); Assert.Equal(-1, tab.OldestUnreadIndex); }
public void GetRelatedResult(bool read, TabClass tab) { var relPosts = new Dictionary<Int64, PostClass>(); if (tab.RelationTargetPost.TextFromApi.Contains("@") && tab.RelationTargetPost.InReplyToStatusId == null) { //検索結果対応 var p = TabInformations.GetInstance()[tab.RelationTargetPost.StatusId]; if (p != null && p.InReplyToStatusId != null) { tab.RelationTargetPost = p; } else { p = this.GetStatusApi(read, tab.RelationTargetPost.StatusId); tab.RelationTargetPost = p; } } relPosts.Add(tab.RelationTargetPost.StatusId, tab.RelationTargetPost); Exception lastException = null; // in_reply_to_status_id を使用してリプライチェインを辿る var nextPost = FindTopOfReplyChain(relPosts, tab.RelationTargetPost.StatusId); var loopCount = 1; while (nextPost.InReplyToStatusId != null && loopCount++ <= 20) { var inReplyToId = nextPost.InReplyToStatusId.Value; var inReplyToPost = TabInformations.GetInstance()[inReplyToId]; if (inReplyToPost == null) { try { inReplyToPost = this.GetStatusApi(read, inReplyToId); } catch (WebApiException ex) { lastException = ex; break; } } relPosts.Add(inReplyToPost.StatusId, inReplyToPost); nextPost = FindTopOfReplyChain(relPosts, nextPost.StatusId); } //MRTとかに対応のためツイート内にあるツイートを指すURLを取り込む var text = tab.RelationTargetPost.Text; var ma = Twitter.StatusUrlRegex.Matches(text).Cast<Match>() .Concat(Twitter.ThirdPartyStatusUrlRegex.Matches(text).Cast<Match>()); foreach (var _match in ma) { Int64 _statusId; if (Int64.TryParse(_match.Groups["StatusId"].Value, out _statusId)) { if (relPosts.ContainsKey(_statusId)) continue; var p = TabInformations.GetInstance()[_statusId]; if (p == null) { try { p = this.GetStatusApi(read, _statusId); } catch (WebApiException ex) { lastException = ex; break; } } if (p != null) relPosts.Add(p.StatusId, p); } } relPosts.Values.ToList().ForEach(p => { if (p.IsMe && !read && this._readOwnPost) p.IsRead = true; else p.IsRead = read; tab.AddPostToInnerStorage(p); }); if (lastException != null) throw new WebApiException(lastException.Message, lastException); }
private long? CreatePostsFromSearchJson(string content, TabClass tab, bool read, int count, bool more) { TwitterSearchResult items; try { items = TwitterSearchResult.ParseJson(content); } catch (SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); throw new WebApiException("Json Parse Error(DataContractJsonSerializer)", content, ex); } catch (Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); throw new WebApiException("Invalid Json!", content, ex); } long? minimumId = null; foreach (var result in items.Statuses) { PostClass post = null; post = CreatePostsFromStatusData(result); if (post == null) { // Search API は相変わらずぶっ壊れたデータを返すことがあるため、必要なデータが欠如しているものは取得し直す try { post = this.GetStatusApi(read, result.Id); } catch (WebApiException) { continue; } } if (minimumId == null || minimumId.Value > post.StatusId) minimumId = post.StatusId; if (!more && post.StatusId > tab.SinceId) tab.SinceId = post.StatusId; //二重取得回避 lock (LockObj) { if (tab == null) { if (TabInformations.GetInstance().ContainsKey(post.StatusId)) continue; } else { if (tab.Contains(post.StatusId)) continue; } } post.IsRead = read; if ((post.IsMe && !read) && this._readOwnPost) post.IsRead = true; //非同期アイコン取得&StatusDictionaryに追加 if (tab != null && tab.IsInnerStorageTabType) tab.AddPostToInnerStorage(post); else TabInformations.GetInstance().AddPost(post); } return minimumId; }
private long? CreatePostsFromJson(string content, MyCommon.WORKERTYPE gType, TabClass tab, bool read) { TwitterStatus[] items; try { items = TwitterStatus.ParseJsonArray(content); } catch(SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); throw new WebApiException("Json Parse Error(DataContractJsonSerializer)", content, ex); } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); throw new WebApiException("Invalid Json!", content, ex); } long? minimumId = null; foreach (var status in items) { PostClass post = null; post = CreatePostsFromStatusData(status); if (post == null) continue; if (minimumId == null || minimumId.Value > post.StatusId) minimumId = post.StatusId; //二重取得回避 lock (LockObj) { if (tab == null) { if (TabInformations.GetInstance().ContainsKey(post.StatusId)) continue; } else { if (tab.Contains(post.StatusId)) continue; } } //RT禁止ユーザーによるもの if (gType != MyCommon.WORKERTYPE.UserTimeline && post.RetweetedByUserId != null && this.noRTId.Contains(post.RetweetedByUserId.Value)) continue; post.IsRead = read; if (post.IsMe && !read && _readOwnPost) post.IsRead = true; //非同期アイコン取得&StatusDictionaryに追加 if (tab != null && tab.IsInnerStorageTabType) tab.AddPostToInnerStorage(post); else TabInformations.GetInstance().AddPost(post); } return minimumId; }
public void GetStatusApi(bool read, long id, TabClass tab) { var post = this.GetStatusApi(read, id); //非同期アイコン取得&StatusDictionaryに追加 if (tab != null && tab.IsInnerStorageTabType) tab.AddPostToInnerStorage(post); else TabInformations.GetInstance().AddPost(post); }
public void NextUnreadId_SortByIdAscTest() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.UnreadManage = true; // ID の昇順でソート tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); // 画面には上から 100 → 200 → 300 の順に並ぶ tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false }); tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, IsRead = false }); tab.AddPostToInnerStorage(new PostClass { StatusId = 300L, IsRead = false }); tab.AddSubmit(); // 昇順/降順に関わらず、ID の小さい順に未読の ID を返す Assert.Equal(100L, tab.NextUnreadId); }
public void GetUnreadIds_Test() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.UnreadManage = true; Assert.Empty(tab.GetUnreadIds()); tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false }); tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, IsRead = true }); tab.AddSubmit(); Assert.Equal(new[] { 100L }, tab.GetUnreadIds()); tab.SetReadState(100L, true); // 既読にする Assert.Empty(tab.GetUnreadIds()); }
public void NextUnreadIndex_Test() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); tab.UnreadManage = true; // 未読なし Assert.Equal(-1, tab.NextUnreadIndex); tab.AddPostToInnerStorage(new PostClass { StatusId = 50L, IsRead = true, // 既読 }); tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddPostToInnerStorage(new PostClass { StatusId = 150L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(1, tab.NextUnreadIndex); }
public void NextUnreadId_SortByScreenNameDescTest() { var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline }; tab.UnreadManage = true; // ScreenName の降順でソート tab.SetSortMode(ComparerMode.Name, SortOrder.Descending); // 画面には上から 300 → 100 → 200 の順に並ぶ tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, ScreenName = "bbb", IsRead = false }); tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, ScreenName = "aaa", IsRead = false }); tab.AddPostToInnerStorage(new PostClass { StatusId = 300L, ScreenName = "ccc", IsRead = false }); tab.AddSubmit(); // 昇順/降順に関わらず、ScreenName の辞書順で小さい順に未読の ID を返す Assert.Equal(200L, tab.NextUnreadId); }