go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/internal/bugs/monorail/monorail_test.go (about)

     1  // Copyright 2022 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package monorail
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"google.golang.org/genproto/protobuf/field_mask"
    23  	"google.golang.org/protobuf/types/known/timestamppb"
    24  
    25  	"go.chromium.org/luci/common/clock/testclock"
    26  
    27  	mpb "go.chromium.org/luci/analysis/internal/bugs/monorail/api_proto"
    28  
    29  	. "github.com/smartystreets/goconvey/convey"
    30  	. "go.chromium.org/luci/common/testing/assertions"
    31  )
    32  
    33  func TestClient(t *testing.T) {
    34  	t.Parallel()
    35  
    36  	Convey("With Existing Issue Data", t, func() {
    37  		issue1 := NewIssueData(1)
    38  		issue2 := NewIssueData(2)
    39  		issue3 := NewIssueData(3)
    40  		f := &FakeIssuesStore{
    41  			Issues: []*IssueData{issue1, issue2, issue3},
    42  			NextID: 4,
    43  		}
    44  		ctx := UseFakeIssuesClient(context.Background(), f, "user@chromium.org")
    45  
    46  		now := time.Date(2044, time.April, 4, 4, 4, 4, 4, time.UTC)
    47  		ctx, _ = testclock.UseTime(ctx, now)
    48  
    49  		Convey("Get issue", func() {
    50  			c, err := NewClient(ctx, "monorailhost")
    51  			So(err, ShouldBeNil)
    52  			result, err := c.GetIssue(ctx, "projects/monorailproject/issues/1")
    53  			So(err, ShouldBeNil)
    54  			So(result, ShouldResembleProto, issue1.Issue)
    55  		})
    56  		Convey("Batch get issues", func() {
    57  			c, err := NewClient(ctx, "monorailhost")
    58  			So(err, ShouldBeNil)
    59  			ids := []string{
    60  				"1",
    61  				"2",
    62  				"4", // Does not exist.
    63  				"1",
    64  				"2",
    65  				"3",
    66  			}
    67  			result, err := c.BatchGetIssues(ctx, "monorailproject", ids)
    68  			So(err, ShouldBeNil)
    69  			So(result, ShouldResembleProto, []*mpb.Issue{issue1.Issue, issue2.Issue, nil, issue1.Issue, issue2.Issue, issue3.Issue})
    70  		})
    71  		Convey("Make issue", func() {
    72  			issue := NewIssue(4)
    73  			issue.Name = ""
    74  			req := &mpb.MakeIssueRequest{
    75  				Parent:      "projects/monorailproject",
    76  				Issue:       issue,
    77  				Description: "Description",
    78  				NotifyType:  mpb.NotifyType_NO_NOTIFICATION,
    79  			}
    80  
    81  			c, err := NewClient(ctx, "monorailhost")
    82  			So(err, ShouldBeNil)
    83  			result, err := c.MakeIssue(ctx, req)
    84  			So(err, ShouldBeNil)
    85  			expectedResult := NewIssue(4)
    86  			expectedResult.StatusModifyTime = timestamppb.New(now)
    87  			So(result, ShouldResembleProto, expectedResult)
    88  
    89  			comments, err := c.ListComments(ctx, result.Name)
    90  			So(err, ShouldBeNil)
    91  			So(len(comments), ShouldEqual, 1)
    92  			So(comments[0].Content, ShouldEqual, "Description")
    93  		})
    94  		Convey("List comments", func() {
    95  			Convey("Single comment", func() {
    96  				c, err := NewClient(ctx, "monorailhost")
    97  				So(err, ShouldBeNil)
    98  				comments, err := c.ListComments(ctx, "projects/monorailproject/issues/1")
    99  				So(err, ShouldBeNil)
   100  				So(len(comments), ShouldEqual, 1)
   101  				So(comments, ShouldResembleProto, issue1.Comments)
   102  			})
   103  			Convey("Many comments", func() {
   104  				issue := NewIssueData(4)
   105  				for i := 2; i <= 3*maxCommentPageSize; i++ {
   106  					issue.Comments = append(issue.Comments, NewComment(issue.Issue.Name, i))
   107  				}
   108  				f.Issues = append(f.Issues, issue)
   109  
   110  				c, err := NewClient(ctx, "monorailhost")
   111  				So(err, ShouldBeNil)
   112  				comments, err := c.ListComments(ctx, issue.Issue.Name)
   113  				So(err, ShouldBeNil)
   114  				So(comments, ShouldResembleProto, issue.Comments)
   115  			})
   116  		})
   117  		Convey("Modify issue", func() {
   118  			issue1.Issue.Labels = []*mpb.Issue_LabelValue{
   119  				{Label: "Test-Label1"},
   120  			}
   121  
   122  			c, err := NewClient(ctx, "monorailhost")
   123  			So(err, ShouldBeNil)
   124  
   125  			req := &mpb.ModifyIssuesRequest{
   126  				Deltas: []*mpb.IssueDelta{
   127  					{
   128  						Issue: &mpb.Issue{
   129  							Name:   issue1.Issue.Name,
   130  							Status: &mpb.Issue_StatusValue{Status: VerifiedStatus},
   131  							Labels: []*mpb.Issue_LabelValue{
   132  								{
   133  									Label: "Test-Label2",
   134  								},
   135  							},
   136  						},
   137  						UpdateMask: &field_mask.FieldMask{
   138  							Paths: []string{"labels", "status"},
   139  						},
   140  					},
   141  				},
   142  				CommentContent: "Changing status and labels.",
   143  			}
   144  			err = c.ModifyIssues(ctx, req)
   145  			So(err, ShouldBeNil)
   146  
   147  			expectedData := NewIssueData(1)
   148  			expectedData.Issue.Labels = []*mpb.Issue_LabelValue{
   149  				{Label: "Test-Label1"},
   150  				{Label: "Test-Label2"},
   151  			}
   152  			expectedData.Issue.Status = &mpb.Issue_StatusValue{Status: VerifiedStatus}
   153  			expectedData.Issue.StatusModifyTime = timestamppb.New(now)
   154  			expectedData.Issue.CloseTime = timestamppb.New(now)
   155  
   156  			read, err := c.GetIssue(ctx, issue1.Issue.Name)
   157  			So(err, ShouldBeNil)
   158  			So(read, ShouldResembleProto, expectedData.Issue)
   159  
   160  			comments, err := c.ListComments(ctx, issue1.Issue.Name)
   161  			So(err, ShouldBeNil)
   162  			So(len(comments), ShouldEqual, 2)
   163  			So(comments[0], ShouldResembleProto, expectedData.Comments[0])
   164  			So(comments[1].Content, ShouldEqual, "Changing status and labels.")
   165  		})
   166  	})
   167  }