Skip to content

Commit

Permalink
Adding -UseProjectId support (#281)
Browse files Browse the repository at this point in the history
* Adding -UseProjectId support
Sepearted related tests to seperate files.

* Changed mock to return object instead of hashtable.
  • Loading branch information
DarqueWarrior committed Mar 13, 2020
1 parent 90ad303 commit 8e28722
Show file tree
Hide file tree
Showing 13 changed files with 468 additions and 338 deletions.
2 changes: 2 additions & 0 deletions .docs/Invoke-VSTeamRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ Adds additional headers to the request
Type: Hashtable
```

<!-- #include "./params/useProjectId.md" -->

## INPUTS

### System.String
Expand Down
11 changes: 11 additions & 0 deletions .docs/params/useProjectId.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### -UseProjectId

Converts the project name to project id before building the URI for the REST API call.

```yaml
Type: SwitchParameter
Required: false
Position: Named
Accept pipeline input: false
Parameter Sets: (All)
```
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 6.4.7

_callAPI, _buildRequestURI and Invoke-VSTeamRequest now support UseProjectId switch if the Project ID is required for the API call.

## 6.4.6

Corrected a display issue were the List view was being used by default instead of Table.
Expand Down
24 changes: 15 additions & 9 deletions Source/Private/common.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ function _buildRequestURI {
[string]$id,
[string]$version,
[string]$subDomain,
[object]$queryString
[object]$queryString,
[switch]$UseProjectId
)
DynamicParam {
_buildProjectNameDynamicParam -Mandatory $false
Expand All @@ -92,7 +93,13 @@ function _buildRequestURI {
$sb.Append($(_addSubDomain -subDomain $subDomain -instance $(_getInstance))) | Out-Null

if ($ProjectName) {
$sb.Append("/$projectName") | Out-Null
if ($UseProjectId.IsPresent) {
$projectId = (Get-VSTeamProject -Name $ProjectName | Select-Object -ExpandProperty id)
$sb.Append("/$projectId") | Out-Null
}
else {
$sb.Append("/$projectName") | Out-Null
}
}

if ($team) {
Expand Down Expand Up @@ -514,7 +521,7 @@ function _buildDynamicParam {
)
# Create the collection of attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
<#
<#
.SYNOPSIS
Short description
Expand Down Expand Up @@ -612,7 +619,8 @@ function _callAPI {
[string]$Team,
[string]$Url,
[object]$QueryString,
[hashtable]$AdditionalHeaders
[hashtable]$AdditionalHeaders,
[switch]$UseProjectId
)

# If the caller did not provide a Url build it.
Expand Down Expand Up @@ -649,16 +657,14 @@ function _callAPI {
$params.Add('Headers', @{Authorization = "Basic $env:TEAM_PAT" })
}

if ($AdditionalHeaders -and $AdditionalHeaders.PSObject.Properties.name -match "Keys")
{
foreach ($key in $AdditionalHeaders.Keys)
{
if ($AdditionalHeaders -and $AdditionalHeaders.PSObject.Properties.name -match "Keys") {
foreach ($key in $AdditionalHeaders.Keys) {
$params['Headers'].Add($key, $AdditionalHeaders[$key])
}
}

# We have to remove any extra parameters not used by Invoke-RestMethod
$extra = 'Area', 'Resource', 'SubDomain', 'Id', 'Version', 'JSON', 'ProjectName', 'Team', 'Url', 'QueryString', 'AdditionalHeaders'
$extra = 'UseProjectId', 'Area', 'Resource', 'SubDomain', 'Id', 'Version', 'JSON', 'ProjectName', 'Team', 'Url', 'QueryString', 'AdditionalHeaders'
foreach ($e in $extra) { $params.Remove($e) | Out-Null }

try {
Expand Down
3 changes: 2 additions & 1 deletion Source/Public/Invoke-VSTeamRequest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ function Invoke-VSTeamRequest {
[switch]$JSON,
[string]$ContentType,
[string]$Url,
[hashtable]$AdditionalHeaders
[hashtable]$AdditionalHeaders,
[switch]$UseProjectId
)
DynamicParam {
_buildProjectNameDynamicParam -Mandatory $false
Expand Down
34 changes: 34 additions & 0 deletions unit/test/Get-VSTeamInfo.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Set-StrictMode -Version Latest

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")

. "$here/../../Source/Classes/VSTeamVersions.ps1"
. "$here/../../Source/Classes/VSTeamProjectCache.ps1"
. "$here/../../Source/Private/common.ps1"
. "$here/../../Source/Public/$sut"

Describe 'Get-VSTeamInfo' {
# Mock the call to Get-Projects by the dynamic parameter for ProjectName
Mock Invoke-RestMethod { return @() } -ParameterFilter {
$Uri -like "*_apis/projects*"
}

. "$PSScriptRoot\mocks\mockProjectDynamicParamMandatoryFalse.ps1"

Context 'Get-VSTeamInfo' {
AfterAll {
$Global:PSDefaultParameterValues.Remove("*:projectName")
}

It 'should return account and default project' {
[VSTeamVersions]::Account = "mydemos"
$Global:PSDefaultParameterValues['*:projectName'] = 'TestProject'

$info = Get-VSTeamInfo

$info.Account | Should Be "mydemos"
$info.DefaultProject | Should Be "TestProject"
}
}
}
44 changes: 44 additions & 0 deletions unit/test/Get-VSTeamOption.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Set-StrictMode -Version Latest

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")

. "$here/../../Source/Classes/VSTeamVersions.ps1"
. "$here/../../Source/Classes/VSTeamProjectCache.ps1"
. "$here/../../Source/Private/common.ps1"
. "$here/../../Source/Private/applyTypes.ps1"
. "$here/../../Source/Public/$sut"

Describe 'Get-VSTeamOption' {
Context 'Get-VSTeamOption' {
# Set the account to use for testing. A normal user would do this
# using the Set-VSTeamAccount function.
Mock _getInstance { return 'https://dev.azure.com/test' } -Verifiable

Mock Invoke-RestMethod { return @{
count = 1
value = @(
@{
id = '5e8a8081-3851-4626-b677-9891cc04102e'
area = 'git'
resourceName = 'annotatedTags'
}
)
}
}

It 'Should return all options' {
Get-VSTeamOption | Should Not Be $null
Assert-MockCalled Invoke-RestMethod -ParameterFilter {
$Uri -eq "https://dev.azure.com/test/_apis"
}
}

It 'Should return release options' {
Get-VSTeamOption -subDomain vsrm | Should Not Be $null
Assert-MockCalled Invoke-RestMethod -ParameterFilter {
$Uri -eq "https://vsrm.dev.azure.com/test/_apis"
}
}
}
}
25 changes: 25 additions & 0 deletions unit/test/Get-VSTeamResourceArea.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Set-StrictMode -Version Latest

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")

. "$here/../../Source/Classes/VSTeamVersions.ps1"
. "$here/../../Source/Classes/VSTeamProjectCache.ps1"
. "$here/../../Source/Private/common.ps1"
. "$here/../../Source/Private/applyTypes.ps1"
. "$here/../../Source/Public/$sut"

Describe 'Get-VSTeamResourceArea' {
Context 'Get-VSTeamResourceArea' {
Mock _callAPI { return @{
value = @{ }
}
}

$actual = Get-VSTeamResourceArea

It 'Should return resources' {
$actual | Should Not Be $null
}
}
}
77 changes: 77 additions & 0 deletions unit/test/Invoke-VSTeamRequest.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Set-StrictMode -Version Latest

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")

. "$here/../../Source/Classes/VSTeamVersions.ps1"
. "$here/../../Source/Classes/VSTeamProjectCache.ps1"
. "$here/../../Source/Private/common.ps1"
. "$here/../../Source/Public/$sut"

Describe 'Invoke-VSTeamRequest' {
# Mock the call to Get-Projects by the dynamic parameter for ProjectName
Mock Invoke-RestMethod {
return @()
} -ParameterFilter {
$Uri -like "*_apis/projects*"
}

Mock Write-Host

Context 'Invoke-VSTeamRequest Options' {
Mock _getInstance { return 'https://dev.azure.com/test' } -Verifiable
Mock Invoke-RestMethod {
# Write-Host $args
}

Invoke-VSTeamRequest -Method Options

It 'Should call API' {
Assert-VerifiableMock
}
}

Context 'Invoke-VSTeamRequest Release' {
Mock _getInstance { return 'https://dev.azure.com/test' } -Verifiable
Mock Invoke-RestMethod {
# Write-Host $args
} -Verifiable

Invoke-VSTeamRequest -Area release -Resource releases -Id 1 -SubDomain vsrm -Version '4.1-preview' -ProjectName testproject -JSON

It 'Should call API' {
Assert-VerifiableMock
}
}

Context 'Invoke-VSTeamRequest AdditionalHeaders' {
Mock _getInstance { return 'https://dev.azure.com/test' } -Verifiable
Mock Invoke-RestMethod { return @() } -Verifiable -ParameterFilter {
$Headers["Test"] -eq 'Test'
}

Invoke-VSTeamRequest -Area release -Resource releases -Id 1 -SubDomain vsrm -Version '4.1-preview' -ProjectName testproject -JSON -AdditionalHeaders @{Test = "Test" }

It 'Should call API' {
Assert-VerifiableMock
}
}

Context 'Invoke-VSTeamRequest By Product ID' {
# Called to convert from ProjectName to ProjectID
Mock Get-VSTeamProject {
return [PSCustomObject]@{
id = '00000000-0000-0000-0000-000000000000'
} } -Verifiable
Mock _getInstance { return 'https://dev.azure.com/test' } -Verifiable
Mock Invoke-RestMethod { return @() } -Verifiable -ParameterFilter {
$Uri -like "*https://vsrm.dev.azure.com/test/00000000-0000-0000-0000-000000000000*"
}

Invoke-VSTeamRequest -ProjectName testproject -UseProjectId -Area release -Resource releases -Id 1 -SubDomain vsrm -Version '4.1-preview'

It 'Should call API' {
Assert-VerifiableMock
}
}
}

0 comments on commit 8e28722

Please sign in to comment.