Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Test/private/MockCall_Project700.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function Get-Mock_Project_700 {
$project.title = $pActual.title
$project.number = $pActual.number
$project.url = $pActual.url
$project.cacheFileName = "$($pActual.owner.login)_$($pActual.number).json"
$project.cacheFileName = "db-$($pActual.owner.login)-$($pActual.number)-project.json"

# Fields info
$project.fields = @{}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{
"data": {
"node": {
"id": "PVTI_lADOAlIw4c4BCe3Vzgeio4o",
"type": "ISSUE",
"fullDatabaseId": "128099210",
"project": {
"id": "PVT_kwDOAlIw4c4BCe3V",
"url": "https://github.com/orgs/octodemo/projects/700"
},
"content": {
"__typename": "Issue",
"id": "I_kwDOPrRnkc7KkwSq",
"body": "Body of issue for development",
"title": "[RULaSG-DeV-1] Issue [RULASG-DEV-1] for [value between] development",
"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": {
"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": {
"nodes": [
{
"__typename": "ProjectV2ItemFieldRepositoryValue",
"repository": {
"url": "https://github.com/octodemo/rulasg-dev-1"
},
"field": {
"__typename": "ProjectV2Field",
"id": "PVTF_lADOAlIw4c4BCe3Vzg0rg-k",
"name": "Repository",
"dataType": "REPOSITORY"
}
},
{
"__typename": "ProjectV2ItemFieldMilestoneValue",
"milestone": {
"title": "Milestone 3: Quality and Deployment",
"description": "Testing, documentation, and deployment pipeline setup",
"dueOn": "2025-10-18T00:00:00Z"
},
"field": {
"__typename": "ProjectV2Field",
"id": "PVTF_lADOAlIw4c4BCe3Vzg0rg-g",
"name": "Milestone",
"dataType": "MILESTONE"
}
},
{
"__typename": "ProjectV2ItemFieldTextValue",
"text": "[RULaSG-DeV-1] Issue [RULASG-DEV-1] for [value between] development",
"field": {
"__typename": "ProjectV2Field",
"id": "PVTF_lADOAlIw4c4BCe3Vzg0rg-M",
"name": "Title",
"dataType": "TITLE"
}
},
{
"__typename": "ProjectV2ItemFieldSingleSelectValue",
"name": "In Progress",
"field": {
"__typename": "ProjectV2SingleSelectField",
"id": "PVTSSF_lADOAlIw4c4BCe3Vzg0rg-U",
"name": "Status",
"dataType": "SINGLE_SELECT",
"options": [
{
"id": "f75ad846",
"name": "Todo"
},
{
"id": "47fc9ee4",
"name": "In Progress"
},
{
"id": "98236657",
"name": "Done"
}
]
}
},
{
"__typename": "ProjectV2ItemFieldNumberValue",
"number": 333.0,
"field": {
"__typename": "ProjectV2Field",
"id": "PVTF_lADOAlIw4c4BCe3Vzg0rhjU",
"name": "field-number",
"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",
"field": {
"__typename": "ProjectV2Field",
"id": "PVTF_lADOAlIw4c4BCe3Vzg0rhko",
"name": "field-text",
"dataType": "TEXT"
}
},
{
"__typename": "ProjectV2ItemFieldSingleSelectValue",
"name": "option-3",
"field": {
"__typename": "ProjectV2SingleSelectField",
"id": "PVTSSF_lADOAlIw4c4BCe3Vzg0rhno",
"name": "field-singleselect",
"dataType": "SINGLE_SELECT",
"options": [
{
"id": "7d96a925",
"name": "option-1"
},
{
"id": "cd02c585",
"name": "option-2"
},
{
"id": "6b66c93a",
"name": "option-3"
}
]
}
}
]
}
}
}
}
51 changes: 51 additions & 0 deletions Test/public/items/edit_project_item.test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,57 @@ function Test_EditProjectItems_NormalizeTitle{
Assert-AreEqual -Expected $newTitle -Presented $result.$itemId.title.Value
}

function Test_EditProjectItems_NormalizeTitle_AlreadyNormalized{

# Arrange
$p = Get-Mock_Project_700 ; $Owner = $p.owner ; $ProjectNumber = $p.number
MockCall_GetProject $p -skipItems
$i= $p.issue ; $itemId = $i.id

MockCall_GetProject $p -SkipItems

$newTitle = "[rulasg-dev-1] Issue [rulasg-dev-1] for [value between] development"

# Mock the direct call for item
MockCallJson -Command "Invoke-GetItem -itemid $itemId" -FileName "invoke-getitem-$itemId-Normalized.json"
# Act
Edit-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $itemId -NormalizeTitle

# Assert
$result = Get-ProjectItemStaged -Owner $owner -ProjectNumber $projectNumber

Assert-Count -Expected 1 -Presented $result.$itemId.Keys
Assert-AreEqual -Expected $newTitle -Presented $result.$itemId.title.Value
}

function Test_NormalizedTitle{

Invoke-PrivateContext{
$cases = @(
@{item = @{Title= "Test"; repositoryName = "rulasg-dev-1"}; expected = "[rulasg-dev-1] Test"}
@{item = @{Title= "[rulasg-dev-1] Test"; repositoryName = "rulasg-dev-1"}; expected = "[rulasg-dev-1] Test"}

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
@{item = @{Title= "[BBVA] Test"; repositoryName = "bBva"}; expected = "[bBva] Test"}

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
@{item = @{Title= "Test [rulasg-dev-1]"; repositoryName = "rulasg-dev-1"}; expected = "Test [rulasg-dev-1]"}

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
@{item = @{Title= "Test [rulasg-dEv-1]"; repositoryName = "rulasg-dev-1"}; expected = "Test [rulasg-dev-1]"}

@{item = @{Title= "[RULaSG-DeV-1] Test"; repositoryName = "rulasg-dev-1"}; expected = "[rulasg-dev-1] Test"}
@{item = @{Title= "[RULaSG-DeV-1] Test [value between] development"; repositoryName = "rulasg-dev-1"}; `
expected = "[rulasg-dev-1] Test [value between] development"}
@{item = @{Title= "[RULaSG-DeV-1] Issue [RULASG-DEV-1] for [value between] development"; repositoryName = "rulasg-dev-1"}; `
expected = "[rulasg-dev-1] Issue [rulasg-dev-1] for [value between] development"}
)

foreach($case in $cases){
$result = Get-NormalizedTitle -Item $case.item
Assert-AreEqual -Expected $case.expected -Presented $result
}

}
}

function Test_EditProjectItems_OpenInBrowser{

# Arrange
Expand Down
23 changes: 23 additions & 0 deletions private/database/databaseV2.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,29 @@ function Save-Database {
$Database | ConvertTo-Json -Depth 10 | Set-Content $path
}

function Get-DatabaseKey{
[CmdletBinding()]
param(
[Parameter(Position = 0)][string]$Owner,
[Parameter(Position = 1)][int]$ProjectNumber,
[Parameter(Position = 2)][string] $Category
)

if([string]::IsNullOrWhiteSpace($Owner)){
throw "Owner is null or empty"
}
if($ProjectNumber -le 0){
throw "ProjectNumber is null or not a positive integer"
}
if([string]::IsNullOrWhiteSpace($Category)){
throw "Category is null or empty"
}

$ret = "db-{0}-{1}-{2}" -f $Owner, $ProjectNumber, $Category

return $ret
}

function Get-DatabaseFile {
[CmdletBinding()]
param(
Expand Down
23 changes: 7 additions & 16 deletions private/projectDatabase/project_database.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function Test-ProjectDatabase{
[Parameter(Position = 1)][int]$ProjectNumber
)

$key = Get-DatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$key = Get-ProjectDatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber

$ret = Test-Database -Key $key

Expand All @@ -21,7 +21,7 @@ function Test-ProjectDatabaseStaged{
[Parameter(Position = 1)][int]$ProjectNumber
)

$key = Get-DatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$key = Get-ProjectDatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$prj = Get-Database -Key $key

if($null -eq $prj){
Expand All @@ -46,7 +46,7 @@ function Get-ProjectFromDatabase{
[Parameter(Position = 1)][int]$ProjectNumber
)

$key = Get-DatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$key = Get-ProjectDatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$prj = Get-Database -Key $key

if($null -eq $prj){
Expand All @@ -67,7 +67,7 @@ function Reset-ProjectDatabase{
[Parameter(Position = 1)][int]$ProjectNumber
)

$dbKey = Get-DatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
$dbKey = Get-ProjectDatabaseKey -Owner $Owner -ProjectNumber $ProjectNumber
Reset-Database -Key $dbKey
}

Expand Down Expand Up @@ -139,7 +139,7 @@ function Save-ProjectDatabase{
throw "Database.number is null or not a positive integer"
}

$dbkey = Get-DatabaseKey -Owner $owner -ProjectNumber $projectnumber
$dbkey = Get-ProjectDatabaseKey -Owner $owner -ProjectNumber $projectnumber

if($Safe){
$oldDatabase = Get-Database -Key $dbkey
Expand All @@ -156,21 +156,12 @@ function Save-ProjectDatabase{
Save-Database -Key $dbkey -Database $Database
}

function Get-DatabaseKey{
function Get-ProjectDatabaseKey{
[CmdletBinding()]
param(
[Parameter(Position = 0)][string]$Owner,
[Parameter(Position = 1)][int]$ProjectNumber
)

if([string]::IsNullOrWhiteSpace($Owner)){
throw "Owner is null or empty"
}
if($ProjectNumber -le 0){
throw "ProjectNumber is null or not a positive integer"
}

$ret = "$($owner)_$($projectnumber)"

return $ret
return Get-DatabaseKey $Owner $ProjectNumber "project"
}
24 changes: 21 additions & 3 deletions public/fields/project_fields_list.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,17 @@ function getFieldsCache{
)

$key = "$Owner-$ProjectNumber"
$ret = $script:fieldsCache[$key]
$lockKey = Get-DatabaseKey $Owner $ProjectNumber "field-cachelock"

return $ret
$lock = Get-Database -Key $lockKey
$cache = $script:fieldsCache[$key]

if($lock -cne $cache.SafeId) {
$script:fieldsCache.Remove($key)
return $null
}

return $cache.List
}

function setFieldsCache{
Expand All @@ -132,5 +139,16 @@ function setFieldsCache{
)

$key = "$Owner-$ProjectNumber"
$script:fieldsCache[$key] = $FieldList
$lockKey = Get-DatabaseKey $Owner $ProjectNumber "field-cachelock"

$safeId = [Guid]::NewGuid().ToString()

# Save safeId to field-lock
Save-Database -Database $safeId -Key $lockKey

# Set lock in database to prevent concurrent updates
$script:fieldsCache[$key] = @{
List = $FieldList
SafeId = $safeId
}
}
Loading
Loading