From c6882040a9eb6cac346fdd3d791ab1cdabc0a458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Sun, 12 Oct 2025 23:34:08 +0200 Subject: [PATCH 1/4] feat(graphql): add comments retrieval to ProjectV2Item queries --- private/item/convertItemToHash.ps1 | 33 +++- public/graphql/getProjectV2Item.query | 18 +- .../orgprojectwithfieldsAndItems.query | 168 ++++++++++-------- 3 files changed, 135 insertions(+), 84 deletions(-) diff --git a/private/item/convertItemToHash.ps1 b/private/item/convertItemToHash.ps1 index 3eb3179..4d8d79d 100644 --- a/private/item/convertItemToHash.ps1 +++ b/private/item/convertItemToHash.ps1 @@ -19,6 +19,13 @@ function Convert-NodeItemToHash { $item.type = $NodeItem.content.__typename $item.body = $NodeItem.content.body $item.contentId = $NodeItem.content.id + + # Comments + if ($NodeItem.content.comments.totalCount -gt 0) { + $item.comments = $NodeItem.content.comments.nodes | Convert-Comment + $item.commentLast = $item.comments[-1] + } + # Title is stored in two places. in the content and as a field. # We will use the field value $item.number = $NodeItem.content.number @@ -77,7 +84,7 @@ function Convert-NodeItemToHash { } } -function Build-ItemPanelUrl{ +function Build-ItemPanelUrl { [CmdletBinding()] [OutputType([string])] param( @@ -102,4 +109,26 @@ function Build-ItemPanelUrl{ $finalUrl = $uriBuilder.ToString() return $finalUrl -} \ No newline at end of file +} + +function Convert-Comment { + [CmdletBinding()] + param( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)][object]$CommentNode + ) + + process { + $comment = New-Object System.Collections.Hashtable + $comment.body = $CommentNode.body + $comment.id = $CommentNode.fullDatabaseId + $comment.url = $CommentNode.url + $comment.author = $CommentNode.author.login + $comment.createdAt = GetDateTime -DateTimeString $CommentNode.createdAt + $comment.updatedAt = GetDateTime -DateTimeString $CommentNode.updatedAt + + + $ret = [PsCustomObject]$comment + + return $ret + } +} \ No newline at end of file diff --git a/public/graphql/getProjectV2Item.query b/public/graphql/getProjectV2Item.query index a56b5b2..dde4f72 100644 --- a/public/graphql/getProjectV2Item.query +++ b/public/graphql/getProjectV2Item.query @@ -1,14 +1,23 @@ -query($itemId: ID!) { +query($itemId: ID ! $lastComments: Int=10) { node(id: $itemId) { ... on ProjectV2Item { id, type, fullDatabaseId, project{ id, url}, content{__typename, ... on DraftIssue {id,body,title,updatedAt,createdAt}, - ... on PullRequest{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}}}, + ... on PullRequest{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} + comments(last: $lastComments){ + totalCount, + nodes{createdAt,updatedAt,url,body,fullDatabaseId,author{login}} + } + }, ... on Issue{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} - }, - } + comments(last: $lastComments){ + totalCount, + nodes{createdAt,updatedAt,url,body,fullDatabaseId,author{login}} + } + } + }, fieldValues(first: 100){ nodes{__typename, ... on ProjectV2ItemFieldDateValue{date,field{__typename,... on ProjectV2Field{id,name,dataType @@ -92,7 +101,6 @@ query($itemId: ID!) { } } } - } } } \ No newline at end of file diff --git a/public/graphql/orgprojectwithfieldsAndItems.query b/public/graphql/orgprojectwithfieldsAndItems.query index 637d942..50c649b 100644 --- a/public/graphql/orgprojectwithfieldsAndItems.query +++ b/public/graphql/orgprojectwithfieldsAndItems.query @@ -1,96 +1,110 @@ -query OrgProjectWithFields($afterFields:String$afterItems:String$firstFields:Int!$firstItems:Int!$login:String!$number:Int!){organization(login: $login){projectV2(number: $number){number,url,shortDescription,public,closed,title,id,readme,items(first: $firstItems, after: $afterItems){pageInfo{endCursor,hasNextPage - },totalCount, - nodes{ - project{ id, number, title, url}, - content{__typename - ,... on DraftIssue {id,body,title,updatedAt,createdAt - },... on PullRequest{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} - },... on Issue{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} +query OrgProjectWithFields( $afterFields:String! $afterItems:String! $lastComments: Int=10 $firstFields:Int!$firstItems:Int!$login:String!$number:Int!){organization(login: $login){ + projectV2(number: $number){number,url,shortDescription,public,closed,title,id,readme, + items(first: $firstItems, after: $afterItems){ + pageInfo{endCursor,hasNextPage}, + totalCount, + nodes{ + id,fullDatabaseId, + project{ id, number, title, url}, + content{__typename, + ... on DraftIssue {id,body,title,updatedAt,createdAt}, + ... on PullRequest{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} + comments(last: $lastComments){ + totalCount, + nodes{createdAt,updatedAt,url,body,fullDatabaseId,author{login}} + } + }, + ... on Issue{id,body,title,updatedAt,createdAt,number,url,state,repository{name,owner{login}} + comments(last: $lastComments){ + totalCount, + nodes{createdAt,updatedAt,url,body,fullDatabaseId,author{login}} + } + } + }, + fieldValues(first: 100){nodes{__typename,... on ProjectV2ItemFieldDateValue{date,field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name + } + } } - },id,fullDatabaseId, - fieldValues(first: 100){nodes{__typename,... on ProjectV2ItemFieldDateValue{date,field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + },... on ProjectV2ItemFieldIterationValue{title,startDate,duration,field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldIterationValue{title,startDate,duration,field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldLabelValue{labels(first: 10){nodes{name + } + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldLabelValue{labels(first: 10){nodes{name - } - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldNumberValue{number,field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldNumberValue{number,field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldSingleSelectValue{name,field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldSingleSelectValue{name,field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldTextValue{text,field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldTextValue{text,field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldMilestoneValue{milestone{title,description,dueOn + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldMilestoneValue{milestone{title,description,dueOn - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldPullRequestValue{pullRequests(first: 10){nodes{url + } + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldPullRequestValue{pullRequests(first: 10){nodes{url - } - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldRepositoryValue{repository{url + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldRepositoryValue{repository{url - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldUserValue{users(first: 10){nodes{login + } + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } - },... on ProjectV2ItemFieldUserValue{users(first: 10){nodes{login - } - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + } + },... on ProjectV2ItemFieldReviewerValue{reviewers(first: 10){nodes{__typename,... on Team{name + },... on User{login } - },... on ProjectV2ItemFieldReviewerValue{reviewers(first: 10){nodes{__typename,... on Team{name - },... on User{login - } - } - },field{__typename,... on ProjectV2Field{id,name,dataType - },... on ProjectV2IterationField{id,name,dataType - },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name - } - } + } + },field{__typename,... on ProjectV2Field{id,name,dataType + },... on ProjectV2IterationField{id,name,dataType + },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } } } } } - },fields(first: $firstFields, after: $afterFields){totalCount,nodes{__typename,... on ProjectV2Field{id,name,dataType + } + } + }, + fields(first: $firstFields, after: $afterFields){totalCount,nodes{__typename,... on ProjectV2Field{id,name,dataType },... on ProjectV2IterationField{id,name,dataType },... on ProjectV2SingleSelectField{id,name,dataType,options{id,name } From 085eed4f40b3a19a42435b1273eaab38022e3ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Sun, 12 Oct 2025 23:34:22 +0200 Subject: [PATCH 2/4] feat(json): add comments field to project items in mock data --- ...tHubOrgProjectWithFields-octodemo-700.json | 256 ++++++++++++++---- 1 file changed, 199 insertions(+), 57 deletions(-) diff --git a/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json b/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json index 0726359..80374ec 100644 --- a/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json +++ b/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json @@ -18,6 +18,8 @@ "totalCount": 28, "nodes": [ { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pU", + "fullDatabaseId": "127726229", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -39,10 +41,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pU", - "fullDatabaseId": "127726229", "fieldValues": { "nodes": [ { @@ -194,6 +198,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pY", + "fullDatabaseId": "127726230", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -215,10 +221,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pY", - "fullDatabaseId": "127726230", "fieldValues": { "nodes": [ { @@ -370,6 +378,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pc", + "fullDatabaseId": "127726231", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -391,10 +401,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pc", - "fullDatabaseId": "127726231", "fieldValues": { "nodes": [ { @@ -546,6 +558,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pg", + "fullDatabaseId": "127726232", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -567,10 +581,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pg", - "fullDatabaseId": "127726232", "fieldValues": { "nodes": [ { @@ -738,6 +754,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pk", + "fullDatabaseId": "127726233", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -759,10 +777,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pk", - "fullDatabaseId": "127726233", "fieldValues": { "nodes": [ { @@ -930,6 +950,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8po", + "fullDatabaseId": "127726234", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -951,10 +973,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8po", - "fullDatabaseId": "127726234", "fieldValues": { "nodes": [ { @@ -1125,6 +1149,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8ps", + "fullDatabaseId": "127726235", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -1146,10 +1172,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8ps", - "fullDatabaseId": "127726235", "fieldValues": { "nodes": [ { @@ -1307,6 +1335,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pw", + "fullDatabaseId": "127726236", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -1328,10 +1358,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8pw", - "fullDatabaseId": "127726236", "fieldValues": { "nodes": [ { @@ -1489,6 +1521,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8p0", + "fullDatabaseId": "127726237", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -1510,10 +1544,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8p0", - "fullDatabaseId": "127726237", "fieldValues": { "nodes": [ { @@ -1671,6 +1707,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8p8", + "fullDatabaseId": "127726239", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -1692,10 +1730,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8p8", - "fullDatabaseId": "127726239", "fieldValues": { "nodes": [ { @@ -1853,6 +1893,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qA", + "fullDatabaseId": "127726240", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -1874,10 +1916,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qA", - "fullDatabaseId": "127726240", "fieldValues": { "nodes": [ { @@ -2032,6 +2076,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qE", + "fullDatabaseId": "127726241", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2053,10 +2099,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qE", - "fullDatabaseId": "127726241", "fieldValues": { "nodes": [ { @@ -2187,6 +2235,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qI", + "fullDatabaseId": "127726242", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2208,10 +2258,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgec8qI", - "fullDatabaseId": "127726242", "fieldValues": { "nodes": [ { @@ -2310,6 +2362,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAHE", + "fullDatabaseId": "127729777", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2324,8 +2378,6 @@ "updatedAt": "2025-09-07T10:06:58Z", "createdAt": "2025-09-07T10:06:58Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAHE", - "fullDatabaseId": "127729777", "fieldValues": { "nodes": [ { @@ -2396,6 +2448,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAHc", + "fullDatabaseId": "127729783", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2410,8 +2464,6 @@ "updatedAt": "2025-09-07T10:07:11Z", "createdAt": "2025-09-07T10:07:11Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAHc", - "fullDatabaseId": "127729783", "fieldValues": { "nodes": [ { @@ -2482,6 +2534,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAIE", + "fullDatabaseId": "127729793", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2496,8 +2550,6 @@ "updatedAt": "2025-09-07T10:07:24Z", "createdAt": "2025-09-07T10:07:24Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAIE", - "fullDatabaseId": "127729793", "fieldValues": { "nodes": [ { @@ -2604,6 +2656,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAIc", + "fullDatabaseId": "127729799", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2618,8 +2672,6 @@ "updatedAt": "2025-09-07T10:07:40Z", "createdAt": "2025-09-07T10:07:40Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAIc", - "fullDatabaseId": "127729799", "fieldValues": { "nodes": [ { @@ -2716,6 +2768,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAJI", + "fullDatabaseId": "127729810", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2730,8 +2784,6 @@ "updatedAt": "2025-09-07T10:07:56Z", "createdAt": "2025-09-07T10:07:56Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAJI", - "fullDatabaseId": "127729810", "fieldValues": { "nodes": [ { @@ -2838,6 +2890,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAUw", + "fullDatabaseId": "127729996", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -2859,10 +2913,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAUw", - "fullDatabaseId": "127729996", "fieldValues": { "nodes": [ { @@ -3014,6 +3070,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAVU", + "fullDatabaseId": "127730005", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3035,10 +3093,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAVU", - "fullDatabaseId": "127730005", "fieldValues": { "nodes": [ { @@ -3190,6 +3250,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAWU", + "fullDatabaseId": "127730021", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3211,10 +3273,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAWU", - "fullDatabaseId": "127730021", "fieldValues": { "nodes": [ { @@ -3366,6 +3430,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAWs", + "fullDatabaseId": "127730027", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3387,10 +3453,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAWs", - "fullDatabaseId": "127730027", "fieldValues": { "nodes": [ { @@ -3542,6 +3610,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgedAwI", + "fullDatabaseId": "127730434", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3563,10 +3633,12 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 0, + "nodes": [] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgedAwI", - "fullDatabaseId": "127730434", "fieldValues": { "nodes": [ { @@ -3614,6 +3686,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgeioBY", + "fullDatabaseId": "128098326", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3635,10 +3709,43 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 3, + "nodes": [ + { + "createdAt": "2025-09-24T08:41:55Z", + "updatedAt": "2025-09-24T08:41:55Z", + "url": "https://github.com/octodemo/rulasg-dev-1/pull/25#issuecomment-3327241861", + "body": "come comment from gh", + "fullDatabaseId": "3327241861", + "author": { + "login": "rulasg" + } + }, + { + "createdAt": "2025-09-24T08:42:05Z", + "updatedAt": "2025-09-24T08:42:05Z", + "url": "https://github.com/octodemo/rulasg-dev-1/pull/25#issuecomment-3327242467", + "body": "come comment from gh", + "fullDatabaseId": "3327242467", + "author": { + "login": "rulasg" + } + }, + { + "createdAt": "2025-09-24T08:56:12Z", + "updatedAt": "2025-09-24T08:56:12Z", + "url": "https://github.com/octodemo/rulasg-dev-1/pull/25#issuecomment-3327293422", + "body": "sample comment 1", + "fullDatabaseId": "3327293422", + "author": { + "login": "rulasg" + } + } + ] } }, - "id": "PVTI_lADOAlIw4c4BCe3VzgeioBY", - "fullDatabaseId": "128098326", "fieldValues": { "nodes": [ { @@ -3787,6 +3894,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgeiodc", + "fullDatabaseId": "128098775", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3801,8 +3910,6 @@ "updatedAt": "2025-09-11T15:14:28Z", "createdAt": "2025-09-09T13:59:21Z" }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgeiodc", - "fullDatabaseId": "128098775", "fieldValues": { "nodes": [ { @@ -3899,6 +4006,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3Vzgeio4o", + "fullDatabaseId": "128099210", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -3910,7 +4019,7 @@ "id": "I_kwDOPrRnkc7KkwSq", "body": "Body of issue for development", "title": "Issue for development", - "updatedAt": "2025-09-24T08:29:13Z", + "updatedAt": "2025-09-30T05:42:49Z", "createdAt": "2025-09-09T14:01:17Z", "number": 26, "url": "https://github.com/octodemo/rulasg-dev-1/issues/26", @@ -3920,10 +4029,43 @@ "owner": { "login": "octodemo" } + }, + "comments": { + "totalCount": 3, + "nodes": [ + { + "createdAt": "2025-09-23T17:51:06Z", + "updatedAt": "2025-09-23T17:51:06Z", + "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3324995787", + "body": "sample comment 1", + "fullDatabaseId": "3324995787", + "author": { + "login": "rulasg" + } + }, + { + "createdAt": "2025-09-24T08:29:13Z", + "updatedAt": "2025-09-24T08:29:13Z", + "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3327194303", + "body": "commetn added", + "fullDatabaseId": "3327194303", + "author": { + "login": "rulasg" + } + }, + { + "createdAt": "2025-09-30T05:42:49Z", + "updatedAt": "2025-09-30T05:42:49Z", + "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3350059109", + "body": "New comment", + "fullDatabaseId": "3350059109", + "author": { + "login": "rulasg" + } + } + ] } }, - "id": "PVTI_lADOAlIw4c4BCe3Vzgeio4o", - "fullDatabaseId": "128099210", "fieldValues": { "nodes": [ { @@ -4046,6 +4188,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgfBGX8", + "fullDatabaseId": "130095487", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -4060,8 +4204,6 @@ "updatedAt": "2025-09-22T14:23:38Z", "createdAt": "2025-09-22T14:23:38Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgfBGX8", - "fullDatabaseId": "130095487", "fieldValues": { "nodes": [ { @@ -4078,6 +4220,8 @@ } }, { + "id": "PVTI_lADOAlIw4c4BCe3VzgfBGZg", + "fullDatabaseId": "130095512", "project": { "id": "PVT_kwDOAlIw4c4BCe3V", "number": 700, @@ -4092,8 +4236,6 @@ "updatedAt": "2025-09-22T14:29:30Z", "createdAt": "2025-09-22T14:23:41Z" }, - "id": "PVTI_lADOAlIw4c4BCe3VzgfBGZg", - "fullDatabaseId": "130095512", "fieldValues": { "nodes": [ { From 5cb08655d9534df36e0f859e9b3fb8cf4b6c8ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 13 Oct 2025 00:05:09 +0200 Subject: [PATCH 3/4] feat(test): add comments validation to GetProjectItem test --- Test/private/MockCall_Project700.ps1 | 64 +++++++++++++++------------- Test/public/project_item.test.ps1 | 22 ++++++++++ 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/Test/private/MockCall_Project700.ps1 b/Test/private/MockCall_Project700.ps1 index 5699c4a..57c342d 100644 --- a/Test/private/MockCall_Project700.ps1 +++ b/Test/private/MockCall_Project700.ps1 @@ -55,31 +55,36 @@ function Get-Mock_Project_700 { $issue = $pActual.items.nodes | Where-Object { $_.content.title -eq "Issue for development" } $fss = $issue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldsingleselect.id) } $project.issue = @{ - id = $issue.id - contentId = $issue.content.id - title = $issue.content.title - repositoryName = $issue.content.repository.name - status = ($issue.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name - fieldtext = ($issue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text + id = $issue.id + contentId = $issue.content.id + title = $issue.content.title + repositoryName = $issue.content.repository.name + status = ($issue.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name + fieldtext = ($issue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text fieldsingleselect = @{ - name = $fss.name - optionId = ($fss.field.options | where-object {$_.name -eq $fss.name}).Id + name = $fss.name + optionId = ($fss.field.options | where-object { $_.name -eq $fss.name }).Id + } + comments = @{ + totalCount = $issue.content.comments.totalCount + last = $issue.content.comments.nodes[-1] + propertyCount = ($issue.content.comments.nodes[-1] | Get-Member -MemberType *Property).Count } } - + # PullRequest for developer $pullRequest = $pActual.items.nodes | Where-Object { $_.content.title -eq "PullRequest for development" } $fss = $pullRequest.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldsingleselect.id) } $project.pullrequest = @{ - id = $pullRequest.id - contentId = $pullRequest.content.id - title = $pullRequest.content.title - repositoryName = $pullRequest.content.repository.name - status = ($pullRequest.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name - fieldtext = ($pullRequest.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text + id = $pullRequest.id + contentId = $pullRequest.content.id + title = $pullRequest.content.title + repositoryName = $pullRequest.content.repository.name + status = ($pullRequest.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name + fieldtext = ($pullRequest.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text fieldsingleselect = @{ - name = $fss.name - optionId = ($fss.field.options | where-object {$_.name -eq $fss.name}).Id + name = $fss.name + optionId = ($fss.field.options | where-object { $_.name -eq $fss.name }).Id } } @@ -87,14 +92,14 @@ function Get-Mock_Project_700 { $draftIssue = $pActual.items.nodes | Where-Object { $_.content.title -eq "DraftIssue for development" } $fss = $draftIssue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldsingleselect.id) } $project.draftissue = @{ - id = $draftIssue.id - contentId = $draftIssue.content.id - title = $draftIssue.content.title - status = ($draftIssue.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name - fieldtext = ($draftIssue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text + id = $draftIssue.id + contentId = $draftIssue.content.id + title = $draftIssue.content.title + status = ($draftIssue.fieldValues.nodes | Where-Object { $_.field.name -eq "Status" }).name + fieldtext = ($draftIssue.fieldValues.nodes | Where-Object { $_.field.id -eq $($fieldtext.id) }).text fieldsingleselect = @{ - name = $fss.name - optionId = ($fss.field.options | where-object {$_.name -eq $fss.name}).Id + name = $fss.name + optionId = ($fss.field.options | where-object { $_.name -eq $fss.name }).Id } } @@ -102,8 +107,8 @@ function Get-Mock_Project_700 { $project.searchInTitle = @{} $project.searchInTitle.titleFilter = "development" $project.searchInTitle.Titles = $pActual.items.nodes.content.title | Where-Object { $_ -like "*development*" } - $project.searchInTitle.attributesDefault = @("Title","id") - $project.searchInTitle.attributes = @("Title","id","url","Status","field-text") + $project.searchInTitle.attributesDefault = @("Title", "id") + $project.searchInTitle.attributes = @("Title", "id", "url", "Status", "field-text") $project.searchInAnyField = @{} $project.searchInAnyField."development" = @{} @@ -115,7 +120,7 @@ function Get-Mock_Project_700 { "PullRequest for development" "Create comprehensive .NET Web API development initialization documentation with 10 structured tasks" "DraftIssue for development" - ) + ) $project.searchInAnyField."development".totalCount = $project.searchInAnyField."development".Titles.Count $project.searchInAnyField."96" = @{} @@ -143,9 +148,10 @@ function MockCall_GetProject_700 { $p = Get-Mock_Project_700 ; $owner = $p.owner ; $projectNumber = $p.number - if( $SkipItems ){ + if ( $SkipItems ) { $filename = $p.projectFile_skipitems - } else { + } + else { $filename = $p.projectFile } diff --git a/Test/public/project_item.test.ps1 b/Test/public/project_item.test.ps1 index f72f7f3..3a18623 100644 --- a/Test/public/project_item.test.ps1 +++ b/Test/public/project_item.test.ps1 @@ -49,6 +49,28 @@ function Test_GetProjectItem_SUCCESS{ Assert-AreEqual -Expected $newFieldTitleValue -Presented $result.$fieldTitle } +function Test_GetProjectItem_Comments{ + Reset-InvokeCommandMock + Mock_DatabaseRoot + $p = Get-Mock_Project_700 ; $Owner = $p.owner ; $projectNumber = $p.number + $i = $p.issue + $itemId = $i.id + + MockCall_GetProject $p -Cache + + #Act + $result = Get-ProjectItem -Owner $Owner -ProjectNumber $ProjectNumber -ItemId $itemId + + $c = $i.comments + Assert-Count -Expected $c.totalCount -Presented $result.comments + Assert-AreEqual -Expected $c.propertyCount -Presented $result.commentLast.Count + Assert-AreEqual -Expected $c.last.body -Presented $result.commentLast.body + Assert-AreEqual -Expected $c.last.author.login -Presented $result.commentLast.author + Assert-AreEqual -Expected $c.last.url -Presented $result.commentLast.url + Assert-AreEqual -Expected $c.last.createdAt -Presented $result.commentLast.createdAt + Assert-AreEqual -Expected $c.last.updatedAt -Presented $result.commentLast.updatedAt +} + function Test_EditProjetItems_SUCCESS{ Reset-InvokeCommandMock From 6f44f57f2eb13bd8ff0c16451b7e861afb45f9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Mon, 13 Oct 2025 00:15:39 +0200 Subject: [PATCH 4/4] feat(project-item): add last comment display to Show-ProjectItem function --- public/items/project_item_show.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/public/items/project_item_show.ps1 b/public/items/project_item_show.ps1 index 7f417e2..2590fc3 100644 --- a/public/items/project_item_show.ps1 +++ b/public/items/project_item_show.ps1 @@ -52,6 +52,19 @@ function Show-ProjectItem{ addJumpLine ; "--- Body ---" | write Cyan ; addJumpLine $item.body | write -Color Gray + addJumpLine + + # LastCommment + if($item.commentLast){ + $l = $item.commentLast + addJumpLine ; "--- Last Comment ---" | write Cyan ; addJumpLine + $l.author | write -Color DarkGray -PreFix "By: " ; addSpace + $l.updatedAt | write -Color DarkGray -PreFix "At: " + addJumpLine + + $item.commentLast.body | write -Color Gray + } + # End of item addJumpLine ; "------------" | write Cyan ; addJumpLine