Skip to content

Conversation

@SokolovskyiK
Copy link
Contributor

@SokolovskyiK SokolovskyiK commented Apr 21, 2025

Fixes #15016

Note

I’d love to contribute more in the future — so if anything I’ve done here is non-idiomatic or misaligned with Pipedream practices, , I’m genuinely happy to adjust and improve.


What’s Included

This PR introduces two new actions for the Google Search Console integration:

  • Retrieve Site Performance Data
    Fetches search analytics with flexible filtering, dimensions, and pagination.

  • Submit URL for Indexing
    Notifies Google that a page's content has been updated.
    ⚠️ Note: The standard Google Search Console app does not include the required Indexing API scope so this action was tested using a manually generated token with appropriate permissions.


Input Validation Philosophy

These actions include input validation before sending requests to the external API, and they clearly identify which field caused the error when one is detected.
While some users may expect to receive raw API errors (e.g. 400, 403, etc.), this validation is intentionally scoped to catch only definitely invalid inputs — not to override meaningful errors from the external service.

For inputs that appear suspicious but are not clearly invalid, the action does not block execution. Instead, it issues a warning in the UI to help users catch potential issues early without interrupting the workflow.


Examples of Validation Behavior

🛑 Inputs That Throw an Error

These inputs are considered definitely invalid, and the action will block execution:

  • Malformed URLs (e.g., http://exa mple.com — contains spaces)
  • Strings consisting only of whitespace
  • Incorrect types (e.g., passing an array when a string is expected)
  • Invalid date formats (must follow YYYY-MM-DD)

⚠️ Inputs That Trigger a Warning

These inputs are suspicious but not clearly invalid. The action continues execution, but a warning is shown in the $summary:

  • URLs containing backslashes (e.g., https:\example.com)
  • Zero-width or non-printable characters, or dubious characters like <, >, ", etc.
  • Unusual formatting that may lead to API-side rejection

These issues are often mishandled by APIs or lead to unclear responses like "invalid url" or "bad request".
Catching them early improves clarity, avoids unnecessary requests, and helps users debug faster.

I’m aware this introduces a layer of abstraction over the API’s native error handling, and I’m happy to revisit this if it becomes a problem.
However, I believe the trade-off is justified — especially in light of the Pipedream documentation:

“Typically, integrating with these services requires custom code to manage connection logic, error handling, and more. Actions handle that for you. You only need to specify the parameters required for the action.”


✅ Testing Notes

These actions were tested both locally (via custom test runners in the /tests folder) and through the Pipedream UI using real authenticated accounts and verified sites.

Test coverage includes:

  • Valid requests with all optional fields
  • Suspicious but non-blocking input (triggering warnings)
  • Validation failures with malformed or incorrect data

📁 About the /tests Folder

You’ll notice a /tests folder included in this PR.

It contains local test runners and helper scripts used to simulate the $ context and invoke the actions outside the Pipedream platform.

While not required for production, it:

  • Documents how the components were tested locally
  • Provides a reproducible setup for future debugging
  • May be helpful to other contributors or reviewers

🧹 It’s 100% safe to delete the folder if you prefer a cleaner repo — it has no effect on runtime or deployment.


Thanks again for the awesome platform!

Summary by CodeRabbit

  • New Features
    • Introduced actions for retrieving Google Search Console site performance data and submitting URLs for indexing via Google APIs.
  • Documentation
    • Added and updated README files detailing available actions, usage instructions, authentication requirements, and example payloads for new features.
  • Tests
    • Added local test scripts and data sets for validating input handling, URL and date validation, and simulating API interactions outside the production environment.
  • Chores
    • Updated package version to 0.7.0.

@vercel
Copy link

vercel bot commented Apr 21, 2025

@SokolovskyiK is attempting to deploy a commit to the Pipedreamers Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link

vercel bot commented Apr 21, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Apr 24, 2025 5:19pm

@adolfo-pd adolfo-pd added the User submitted Submitted by a user label Apr 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 21, 2025

Walkthrough

This update introduces two new actions for the Google Search Console component: one to submit URLs for indexing via the Google Indexing API, and another to retrieve site performance analytics data. Each action includes new implementation modules, detailed documentation, and input validation logic. Utility and validation methods are added to a shared module, and local test scripts with supporting data and mocks are provided for development and validation. The component's main app file is updated to incorporate the new methods, and the package version is incremented to 0.7.0. Documentation is expanded to describe the new actions and testing setup.

Changes

File(s) Change Summary
components/google_search_console/README.md, actions/retrieve-site-performance-data/README.md, actions/submit-url-for-indexing/README.md Updated/added documentation for the component and both new actions, describing usage, authentication, endpoints, and examples.
actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs, actions/submit-url-for-indexing/submit-url-for-indexing.mjs Added new action modules for retrieving site performance data and submitting URLs for indexing, with input validation, error handling, and API calls.
common/methods.mjs, common/utils.mjs Introduced shared validation, error handling, and utility functions for input processing and object manipulation.
google_search_console.app.mjs Extended the app's methods with the new validation and utility functions.
package.json Updated the package version from 0.6.0 to 0.7.0.
common/tests/README.md, common/tests/action-tests/test-retrieve-site-performance-data.mjs, common/tests/action-tests/test-submit-url-for-indexing.mjs, common/tests/get-token.mjs, common/tests/mockery-dollar.mjs Added local test documentation, test runners for both actions, an OAuth token utility, and a mock $ object for local testing.
common/tests/methods/bogus-data/bogus-data-google-date.mjs, common/tests/methods/bogus-data/bogus-data-url.mjs Provided bogus data sets for edge-case and type validation testing.
common/tests/methods/test-checkIfUrlValid.mjs, common/tests/methods/test-throwIfNotYMDDashDate.mjs Added unit test scripts for URL and date validation methods.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action
    participant GoogleAPI

    User->>Action: Provide input (siteUrl, etc.)
    Action->>Action: Validate and trim input
    Action->>GoogleAPI: Make authenticated API request
    GoogleAPI-->>Action: Return API response
    Action-->>User: Return summary and raw response
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement "submit-url-for-indexing" action per requirements (#15016)
Implement "retrieve-site-performance-data" action with configurable filters (#15016)
Input validation, error handling, and documentation for both actions (#15016)

Suggested labels

ai-assisted

Suggested reviewers

  • lcaresia

Poem

A bunny hopped in code’s domain,
With Google tools to entertain—
URLs indexed, data fetched,
Each input trimmed and warnings checked.
Now rabbits dance, the tests all pass,
Version bumped, we’re shipping fast!
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/google_search_console/common/tests/action-tests/test-submit-url-for-indexing.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 127e8db and fbf3961.

📒 Files selected for processing (1)
  • components/google_search_console/common/tests/action-tests/test-submit-url-for-indexing.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/google_search_console/common/tests/action-tests/test-submit-url-for-indexing.mjs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai 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 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

Documentation and Community

  • 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.

@pipedream-component-development
Copy link
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (32)
components/google_search_console/tests/mockery-dollar.mjs (1)

1-1: Fix typo in comment. The word "Immitiates" is misspelled; it should be "Imitates".

components/google_search_console/common/utils.mjs (2)

23-23: Fix typo in comment. Change "rimmed" to "trimmed" to accurately describe the behavior of trimIfString.


4-21: Guard against inherited properties and optimize loops.
Using for…in can iterate over prototype properties; consider switching to Object.keys() and replace the blacklist array with a Set for better performance and clarity.

-export function removeCustomPropFields(input) {
-  const blacklist = ["extendedType", "postBody"];
-  const clean = {};
-
-  for (const key in input) {
-    const prop = input[key];
-    const cloned = {};
-
-    for (const field in prop) {
-      if (!blacklist.includes(field)) {
-        cloned[field] = prop[field];
-      }
-    };
-
-    clean[key] = cloned;
-  };
-
-  return clean;
-}
+export function removeCustomPropFields(input) {
+  const blacklist = new Set(["extendedType", "postBody"]);
+  const clean = {};
+
+  for (const key of Object.keys(input)) {
+    const prop = input[key];
+    const cloned = {};
+
+    for (const field of Object.keys(prop)) {
+      if (!blacklist.has(field)) {
+        cloned[field] = prop[field];
+      }
+    }
+
+    clean[key] = cloned;
+  }
+
+  return clean;
+}
components/google_search_console/actions/submit-url-for-indexing/README.md (1)

1-31: Clear and comprehensive documentation.

The README is well-structured and provides excellent information about the action's purpose, use cases, internals, authentication requirements, and endpoint.

Consider formatting the bare URLs as proper markdown links for better adherence to markdown best practices:

-Requires OAuth 2.0 with this scope: https://www.googleapis.com/auth/indexing
+Requires OAuth 2.0 with this scope: [https://www.googleapis.com/auth/indexing](https://www.googleapis.com/auth/indexing)

-https://indexing.googleapis.com/v3/urlNotifications:publish
+[https://indexing.googleapis.com/v3/urlNotifications:publish](https://indexing.googleapis.com/v3/urlNotifications:publish)
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

27-27: Bare URL used
null

(MD034, no-bare-urls)


31-31: Bare URL used
null

(MD034, no-bare-urls)

components/google_search_console/tests/methods/test-checkIfUrlValid.mjs (2)

5-6: Fix typo in comment.

There's a small typo in the comment.

-// Any other case from bogus data shoul lead to throw
+// Any other case from bogus data should lead to throw

55-96: Robust test logic with minor enhancement opportunities.

The test provides comprehensive coverage of various URL formats and edge cases, which aligns well with the PR's focus on robust input validation.

Consider adding a check to ensure bogusCase exists in validCases before trying to access it to prevent potential undefined property access:

        console.log ("==============");
    
        let result;
        const testArg = bogus[bogusCase].value;
        const extendedType = bogus[bogusCase].extendedType;

        try {
            console.log("ENTERED VALUE", testArg, "of extended type ", extendedType);
            result = methods.checkIfUrlValid(testArg);
            
        } catch(err) {
            if (err.isCustom) {
                console.log ("------- \x1b[32m EXPECTED THROW PASS!\x1b[0m", "Custom error was thrown as expected" );
                console.log();
            } else {
                console.log ("--- \x1b[31m HARD FAIL! \x1b[0m", "UNEXPECTED ERROR WAS THROWN");
                console.log (err);
                counterOfFails++;
            };
            continue;
        }
        
  
+       // Skip validation if this case isn't in our validCases mapping
+       if (!validCases[bogusCase]) {
+           console.log ("--- \x1b[33m SKIPPED! \x1b[0m", "No expected values defined for this case");
+           continue;
+       }

        const pass = 
        (result.warnings.length === validCases[bogusCase].warnings )&&
        (result.url === validCases[bogusCase].url);
components/google_search_console/tests/README.md (1)

1-44: Well-organized testing documentation.

This README provides clear information about the test suite structure and purpose. The explicit notes about the tests being for local development only and that they can be safely deleted are particularly helpful.

Fix the markdown linting issues by removing extra spaces after the hash marks in headings:

-#  Local Tests Directory
+# Local Tests Directory

-##  Folder Structure
+## Folder Structure
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


8-8: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)

components/google_search_console/tests/methods/test-throwIfNotYMDDashDate.mjs (3)

15-15: Incorrect console log message

The console log message indicates "Running checkUrl() tests..." but this script is testing the throwIfNotYMDDashDate function, not checkUrl().

-console.log("Running checkUrl() tests...");
+console.log("Running throwIfNotYMDDashDate() tests...");

7-10: Improve test coverage with more valid test cases

The test only defines one valid test case (aValidYMDDashDate). Consider adding more valid date formats to ensure comprehensive test coverage.

const validCases = {
    
    aValidYMDDashDate: bogus.aValidYMDDashDate.value,
+   // Add more valid test cases
+   // For example:
+   anotherValidDate: "2023-01-01",
+   validLeapYearDate: "2024-02-29",
};

61-63: Add overall test pass/fail status

The test reports the total number of failures but doesn't clearly indicate whether the overall test suite passed or failed. Add a clear pass/fail indicator based on the counter value.

console.log ("OOOOOOOOOOOOOOOOOOOOOOOOOOOO");
console.log ("TOTAL FAILS = ", counterOfFails);
+console.log (counterOfFails === 0 ? "\x1b[32mALL TESTS PASSED!\x1b[0m" : "\x1b[31mTEST SUITE FAILED!\x1b[0m");
console.log ("OOOOOOOOOOOOOOOOOOOOOOOOOOOO");
+process.exit(counterOfFails > 0 ? 1 : 0); // Exit with appropriate code for CI/CD integration
components/google_search_console/tests/get-token.mjs (3)

9-9: Fix typo in placeholder text

There's a typo in the client ID placeholder.

-const clientId = "*CLIEN ID HERE*";
+const clientId = "*CLIENT ID HERE*";

56-56: Fix incomplete placeholder format

The client secret placeholder is missing the closing asterisk.

-        client_secret: "*CLIENT SECRET HERE", 
+        client_secret: "*CLIENT SECRET HERE*", 

4-23: Add token storage capability for reuse in tests

The current script displays the tokens in the console, but doesn't save them for later use in tests. Consider adding an option to save tokens to a local file (excluded from git) for test reuse.

// Bare-bones OAuth script to fetch a token.
// For testing purposes only — no timeouts, no browser response.
// Manually terminate the script from the console when finished.

import open from "open";
import http from "http";
+import fs from "fs";
+import path from "path";

+// Optional: Save tokens to a local file for reuse in tests
+const SAVE_TOKENS = true;
+const TOKEN_FILE_PATH = path.join(process.cwd(), '.google_tokens.json');

// --- Google OAuth Config ---
const clientId = "*CLIENT ID HERE*";
const redirectUri = "http://localhost:3000";
const scopes = [
  "https://www.googleapis.com/auth/webmasters.readonly",
  "https://www.googleapis.com/auth/indexing",
].join(" ");

+// Function to save tokens to a local file
+function saveTokens(tokens) {
+  if (!SAVE_TOKENS) return;
+  try {
+    fs.writeFileSync(TOKEN_FILE_PATH, JSON.stringify(tokens, null, 2));
+    console.log(`Tokens saved to ${TOKEN_FILE_PATH}`);
+    console.log('IMPORTANT: This file contains sensitive credentials. Do not commit it to version control.');
+  } catch (err) {
+    console.error('Failed to save tokens:', err);
+  }
+}

And in the token response handler:

.then((data) => {
  if (data.access_token) {
    console.log("🎉 Tokens received!");
    console.log("Access Token:", data.access_token);
    console.log("Refresh Token:", data.refresh_token);
    console.log("Expires In:", data.expires_in);
+   saveTokens({
+     access_token: data.access_token,
+     refresh_token: data.refresh_token,
+     expires_in: data.expires_in,
+     created_at: Date.now()
+   });
    console.log("✅ Token retrieval complete. Shutting down server...");
    process.exit(0);
  } else {
components/google_search_console/tests/action-tests/test-submit-url-for-indexing.mjs (4)

64-64: Replace hardcoded token placeholder with instructions

The current placeholder for the token doesn't include clear instructions on how to replace it or where to get a valid token.

-          Authorization: `Bearer *HARDCODED TOKEN HERE*`,
+          Authorization: `Bearer YOUR_ACCESS_TOKEN`, // Replace with a token from get-token.mjs with scope: "https://www.googleapis.com/auth/indexing"

76-76: Improve error message clarity

The current error message concatenates warnings with an unusual delimiter "!" which could be confusing to users.

-      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + warnings.join("*!*"));
+      const warningStr = warnings.length > 0 ? ` Warnings: ${warnings.join(", ")}` : "";
+      throw new Error(`Failed to fetch data (${thrower.whoThrew} error): ${error.message}.${warningStr}`);

80-80: Improve warning display in summary message

Similar to the error message, the summary message concatenates warnings with an unusual delimiter.

-    $.export("$summary", ` URL submitted to Google: ${this.siteUrl}`  + warnings.join("*!*"));
+    const warningStr = warnings.length > 0 ? ` (Warnings: ${warnings.join(", ")})` : "";
+    $.export("$summary", `URL submitted to Google: ${this.siteUrl}${warningStr}`);

50-52: Avoid modifying URL check result directly

The code directly accesses the URL check result's warnings property and manipulates it. Consider using a more robust approach.

-    const urlCheck = gsConsole.methods.checkIfUrlValid(this.siteUrl); // TEST ONLY. Replace to "this"
-
-    if (urlCheck.warnings) warnings.push(...urlCheck.warnings);
+    const urlCheck = gsConsole.methods.checkIfUrlValid(this.siteUrl); // TEST ONLY. Replace to "this"
+    
+    // Safely extract warnings if they exist
+    if (urlCheck && urlCheck.warnings && Array.isArray(urlCheck.warnings)) {
+      warnings.push(...urlCheck.warnings);
+    }
components/google_search_console/actions/retrieve-site-performance-data/README.md (4)

1-1: Fix markdown heading formatting

There are multiple spaces after the hash symbol in the heading, which is flagged by markdown linting.

-#  Google Search Console – Site Performance (Analytics) Action
+# Google Search Console – Site Performance (Analytics) Action
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


12-12: Fix multiple markdown heading formatting issues

All section headings have multiple spaces after the hash, which is flagged by markdown linting.

-##  Use Cases
+## Use Cases

-##  Internals
+## Internals

-##  Auth
+## Auth

-##  Endpoint
+## Endpoint

Also applies to: 20-20, 31-31, 36-36

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

12-12: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


33-33: Fix bare URLs in markdown

The markdown linter flags bare URLs. Consider enclosing them in angle brackets or using markdown link syntax.

-Requires OAuth 2.0 with the following scope: https://www.googleapis.com/auth/webmasters.readonly
+Requires OAuth 2.0 with the following scope: `https://www.googleapis.com/auth/webmasters.readonly`

-https://searchconsole.googleapis.com/webmasters/v3/sites/{siteUrl}/searchAnalytics/query
+`https://searchconsole.googleapis.com/webmasters/v3/sites/{siteUrl}/searchAnalytics/query`

-  "siteUrl": "https://falc1.com/soda_can",
+  "siteUrl": "https://example.com/page",

Also applies to: 37-37, 48-48

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

33-33: Bare URL used
null

(MD034, no-bare-urls)


40-109: Improve example payload formatting

The example JSON payload lacks proper code block formatting and contains unnecessary comments within the JSON structure, which could confuse users trying to copy and modify it.

Consider reformatting the example as:

## 📦 Example Request Payload

+```json
{
-  // The site you want to query data for.
-  // Must be verified in your Google Search Console account.
  "siteUrl": "https://example.com/page",

-  // The start date of the reporting period (inclusive), in YYYY-MM-DD format.
  "startDate": "2025-12-22",

-  // The end date of the reporting period (inclusive), in YYYY-MM-DD format.
  "endDate": "2025-12-31",

-  // The dimensions you want to break down the data by.
-  // Valid values: "query", "page", "country", "device", "searchAppearance", "date".
-  // Order matters — it affects how rows are grouped in the response.
  "dimensions": ["query", "page", "country", "device"],

-  // The type of search data to include.
-  // Valid values: "web", "image", "video", "news", "googleNews", "discover"
  "searchType": "web",

-  // Maximum number of rows to return (1–25,000)
  "rowLimit": 10,

-  // Optional: Skips the first N rows — used for pagination.
  "startRow": 0,

-  // Optional: How to group data.
-  // "auto" = Google's default grouping.
-  // "byPage" = Group by page (useful for getting per-page breakdowns).
  "aggregationType": "auto",

-  // Optional: Data freshness filter.
-  // "final" = Only finalized data (more accurate).
-  // "all" = Includes fresh but possibly incomplete data.
  "dataState": "final",

-  // Optional filter group(s) to restrict which rows are returned.
-  // Each group applies logical AND/OR across its filters.
  "dimensionFilterGroups": [
    {
-      // Logical grouping operator for the filters inside this group.
-      // "and" = all filters must match
-      // "or" = any filter can match
      "groupType": "and",

-      // List of individual filters to apply within the group
      "filters": [
        {
-          // Which dimension to filter by (must match a dimension in your request)
          "dimension": "query",

-          // Filter operator — e.g., "equals", "contains", "notEquals", etc.
          "operator": "contains",

-          // Value to match against
          "expression": "example"
        },
        {
          "dimension": "country",
          "operator": "equals",
          "expression": "USA"
        }
      ]
    }
  ]
}
+```

+### Field Descriptions
+
+- **siteUrl**: The site you want to query data for. Must be verified in your Google Search Console account.
+- **startDate**: The start date of the reporting period (inclusive), in YYYY-MM-DD format.
+- **endDate**: The end date of the reporting period (inclusive), in YYYY-MM-DD format.
+- **dimensions**: The dimensions you want to break down the data by. Valid values: "query", "page", "country", "device", "searchAppearance", "date". Order matters — it affects how rows are grouped in the response.
+- **searchType**: The type of search data to include. Valid values: "web", "image", "video", "news", "googleNews", "discover"
+- **rowLimit**: Maximum number of rows to return (1–25,000)
+- **startRow**: Optional: Skips the first N rows — used for pagination.
+- **aggregationType**: Optional: How to group data. "auto" = Google's default grouping. "byPage" = Group by page (useful for getting per-page breakdowns).
+- **dataState**: Optional: Data freshness filter. "final" = Only finalized data (more accurate). "all" = Includes fresh but possibly incomplete data.
+- **dimensionFilterGroups**: Optional filter group(s) to restrict which rows are returned. Each group applies logical AND/OR across its filters.
+  - **groupType**: Logical grouping operator for the filters inside this group. "and" = all filters must match, "or" = any filter can match
+  - **filters**: List of individual filters to apply within the group
+    - **dimension**: Which dimension to filter by (must match a dimension in your request)
+    - **operator**: Filter operator — e.g., "equals", "contains", "notEquals", etc.
+    - **expression**: Value to match against
🧰 Tools
🪛 LanguageTool

[uncategorized] ~109-~109: Loose punctuation mark.
Context: ...ssion": "USA" } ] } ] }

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)

48-48: Bare URL used
null

(MD034, no-bare-urls)

components/google_search_console/actions/submit-url-for-indexing/submit-url-for-indexing.mjs (4)

8-8: Import formatting and organization can be improved.

The spacing after trimIfString import is inconsistent. Consider adding a comma after the import.

-import {trimIfString } from "../../common/utils.mjs"
+import { trimIfString } from "../../common/utils.mjs"

60-60: Fix extra space in Authorization header.

There's an extra space between "Bearer" and the token which could potentially cause authentication issues.

-          Authorization: `Bearer  ${this.gsConsole.$auth.oauth_access_token}`,
+          Authorization: `Bearer ${this.gsConsole.$auth.oauth_access_token}`,

78-79: Improve error message readability.

The warning separator might make error messages difficult to read. Consider adding a space before warnings are appended.

-      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + warnings.join("*!*"));
+      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + (warnings.length ? " " + warnings.join("*!*") : ""));

82-82: Improve summary message readability.

Similar to the error message, consider adding a space before appending warnings.

-    $.export("$summary", ` URL submitted to Google: ${this.siteUrl}`  + warnings.join("*!*"));
+    $.export("$summary", ` URL submitted to Google: ${this.siteUrl}`  + (warnings.length ? " " + warnings.join("*!*") : ""));
components/google_search_console/actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs (2)

183-183: Consider improving error message readability.

Similar to the submit-url action, the error message could be more readable with proper spacing before warnings.

-      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + warnings.join("*!*"));
+      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + (warnings.length ? " " + warnings.join("*!*") : ""));

188-188: Improve summary message readability.

The summary message could be more readable with proper spacing before warnings.

-    $.export("$summary", ` Fetched ${response.rows?.length || 0} rows of data. ` + warnings.join("*!*"));
+    $.export("$summary", ` Fetched ${response.rows?.length || 0} rows of data. ` + (warnings.length ? " " + warnings.join("*!*") : ""));
components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (3)

179-180: Remove debugging console.log statements.

Production code should not contain debugging statements. Consider removing or using a conditional debug flag.

-      console.log("===VALUE", this[propName]); // TEST ONLY

198-199: Remove another debugging console.log statement.

Production code should not contain debugging statements.

-      console.log(" SUCCESS"); // TEST ONLY

223-223: Add warnings to the error message.

Unlike the actual implementation, the test code doesn't append warnings to the error message, which means the test doesn't fully match the production behavior.

-      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. `);
+      throw new Error(`Failed to fetch data ( ${thrower.whoThrew} error ) : ${error.message}. ` + (warnings.length ? " " + warnings.join("*!*") : ""));
components/google_search_console/common/methods.mjs (2)

171-237: URL validation is comprehensive but has inconsistent return format.

The checkIfUrlValid function returns an object { warnings, url } while other validators return the validated value directly. This inconsistency could lead to unexpected behavior when using these functions interchangeably.

Consider either:

  1. Renaming to validateUrl and returning just the URL like other validators
  2. Making all validators return the { warnings, value } format
🧰 Tools
🪛 Biome (1.9.4)

[error] 189-189: A character class cannot match a joined character sequence.

A zero width joiner composes several emojis into a new one. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)


303-305: Error handling in parseIfJsonString could be improved.

Consider keeping the original error as the cause of the new error for better debugging.

-        this.throwCustomError( `Can not parse JSON. Error : ${err}`  +  this._reasonMsg(reason))
+        const error = new Error(`Can not parse JSON: ${err.message}` + this._reasonMsg(reason));
+        error.cause = err;
+        error.isCustom = true;
+        throw error;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c5072e and 6b15621.

📒 Files selected for processing (17)
  • components/google_search_console/README.md (1 hunks)
  • components/google_search_console/actions/retrieve-site-performance-data/README.md (1 hunks)
  • components/google_search_console/actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs (1 hunks)
  • components/google_search_console/actions/submit-url-for-indexing/README.md (1 hunks)
  • components/google_search_console/actions/submit-url-for-indexing/submit-url-for-indexing.mjs (1 hunks)
  • components/google_search_console/common/methods.mjs (1 hunks)
  • components/google_search_console/common/utils.mjs (1 hunks)
  • components/google_search_console/google_search_console.app.mjs (1 hunks)
  • components/google_search_console/tests/README.md (1 hunks)
  • components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (1 hunks)
  • components/google_search_console/tests/action-tests/test-submit-url-for-indexing.mjs (1 hunks)
  • components/google_search_console/tests/get-token.mjs (1 hunks)
  • components/google_search_console/tests/methods/bogus-data/bogus-data-google-date.mjs (1 hunks)
  • components/google_search_console/tests/methods/bogus-data/bogus-data-url.mjs (1 hunks)
  • components/google_search_console/tests/methods/test-checkIfUrlValid.mjs (1 hunks)
  • components/google_search_console/tests/methods/test-throwIfNotYMDDashDate.mjs (1 hunks)
  • components/google_search_console/tests/mockery-dollar.mjs (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
components/google_search_console/actions/submit-url-for-indexing/README.md

27-27: Bare URL used
null

(MD034, no-bare-urls)


31-31: Bare URL used
null

(MD034, no-bare-urls)

components/google_search_console/tests/README.md

1-1: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


8-8: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)

components/google_search_console/actions/retrieve-site-performance-data/README.md

1-1: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


12-12: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


20-20: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


31-31: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


33-33: Bare URL used
null

(MD034, no-bare-urls)


36-36: Multiple spaces after hash on atx style heading
null

(MD019, no-multiple-space-atx)


37-37: Bare URL used
null

(MD034, no-bare-urls)


48-48: Bare URL used
null

(MD034, no-bare-urls)

🪛 LanguageTool
components/google_search_console/actions/retrieve-site-performance-data/README.md

[uncategorized] ~109-~109: Loose punctuation mark.
Context: ...ssion": "USA" } ] } ] }

(UNLIKELY_OPENING_PUNCTUATION)

🪛 Biome (1.9.4)
components/google_search_console/common/methods.mjs

[error] 189-189: A character class cannot match a joined character sequence.

A zero width joiner composes several emojis into a new one. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)

🔇 Additional comments (8)
components/google_search_console/google_search_console.app.mjs (1)

1-2: Well-structured integration of shared methods.

The approach of importing validation methods from a common module and integrating them with the spread operator is clean and maintainable. This pattern promotes code reuse and ensures consistent validation behavior across the component's actions.

Also applies to: 8-8

components/google_search_console/actions/submit-url-for-indexing/submit-url-for-indexing.mjs (1)

33-48: The validation and warning handling looks robust.

The approach of accumulating warnings without blocking execution aligns well with the PR objective of identifying suspicious but not clearly invalid inputs.

components/google_search_console/actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs (3)

27-99: Well-structured prop metadata with comprehensive validation.

The approach of defining extended metadata separately from standard Pipedream props enables rich validation while maintaining UI compatibility. The postBody flag efficiently marks which props should be included in the API request.


119-127: This approach to JSON validation is robust.

Handling both object and string inputs for dimensionFilterGroups provides good flexibility for users, whether they're configuring through the UI or programmatically.


141-160: The validation loop is elegant and handles optional fields correctly.

The loop efficiently processes all props using their metadata, respecting optional fields and accumulating warnings without blocking execution.

components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (1)

1-18: Well-documented test file with clear instructions.

The header comments clearly explain the purpose of this file and how to use it, which is excellent for maintainability.

components/google_search_console/common/methods.mjs (2)

8-12: Good approach for custom error handling.

Adding the isCustom flag to errors makes it easier to distinguish between internal validation errors and external API errors.


255-284: The validateUserInput function is well designed.

Using a mapping object to dispatch to the appropriate validator based on type is a clean approach and makes adding new validators easy.

@SokolovskyiK SokolovskyiK changed the title feat(google_search_console): add “Retrieve Site Performance” & “Submit URL for Indexing” actions [Components] google_search_console : add “Retrieve Site Performance” & “Submit URL for Indexing” actions Apr 21, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (5)
components/google_search_console/common/methods.mjs (4)

94-102: 🛠️ Refactor suggestion

Method implementation is inverted from what its name suggests.

Similar to the array validation method, the name suggests it throws when the input is not an object, but the implementation returns the input when it is an object and throws otherwise.

Rename the method to match its behavior:

-  throwIfNotObject(input, reason) {
+  validateObject(input, reason) {
    
    if( typeof input === "object" && input !== null && !Array.isArray(input)){
      return input;
    };
      
    this.throwCustomError(`Invalid argument type. Expected an object ` +  this._reasonMsg(reason));

  },

189-189: ⚠️ Potential issue

Fix misleading character class in regex.

The character class contains zero-width joiners which can't be matched correctly in a character class.

Replace with alternation as recommended by the static analysis tool:

-    const dubiousCharRegex = /[\\<>{}|"`^]|[\u200B\u200C\u200D\u2060\uFEFF\u00A0]/g;
+    const dubiousCharRegex = /[\\<>{}|"`^]|\u200B|\u200C|\u200D|\u2060|\uFEFF|\u00A0/g;
🧰 Tools
🪛 Biome (1.9.4)

[error] 189-189: A character class cannot match a joined character sequence.

A zero width joiner composes several emojis into a new one. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)


63-70: 🛠️ Refactor suggestion

Method names don't match implementation logic.

The method name throwIfNotArray suggests it throws when the condition isn't met, but it returns the input when the condition is met and throws otherwise. This creates confusion about the expected behavior.

Rename the method to better reflect its behavior:

-  throwIfNotArray(input, reason) {
+  validateArray(input, reason) {

     if (!Array.isArray(input)) {
       this.throwCustomError(`Invalid argument type. Expected an array ` +  this._reasonMsg(reason));
     };

     return input;
   },

109-117: 🛠️ Refactor suggestion

Method name contradicts its implementation.

The naming pattern continues to be inconsistent with the implementation. The method returns the input when it is an object or array, rather than throwing when it's not.

Rename for clarity:

-throwIfNotObjectOrArray(input, reason) {
+validateObjectOrArray(input, reason) {
    
  if( typeof input === "object" && input !== null){
    return input;
  };
    
  this.throwCustomError(`Invalid argument type. Expected an object or array` +  this._reasonMsg(reason));

},
components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (1)

211-214: ⚠️ Potential issue

Replace hardcoded token with environment variable.

Hardcoded tokens—even placeholders—risk accidental commits of real credentials.

Load tokens from environment variables instead:

-            Authorization: `Bearer  *HARDCODED TOKEN HERE*`,
+            Authorization: `Bearer ${process.env.GSC_API_TOKEN}`,

Add a .env.example file with GSC_API_TOKEN=your_token_here and ensure .env is in .gitignore.

🧹 Nitpick comments (2)
components/google_search_console/common/methods.mjs (1)

232-235: Return trimmed URL for consistency.

The method trims the input URL for validation but returns the original untrimmed URL, which could lead to inconsistencies.

Return the trimmed version for consistency:

  return {
    warnings : warnings,
-    url : input,
+    url : trimmedInput,
  };
components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (1)

179-179: Remove debug logging statement.

This console log is useful for development but should be removed or commented out before submission.

-      console.log("===VALUE", this[propName]);
+      // console.log("===VALUE", this[propName]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 173277a and f4c36fb.

📒 Files selected for processing (6)
  • components/google_search_console/actions/retrieve-site-performance-data/README.md (1 hunks)
  • components/google_search_console/actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs (1 hunks)
  • components/google_search_console/actions/submit-url-for-indexing/submit-url-for-indexing.mjs (1 hunks)
  • components/google_search_console/common/methods.mjs (1 hunks)
  • components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (1 hunks)
  • components/google_search_console/tests/action-tests/test-submit-url-for-indexing.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • components/google_search_console/actions/retrieve-site-performance-data/README.md
  • components/google_search_console/actions/submit-url-for-indexing/submit-url-for-indexing.mjs
  • components/google_search_console/tests/action-tests/test-submit-url-for-indexing.mjs
  • components/google_search_console/actions/retrieve-site-performance-data/retrieve-site-performance-data.mjs
🧰 Additional context used
🪛 Biome (1.9.4)
components/google_search_console/common/methods.mjs

[error] 189-189: A character class cannot match a joined character sequence.

A zero width joiner composes several emojis into a new one. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)

🔇 Additional comments (3)
components/google_search_console/common/methods.mjs (1)

265-273: Good implementation of validator selection.

The validator mapping approach makes the code maintainable and easy to extend. The use of extended types is a nice design that allows specialized validation beyond basic types.

components/google_search_console/tests/action-tests/test-retrieve-site-performance-data.mjs (2)

31-69: Well-structured test data with comprehensive coverage.

The test data covers all required fields and includes optional parameters with valid values, making it an excellent test case for the action.


167-199: Good validation loop with warning accumulation.

The validation approach is robust and user-friendly:

  1. Trims string inputs
  2. Skips optional empty fields
  3. Validates inputs with appropriate validators
  4. Accumulates warnings instead of failing immediately
  5. Builds the request body dynamically

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (5)
components/google_search_console/common/tests/methods/test-throwIfNotYMDDashDate.mjs (2)

6-9: Consider expanding test coverage with additional valid cases.

The validCases object only contains a single test case. Adding more explicit valid test cases would improve test coverage and make the validation logic more robust.

const validCases = {
  aValidYMDDashDate: bogus.aValidYMDDashDate.value,
+  // Add more valid cases with expected results
+  aValidFutureDate: "2030-01-01", 
+  aValidPastDate: "2000-12-31",
};

15-52: Consider using a standard testing framework.

The custom test harness with console logs works but lacks the structure and reporting capabilities of standard testing frameworks. Consider migrating to Jest, Mocha, or another testing framework for more maintainable tests.

For example, with Jest:

import methods from "../../common/methods.mjs";
import bogus from "./bogus-data/bogus-data-google-date.mjs";

describe('throwIfNotYMDDashDate', () => {
  // Test valid cases
  test.each([
    ['aValidYMDDashDate', bogus.aValidYMDDashDate.value],
  ])('valid date %s returns expected result', (testName, value) => {
    expect(methods.throwIfNotYMDDashDate(value)).toBe(value);
  });
  
  // Test invalid cases
  test.each(
    Object.entries(bogus)
      .filter(([key]) => key !== 'aValidYMDDashDate')
      .map(([key, data]) => [key, data.value, data.extendedType])
  )('invalid date %s throws custom error', (testName, value, type) => {
    expect(() => methods.throwIfNotYMDDashDate(value)).toThrow();
  });
});
components/google_search_console/common/tests/methods/test-checkIfUrlValid.mjs (1)

51-89: Consider using a standard testing framework.

Similar to the previous file, consider migrating this custom test harness to a standard testing framework like Jest or Mocha for better maintainability and reporting.

For example with Jest:

import methods from "../../../common/methods.mjs";
import bogus from "./bogus-data/bogus-data-url.mjs";

describe('checkIfUrlValid', () => {
  // Test valid cases
  test.each([
    ['aValidHttpsUrl', bogus.aValidHttpsUrl.value, 0, bogus.aValidHttpsUrl.value],
    ['aValidUrlWithoutProtocol', bogus.aValidUrlWithoutProtocol.value, 1, bogus.aValidUrlWithoutProtocol.value],
    // Add more test cases...
  ])('valid URL %s returns expected result', (testName, url, warningCount, normalizedUrl) => {
    const result = methods.checkIfUrlValid(url);
    expect(result.warnings.length).toBe(warningCount);
    expect(result.url).toBe(normalizedUrl);
  });
  
  // Test invalid cases that should throw
  test.each(
    // Filter for cases that should throw
    // ...
  )('invalid URL %s throws custom error', (testName, url) => {
    expect(() => methods.checkIfUrlValid(url)).toThrow();
  });
});
components/google_search_console/common/tests/action-tests/test-retrieve-site-performance-data.mjs (1)

35-39: Future test dates may cause issues with the API.

The test data includes future dates (2025), which may be rejected by the Google Search Console API. Consider using dates in the past for more reliable testing.

  // Required
-  startDate: "2025-12-22",
-  endDate: "2025-12-31",
+  startDate: "2023-01-01",
+  endDate: "2023-01-31",
components/google_search_console/common/tests/action-tests/test-submit-url-for-indexing.mjs (1)

53-53: Confusing inline comment.

The comment "TEST ONLY. Replace to 'this'" is ambiguous and doesn't clearly indicate what should be replaced in production code.

-  const urlCheck = gsConsole.methods.checkIfUrlValid(this.siteUrl); // TEST ONLY. Replace to "this"
+  const urlCheck = gsConsole.methods.checkIfUrlValid(this.url); // In production code, use the correct property name
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de82ab9 and 127e8db.

📒 Files selected for processing (9)
  • components/google_search_console/common/tests/README.md (1 hunks)
  • components/google_search_console/common/tests/action-tests/test-retrieve-site-performance-data.mjs (1 hunks)
  • components/google_search_console/common/tests/action-tests/test-submit-url-for-indexing.mjs (1 hunks)
  • components/google_search_console/common/tests/get-token.mjs (1 hunks)
  • components/google_search_console/common/tests/methods/bogus-data/bogus-data-google-date.mjs (1 hunks)
  • components/google_search_console/common/tests/methods/bogus-data/bogus-data-url.mjs (1 hunks)
  • components/google_search_console/common/tests/methods/test-checkIfUrlValid.mjs (1 hunks)
  • components/google_search_console/common/tests/methods/test-throwIfNotYMDDashDate.mjs (1 hunks)
  • components/google_search_console/common/tests/mockery-dollar.mjs (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • components/google_search_console/common/tests/mockery-dollar.mjs
  • components/google_search_console/common/tests/README.md
  • components/google_search_console/common/tests/methods/bogus-data/bogus-data-url.mjs
  • components/google_search_console/common/tests/get-token.mjs
  • components/google_search_console/common/tests/methods/bogus-data/bogus-data-google-date.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (5)
components/google_search_console/common/tests/methods/test-checkIfUrlValid.mjs (2)

6-45: Well-defined test cases covering diverse URL formats.

The test includes a comprehensive set of valid cases with expected warnings and normalized URLs for various URL formats including:

  • Valid HTTP/HTTPS URLs
  • URLs without protocols
  • URLs with dubious characters
  • Malformed slashes

This thorough approach ensures robust validation.


75-78: Robust validation checking both warnings and URL normalization.

The test correctly validates both aspects of the URL validation function:

  1. The number of warnings generated
  2. The normalized URL output

This dual validation ensures the function provides both proper feedback and correctly handles the URL.

components/google_search_console/common/tests/action-tests/test-retrieve-site-performance-data.mjs (3)

1-18: Clear documentation for local test runner.

The file header provides excellent documentation explaining the purpose, usage requirements, and limitations of the test runner. This helps developers understand how to use it safely for local debugging.


189-213: Comprehensive validation and prop processing logic.

The input processing loop effectively:

  1. Validates user inputs with appropriate validation rules
  2. Collects warnings without blocking execution for suspicious inputs
  3. Populates the request body with validated values
  4. Handles optional props appropriately

This robust approach ensures API requests are well-formed while providing clear feedback.


233-239: Good error handling with detailed context.

The error handling logic:

  1. Distinguishes between internal validation errors and API errors
  2. Includes accumulated warnings in the error message
  3. Preserves the original error message for debugging

This helps developers quickly identify whether issues come from input validation or the external API.

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution! Ready for QA!

@SokolovskyiK
Copy link
Contributor Author

@michelle0927 Cool. Thanks =)

@michelle0927 michelle0927 merged commit 4a30ccc into PipedreamHQ:master Apr 25, 2025
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

User submitted Submitted by a user

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Components] google_search_console

4 participants