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
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- `DatabasePermission`
- Fixed `Equals()` method to compare both `State` and `Permission` properties.
Previously, the method incorrectly referenced a non-existent `Grant` property,
causing incorrect equality comparisons when instances had different `State`
values ([issue #2386](https://github.com/dsccommunity/SqlServerDsc/issues/2386)).
- Added `GetHashCode()` override to align with `Equals()` semantics, ensuring
consistent behavior when instances are used in hash-based collections
([issue #2386](https://github.com/dsccommunity/SqlServerDsc/issues/2386)).
- `ServerPermission`
- Fixed `Equals()` method to compare both `State` and `Permission` properties.
Previously, the method incorrectly referenced a non-existent `Grant` property,
causing incorrect equality comparisons when instances had different `State`
values ([issue #2386](https://github.com/dsccommunity/SqlServerDsc/issues/2386)).
- Added `GetHashCode()` override to align with `Equals()` semantics, ensuring
consistent behavior when instances are used in hash-based collections
([issue #2386](https://github.com/dsccommunity/SqlServerDsc/issues/2386)).
Comment thread
johlju marked this conversation as resolved.
Comment thread
johlju marked this conversation as resolved.
- Unit Tests
- Fixed misleading variable naming in ServerPermission.Tests.ps1 where
`$databasePermissionInstance` was used for `[ServerPermission]` objects.
All instances have been renamed to `$serverPermissionInstance`.
- `Set-SqlDscServerPermission`
- Fixed an issue where unspecified permission parameters would incorrectly
revoke existing permissions. The command now only processes permission
Expand Down
14 changes: 13 additions & 1 deletion source/Classes/002.DatabasePermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class DatabasePermission : IComparable, System.IEquatable[Object]

if ($object -is $this.GetType())
{
if ($this.Grant -eq $object.Grant)
if ($this.State -eq $object.State)
{
if (-not (Compare-Object -ReferenceObject $this.Permission -DifferenceObject $object.Permission))
{
Expand All @@ -195,6 +195,18 @@ class DatabasePermission : IComparable, System.IEquatable[Object]
return $isEqual
}

[System.Int32] GetHashCode()
{
[System.Int32] $hashCode = $this.State.GetHashCode()

foreach ($permission in ($this.Permission | Sort-Object))
{
$hashCode = $hashCode -bxor $permission.GetHashCode()
}

return $hashCode
}

[System.Int32] CompareTo([Object] $object)
{
[System.Int32] $returnValue = 0
Expand Down
14 changes: 13 additions & 1 deletion source/Classes/002.ServerPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ServerPermission : IComparable, System.IEquatable[Object]

if ($object -is $this.GetType())
{
if ($this.Grant -eq $object.Grant)
if ($this.State -eq $object.State)
{
if (-not (Compare-Object -ReferenceObject $this.Permission -DifferenceObject $object.Permission))
{
Expand All @@ -127,6 +127,18 @@ class ServerPermission : IComparable, System.IEquatable[Object]
return $isEqual
}

[System.Int32] GetHashCode()
{
[System.Int32] $hashCode = $this.State.GetHashCode()

foreach ($permission in ($this.Permission | Sort-Object))
{
$hashCode = $hashCode -bxor $permission.GetHashCode()
}

return $hashCode
}

<#
TODO: It was not possible to move this to a parent class. But since these are
generic functions for DatabasePermission and ServerPermission we
Expand Down
122 changes: 104 additions & 18 deletions tests/Unit/Classes/DatabasePermission.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -130,34 +130,64 @@ Describe 'DatabasePermission' -Tag 'DatabasePermission' {
}

Context 'When object has different value for property State' {
It 'Should instantiate two objects' {
$script:mockDatabasePermissionInstance1 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0
Context 'When comparing Deny with Grant' {
It 'Should instantiate two objects' {
$script:mockDatabasePermissionInstance1 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance = [DatabasePermission]::new()
$databasePermissionInstance = [DatabasePermission]::new()

$databasePermissionInstance.State = 'Deny'
$databasePermissionInstance.Permission = 'select'
$databasePermissionInstance.State = 'Deny'
$databasePermissionInstance.Permission = 'select'

return $databasePermissionInstance
}
return $databasePermissionInstance
}

$script:mockDatabasePermissionInstance2 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0
$script:mockDatabasePermissionInstance2 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance = [DatabasePermission]::new()
$databasePermissionInstance = [DatabasePermission]::new()

$databasePermissionInstance.State = 'Grant'
$databasePermissionInstance.Permission = 'select'
$databasePermissionInstance.State = 'Grant'
$databasePermissionInstance.Permission = 'select'

return $databasePermissionInstance
return $databasePermissionInstance
}
}

It 'Should return $false' {
$mockDatabasePermissionInstance1 -eq $mockDatabasePermissionInstance2 | Should -BeFalse
}
}

It 'Should return $false' {
# BUG: Equals only compares the Permission property not State.
# $mockDatabasePermissionInstance1 -eq $mockDatabasePermissionInstance2 | Should -BeFalse
$mockDatabasePermissionInstance1 -eq $mockDatabasePermissionInstance2 | Should -BeTrue
Context 'When comparing Grant with GrantWithGrant' {
It 'Should instantiate two objects' {
$script:mockDatabasePermissionInstance1 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance = [DatabasePermission]::new()

$databasePermissionInstance.State = 'Grant'
$databasePermissionInstance.Permission = 'select'

return $databasePermissionInstance
}

$script:mockDatabasePermissionInstance2 = InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance = [DatabasePermission]::new()

$databasePermissionInstance.State = 'GrantWithGrant'
$databasePermissionInstance.Permission = 'select'

return $databasePermissionInstance
}
}

It 'Should return $false' {
$mockDatabasePermissionInstance1 -eq $mockDatabasePermissionInstance2 | Should -BeFalse
}
}
}

Expand Down Expand Up @@ -192,6 +222,62 @@ Describe 'DatabasePermission' -Tag 'DatabasePermission' {
}
}

Context 'When calling method GetHashCode()' {
Context 'When two objects are equal' {
It 'Should return the same hash code' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance1 = [DatabasePermission]::new()
$databasePermissionInstance1.State = 'Grant'
$databasePermissionInstance1.Permission = @('Select', 'Update')

$databasePermissionInstance2 = [DatabasePermission]::new()
$databasePermissionInstance2.State = 'Grant'
$databasePermissionInstance2.Permission = @('Update', 'Select')

$databasePermissionInstance1.GetHashCode() | Should -Be $databasePermissionInstance2.GetHashCode()
}
}
}

Context 'When two objects have different State' {
It 'Should return different hash codes' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance1 = [DatabasePermission]::new()
$databasePermissionInstance1.State = 'Grant'
$databasePermissionInstance1.Permission = 'Select'

$databasePermissionInstance2 = [DatabasePermission]::new()
$databasePermissionInstance2.State = 'Deny'
$databasePermissionInstance2.Permission = 'Select'

$databasePermissionInstance1.GetHashCode() | Should -Not -Be $databasePermissionInstance2.GetHashCode()
}
}
}

Context 'When two objects have different Permission' {
It 'Should return different hash codes' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

$databasePermissionInstance1 = [DatabasePermission]::new()
$databasePermissionInstance1.State = 'Grant'
$databasePermissionInstance1.Permission = 'Select'

$databasePermissionInstance2 = [DatabasePermission]::new()
$databasePermissionInstance2.State = 'Grant'
$databasePermissionInstance2.Permission = 'Update'

$databasePermissionInstance1.GetHashCode() | Should -Not -Be $databasePermissionInstance2.GetHashCode()
}
}
}
}

Context 'When comparing two objects using method CompareTo()' {
Context 'When the instance is compared against an invalid object' {
It 'Should return a value less than zero' {
Expand Down
Loading
Loading