diff --git a/internal/repository/article.go b/internal/repository/article.go index f129e80..44fbbba 100644 --- a/internal/repository/article.go +++ b/internal/repository/article.go @@ -25,6 +25,34 @@ type PushRecord interface { Time() time.Time } +type Push struct { + appendType string + id string + ipAddr string + text string + time time.Time +} + +func (p *Push) Type() string { + return p.appendType +} + +func (p *Push) ID() string { + return p.id +} + +func (p *Push) IPAddr() string { + return p.ipAddr +} + +func (p *Push) Text() string { + return p.text +} + +func (p *Push) Time() time.Time { + return p.time +} + func (repo *repository) GetPopularArticles(ctx context.Context) ([]PopularArticleRecord, error) { // Note: go-bbs has not implemented this yet // TODO: delegate to repo.db when it is ready @@ -37,7 +65,15 @@ func (repo *repository) AppendComment(ctx context.Context, userID, boardID, file if err != nil { return nil, err } - return nil, nil + + p := &Push{ + appendType: appendType, + id: userID, + ipAddr: "", // not sure how to get IPAddr + text: text, + time: time.Now(), + } + return p, nil } func (repo *repository) AppendArticle(ctx context.Context, userID, boardID, title, content string) (bbs.ArticleRecord, error) { diff --git a/internal/usecase/article.go b/internal/usecase/article.go index 5cfc79e..0e4d6eb 100644 --- a/internal/usecase/article.go +++ b/internal/usecase/article.go @@ -3,6 +3,8 @@ package usecase import ( "context" "fmt" + "strings" + "unicode/utf8" "github.com/Ptt-official-app/go-bbs" @@ -19,7 +21,60 @@ func (usecase *usecase) GetPopularArticles(ctx context.Context) ([]repository.Po } func (usecase *usecase) UpdateUsefulness(ctx context.Context, userID, boardID, filename, appendType string) (repository.PushRecord, error) { - return nil, nil + articleRecords, err := usecase.repo.GetBoardArticleRecords(ctx, boardID) + + if err != nil { + return nil, fmt.Errorf("UpdateUsefulness error: %w", err) + } + + var owner string + for _, record := range articleRecords { + if record.Filename() == filename { + owner = record.Owner() + } + } + + if owner == userID { + return nil, fmt.Errorf("UpdateUsefuleness error: Owners cannot push their own article") + } + + article, err := usecase.GetBoardArticle(ctx, boardID, filename) + if err != nil { + return nil, fmt.Errorf("UpdateUsefulness error: %w", err) + } + + articleStr := string(article) + + cur := 0 + numRecommend := 0 + for { + cur = strings.Index(articleStr[cur:], userID) + if cur < 0 { + break + } + + r, _ := utf8.DecodeLastRuneInString(articleStr[:cur]) + if r == utf8.RuneError { + return nil, fmt.Errorf("UpdateUsefulness error: DecodeLastRuneError") + } + if numRecommend < 1 && string(r) == "\u2191" { + numRecommend++ + } + + if numRecommend > -1 && string(r) == "\u2193" { + numRecommend-- + } + } + + if (appendType == "\u2191" && numRecommend == 1) || (appendType == "\u2193" && numRecommend == -1) { + return nil, fmt.Errorf("User with userID:%s has already pushed", userID) + } + + p, err := usecase.repo.AppendComment(ctx, userID, boardID, filename, appendType, "") + if err != nil { + return nil, fmt.Errorf("UpdateUsefulness error: %w", err) + } + return p, nil } // AppendComment append comment to specific article diff --git a/internal/usecase/article_test.go b/internal/usecase/article_test.go index 43214ef..db7d72e 100644 --- a/internal/usecase/article_test.go +++ b/internal/usecase/article_test.go @@ -26,6 +26,30 @@ func TestGetPopularArticles(t *testing.T) { } } +func TestUpdateUsefulness(t *testing.T) { + repo := &MockRepository{} + userID := "mockUserID" + boardID := "board1" + filename := "filename1" + appendType := "↑" + + usecase := NewUsecase(&config.Config{}, repo) + + record, err := usecase.UpdateUsefulness(context.TODO(), userID, boardID, filename, appendType) + + if err != nil { + t.Errorf("UpdateUsefulness expected err == nil, got %v", err) + } + + if record.Type() != appendType { + t.Errorf("Push record with incorrect appendType, want %s, get %s", appendType, record.Type()) + } + + if record.ID() != userID { + t.Errorf("Push record with incorrect userID, want %s, get %s", userID, record.ID()) + } +} + func TestForwardArticleToEmail(t *testing.T) { repo := &MockRepository{}