Skip to content

Unit Test Cases Added for ZAP#4290

Merged
Maheshkale447 merged 3 commits into
Releases/Betafrom
Enhancements/UnitTestCasesForZAP
Sep 4, 2025
Merged

Unit Test Cases Added for ZAP#4290
Maheshkale447 merged 3 commits into
Releases/Betafrom
Enhancements/UnitTestCasesForZAP

Conversation

@AmanPrasad43

@AmanPrasad43 AmanPrasad43 commented Sep 3, 2025

Copy link
Copy Markdown
Contributor

Thank you for your contribution.
Before submitting this PR, please make sure:

  • PR description and commit message should describe the changes done in this PR
  • Verify the PR is pointing to correct branch i.e. Release or Beta branch if the code fix is for specific release , else point it to master
  • Latest Code from master or specific release branch is merged to your branch
  • No unwanted\commented\junk code is included
  • No new warning upon build solution
  • Code Summary\Comments are added to my code which explains what my code is doing
  • Existing unit test cases are passed
  • New Unit tests are added for your development
  • Sanity Tests are successfully executed for New and Existing Functionality
  • Verify that changes are compatible with all relevant browsers and platforms.
  • After creating pull request there should not be any conflicts
  • Resolve all Codacy comments
  • Builds and checks are passed before PR is sent for review
  • Resolve code review comments
  • Update the Help Library document to match any feature changes

Summary by CodeRabbit

  • New Features
    • Integrated OWASP ZAP capabilities: active/passive scans, URL enrollment, scan status polling, alert summaries, and configurable report generation.
  • Bug Fixes
    • More resilient URL parsing across formats and improved error handling when ZAP is unavailable or operations fail.
  • Refactor
    • ZAP access decoupled behind an injectable client with a default wrapper for flexibility and easier testing.
  • Tests
    • Added unit tests covering URL parsing, health checks, scan workflows, report generation errors, and alert evaluation.

@coderabbitai

coderabbitai Bot commented Sep 3, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new public IZapClient interface and ZapClientWrapper implementation, refactors ZapProxyService to depend on IZapClient (adds DI constructor and replaces direct ClientApi calls), enhances URL parsing and error handling, and introduces unit tests mocking IZapClient.

Changes

Cohort / File(s) Summary
ZAP client interface
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
New public IZapClient declaring methods that mirror ZAP API endpoints (Version, RecordsToScan, GenerateReport, AccessUrl, Urls, Scan, ScanStatus, AlertsSummary) returning OWASPZAPDotNetAPI.IApiResponse.
ZAP client wrapper
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
New ZapClientWrapper implementing IZapClient; holds ClientApi and delegates calls to core/pscan/ascan/alert/reports. Constructor: ZapClientWrapper(string host, int port, string apiKey).
ZapProxyService refactor
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
Replaces direct ClientApi usage with IZapClient, adds DI constructor ZapProxyService(IZapClient), updates all ZAP interactions to use the interface, improves exception handling and logging, tightens AddUrlToScanTree behavior, and enhances host/port parsing (including IPv6 and multiple URL forms); default constructor still wires ZapClientWrapper.
Unit tests
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
New test suite using Mock<IZapClient> covering URL parsing, IsZapRunning, passive/active scan polling, report generation exception path, scan-tree operations, alert summary parsing/evaluation, and related edge cases.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant Service as ZapProxyService
  participant Client as IZapClient (ZapClientWrapper)
  Note over Caller,Service: Start active scan → poll → complete
  Caller->>Service: PerformActiveScan(url,...)
  Service->>Client: Scan(url, recurse, inscopeonly, policy, method, postdata, contextId)
  Client-->>Service: scanId
  loop poll until status == "100"
    Service->>Client: ScanStatus(scanId)
    Client-->>Service: status
  end
  Service-->>Caller: scanId (completed)
Loading
sequenceDiagram
  autonumber
  actor Caller
  participant Service as ZapProxyService
  participant Client as IZapClient (ZapClientWrapper)
  Note over Caller,Service: Retrieve alerts summary for evaluation
  Caller->>Service: GetAlertSummary(targetUrl)
  Service->>Client: AlertsSummary(targetUrl)
  Client-->>Service: IApiResponse (summary)
  Service-->>Caller: parsed alert summary / evaluation result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Maheshkale447
  • IamRanjeetSingh

Poem

I nibble code beneath the moon's light,
New interface hopped in, tidy and bright.
Wrapper snug, tests all set to run,
Scans and reports now neatly spun.
Hooray — alerts sorted, carrot munch begun! 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch Enhancements/UnitTestCasesForZAP

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (5)

67-79: Async method uses Thread.Sleep and has no await — fixes needed (also removes build warning)

