diff --git a/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json b/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json index 80374ec..5385d6a 100644 --- a/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json +++ b/Test/private/mocks/invoke-GitHubOrgProjectWithFields-octodemo-700.json @@ -4019,7 +4019,7 @@ "id": "I_kwDOPrRnkc7KkwSq", "body": "Body of issue for development", "title": "Issue for development", - "updatedAt": "2025-09-30T05:42:49Z", + "updatedAt": "2025-10-15T21:30:02Z", "createdAt": "2025-09-09T14:01:17Z", "number": 26, "url": "https://github.com/octodemo/rulasg-dev-1/issues/26", @@ -4035,9 +4035,9 @@ "nodes": [ { "createdAt": "2025-09-23T17:51:06Z", - "updatedAt": "2025-09-23T17:51:06Z", + "updatedAt": "2025-10-15T21:29:45Z", "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3324995787", - "body": "sample comment 1", + "body": "Sample comment 1", "fullDatabaseId": "3324995787", "author": { "login": "rulasg" @@ -4045,9 +4045,9 @@ }, { "createdAt": "2025-09-24T08:29:13Z", - "updatedAt": "2025-09-24T08:29:13Z", + "updatedAt": "2025-10-15T21:29:55Z", "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3327194303", - "body": "commetn added", + "body": "Sample comment 2", "fullDatabaseId": "3327194303", "author": { "login": "rulasg" @@ -4055,9 +4055,9 @@ }, { "createdAt": "2025-09-30T05:42:49Z", - "updatedAt": "2025-09-30T05:42:49Z", + "updatedAt": "2025-10-15T21:30:02Z", "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3350059109", - "body": "New comment", + "body": "Sample comment 3", "fullDatabaseId": "3350059109", "author": { "login": "rulasg" diff --git a/Test/private/mocks/invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeio4o.json b/Test/private/mocks/invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeio4o.json index e1aaf27..01f63b3 100644 --- a/Test/private/mocks/invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeio4o.json +++ b/Test/private/mocks/invoke-getitem-PVTI_lADOAlIw4c4BCe3Vzgeio4o.json @@ -13,13 +13,51 @@ "id": "I_kwDOPrRnkc7KkwSq", "body": "Body of issue for development", "title": "Issue for development", - "updatedAt": "2025-09-11T13:06:24Z", + "updatedAt": "2025-10-15T21:30:02Z", "createdAt": "2025-09-09T14:01:17Z", "number": 26, "url": "https://github.com/octodemo/rulasg-dev-1/issues/26", "state": "OPEN", "repository": { - "nameWithOwner": "octodemo/rulasg-dev-1" + "name": "rulasg-dev-1", + "owner": { + "login": "octodemo" + } + }, + "comments": { + "totalCount": 3, + "nodes": [ + { + "createdAt": "2025-09-23T17:51:06Z", + "updatedAt": "2025-10-15T21:29:45Z", + "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-10-15T21:29:55Z", + "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3327194303", + "body": "Sample comment 2", + "fullDatabaseId": "3327194303", + "author": { + "login": "rulasg" + } + }, + { + "createdAt": "2025-09-30T05:42:49Z", + "updatedAt": "2025-10-15T21:30:02Z", + "url": "https://github.com/octodemo/rulasg-dev-1/issues/26#issuecomment-3350059109", + "body": "Sample comment 3", + "fullDatabaseId": "3350059109", + "author": { + "login": "rulasg" + } + } + ] } }, "fieldValues": { @@ -94,6 +132,18 @@ "dataType": "NUMBER" } }, + { + "__typename": "ProjectV2ItemFieldIterationValue", + "title": "field-iteration 3", + "startDate": "2025-10-05", + "duration": 14, + "field": { + "__typename": "ProjectV2IterationField", + "id": "PVTIF_lADOAlIw4c4BCe3Vzg0rhqQ", + "name": "field-iteration", + "dataType": "ITERATION" + } + }, { "__typename": "ProjectV2ItemFieldTextValue", "text": "text3", @@ -127,18 +177,6 @@ } ] } - }, - { - "__typename": "ProjectV2ItemFieldIterationValue", - "title": "field-iteration 3", - "startDate": "2025-10-05", - "duration": 14, - "field": { - "__typename": "ProjectV2IterationField", - "id": "PVTIF_lADOAlIw4c4BCe3Vzg0rhqQ", - "name": "field-iteration", - "dataType": "ITERATION" - } } ] } diff --git a/Test/public/edit-sync-projectitem-comments.test.ps1 b/Test/public/edit-sync-projectitem-comments.test.ps1 index e90b757..e3a556b 100644 --- a/Test/public/edit-sync-projectitem-comments.test.ps1 +++ b/Test/public/edit-sync-projectitem-comments.test.ps1 @@ -6,23 +6,52 @@ function Test_Edit_Sync_ProjectItem_AddComments_Issue { $p = Get-Mock_Project_700 ; $owner = $p.owner ; $projectNumber = $p.number $i = $p.issue - $comment = "New comment" + $comment = "New comment" + $comment2 = "Another comment2" - MockCall_GetProject -MockProject $p -skipItems - MockCall_GetItem $i.id + + MockCall_GetProject -MockProject $p -SkipItems + MockCall_GetItem $i.id MockCallJson -Command "Invoke-AddComment -SubjectId $($i.contentId) -Comment ""New comment""" -filename "invoke-addcomment-$($i.contentId).json" + MockCallJson -Command "Invoke-AddComment -SubjectId $($i.contentId) -Comment ""Another comment2""" -filename "invoke-addcomment-$($i.contentId).json" + + # Check the status of comments + # $i = Get-projectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id + # Act the edit part Edit-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id -FieldName "AddComment" -Value $comment - + # Assert the Edit part $staged = Get-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber Assert-AreEqual -Expected $comment -Presented $staged.$($i.id).addcomment.Value + # Confirm that staged values are merged on GetItem + $item = Get-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id + Assert-AreEqual -Expected $comment -Presented $item.comments[-1].body + Assert-AreEqual -Expected $comment -Presented $item.commentLast.body + # Act the sync part Sync-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber $staged = Get-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber Assert-Count -Expected 0 -Presented $staged.Count + + # Assert comment is commited to database + $item = Get-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id + Assert-AreEqual -Expected $comment -Presented $item.comments[-1].body + Assert-AreEqual -Expected $comment -Presented $item.commentLast.body + + # Act more comments on a item with already has comments + Edit-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id -FieldName "AddComment" -Value $comment2 + + $item = Get-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id + + Sync-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber + $staged = Get-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber + Assert-Count -Expected 0 -Presented $staged.Count + $item = Get-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $i.id + Assert-AreEqual -Expected $comment2 -Presented $item.comments[-1].body + Assert-AreEqual -Expected $comment2 -Presented $item.commentLast.body } \ No newline at end of file diff --git a/Test/public/issues/Add-IssuePullRequestComment.test.ps1 b/Test/public/issues/Add-IssuePullRequestComment.test.ps1 index bbc9ae6..903150b 100644 --- a/Test/public/issues/Add-IssuePullRequestComment.test.ps1 +++ b/Test/public/issues/Add-IssuePullRequestComment.test.ps1 @@ -8,7 +8,8 @@ function Test_AddComment_SUCCESS_Using_Cache{ $contentId = $i.contentId $comment = "sample comment 1" - MockCall_GetProject_700 + MockCall_GetProject -MockProject $p -SkipItems + MockCall_GetItem -ItemId $i.id Set-ProjectHelperEnvironment -Owner $owner -ProjectNumber $projectNumber -DisplayFields @("Status","FieldText") diff --git a/Test/public/project_item.test.ps1 b/Test/public/project_item.test.ps1 index 77d70eb..a71c356 100644 --- a/Test/public/project_item.test.ps1 +++ b/Test/public/project_item.test.ps1 @@ -16,7 +16,10 @@ function Test_GetProjectItem_SUCCESS{ $itemFieldCommentValue = $projectFieldCommentValue + " updated" # allow get project - MockCall_GetProject_700 + MockCall_GetProject -MockProject $p -cache + MockCall_GetProject -MockProject $p -SkipItems + + MockCall_GetItem -ItemId $itemId # Even if id is in project we make a direct call when with Force MockCallJson -Command "Invoke-GetItem -itemid $itemId" -FileName "invoke-getitem-$itemId-updated.json" @@ -256,11 +259,12 @@ function Test_ShowProjectItem_SUCCESS{ Reset-InvokeCommandMock Mock_DatabaseRoot - MockCall_GetProject_700 - $p = Get-Mock_Project_700; $Owner = "octodemo" ; $ProjectNumber = 700 - $i = $p.issue + + MockCall_GetProject -MockProject $p -SkipItems + MockCall_GetItem -ItemId $i.id + $id = $i.Id $title = $i.title $status = $i.status diff --git a/private/projectDatabase/project_database_Item.ps1 b/private/projectDatabase/project_database_Item.ps1 index 05861c9..e6c5342 100644 --- a/private/projectDatabase/project_database_Item.ps1 +++ b/private/projectDatabase/project_database_Item.ps1 @@ -14,8 +14,19 @@ function Get-Item{ # Check if is staged if($database.Staged.$ItemId){ + + # Update ret with all staged fields values foreach($fieldKey in $database.Staged.$ItemId.keys){ + + $value = $database.Staged.$ItemId.$fieldKey.Value + + if($fieldKey -eq "AddComment"){ + Set-LastComment -Database $database -Item $ret -comment $value + continue + } + + # Get fieldname $fieldname = $database.Staged.$ItemId.$fieldKey.Field.name # Make type conversions to string $ret.$fieldname = $database.Staged.$ItemId.$fieldKey.Value @@ -36,6 +47,29 @@ function Get-Item{ } } +function Set-LastComment{ + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Position = 0)][object[]]$Database, + [Parameter(ValueFromPipeline, Position = 1)][hashtable]$Item, + [Parameter()][string]$comment + ) + + $commentobj = @{ + body = $comment + } + + # init comments array if needed + if($null -eq $Item.comments){ + $Item.comments = @() + } + + # Update commentLast field + $Item.commentLast = $commentobj + $Item.comments += $commentobj +} + function Find-Item { [CmdletBinding()] param( @@ -117,6 +151,11 @@ function Set-ItemValue{ $item = $db | AddHashLink items | AddHashLink $ItemId + # Special case for comments + if($FieldName -eq "AddComment"){ + Set-LastComment -Database $db -Item $item -comment $Value + } + $item.$FieldName = $Value } @@ -148,6 +187,26 @@ function Get-ItemStaged{ } } +function Remove-ItemStaged{ + [CmdletBinding()] + param( + [Parameter(Position = 0)][object]$Database, + [Parameter(Position = 1)][string]$ItemId, + [Parameter(Position = 2)][string]$FieldId + ) + + $db = $Database + + if ($db.Staged.$ItemId.$FieldId) { + $db.Staged.$ItemId.Remove($FieldId) + } + + # If no more fields in item remove item + if ($db.Staged.$ItemId.Count -eq 0) { + $db.Staged.Remove($ItemId) + } +} + <# .SYNOPSIS Stage a change to the database diff --git a/private/projectDatabase/project_database_Sync.ps1 b/private/projectDatabase/project_database_Sync.ps1 index 4ee983f..7c0a146 100644 --- a/private/projectDatabase/project_database_Sync.ps1 +++ b/private/projectDatabase/project_database_Sync.ps1 @@ -84,24 +84,4 @@ function Sync-Project{ } return $db -} - -function Remove-ItemStaged{ - [CmdletBinding()] - param( - [Parameter(Position = 0)][object]$Database, - [Parameter(Position = 1)][string]$ItemId, - [Parameter(Position = 2)][string]$FieldId - ) - - $db = $Database - - if ($db.Staged.$ItemId.$FieldId) { - $db.Staged.$ItemId.Remove($FieldId) - } - - # If no more fields in item remove item - if ($db.Staged.$ItemId.Count -eq 0) { - $db.Staged.Remove($ItemId) - } } \ No newline at end of file diff --git a/public/items/project_item.ps1 b/public/items/project_item.ps1 index cd2fc2b..a97b882 100644 --- a/public/items/project_item.ps1 +++ b/public/items/project_item.ps1 @@ -24,9 +24,7 @@ function Get-ProjectItem { ($Owner, $ProjectNumber) = Get-OwnerAndProjectNumber -Owner $Owner -ProjectNumber $ProjectNumber if ([string]::IsNullOrWhiteSpace($owner) -or [string]::IsNullOrWhiteSpace($ProjectNumber)) { "Owner and ProjectNumber are required" | Write-MyError; return $null } - - # Get Item from Project database - $db = Get-Project -Owner $Owner -ProjectNumber $ProjectNumber + $db = Get-Project -Owner $Owner -ProjectNumber $ProjectNumber -SkipItems if(! $db){ "Project not found for Owner [$Owner] and ProjectNumber [$ProjectNumber]" | Write-MyError; return $null}