Skip to content

Enhance NinjaOne module with tests, coverage improvements, and new features#81

Merged
homotechsual merged 30 commits into
mainfrom
develop
May 12, 2026
Merged

Enhance NinjaOne module with tests, coverage improvements, and new features#81
homotechsual merged 30 commits into
mainfrom
develop

Conversation

@homotechsual

Copy link
Copy Markdown
Owner

This pull request introduces significant improvements to test coverage reporting, CI documentation, and internal API request handling. It standardizes how coverage is measured and reported, adds new VS Code tasks for developer workflows, enforces minimum coverage thresholds in CI, and refactors internal query string handling for API requests to use a more robust type.

Test Coverage & Quality Reporting Improvements:

  • Added new scripts (show-coverage.ps1, run-public-suite-tail.ps1) to standardize coverage reporting and test suite tailing, and integrated them as VS Code tasks for easier access. (DevOps/Quality/show-coverage.ps1, DevOps/Quality/run-public-suite-tail.ps1, .vscode/tasks.json, [1] [2] [3]
  • Updated documentation to instruct contributors to use repository scripts/tasks as the single source of truth for coverage and quality reporting, discouraging ad-hoc commands. (.github/copilot-instructions.md, .github/copilot-instructions.mdR21-R30)
  • Enforced minimum line coverage thresholds per suite in test.ps1, causing CI to fail if coverage drops below configured levels and reporting readiness for the next 5% coverage target. (DevOps/Quality/test.ps1, [1] [2]

CI/CD Pipeline & Workflow Enhancements:

  • Updated CI workflow to include publishing development docs artifacts and adjusted the docs sync workflow to download artifacts instead of checking out the repo, improving reliability and efficiency. (.github/workflows/ci.yml, .github/workflows/sync-development-docs.yml, [1] [2] [3]

Internal API Request Handling Refactor:

  • Refactored all internal API request functions (New-NinjaOneGETRequest, New-NinjaOnePOSTRequest, New-NinjaOnePUTRequest, New-NinjaOnePATCHRequest, New-NinjaOneQuery) to use NameValueCollection for query string parameters instead of hashtables, simplifying code and improving type safety. (Source/Private/New-NinjaOneGETRequest.ps1, Source/Private/New-NinjaOnePOSTRequest.ps1, Source/Private/New-NinjaOnePUTRequest.ps1, Source/Private/New-NinjaOnePATCHRequest.ps1, Source/Private/New-NinjaOneQuery.ps1, [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

VS Code & Command Approval Improvements:

  • Added approval-friendly commands and coverage utilities to the workspace settings to streamline code review and command approval processes. (NinjaOne.code-workspace, NinjaOne.code-workspaceR114-R118)

These changes collectively improve the reliability, transparency, and maintainability of test coverage reporting and internal development workflows.

…oduce Test Coverage Enhancement Plan documentation
…n GET, POST, PATCH, and PUT request functions
…injaOneDevices, Get-NinjaOneGroups, and Get-NinjaOnePolicies endpoints
…or Get-NinjaOneAutomations, Get-NinjaOneContact, Get-NinjaOneDeviceCustomFields, Get-NinjaOneSoftwareProducts, and Get-NinjaOneSystemContacts
…jaOneDevice, Set-NinjaOneOrganisationCustomFields, Set-NinjaOneDeviceCustomFields, Set-NinjaOneTicket, Set-NinjaOneDeviceApproval, and Set-NinjaOneOrganisationPolicies functions with error handling
…or Get-NinjaOneDeviceDisks, Get-NinjaOneDeviceNetworkInterfaces, Get-NinjaOneDeviceVolumes, Get-NinjaOneTicketAttributes, and Get-NinjaOneTicketBoards functions with error handling
…or New-NinjaOneDocumentTemplate and Set-NinjaOneDocumentTemplate functions with error handling
…or New-NinjaOneCustomField and Set-NinjaOneDeviceMaintenance functions with error handling
…ctions, update sync workflow to download artifacts, and introduce new tasks for VS Code.
Copilot AI review requested due to automatic review settings May 12, 2026 19:23
@homotechsual
homotechsual merged commit ed02739 into main May 12, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR improves the NinjaOne PowerShell module’s reliability and contributor workflow by standardizing coverage reporting/gates, expanding tests, and refactoring internal request/query handling to use query-string collections.

Changes:

  • Adds/updates test suites (schema/public/private) to increase coverage and validate endpoint/metadata contracts.
  • Standardizes coverage reporting with new scripts/VS Code tasks and enforces per-suite minimum line coverage thresholds in CI.
  • Refactors internal request/query helpers to use NameValueCollection for query string handling and updates docs/CI workflows accordingly.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/NinjaOne/development/test-coverage-enhancement-plan.mdx Adds an incremental plan for raising coverage with clear batch targets.
docs/NinjaOne/development/index.mdx Links the new coverage enhancement plan in development docs index.
Tests/NinjaOne.Schema.Tests.ps1 Adds stronger schema validations (duplicate metadata, method support, template matching).
Tests/NinjaOne.Public.Tests.ps1 Expands public cmdlet contract tests significantly (routing, query promotion, error delegation).
Tests/NinjaOne.Private.Tests.ps1 Adds deeper private helper tests and updates query collection usage in request tests.
Source/Public/System/Get/Get-NinjaOneJobs.ps1 Adjusts GET request params (removes NoDrill).
Source/Public/RelatedItems/New/New-NinjaOneSecureRelation.ps1 Fixes user-facing Write-Information message formatting.
Source/Public/Management/Set/Set-NinjaOneDeviceMaintenance.ps1 Alters parameter cleanup logic for unix epoch inputs.
Source/Public/Management/New/New-NinjaOnePolicy.ps1 Tightens COPY-mode validation for templatePolicyId.
Source/Public/Document Templates/Set/Set-NinjaOneDocumentTemplate.ps1 Fixes resource string formatting for template updates.
Source/Private/New-NinjaOneQuery.ps1 Switches to NameValueCollection query building and refines array handling.
Source/Private/New-NinjaOnePUTRequest.ps1 Updates QS handling to accept and emit query collections consistently.
Source/Private/New-NinjaOnePOSTRequest.ps1 Updates QS handling to accept query collections instead of hashtables.
Source/Private/New-NinjaOnePATCHRequest.ps1 Updates QS handling to accept and emit query collections consistently.
Source/Private/New-NinjaOneGETRequest.ps1 Updates QS handling to accept query collections instead of hashtables.
NinjaOne.code-workspace Adds approval-friendly commands for coverage and public-suite tailing.
DevOps/Quality/test.ps1 Adds per-suite coverage gates and prints readiness toward next 5% targets.
DevOps/Quality/show-coverage.ps1 Adds standardized coverage summary/detail reporting from artifacts.
DevOps/Quality/run-public-suite-tail.ps1 Adds a stable wrapper for tailing public suite output.
.vscode/tasks.json Adds tasks for coverage display and public suite tailing.
.github/workflows/sync-development-docs.yml Switches docs sync to downloading CI artifacts instead of checkout.
.github/workflows/ci.yml Publishes dev docs as a CI artifact via build tasks.
.github/copilot-instructions.md Documents the intended source-of-truth scripts/tasks for coverage reporting.

Write-Verbose 'Building comma separated array string.'
$QueryValue = $Value -join ','
$QSCollection.Add($Query, $QueryValue.ToUnixEpoch())
$QueryValue = ($Value | ForEach-Object { ConvertTo-UnixEpoch -DateTime $_ }) -join ','
Comment on lines 68 to 76
if ($start) {
[Int]$start = ConvertTo-UnixEpoch -DateTime $start
} elseif ($unixStart) {
$Parameters.Remove('unixStart') | Out-Null
[Int]$start = $unixStart
}
if ($end) {
[Int]$end = ConvertTo-UnixEpoch -DateTime $end
} elseif ($unixEnd) {
$Parameters.Remove('unixEnd') | Out-Null
[Int]$end = $unixEnd
Comment on lines +29 to +34
$instrCovered = [int]($reportCounters | Where-Object { $_.type -eq 'INSTRUCTION' } | Select-Object -ExpandProperty covered)
$instrMissed = [int]($reportCounters | Where-Object { $_.type -eq 'INSTRUCTION' } | Select-Object -ExpandProperty missed)
$lineCovered = [int]($reportCounters | Where-Object { $_.type -eq 'LINE' } | Select-Object -ExpandProperty covered)
$lineMissed = [int]($reportCounters | Where-Object { $_.type -eq 'LINE' } | Select-Object -ExpandProperty missed)
$methodCovered = [int]($reportCounters | Where-Object { $_.type -eq 'METHOD' } | Select-Object -ExpandProperty covered)
$methodMissed = [int]($reportCounters | Where-Object { $_.type -eq 'METHOD' } | Select-Object -ExpandProperty missed)
if ($mode -eq 'CHILD' -and $null -eq $policy.parentPolicyId) {
throw 'The policy must have a parent policy id if using "CHILD" mode.'
} elseif ($mode -eq 'COPY' -and $null -eq $templatePolicyId) {
} elseif ($mode -eq 'COPY' -and -not $templatePolicyId) {
Comment on lines +69 to +83
$PSItem.Method | Should -BeIn @('get', 'post', 'patch', 'put', 'delete', 'options', 'head')
}

It ('should match an endpoint') {
$MetadataItem = $_
$MatchedEndpoint = $Endpoints | Where-Object { $_.Path -eq $MetadataItem.Endpoint -and $_.Method -eq $MetadataItem.Method }
$MatchedEndpoint | Should -Not -BeNullOrEmpty -Because ('{0}: {1} should match an endpoint' -f $MetadataItem.Method, $MetadataItem.Endpoint)
}

It ('should match an endpoint template ignoring placeholder names') {
$MetadataItem = $_
$MetadataTemplate = [regex]::Replace([string]$MetadataItem.Endpoint, '\{[^/]+\}', '{}')
$MatchedEndpoint = $Endpoints | Where-Object {
$EndpointTemplate = [regex]::Replace([string]$PSItem.Path, '\{[^/]+\}', '{}')
$EndpointTemplate -eq $MetadataTemplate -and $PSItem.Method -eq $MetadataItem.Method
Comment thread DevOps/Quality/test.ps1
Comment on lines +208 to +209
$nextTarget = [double](([math]::Floor($linePct / 5) * 5) + 5)
$toNextTarget = [math]::Round([math]::Max($nextTarget - $linePct, 0), 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants