|  | /** | 
|  | * @license | 
|  | * Copyright (C) 2020 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | * http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | import '../test/common-test-setup-karma'; | 
|  | import { | 
|  | isUnresolved, | 
|  | getPatchRangeForCommentUrl, | 
|  | createCommentThreads, | 
|  | sortComments, | 
|  | } from './comment-util'; | 
|  | import {createComment, createCommentThread} from '../test/test-data-generators'; | 
|  | import {CommentSide, Side} from '../constants/constants'; | 
|  | import { | 
|  | BasePatchSetNum, | 
|  | ParentPatchSetNum, | 
|  | PatchSetNum, | 
|  | RevisionPatchSetNum, | 
|  | Timestamp, | 
|  | UrlEncodedCommentId, | 
|  | } from '../types/common'; | 
|  |  | 
|  | suite('comment-util', () => { | 
|  | test('isUnresolved', () => { | 
|  | const thread = createCommentThread([createComment()]); | 
|  |  | 
|  | assert.isFalse(isUnresolved(undefined)); | 
|  | assert.isFalse(isUnresolved(thread)); | 
|  |  | 
|  | assert.isTrue( | 
|  | isUnresolved({ | 
|  | ...thread, | 
|  | comments: [{...createComment(), unresolved: true}], | 
|  | }) | 
|  | ); | 
|  | assert.isFalse( | 
|  | isUnresolved({ | 
|  | ...thread, | 
|  | comments: [{...createComment(), unresolved: false}], | 
|  | }) | 
|  | ); | 
|  | assert.isTrue( | 
|  | isUnresolved({ | 
|  | ...thread, | 
|  | comments: [ | 
|  | {...createComment(), unresolved: false}, | 
|  | {...createComment(), unresolved: true}, | 
|  | ], | 
|  | }) | 
|  | ); | 
|  | assert.isFalse( | 
|  | isUnresolved({ | 
|  | ...thread, | 
|  | comments: [ | 
|  | {...createComment(), unresolved: true}, | 
|  | {...createComment(), unresolved: false}, | 
|  | ], | 
|  | }) | 
|  | ); | 
|  | }); | 
|  |  | 
|  | test('getPatchRangeForCommentUrl', () => { | 
|  | test('comment created with side=PARENT does not navigate to latest ps', () => { | 
|  | const comment = { | 
|  | ...createComment(), | 
|  | id: 'c4' as UrlEncodedCommentId, | 
|  | line: 10, | 
|  | patch_set: 4 as PatchSetNum, | 
|  | side: CommentSide.PARENT, | 
|  | path: '/COMMIT_MSG', | 
|  | }; | 
|  | assert.deepEqual( | 
|  | getPatchRangeForCommentUrl(comment, 11 as RevisionPatchSetNum), | 
|  | { | 
|  | basePatchNum: ParentPatchSetNum, | 
|  | patchNum: 4 as PatchSetNum, | 
|  | } | 
|  | ); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('comments sorting', () => { | 
|  | const comments = [ | 
|  | { | 
|  | id: 'new_draft' as UrlEncodedCommentId, | 
|  | message: 'i do not like either of you', | 
|  | diffSide: Side.LEFT, | 
|  | __draft: true, | 
|  | updated: '2015-12-20 15:01:20.396000000' as Timestamp, | 
|  | }, | 
|  | { | 
|  | id: 'sallys_confession' as UrlEncodedCommentId, | 
|  | message: 'i like you, jack', | 
|  | updated: '2015-12-23 15:00:20.396000000' as Timestamp, | 
|  | line: 1, | 
|  | diffSide: Side.LEFT, | 
|  | }, | 
|  | { | 
|  | id: 'jacks_reply' as UrlEncodedCommentId, | 
|  | message: 'i like you, too', | 
|  | updated: '2015-12-24 15:01:20.396000000' as Timestamp, | 
|  | diffSide: Side.LEFT, | 
|  | line: 1, | 
|  | in_reply_to: 'sallys_confession', | 
|  | }, | 
|  | ]; | 
|  | const sortedComments = sortComments(comments); | 
|  | assert.equal(sortedComments[0], comments[1]); | 
|  | assert.equal(sortedComments[1], comments[2]); | 
|  | assert.equal(sortedComments[2], comments[0]); | 
|  | }); | 
|  |  | 
|  | suite('createCommentThreads', () => { | 
|  | test('creates threads from individual comments', () => { | 
|  | const comments = [ | 
|  | { | 
|  | id: 'sallys_confession' as UrlEncodedCommentId, | 
|  | message: 'i like you, jack', | 
|  | updated: '2015-12-23 15:00:20.396000000' as Timestamp, | 
|  | line: 1, | 
|  | patch_set: 1 as PatchSetNum, | 
|  | path: 'some/path', | 
|  | }, | 
|  | { | 
|  | id: 'jacks_reply' as UrlEncodedCommentId, | 
|  | message: 'i like you, too', | 
|  | updated: '2015-12-24 15:01:20.396000000' as Timestamp, | 
|  | line: 1, | 
|  | in_reply_to: 'sallys_confession' as UrlEncodedCommentId, | 
|  | patch_set: 1 as PatchSetNum, | 
|  | path: 'some/path', | 
|  | }, | 
|  | { | 
|  | id: 'new_draft' as UrlEncodedCommentId, | 
|  | message: 'i do not like either of you' as UrlEncodedCommentId, | 
|  | __draft: true, | 
|  | updated: '2015-12-20 15:01:20.396000000' as Timestamp, | 
|  | patch_set: 1 as PatchSetNum, | 
|  | path: 'some/path', | 
|  | }, | 
|  | ]; | 
|  |  | 
|  | const actualThreads = createCommentThreads(comments, { | 
|  | basePatchNum: 1 as BasePatchSetNum, | 
|  | patchNum: 4 as RevisionPatchSetNum, | 
|  | }); | 
|  |  | 
|  | assert.equal(actualThreads.length, 2); | 
|  |  | 
|  | assert.equal(actualThreads[0].diffSide, Side.LEFT); | 
|  | assert.equal(actualThreads[0].comments.length, 2); | 
|  | assert.deepEqual(actualThreads[0].comments[0], comments[0]); | 
|  | assert.deepEqual(actualThreads[0].comments[1], comments[1]); | 
|  | assert.equal(actualThreads[0].patchNum, 1 as PatchSetNum); | 
|  | assert.equal(actualThreads[0].line, 1); | 
|  |  | 
|  | assert.equal(actualThreads[1].diffSide, Side.LEFT); | 
|  | assert.equal(actualThreads[1].comments.length, 1); | 
|  | assert.deepEqual(actualThreads[1].comments[0], comments[2]); | 
|  | assert.equal(actualThreads[1].patchNum, 1 as PatchSetNum); | 
|  | assert.equal(actualThreads[1].line, 'FILE'); | 
|  | }); | 
|  |  | 
|  | test('derives patchNum and range', () => { | 
|  | const comments = [ | 
|  | { | 
|  | id: 'betsys_confession' as UrlEncodedCommentId, | 
|  | message: 'i like you, jack', | 
|  | updated: '2015-12-24 15:00:10.396000000' as Timestamp, | 
|  | range: { | 
|  | start_line: 1, | 
|  | start_character: 1, | 
|  | end_line: 1, | 
|  | end_character: 2, | 
|  | }, | 
|  | patch_set: 5 as PatchSetNum, | 
|  | path: '/p', | 
|  | line: 1, | 
|  | }, | 
|  | ]; | 
|  |  | 
|  | const expectedThreads = [ | 
|  | { | 
|  | diffSide: Side.LEFT, | 
|  | commentSide: CommentSide.REVISION, | 
|  | path: '/p', | 
|  | rootId: 'betsys_confession' as UrlEncodedCommentId, | 
|  | mergeParentNum: undefined, | 
|  | comments: [ | 
|  | { | 
|  | id: 'betsys_confession' as UrlEncodedCommentId, | 
|  | path: '/p', | 
|  | message: 'i like you, jack', | 
|  | updated: '2015-12-24 15:00:10.396000000' as Timestamp, | 
|  | range: { | 
|  | start_line: 1, | 
|  | start_character: 1, | 
|  | end_line: 1, | 
|  | end_character: 2, | 
|  | }, | 
|  | patch_set: 5 as PatchSetNum, | 
|  | line: 1, | 
|  | }, | 
|  | ], | 
|  | patchNum: 5 as PatchSetNum, | 
|  | range: { | 
|  | start_line: 1, | 
|  | start_character: 1, | 
|  | end_line: 1, | 
|  | end_character: 2, | 
|  | }, | 
|  | line: 1, | 
|  | }, | 
|  | ]; | 
|  |  | 
|  | assert.deepEqual( | 
|  | createCommentThreads(comments, { | 
|  | basePatchNum: 5 as BasePatchSetNum, | 
|  | patchNum: 10 as RevisionPatchSetNum, | 
|  | }), | 
|  | expectedThreads | 
|  | ); | 
|  | }); | 
|  |  | 
|  | test('does not thread unrelated comments at same location', () => { | 
|  | const comments = [ | 
|  | { | 
|  | id: 'sallys_confession' as UrlEncodedCommentId, | 
|  | message: 'i like you, jack', | 
|  | updated: '2015-12-23 15:00:20.396000000' as Timestamp, | 
|  | diffSide: Side.LEFT, | 
|  | path: '/p', | 
|  | }, | 
|  | { | 
|  | id: 'jacks_reply' as UrlEncodedCommentId, | 
|  | message: 'i like you, too', | 
|  | updated: '2015-12-24 15:01:20.396000000' as Timestamp, | 
|  | diffSide: Side.LEFT, | 
|  | path: '/p', | 
|  | }, | 
|  | ]; | 
|  | assert.equal(createCommentThreads(comments).length, 2); | 
|  | }); | 
|  | }); | 
|  | }); |