Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Get-SatisfactionRating & New-SatisfactionRating +semver: feature #37

Merged
merged 1 commit into from
Mar 30, 2020
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: 2 additions & 0 deletions PwshZendesk.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
'Get-OrganizationMembership', 'Get-ZendeskOrganizationMembership'
'Get-OrganizationRelated', 'Get-ZendeskOrganizationRelated'
'Get-Problem', 'Get-ZendeskProblem'
'Get-SatisfactionRating', 'Get-ZendeskSatisfactionRating'
'Get-SearchCount', 'Get-ZendeskSearchCount'
'Get-SharingAgreement', 'Get-ZendeskSharingAgreement'
'Get-SuspendedTicket', 'Get-ZendeskSuspendedTicket'
Expand All @@ -119,6 +120,7 @@
'New-GroupMembership', 'New-ZendeskGroupMembership'
'New-Organization', 'New-ZendeskOrganization'
'New-OrganizationMembership', 'New-ZendeskOrganizationMembership'
'New-SatisfactionRating', 'New-ZendeskSatisfactionRating'
'New-SharingAgreement', 'New-ZendeskSharingAgreement'
'New-Ticket', 'New-ZendeskTicket'
'New-UserIdentity', 'New-ZendeskUserIdentity'
Expand Down
102 changes: 102 additions & 0 deletions functions/Get-SatisfactionRating.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
function Get-SatisfactionRating {
<#
.SYNOPSIS
Retrieves Satisfaction Ratings
.DESCRIPTION
Retrieves Satisfaction Ratings
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating

Retrieves all satisfaction ratings
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -Id 1

Retrieves satisfaction rating with id 1
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -Score 'good_with_comment'

Retrieves all good satisfaction ratings that include a comment
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -Score 'good'

Retrieves all good satisfaction ratings regardless of whether a comment was included
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -Score 'received'

Retrieves all satisfaction ratings that have been received whether the rating is good or bad.
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -Score 'offered'

Retrieves all satisfaction ratings that have been offered but not responded to.
.EXAMPLE
PS C:\> Get-ZendeskSatisfactionRating -StartTime [DateTime]::Now.AddHours(-1)
mderriey marked this conversation as resolved.
Show resolved Hide resolved

Retrieves all satisfaction ratings from the past hour.
.NOTES
If you specify an unqualified score such as good, the results include all the records with and without comments.
#>
[CmdletBinding(DefaultParameterSetName = 'Filter')]
Param (
# Unique Id of the satisfaction rating to retrieve
[Parameter(Mandatory = $false,
ParameterSetName = 'Id')]
[ValidateRange(1, [Int64]::MaxValue)]
[Int64]
$Id,

# Parameter help description
[Parameter(Mandatory = $false,
ParameterSetName = 'Filter')]
[ValidateSet('offered', 'unoffered',
'received', 'received_with_comment', 'received_without_comment',
'good', 'good_with_comment', 'good_without_comment',
'bad', 'bad_with_comment', 'bad_without_comment')]
[String]
$Score,

# Time of the oldest satisfaction rating, as a Unix epoch time
[Parameter(Mandatory = $false,
ParameterSetName = 'Filter')]
[DateTimeOffset]
$StartTime,

# Time of the most recent satisfaction rating, as a Unix epoch time
[Parameter(Mandatory = $false,
ParameterSetName = 'Filter')]
[DateTimeOffset]
$EndTime,

# Zendesk Connection Context from `Get-ZendeskConnection`
[Parameter(Mandatory = $false)]
[PSTypeName('ZendeskContext')]
[PSCustomObject]
$Context = $null
)

Assert-IsAdmin -Context $Context

if ($PSBoundParameters.ContainsKey('Id')) {
$path = "/api/v2/satisfaction_ratings/$Id.json"
$key = 'satisfaction_rating'
} else {
$path = '/api/v2/satisfaction_ratings.json'
$key = 'satisfaction_ratings'
}

$parameters = @()
if ($PSBoundParameters.ContainsKey('Score')) {
$parameters += "score=$Score"
}
if ($PSBoundParameters.ContainsKey('StartTime')) {
$parameters += 'start_time={0}' -f $StartTime.ToUnixTimeSeconds()
}
if ($PSBoundParameters.ContainsKey('EndTime')) {
$parameters += 'end_time={0}' -f $EndTime.ToUnixTimeSeconds()
}
if ($parameters.Count -gt 0) {
$path += '?' + $parameters -join '&'
}

$result = Invoke-Method -Context $Context -Path $path -Verbose:$VerbosePreference
$result | Select-Object -Expand $key
}
75 changes: 75 additions & 0 deletions functions/New-SatisfactionRating.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function New-SatisfactionRating {
<#
.SYNOPSIS
Creates a CSAT rating for a solved ticket, or for a ticket that was previously solved and then reopened.
.DESCRIPTION
Creates a CSAT rating for a solved ticket, or for a ticket that was previously solved and then reopened.
.EXAMPLE
PS C:\> New-ZendeskSatisfactionRating -TicketId 1 -Score 'good'

Creates a good satisfaction rating for ticket with id 1
.EXAMPLE
PS C:\> New-ZendeskSatisfactionRating -TicketId 1 -Score 'good' -Comment 'fast'

Creates a good satisfaction rating for ticket with id 1 including a comment.
.EXAMPLE
PS C:\> New-ZendeskSatisfactionRating -TicketId 1 -Score 'bad' -ReasonCode 5

Creates a bad satisfaction rating for ticket with id 1 including a reason for the bad rating.
.NOTES
Only the end user listed as the ticket requester can create a satisfaction rating for the ticket.
#>
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param (
# The internal id of the ticket to create a rating for
[Parameter(Mandatory = $true)]
[ValidateRange(1, [Int64]::MaxValue)]
[Int64]
$TicketId,

# The rating
[Parameter(Mandatory = $true)]
[ValidateSet('good', 'bad')]
[String]
$Score,

# The comment
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[String]
$Comment,

# The reason for a bad rating given by the requester
[Parameter(Mandatory = $false)]
[Int]
$ReasonCode = 0,

# Zendesk Connection Context from `Get-ZendeskConnection`
[Parameter(Mandatory = $false)]
[PSTypeName('ZendeskContext')]
[PSCustomObject]
$Context = $null
)

Assert-IsEndUser -Context $Context

$path = "/api/v2/tickets/$TicketId/satisfaction_rating.json"
$body = @{
satisfaction_rating = @{
score = $Score
}
}

if ($PSBoundParameters.ContainsKey('Comment')) {
$body.satisfaction_rating.comment = $Comment
}

if ($Score -eq 'bad') {
$body.satisfaction_rating.reason_code = $ReasonCode
mderriey marked this conversation as resolved.
Show resolved Hide resolved
}

if ($PSCmdlet.ShouldProcess($TicketId, 'Create Group')) {
$result = Invoke-Method -Context $Context -Method 'Post' -Path $path -Body $body -Verbose:$VerbosePreference
$result
}
}
117 changes: 117 additions & 0 deletions tests/Routes-SatisfactionRatings.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]
Param()