Replace Thread.Sleep with await Task.Delay to avoid blocking and eliminate CS1998. Consider a timeout to prevent indefinite waits.

-        public async Task WaitTillPassiveScanCompleted()
+        public async Task WaitTillPassiveScanCompleted()
         {
             try
             {
                 IApiResponse apiResponse = _zapClient.RecordsToScan();
                 string tempVal = ((ApiResponseElement)apiResponse).Value;
                 while (!tempVal.Equals("0"))
                 {
-                    Thread.Sleep(1000);
+                    await Task.Delay(1000).ConfigureAwait(false);
                     apiResponse = _zapClient.RecordsToScan();
                     tempVal = ((ApiResponseElement)apiResponse).Value;
                 }
             }

Optional: add a cancellation token/timeout in a follow-up.


200-219: Method contradicts its XML comment; exceptions are swallowed

The summary says it throws when the URL isn't added, but the catch logs and returns. This can lead to ActiveScan continuing on a bad setup.

-        public void AddUrlToScanTree(string siteToTest)
+        public void AddUrlToScanTree(string siteToTest)
         {
             try
             {
                 _zapClient.AccessUrl(siteToTest, "false");
                 var urls = GetUrlsFromScanTree(siteToTest);
                 if (urls.Contains(siteToTest))
                 {
                     Reporter.ToLog(eLogLevel.INFO, $"{siteToTest} has been added to scan tree");
                 }
                 else
                 {
-                    throw new InvalidOperationException($"{siteToTest} not added to scan tree, active scan will not be possible");
+                    throw new InvalidOperationException($"{siteToTest} not added to scan tree, active scan will not be possible");
                 }
             }
             catch (Exception ex)
             {
-                Reporter.ToLog(eLogLevel.ERROR, $"Failed to add {siteToTest} to scan tree: {ex.Message}", ex);
+                Reporter.ToLog(eLogLevel.ERROR, $"Failed to add {siteToTest} to scan tree: {ex.Message}", ex);
+                throw;
             }
         }

If you prefer not to throw, change the summary and return a bool indicating success.


279-309: EvaluateScanResultWeb should only fail on disallowed alerts with count > 0; also guard null list

Currently it fails even when count == 0 and will NRE if allowedAlertNames is null.

-                foreach (var alertEntry in alertSummary.Dictionary)
+                foreach (var alertEntry in alertSummary.Dictionary)
                 {
                     string alertName = alertEntry.Key;
                     string valueString = alertEntry.Value is ApiResponseElement element ? element.Value : alertEntry.Value?.ToString();
-                    if (!int.TryParse(valueString, out int count))
+                    if (!int.TryParse(valueString, out int count))
                     {
                         continue;
                     }
 
-                    if (!allowedAlertNames.Any(a => a.Value == alertName))
+                    if (count > 0 && !(allowedAlertNames?.Any(a => a.Value == alertName) ?? false))
                     {
                         testPassed = false;
                     }
                 }

(Used retrieved learnings: keep alert names as-is; case sensitivity rules unchanged here.)


102-108: XML doc says “string” but method returns int?

Fix the XML comment to match the signature and behavior.

-        /// <returns>The port number as string, or null if not found.</returns>
+        /// <returns>The port number as int?, or null if not found.</returns>

256-270: Optional: make active-scan wait non-blocking and include progress

Swap Thread.Sleep for Task.Delay and log the numeric percentage to reduce log noise and allow responsiveness.

If you choose to keep it sync, at least log the current percentage:

-                Reporter.ToLog(eLogLevel.INFO, "Active scan is in progress");
+                Reporter.ToLog(eLogLevel.INFO, $"Active scan is in progress: {status}%");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fd572e4 and 06cd9ea.

📒 Files selected for processing (4)
  • Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (1 hunks)
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (1 hunks)
  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (12 hunks)
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-08-25T09:20:17.608Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.

Applied to files:

  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
  • Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-08-25T08:48:11.915Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCore/GingerCore.csproj:538-538
Timestamp: 2025-08-25T08:48:11.915Z
Learning: In the Ginger codebase, the OWASPZAPDotNetAPI package reference in GingerCore.csproj is required for architectural reasons, even when direct usage is not immediately visible in the codebase. This was confirmed by AmanPrasad43 during the security testing feature implementation.

Applied to files:

  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-08-28T09:27:18.793Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/Ginger/Drivers/DriversConfigsEditPages/WebAgentConfigEditPage.xaml.cs:556-571
Timestamp: 2025-08-28T09:27:18.793Z
Learning: In Ginger's WebAgentConfigEditPage.xaml.cs ZAP configuration, when ZAP Security Testing is enabled, the manual proxy UI should remain enabled/accessible even though ZAP will override the proxy settings in the background. This allows users to see and modify their proxy configurations for transparency and future use when ZAP is disabled. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-06-16T10:37:13.073Z
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4232
File: Ginger/GingerCoreNET/ActionsLib/UI/VisualTesting/VRTAnalyzer.cs:19-22
Timestamp: 2025-06-16T10:37:13.073Z
Learning: In Ginger codebase, both `using amdocs.ginger.GingerCoreNET;` and `using Amdocs.Ginger.CoreNET;` are valid and serve different purposes. The first (lowercase) contains the WorkSpace class and related workspace functionality, while the second (proper case) contains drivers like GenericAppiumDriver and other core functionality. Both may be required in files that use types from both namespaces.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-08-25T09:30:08.106Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreCommon/External/Configurations/ZAPConfiguration.cs:37-58
Timestamp: 2025-08-25T09:30:08.106Z
Learning: In the Ginger codebase, URL validation in configuration classes like ZAPConfiguration should not throw exceptions for invalid URLs. The team prefers simple normalization (like trimming trailing slashes) over strict validation with exception throwing. This was confirmed by AmanPrasad43 in PR #4281 for the ZAPConfiguration.ZAPUrl property setter.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-04-25T13:29:45.059Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4188
File: Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs:22-23
Timestamp: 2025-04-25T13:29:45.059Z
Learning: The `using Amdocs.Ginger.Repository;` statement in Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs is necessary as it provides access to the `ObservableList<>` class which is used throughout the file for collections of RunSetConfig, AnalyzerItemBase, and ApplicationPOMModel objects.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-08-29T09:35:45.994Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:287-309
Timestamp: 2025-08-29T09:35:45.994Z
Learning: In Ginger ZAP security testing, alert names should preserve their original formatting with spaces and hyphens. When comparing alert names in EvaluateScanResultAPI and similar methods, use StringComparison.OrdinalIgnoreCase for case-insensitive matching but do not normalize by removing spaces or hyphens, as alert names like "False Positive" need to remain as separate words. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
🧬 Code graph analysis (2)
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (2)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (13)
  • ZapProxyService (16-369)
  • ZapProxyService (27-39)
  • ZapProxyService (42-45)
  • GetPortFromUrl (108-148)
  • GetHostFromUrl (155-193)
  • IsZapRunning (52-65)
  • GenerateZapReport (86-100)
  • List (225-230)
  • List (351-367)
  • AddUrlToScanTree (200-219)
  • PerformActiveScan (236-250)
  • EvaluateScanResultWeb (279-309)
  • EvaluateScanResultAPI (311-341)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (8)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
  • IApiResponse (17-17)
  • IApiResponse (18-18)
  • IApiResponse (19-21)
  • IApiResponse (23-23)
  • IApiResponse (24-24)
  • IApiResponse (26-31)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (2)
Ginger/GingerCoreCommon/External/Configurations/ZAPConfiguration.cs (1)
  • ZAPConfiguration (5-71)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (10)
  • ZapClientWrapper (5-32)
  • ZapClientWrapper (9-12)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
  • IApiResponse (17-17)
  • IApiResponse (18-18)
  • IApiResponse (19-21)
  • IApiResponse (23-23)
  • IApiResponse (24-24)
  • IApiResponse (26-31)
🔇 Additional comments (4)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (4)

14-16: LGTM: simple pass-throughs for version/pscan are correct


23-24: LGTM: status and alerts summary mapping looks correct


7-12: Dispose pattern (if ClientApi is disposable)
If ClientApi implements IDisposable, wrap the wrapper with IDisposable and dispose it. If not, ignore.

Would you like me to confirm the type’s disposability and generate the minimal implementation?


1-1: Package reference present and consistent
GingerCoreNET.csproj includes <PackageReference Include="OWASPZAPDotNetAPI" Version="2.12.0" />, matching GingerCore.csproj—no changes needed.

Comment thread Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/IZapClient.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 13

♻️ Duplicate comments (1)
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (1)

138-151: Skip: polling verification already discussed earlier in the PR

Prior review suggested verifying ScanStatus polling; author confirmed coverage via SetupSequence. No further action.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 06cd9ea and e4394c7.

📒 Files selected for processing (2)
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (1 hunks)
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.
📚 Learning: 2025-09-03T17:35:32.098Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs:17-21
Timestamp: 2025-09-03T17:35:32.098Z
Learning: In the Ginger ZAP integration, the OWASPZAPDotNetAPI library requires string values ("true"/"false") for boolean parameters in methods like AccessUrl, Scan, etc. The ZapClientWrapper should maintain this string-based interface to stay consistent with the underlying ZAP library's API requirements rather than adding boolean overloads.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
📚 Learning: 2025-08-25T08:48:11.915Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCore/GingerCore.csproj:538-538
Timestamp: 2025-08-25T08:48:11.915Z
Learning: In the Ginger codebase, the OWASPZAPDotNetAPI package reference in GingerCore.csproj is required for architectural reasons, even when direct usage is not immediately visible in the codebase. This was confirmed by AmanPrasad43 during the security testing feature implementation.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-03T17:37:45.916Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:56-59
Timestamp: 2025-09-03T17:37:45.916Z
Learning: In the Ginger ZAP integration, the ZAP library's version API returns a string value, which is why the code uses ToString() to convert the IApiResponse to string format in the IsZapRunning method in ZapProxyService.cs.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-03T17:37:09.236Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:34-39
Timestamp: 2025-09-03T17:37:09.236Z
Learning: In Ginger's ZAP integration, when GetPortFromUrl() returns null (URL without port), avoid using hardcoded fallback ports as they may conflict with other applications. Instead, require explicit port specification in the ZAP configuration and provide clear error messages when port is missing.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-25T09:30:08.106Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreCommon/External/Configurations/ZAPConfiguration.cs:37-58
Timestamp: 2025-08-25T09:30:08.106Z
Learning: In the Ginger codebase, URL validation in configuration classes like ZAPConfiguration should not throw exceptions for invalid URLs. The team prefers simple normalization (like trimming trailing slashes) over strict validation with exception throwing. This was confirmed by AmanPrasad43 in PR #4281 for the ZAPConfiguration.ZAPUrl property setter.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-28T09:27:18.793Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/Ginger/Drivers/DriversConfigsEditPages/WebAgentConfigEditPage.xaml.cs:556-571
Timestamp: 2025-08-28T09:27:18.793Z
Learning: In Ginger's WebAgentConfigEditPage.xaml.cs ZAP configuration, when ZAP Security Testing is enabled, the manual proxy UI should remain enabled/accessible even though ZAP will override the proxy settings in the background. This allows users to see and modify their proxy configurations for transparency and future use when ZAP is disabled. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-25T09:20:17.608Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-29T09:35:45.994Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:287-309
Timestamp: 2025-08-29T09:35:45.994Z
Learning: In Ginger ZAP security testing, alert names should preserve their original formatting with spaces and hyphens. When comparing alert names in EvaluateScanResultAPI and similar methods, use StringComparison.OrdinalIgnoreCase for case-insensitive matching but do not normalize by removing spaces or hyphens, as alert names like "False Positive" need to remain as separate words. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-03T17:39:51.349Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:343-349
Timestamp: 2025-09-03T17:39:51.349Z
Learning: The user AmanPrasad43 initially claimed that ApiResponseSet in the ZAP library is a string type, but the ZAP .NET API library source code and the existing code patterns in ZapProxyService.cs show that ApiResponseSet has a Dictionary property that should be used instead of ToString() for parsing alert summaries. The Dictionary property provides structured access to alert data with key-value pairs.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
📚 Learning: 2025-01-30T07:38:05.310Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:137-150
Timestamp: 2025-01-30T07:38:05.310Z
Learning: In the Ginger automation framework, element existence checks using polling with 100ms delay is an acceptable approach, as confirmed by the maintainers.

Applied to files:

  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
🧬 Code graph analysis (2)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (1)
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (8)
  • IApiResponse (7-7)
  • IApiResponse (8-8)
  • IApiResponse (9-9)
  • IApiResponse (10-10)
  • IApiResponse (11-11)
  • IApiResponse (12-13)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (3)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (13)
  • ZapProxyService (16-369)
  • ZapProxyService (27-39)
  • ZapProxyService (42-45)
  • GetPortFromUrl (108-148)
  • GetHostFromUrl (155-193)
  • IsZapRunning (52-65)
  • GenerateZapReport (86-100)
  • List (225-230)
  • List (351-367)
  • AddUrlToScanTree (200-219)
  • PerformActiveScan (236-250)
  • EvaluateScanResultWeb (279-309)
  • EvaluateScanResultAPI (311-341)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (8)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
  • IApiResponse (17-17)
  • IApiResponse (18-18)
  • IApiResponse (19-21)
  • IApiResponse (23-23)
  • IApiResponse (24-24)
  • IApiResponse (26-31)
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (8)
  • IApiResponse (7-7)
  • IApiResponse (8-8)
  • IApiResponse (9-9)
  • IApiResponse (10-10)
  • IApiResponse (11-11)
  • IApiResponse (12-13)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
🔇 Additional comments (9)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (4)

9-12: Constructor delegation looks good

Simple, focused initialization; aligns with upstream validation strategy noted earlier.


14-16: Core version and passive-scan delegates are correct

Signatures and targets match the ZAP API.


23-24: Status and alerts summary delegates are correct

Good coverage of common queries.


26-31: Bug fix confirmed: GenerateReport now forwards theme/pattern/display

Parameter ordering matches the underlying API; prevents silent option loss.

Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (5)

21-26: Good DI setup for testability

Using IZapClient with a TestInitialize to create the SUT is clean and enables focused unit tests.


57-65: LGTM: Positive IsZapRunning path

Using ApiResponseElement and ToString() matches the service behavior for version detection (per team learning about Version API returning string).


113-122: LGTM: Negative path correctly asserts InvalidOperationException

Good failure coverage when URL is not added to the scan tree.


173-184: LGTM: Positive Web evaluation path covered

Confirms allowed-only alerts return true.


75-82: Optional: test passive scan evaluation with empty target URL (session-wide aggregation)

Team guidance says passive scans aggregate across the session when target URL is empty. Add a test ensuring EvaluateScanResultWeb handles empty string target and forwards it to AlertsSummary.

+        [TestMethod]
+        public void EvaluateScanResultWeb_WithEmptyTarget_UsesSessionAggregation()
+        {
+            var alertSummary = new ApiResponseSet("alerts", new Dictionary<string, IApiResponse>());
+            _mockZap.Setup(c => c.AlertsSummary("")).Returns(alertSummary);
+            var allowed = new ObservableList<OperationValues>();
+            var result = _service.EvaluateScanResultWeb("", allowed);
+            Assert.IsTrue(result);
+            _mockZap.Verify(c => c.AlertsSummary(""), Times.Once);
+        }

Also applies to: 153-171

⛔ Skipped due to learnings
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:287-309
Timestamp: 2025-08-29T09:35:45.994Z
Learning: In Ginger ZAP security testing, alert names should preserve their original formatting with spaces and hyphens. When comparing alert names in EvaluateScanResultAPI and similar methods, use StringComparison.OrdinalIgnoreCase for case-insensitive matching but do not normalize by removing spaces or hyphens, as alert names like "False Positive" need to remain as separate words. Confirmed by AmanPrasad43 in PR #4286.

Comment thread Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
Comment thread Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
Comment thread Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (5)

67-84: Async method uses Thread.Sleep; can block threads and hang on bad values

Use Task.Delay in async loop; also guard against unexpected non-numeric responses.

-        public async Task WaitTillPassiveScanCompleted()
+        public async Task WaitTillPassiveScanCompleted()
         {
             try
             {
                 IApiResponse apiResponse = _zapClient.RecordsToScan();
-                string tempVal = ((ApiResponseElement)apiResponse).Value;
-                while (!tempVal.Equals("0"))
+                string tempVal = ((ApiResponseElement)apiResponse).Value;
+                while (!string.Equals(tempVal, "0", StringComparison.Ordinal))
                 {
-                    Thread.Sleep(1000);
+                    await Task.Delay(1000).ConfigureAwait(false);
                     apiResponse = _zapClient.RecordsToScan();
                     tempVal = ((ApiResponseElement)apiResponse).Value;
+                    if (!int.TryParse(tempVal, out _))
+                    {
+                        throw new InvalidOperationException($"Unexpected passive-scan counter: '{tempVal}'");
+                    }
                 }
             }
             catch (Exception ex)
             {
                 throw new InvalidOperationException("Error during passive scan: " + ex.Message, ex);
             }
         }

102-108: XML doc mismatch: return type isn't "string"

Method returns int?, not string. Fix the comment.

-        /// <returns>The port number as string, or null if not found.</returns>
+        /// <returns>The port number, or null if not found.</returns>

171-177: Normalize IPv6 host to bracketless form for non-URL inputs

When input is "[::1]:8080", current branch returns "[::1]" (with brackets). Client libraries typically expect "::1". Align with Uri.Host behavior.

-                    if (idx > 0)
-                    {
-                        return url.Substring(0, idx + 1);
-                    }
+                    if (idx > 0)
+                    {
+                        var hostWithBrackets = url.Substring(0, idx + 1);
+                        return hostWithBrackets.Trim('[', ']');
+                    }

250-264: Active scan polling: add timeout/cancellation and avoid blocking

Consider async polling with timeout to prevent indefinite waits on network issues.

-        private void WaitTillActiveScanIsCompleted(string scanId)
+        private async Task WaitTillActiveScanIsCompletedAsync(string scanId, TimeSpan? timeout = null)
         {
-            var apiResponse = _zapClient.ScanStatus(scanId);
-            string status = ((ApiResponseElement)apiResponse).Value;
-
-            while (!status.Equals("100"))
-            {
-                Thread.Sleep(1000);
-                apiResponse = _zapClient.ScanStatus(scanId);
-                status = ((ApiResponseElement)apiResponse).Value;
-                Reporter.ToLog(eLogLevel.INFO, "Active scan is in progress");
-            }
+            var deadline = DateTime.UtcNow + (timeout ?? TimeSpan.FromMinutes(10));
+            while (true)
+            {
+                var apiResponse = _zapClient.ScanStatus(scanId);
+                string status = ((ApiResponseElement)apiResponse).Value;
+                if (string.Equals(status, "100", StringComparison.Ordinal)) break;
+                if (DateTime.UtcNow >= deadline)
+                    throw new TimeoutException($"Active scan {scanId} did not complete before timeout.");
+                await Task.Delay(1000).ConfigureAwait(false);
+                Reporter.ToLog(eLogLevel.INFO, "Active scan is in progress");
+            }
             Reporter.ToLog(eLogLevel.INFO, "Active scan has completed");
         }

Call site example:

-            WaitTillActiveScanIsCompleted(scanId);
+            _ = WaitTillActiveScanIsCompletedAsync(scanId).GetAwaiter().GetResult();

291-296: Web evaluation should be case-insensitive (keep delimiters)
Use OrdinalIgnoreCase like API path; preserves spaces/hyphens as required.

-                    if (!allowedAlertNames.Any(a => a.Value == alertName))
+                    if (!(allowedAlertNames?.Any(a =>
+                          string.Equals(a.Value, alertName, StringComparison.OrdinalIgnoreCase)) ?? false))
                     {
                         testPassed = false;
                     }
♻️ Duplicate comments (3)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (3)

29-36: Don't cast nullable port; fail fast with a clear message

GetPortFromUrl can return null; (int)null throws "Nullable object must have a value." Throw a descriptive error instead, per team decision to require explicit port in config.

Apply:

-            _zapHost = GetHostFromUrl(ValueExpression.PasswordCalculation(zAPConfiguration.ZAPUrl));
-            _zapPort = (int)GetPortFromUrl(ValueExpression.PasswordCalculation(zAPConfiguration.ZAPUrl));
+            _zapHost = GetHostFromUrl(ValueExpression.PasswordCalculation(zAPConfiguration.ZAPUrl));
+            var parsedPort = GetPortFromUrl(ValueExpression.PasswordCalculation(zAPConfiguration.ZAPUrl));
+            if (parsedPort == null)
+            {
+                throw new InvalidOperationException($"ZAP URL must include an explicit port. Current value: '{zAPConfiguration.ZAPUrl}'");
+            }
+            _zapPort = parsedPort.Value;

56-59: Prefer typed check over ToString() for version (null-safe)

Cast to ApiResponseElement and check Value; safer and clearer.

-                IApiResponse version = _zapClient.Version();
-                return !string.IsNullOrEmpty(version.ToString());
+                IApiResponse version = _zapClient.Version();
+                if (version is ApiResponseElement v) return !string.IsNullOrEmpty(v.Value);
+                return !string.IsNullOrEmpty(version?.ToString());

337-343: EvaluateScanResult should compute from counts, not ToString()

Parse ApiResponseSet.Dictionary and return true only if any count > 0.

-            var summaryResponse = _zapClient.AlertsSummary(targetUrl);
-            var alertSummary = (ApiResponseSet)summaryResponse;
-            return !string.IsNullOrEmpty(alertSummary.ToString());
+            var summaryResponse = _zapClient.AlertsSummary(targetUrl);
+            var alertSummary = (ApiResponseSet)summaryResponse;
+            foreach (var kv in alertSummary.Dictionary)
+            {
+                var valueString = kv.Value is ApiResponseElement e ? e.Value : kv.Value?.ToString();
+                if (int.TryParse(valueString, out var count) && count > 0) return true;
+            }
+            return false;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e4394c7 and 2bddacb.

📒 Files selected for processing (3)
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (1 hunks)
  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (12 hunks)
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs:17-21
Timestamp: 2025-09-03T17:35:32.098Z
Learning: In the Ginger ZAP integration, the OWASPZAPDotNetAPI library requires string values ("true"/"false") for boolean parameters in methods like AccessUrl, Scan, etc. The ZapClientWrapper should maintain this string-based interface to stay consistent with the underlying ZAP library's API requirements rather than adding boolean overloads.
📚 Learning: 2025-09-03T17:35:32.098Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs:17-21
Timestamp: 2025-09-03T17:35:32.098Z
Learning: In the Ginger ZAP integration, the OWASPZAPDotNetAPI library requires string values ("true"/"false") for boolean parameters in methods like AccessUrl, Scan, etc. The ZapClientWrapper should maintain this string-based interface to stay consistent with the underlying ZAP library's API requirements rather than adding boolean overloads.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
📚 Learning: 2025-09-03T17:37:45.916Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:56-59
Timestamp: 2025-09-03T17:37:45.916Z
Learning: In the Ginger ZAP integration, the ZAP library's version API returns a string value, which is why the code uses ToString() to convert the IApiResponse to string format in the IsZapRunning method in ZapProxyService.cs.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-28T09:27:18.793Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/Ginger/Drivers/DriversConfigsEditPages/WebAgentConfigEditPage.xaml.cs:556-571
Timestamp: 2025-08-28T09:27:18.793Z
Learning: In Ginger's WebAgentConfigEditPage.xaml.cs ZAP configuration, when ZAP Security Testing is enabled, the manual proxy UI should remain enabled/accessible even though ZAP will override the proxy settings in the background. This allows users to see and modify their proxy configurations for transparency and future use when ZAP is disabled. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-03T17:37:09.236Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:34-39
Timestamp: 2025-09-03T17:37:09.236Z
Learning: In Ginger's ZAP integration, when GetPortFromUrl() returns null (URL without port), avoid using hardcoded fallback ports as they may conflict with other applications. Instead, require explicit port specification in the ZAP configuration and provide clear error messages when port is missing.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-25T09:30:08.106Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreCommon/External/Configurations/ZAPConfiguration.cs:37-58
Timestamp: 2025-08-25T09:30:08.106Z
Learning: In the Ginger codebase, URL validation in configuration classes like ZAPConfiguration should not throw exceptions for invalid URLs. The team prefers simple normalization (like trimming trailing slashes) over strict validation with exception throwing. This was confirmed by AmanPrasad43 in PR #4281 for the ZAPConfiguration.ZAPUrl property setter.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-25T09:27:30.249Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1433-1441
Timestamp: 2025-08-25T09:27:30.249Z
Learning: In Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs, SetProxy(dynamic options) should not force options.AcceptInsecureCertificates = false. Only set AcceptInsecureCertificates = true when UseZAP is enabled to avoid breaking setups that permit self-signed/dev certificates.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-08-25T09:20:17.608Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs:1958-1970
Timestamp: 2025-08-25T09:20:17.608Z
Learning: In Ginger security testing, passive ZAP scans should be invoked with an empty testURL (ActSecurityTesting.ExecutePassiveZapScan("", act)) to aggregate alerts across the entire ZAP session. Passing a URL scopes results to that base URL. Only the active scan path should pass Driver.Url, with null/empty checks. Context: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Selenium/SeleniumDriver.cs :: ActSecurity. Confirmed by AmanPrasad43 in PR #4281.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-04T05:43:12.360Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs:66-73
Timestamp: 2025-09-04T05:43:12.360Z
Learning: In Ginger's ZAP integration, the ZAP API Version() method always returns a valid IApiResponse object and cannot return null, so null checks in unit tests for Version() are not valid test cases.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-08-29T09:35:45.994Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4286
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:287-309
Timestamp: 2025-08-29T09:35:45.994Z
Learning: In Ginger ZAP security testing, alert names should preserve their original formatting with spaces and hyphens. When comparing alert names in EvaluateScanResultAPI and similar methods, use StringComparison.OrdinalIgnoreCase for case-insensitive matching but do not normalize by removing spaces or hyphens, as alert names like "False Positive" need to remain as separate words. Confirmed by AmanPrasad43 in PR #4286.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-09-03T17:39:51.349Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4290
File: Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs:343-349
Timestamp: 2025-09-03T17:39:51.349Z
Learning: The user AmanPrasad43 initially claimed that ApiResponseSet in the ZAP library is a string type, but the ZAP .NET API library source code and the existing code patterns in ZapProxyService.cs show that ApiResponseSet has a Dictionary property that should be used instead of ToString() for parsing alert summaries. The Dictionary property provides structured access to alert data with key-value pairs.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
📚 Learning: 2025-08-25T08:48:11.915Z
Learnt from: AmanPrasad43
PR: Ginger-Automation/Ginger#4281
File: Ginger/GingerCore/GingerCore.csproj:538-538
Timestamp: 2025-08-25T08:48:11.915Z
Learning: In the Ginger codebase, the OWASPZAPDotNetAPI package reference in GingerCore.csproj is required for architectural reasons, even when direct usage is not immediately visible in the codebase. This was confirmed by AmanPrasad43 during the security testing feature implementation.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
📚 Learning: 2025-06-16T10:37:13.073Z
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4232
File: Ginger/GingerCoreNET/ActionsLib/UI/VisualTesting/VRTAnalyzer.cs:19-22
Timestamp: 2025-06-16T10:37:13.073Z
Learning: In Ginger codebase, both `using amdocs.ginger.GingerCoreNET;` and `using Amdocs.Ginger.CoreNET;` are valid and serve different purposes. The first (lowercase) contains the WorkSpace class and related workspace functionality, while the second (proper case) contains drivers like GenericAppiumDriver and other core functionality. Both may be required in files that use types from both namespaces.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-04-25T13:29:45.059Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4188
File: Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs:22-23
Timestamp: 2025-04-25T13:29:45.059Z
Learning: The `using Amdocs.Ginger.Repository;` statement in Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs is necessary as it provides access to the `ObservableList<>` class which is used throughout the file for collections of RunSetConfig, AnalyzerItemBase, and ApplicationPOMModel objects.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
📚 Learning: 2025-07-16T14:17:56.429Z
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4254
File: Ginger/GingerCoreNET/GeneralLib/ElementWrapperInfo.cs:89-93
Timestamp: 2025-07-16T14:17:56.429Z
Learning: In Ginger/GingerCoreNET/GeneralLib/ElementWrapperInfo.cs, the user prashelke prefers to keep the current casing for properties `insideIframe` and `insideShadowDOM` in the `ElementwrapperContext` class rather than changing them to PascalCase.

Applied to files:

  • Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs
📚 Learning: 2025-01-30T07:38:05.310Z
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:137-150
Timestamp: 2025-01-30T07:38:05.310Z
Learning: In the Ginger automation framework, element existence checks using polling with 100ms delay is an acceptable approach, as confirmed by the maintainers.

Applied to files:

  • Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs
🧬 Code graph analysis (3)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (4)
Ginger/GingerCoreCommon/External/Configurations/ZAPConfiguration.cs (1)
  • ZAPConfiguration (5-71)
Ginger/GingerCoreNET/ValueExpressionLib/ValueExpression.cs (1)
  • PasswordCalculation (2039-2064)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (10)
  • ZapClientWrapper (5-33)
  • ZapClientWrapper (9-12)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
  • IApiResponse (18-18)
  • IApiResponse (19-19)
  • IApiResponse (20-22)
  • IApiResponse (24-24)
  • IApiResponse (25-25)
  • IApiResponse (27-32)
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (8)
  • IApiResponse (7-7)
  • IApiResponse (8-8)
  • IApiResponse (9-9)
  • IApiResponse (10-10)
  • IApiResponse (11-11)
  • IApiResponse (12-13)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (1)
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (8)
  • IApiResponse (7-7)
  • IApiResponse (8-8)
  • IApiResponse (9-9)
  • IApiResponse (10-10)
  • IApiResponse (11-11)
  • IApiResponse (12-13)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (3)
Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs (14)
  • ZapProxyService (16-363)
  • ZapProxyService (27-39)
  • ZapProxyService (42-45)
  • GetPortFromUrl (108-148)
  • GetHostFromUrl (155-193)
  • IsZapRunning (52-65)
  • Task (67-84)
  • GenerateZapReport (86-100)
  • List (219-224)
  • List (345-361)
  • AddUrlToScanTree (200-213)
  • PerformActiveScan (230-244)
  • EvaluateScanResultWeb (273-303)
  • EvaluateScanResultAPI (305-335)
Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (8)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
  • IApiResponse (18-18)
  • IApiResponse (19-19)
  • IApiResponse (20-22)
  • IApiResponse (24-24)
  • IApiResponse (25-25)
  • IApiResponse (27-32)
Ginger/GingerCoreNET/External/ZAP/IZapClient.cs (8)
  • IApiResponse (7-7)
  • IApiResponse (8-8)
  • IApiResponse (9-9)
  • IApiResponse (10-10)
  • IApiResponse (11-11)
  • IApiResponse (12-13)
  • IApiResponse (14-14)
  • IApiResponse (15-15)
🔇 Additional comments (7)
Ginger/GingerCoreNETUnitTest/ZAP/ZapProxyServiceTests.cs (5)

21-26: Good DI setup for service under test

Constructor-injected IZapClient mock keeps tests fast and isolated.


76-86: Nice polling verification for passive scan

SetupSequence + Verify ensures loop behavior without flakiness.


110-127: Solid positive-path assertion for AddUrlToScanTree

Verifies both AccessUrl and Urls were invoked as expected.


190-201: Positive Web evaluation test adds valuable coverage

Covers allowed-alerts-only success path.


236-264: Alert summary tests are thorough (content and edge cases)

Checks tuple contents and ignores non-integer counts—great.

Ginger/GingerCoreNET/External/ZAP/ZapClientWrapper.cs (2)

17-23: Doc note for string booleans is helpful

Keeps wrapper aligned with ZAP API expectations.


27-32: GenerateReport now forwards all options correctly

Passing theme/pattern/display fixes silent option loss.

Comment thread Ginger/GingerCoreNET/External/ZAP/ZapProxyService.cs
@Maheshkale447
Maheshkale447 merged commit e7c2d18 into Releases/Beta Sep 4, 2025
11 checks passed
@Maheshkale447
Maheshkale447 deleted the Enhancements/UnitTestCasesForZAP branch September 4, 2025 07:19
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