From 0b0b8e996da76bc0b47adc9fc80cfce3c2f19ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 11 Dec 2025 16:52:31 +0100 Subject: [PATCH 1/4] fix(module.helper): fix missing newline at end of file in Get-ModuleFolder function --- helper/module.helper.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/module.helper.ps1 b/helper/module.helper.ps1 index 7fd1786..ff278b0 100644 --- a/helper/module.helper.ps1 +++ b/helper/module.helper.ps1 @@ -168,4 +168,4 @@ function Get-ModuleFolder{ } } return $moduleFolder -} Export-ModuleMember -Function Get-ModuleFolder +} \ No newline at end of file From 30fb5e46cc07cf34b7708f6a6eb86f9c5cd8e2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 11 Dec 2025 16:53:29 +0100 Subject: [PATCH 2/4] feat(import): add Import-HubbersListV2 and Build-HubbersTreeV2 functions with JSON parsing and tree structure generation --- Test/private/mocks/hubbersV2.json | 173 ++++++++++++++++++++++++++++++ Test/public/buildTreeV2.test.ps1 | 50 +++++++++ public/buildTreeV2.ps1 | 70 ++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 Test/private/mocks/hubbersV2.json create mode 100644 Test/public/buildTreeV2.test.ps1 create mode 100644 public/buildTreeV2.ps1 diff --git a/Test/private/mocks/hubbersV2.json b/Test/private/mocks/hubbersV2.json new file mode 100644 index 0000000..261b6c1 --- /dev/null +++ b/Test/private/mocks/hubbersV2.json @@ -0,0 +1,173 @@ +{ + "user3": { + "manager": "user0", + "employment_type": "employee", + "github_login": "user3", + "msft_alias": "user3MSFT", + "name": "Sarah Mitchell", + "email": "user3@github.com", + "title": "Chief Operating Officer", + "cost_center": "Strategic Operations", + "country": "United States of America", + "state": "Connecticut" + }, + "user1": { + "manager": "user0", + "employment_type": "employee", + "github_login": "user1", + "msft_alias": "user1MSFT", + "name": "Michael Johnson", + "email": "user1@github.com", + "title": "Chief Operating Officer", + "cost_center": "Strategic Operations", + "country": "United States of America", + "state": "Connecticut" + }, + "user2": { + "manager": "user0", + "employment_type": "microsoft_employee", + "github_login": "user2", + "msft_alias": "user2MSFT", + "name": "Jennifer Davis", + "email": "user2@github.com", + "title": "Chief Revenue Officer", + "cost_center": "Office of the CEO", + "country": "United States of America", + "state": "Maryland" + }, + "user0": { + "manager": "user0", + "employment_type": "microsoft_employee", + "github_login": "user0", + "msft_alias": "user0MSFT", + "name": "Robert Thompson", + "email": "user0@github.com", + "title": "CEO", + "cost_center": "Office of the CEO", + "country": "United States of America\"", + "state": "Washington" + }, + "user4": { + "manager": "user2", + "employment_type": "employee", + "github_login": "user4", + "msft_alias": "user4MSFT", + "name": "Amanda Rodriguez", + "email": "user4@github.com", + "title": "Chief Product Officer", + "cost_center": "Product Management", + "country": "United States of America", + "state": "North Carolina" + }, + "user5": { + "manager": "user1", + "employment_type": "microsoft_employee", + "github_login": "user5", + "msft_alias": "user5MSFT", + "name": "David Wilson", + "email": "user5@github.com", + "title": "VP, Advisor to the CEO", + "cost_center": "Office of the CEO", + "country": "United States of America" + }, + "user6": { + "manager": "user3", + "employment_type": "employee", + "github_login": "user6", + "msft_alias": "user6MSFT", + "name": "Lisa Anderson", + "email": "user6@github.com", + "title": "VP, COS to the CEO", + "cost_center": "Office of the CEO", + "country": "United States of America", + "state": "North Carolina" + }, + "user7": { + "manager": "user1", + "employment_type": "microsoft_employee", + "github_login": "user7", + "msft_alias": "user7MSFT", + "name": "Christopher Lee", + "email": "user7@github.com", + "title": "Chief Legal Officer", + "cost_center": "Legal", + "country": "United States of America" + }, + "user8": { + "manager": "user2", + "employment_type": "employee", + "github_login": "user8", + "msft_alias": "user8MSFT", + "name": "Michelle Brown", + "email": "user8@github.com", + "title": "CISO", + "cost_center": "Security", + "country": "United States of America", + "state": "Virginia" + }, + "user9": { + "manager": "user3", + "employment_type": "microsoft_employee", + "github_login": "user9", + "name": "Daniel Martinez", + "user9MSFT": "jayparikh@github.com", + "title": "CFO", + "cost_center": "user9 of the CEO", + "country": "United States of America" + }, + "user10": { + "manager": "user2", + "employment_type": "microsoft_employee", + "github_login": "user10", + "msft_alias": "user10MSFT", + "name": "Ashley Taylor", + "email": "user10@github.com", + "title": "Chief People Officer", + "cost_center": "Office of the CEO", + "country": "United States of America" + }, + "user11": { + "manager": "user1", + "employment_type": "microsoft_employee", + "github_login": "user11", + "msft_alias": "user11MSFT", + "name": "James Garcia", + "email": "user11h@github.com", + "title": "Chief Technology Officer", + "cost_center": "Office of the CEO", + "country": "United States of America" + }, + "user12": { + "manager": "user3", + "employment_type": "microsoft_employee", + "github_login": "user12", + "msft_alias": "user12MSFT", + "name": "Emily White", + "email": "user12@github.com", + "title": "Chief Financial Officer", + "cost_center": "Office of the CEO", + "country": "United States of America" + }, + "user13": { + "manager": "kk", + "employment_type": "microsoft_employee", + "github_login": "user13", + "msft_alias": "user13MSFT", + "name": "Emily White", + "email": "user13@github.com", + "title": "Chief Financial Officer", + "cost_center": "Office of the CEO", + "country": "United States of America" + }, + "user131": { + "manager": "user13", + "employment_type": "microsoft_employee", + "github_login": "user131", + "msft_alias": "user131MSFT", + "name": "Emily White", + "email": "user131@github.com", + "title": "Chief Financial Officer", + "cost_center": "Office of the CEO", + "country": "United States of America" + } +} \ No newline at end of file diff --git a/Test/public/buildTreeV2.test.ps1 b/Test/public/buildTreeV2.test.ps1 new file mode 100644 index 0000000..06e97a8 --- /dev/null +++ b/Test/public/buildTreeV2.test.ps1 @@ -0,0 +1,50 @@ +function Test_ImportHubbersListV2{ + + Reset-InvokeCommandMock + Mock_Database + + $filePath = Get-MockFileFullPath -fileName "hubbersV2.json" + + $result = Import-HubbersListV2 -Path $filePath + + Assert-AreEqual -Expected user0 -Presented $result.HubbersList.user12.manager.manager.github_login + + # total employeed + Assert-AreEqual -Expected 15 -Presented $result.totalHubbers + Assert-AreEqual -Expected 15 -Presented $result.HubbersList.count + + # tree structure + Assert-AreEqual -Expected 2 -Presented $result.HubbersTree.Count + Assert-Contains -Expected "user0" -Presented $result.HubbersTree.Keys + Assert-Contains -Expected "user13" -Presented $result.HubbersTree.Keys +} + +function Test_GetHubbersListV2{ + Reset-InvokeCommandMock + Mock_Database + + $filePath = Get-MockFileFullPath -fileName "hubbers.json" + + $result = Import-HubbersListV2 -Path $filePath + + $result = Get-HubbersList + + Assert-AreEqual -Expected user0 -Presented $result.user12.manager.manager.github_login +} + +function Test_GetHubbersTreeV2{ + Reset-InvokeCommandMock + Mock_Database + + $filePath = Get-MockFileFullPath -fileName "hubbers.json" + + $result = Import-HubbersListV2 -Path $filePath + + $result = Get-HubbersTree + + Assert-Count -Expected 1 -Presented $result.Count + Assert-AreEqual -Expected "user0" -Presented $result.Keys[0] + Assert-AreEqual -Expected user0 -Presented $result.user0.github_login + Assert-AreEqual -Expected user12 -Presented $result.user0.reports.user3.reports.user12.github_login +} + diff --git a/public/buildTreeV2.ps1 b/public/buildTreeV2.ps1 new file mode 100644 index 0000000..e9e720d --- /dev/null +++ b/public/buildTreeV2.ps1 @@ -0,0 +1,70 @@ + +function Import-HubbersListV2 { + [cmdletbinding()] + param ( + #path to hubber list + [Parameter(Mandatory, Position = 1)][string]$Path + ) + + try{ + $hubbersRawList = Get-Content $Path -Raw | ConvertFrom-Json -AsHashtable + } catch { + Write-Error -Message "Failed to read or parse JSON file: $_" + return $null + } + + # Calculate the tree + $result = Build-HubbersTreeV2 -Hubbers $hubbersRawList + + # Save to local cache + Save-HubbersListDb -Hubbers $result.HubbersList + Save-HubbersTreeDb -Hubbers $result.HubbersTree + + return $result + +} Export-ModuleMember -Function Import-HubbersListV2 + + +function Build-HubbersTreeV2 { + [cmdletbinding()] + param ( + [Parameter(mandatory)][hashtable]$Hubbers + ) + + $heads = @() + $tree = @{} + + # Find all the heads of the treed + $ceo = $hubbers.Values | Where-Object { $_.manager -eq $_.github_login } + + if($null -ne $ceo){ + $heads += $ceo + } + + $moreheads = $Hubbers.Keys | where-object { + # $h = $hubbersRawList.$_.github_login + $mh = $hubbers.$_.manager + + $null -eq $hubbers.$mh + } + + $heads += $moreheads | ForEach-Object { $hubbers.$_ } + + foreach($h in $heads){ + $hh = $h.github_login + Write-Host "" + Write-Host "Building tree for head: $hh" + $result = Build-Node $hubbers $h + + $tree.$hh = $result + } + + $global:ResultHubbersBuild = @{ + totalHubbers = $hubbers.count + "HubbersList" = $hubbers + "HubbersTree" = $tree + } + + return $global:ResultHubbersBuild + +} \ No newline at end of file From 1f38062e9a9fe49b0f7bff9ab9f184e9147cbb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 11 Dec 2025 17:55:35 +0100 Subject: [PATCH 3/4] feat(getHubberPath): add success test for Get-HubberPath function --- Test/public/gethubberpath.test.ps1 | 15 +++++++++++++++ public/gethubberpath.ps1 | 3 +++ 2 files changed, 18 insertions(+) create mode 100644 Test/public/gethubberpath.test.ps1 diff --git a/Test/public/gethubberpath.test.ps1 b/Test/public/gethubberpath.test.ps1 new file mode 100644 index 0000000..029e0cb --- /dev/null +++ b/Test/public/gethubberpath.test.ps1 @@ -0,0 +1,15 @@ +function Test_GetHubberPath_Success{ + + Reset-InvokeCommandMock + Mock_Database + $filePath = Get-MockFileFullPath -fileName "hubbers.json" + $result = Import-HubbersList -Path $filePath + + $result = Get-HubberPath -Handle "user4" + + Assert-Count -Expected 3 -Presented $result + + Assert-AreEqual -Expected "user4" -Presented $result[0].github_login + Assert-AreEqual -Expected "user2" -Presented $result[1].github_login + Assert-AreEqual -Expected "user0" -Presented $result[2].github_login +} \ No newline at end of file diff --git a/public/gethubberpath.ps1 b/public/gethubberpath.ps1 index 4d0bf3a..19c414a 100644 --- a/public/gethubberpath.ps1 +++ b/public/gethubberpath.ps1 @@ -18,6 +18,9 @@ function Get-HubberPath{ $h = $h.manager } + # Convert to PSCustomObject + $ret = $ret | ForEach-Object{ [pscustomobject]$_} + return $ret } Export-ModuleMember -Function Get-HubberPath \ No newline at end of file From 5ec07e3bd036987584989039b23222009981fe2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20=28Dibildos=29=20Gonz=C3=A1lez?= Date: Thu, 11 Dec 2025 17:55:41 +0100 Subject: [PATCH 4/4] refactor(searchhubber): convert hubbers to PSCustomObject for consistency --- public/searchhubber.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/searchhubber.ps1 b/public/searchhubber.ps1 index dc1d8c9..8352138 100644 --- a/public/searchhubber.ps1 +++ b/public/searchhubber.ps1 @@ -25,5 +25,8 @@ function Search-Hubber { $hubbers = $hubbers | Where-Object { $_.name -like "*$Name*" } } + # Convert to PSCustomObject + $hubbers = $hubbers | ForEach-Object{ [pscustomobject]$_} + return $hubbers } Export-ModuleMember -Function Search-Hubber \ No newline at end of file