Import-Module "$PSScriptRoot/../PwshZendesk.psm1" -Force

Describe 'Satisfaction Rating Routes' {

InModuleScope PwshZendesk {

$IsInteractive = [Environment]::GetCommandLineArgs() -join ' ' -notmatch '-NonI'

$context = @{
Organization = 'company'
BaseUrl = 'https://company.testdesk.com'
Credential = [System.Management.Automation.PSCredential]::New('email', ('api-key' | ConvertTo-SecureString -AsPlainText -Force))
User = [PSCustomObject]@{ role = '' }
}
$context | Add-Member -TypeName 'ZendeskContext'

Mock -ModuleName PwshZendesk Invoke-RestMethod { [PSCustomObject]@{ satisfaction_rating = $null; satisfaction_ratings = $null } }

Context 'List Satisfaction Ratings' {
It 'Matches the endpoint' {
if ($IsInteractive) {
throw 'Please run test in non-interactive mode'
}

$context.User.role = 'admin'

{ Get-SatisfactionRating -Context $context } | Should -Not -Throw
Assert-MockCalled Invoke-RestMethod -Exactly 1 -ParameterFilter { $Method -eq 'Get' -and $Uri -match '/api/v2/satisfaction_ratings\.json' } -Scope It
}

It 'Does not allow end users to call' {
$context.User.role = 'end-user'

{ Get-SatisfactionRating -Context $context } | Should -Throw 'Authenticated user must have role'
mderriey marked this conversation as resolved.
Show resolved Hide resolved
}

It 'Does not allow agents to call' {
$context.User.role = 'agent'

{ Get-SatisfactionRating -Context $context } | Should -Throw 'Authenticated user must have role'
}

It 'Allows admins to call' {
$context.User.role = 'admin'

{ Get-SatisfactionRating -Context $context } | Should -Not -Throw
}
}

Context 'Show Satisfaction Rating' {
It 'Matches the endpoint' {
if ($IsInteractive) {
throw 'Please run test in non-interactive mode'
}

$context.User.role = 'admin'

{ Get-SatisfactionRating -Context $context -Id 1 } | Should -Not -Throw
Assert-MockCalled Invoke-RestMethod -Exactly 1 -ParameterFilter { $Method -eq 'Get' -and $Uri -match '/api/v2/satisfaction_ratings/\d+\.json' } -Scope It
}

It 'Does not allow end users to call' {
$context.User.role = 'end-user'

{ Get-SatisfactionRating -Context $context -Id 1 } | Should -Throw 'Authenticated user must have role'
}

It 'Does not allow agents to call' {
$context.User.role = 'agent'

{ Get-SatisfactionRating -Context $context -Id 1 } | Should -Throw 'Authenticated user must have role'
}

It 'Allows admins to call' {
$context.User.role = 'admin'

{ Get-SatisfactionRating -Context $context -Id 1 } | Should -Not -Throw
}
}

Context 'Create a Satisfaction Rating' {
It 'Matches the endpoint' {
if ($IsInteractive) {
throw 'Please run test in non-interactive mode'
}

$context.User.role = 'end-user'

{ New-SatisfactionRating -Context $context -TicketId 1 -Score 'good' -Confirm:$false } | Should -Not -Throw
Assert-MockCalled Invoke-RestMethod -Exactly 1 -ParameterFilter { $Method -eq 'Post' -and $Uri -match '/api/v2/tickets/\d+/satisfaction_rating\.json' } -Scope It
}

It 'Allows end users to call' {
$context.User.role = 'end-user'

{ New-SatisfactionRating -Context $context -TicketId 1 -Score 'good' -Confirm:$false } | Should -Not -Throw
}

It 'Does not allow agents to call' {
$context.User.role = 'agent'

{ New-SatisfactionRating -Context $context -TicketId 1 -Score 'good' -Confirm:$false } | Should -Throw 'Authenticated user must have role'
}

It 'Does not allow admins to call' {
$context.User.role = 'admin'

{ New-SatisfactionRating -Context $context -TicketId 1 -Score 'good' -Confirm:$false } | Should -Throw 'Authenticated user must have role'
}
}

}

}