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 }