diff --git a/.changes/unreleased/added-20260209-171617.yaml b/.changes/unreleased/added-20260209-171617.yaml new file mode 100644 index 000000000..5ee9486c6 --- /dev/null +++ b/.changes/unreleased/added-20260209-171617.yaml @@ -0,0 +1,6 @@ +kind: added +body: Add new 'fab find' command for searching the Fabric catalog across workspaces +time: 2026-02-09T17:16:17.2056327+02:00 +custom: + Author: nschachter + AuthorLink: https://github.com/nschachter diff --git a/MANIFEST.in b/MANIFEST.in index bdf02e3e5..b1c8264c9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include src/fabric_cli/core/fab_config/command_support.yaml +include src/fabric_cli/commands/find/type_supported.yaml recursive-include src/fabric_cli/commands/fs/payloads * \ No newline at end of file diff --git a/docs/commands/find.md b/docs/commands/find.md new file mode 100644 index 000000000..d00c53c19 --- /dev/null +++ b/docs/commands/find.md @@ -0,0 +1,55 @@ +# `find` Command + +Search the Fabric catalog for items across all workspaces. + +**Usage:** + +``` +fab find [-P ] [-l] [-q ] +``` + +**Parameters:** + +- ``: Search text. Matches display name, description, and workspace name. +- `-P, --params`: Filter parameters in `key=value` or `key!=value` format. Use brackets for multiple values: `type=[Lakehouse,Notebook]`. Use `!=` to exclude: `type!=Dashboard`. +- `-l, --long`: Show detailed table with IDs (name, id, type, workspace, workspace_id, description). Optional. +- `-q, --query`: JMESPath query to filter results client-side. Optional. + +**Examples:** + +``` +# search for items by name or description +fab find 'sales report' + +# search for lakehouses only +fab find 'data' -P type=Lakehouse + +# search for multiple item types (bracket syntax) +fab find 'dashboard' -P type=[Report,SemanticModel] + +# exclude a type +fab find 'data' -P type!=Dashboard + +# show detailed output with IDs +fab find 'sales' -l + +# combine filters +fab find 'finance' -P type=[Warehouse,Lakehouse] -l + +# project specific fields +fab find 'data' -q "[].{name: name, workspace: workspace}" +``` + +**Behavior:** + +- In interactive mode (`fab` shell), results are paged 50 at a time with "Press Enter to continue..." prompts. +- In command-line mode (`fab find ...`), all results are fetched in a single pass (up to 1000 per API call). +- Type names are case-insensitive. `type=lakehouse` matches `Lakehouse`. +- The `-q` JMESPath filter is applied client-side after results are returned from the API. + +**Supported filter parameters:** + +| Parameter | Description | +|-----------|-------------| +| `type` | Filter by item type. Supports `eq` (default) and `ne` (`!=`) operators. | + diff --git a/pyproject.toml b/pyproject.toml index 62e6938fd..f2c52dc5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,8 @@ package-data = { "fabric_cli.core.fab_config" = [ "command_support.yaml", ], "fabric_cli.commands.fs" = [ "payloads/*", +], "fabric_cli.commands.find" = [ + "type_supported.yaml", ] } [tool.mypy] diff --git a/src/fabric_cli/client/fab_api_catalog.py b/src/fabric_cli/client/fab_api_catalog.py new file mode 100644 index 000000000..da09a31ef --- /dev/null +++ b/src/fabric_cli/client/fab_api_catalog.py @@ -0,0 +1,47 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Catalog API client for searching Fabric items across workspaces. + +API Reference: POST https://api.fabric.microsoft.com/v1/catalog/search +Required Scope: Catalog.Read.All +""" + +from argparse import Namespace + +from fabric_cli.client import fab_api_client as fabric_api +from fabric_cli.client.fab_api_types import ApiResponse + + +def search(args: Namespace, payload: dict) -> ApiResponse: + """Search the Fabric catalog for items. + + https://learn.microsoft.com/en-us/rest/api/fabric/core/catalog/search + + Args: + args: Namespace with request configuration + payload: Dict with search request body: + - search (required): Text to search across displayName, description, workspaceName + - pageSize: Number of results per page + - continuationToken: Token for pagination + - filter: OData filter string, e.g., "Type eq 'Report' or Type eq 'Lakehouse'" + + Returns: + ApiResponse with search results containing: + - value: List of ItemCatalogEntry objects + - continuationToken: Token for next page (if more results exist) + + Note: + The following item types are NOT searchable via this API: + Dashboard + + Note: Dataflow Gen1 and Gen2 are currently not searchable; only Dataflow Gen2 + CI/CD items are returned (as type 'Dataflow'). + Scorecards are returned as type 'Report'. + """ + args.uri = "catalog/search" + args.method = "post" + # raw_response=True so we handle pagination ourselves in fab_find + args.raw_response = True + return fabric_api.do_request(args, json=payload) + diff --git a/src/fabric_cli/commands/find/__init__.py b/src/fabric_cli/commands/find/__init__.py new file mode 100644 index 000000000..59e481eb9 --- /dev/null +++ b/src/fabric_cli/commands/find/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. diff --git a/src/fabric_cli/commands/find/fab_find.py b/src/fabric_cli/commands/find/fab_find.py new file mode 100644 index 000000000..aacba9c01 --- /dev/null +++ b/src/fabric_cli/commands/find/fab_find.py @@ -0,0 +1,347 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Find command for searching the Fabric catalog.""" + +import json +import os +from argparse import Namespace +from typing import Any + +import yaml + +from fabric_cli.client import fab_api_catalog as catalog_api +from fabric_cli.core import fab_constant, fab_logger +from fabric_cli.core.fab_decorators import handle_exceptions, set_command_context +from fabric_cli.core.fab_exceptions import FabricCLIError +from fabric_cli.errors import ErrorMessages +from fabric_cli.utils import fab_jmespath as utils_jmespath +from fabric_cli.utils import fab_ui as utils_ui +from fabric_cli.utils import fab_util as utils + + +def _load_type_config() -> dict[str, list[str]]: + """Load item type definitions from type_supported.yaml.""" + yaml_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "type_supported.yaml" + ) + with open(yaml_path, "r", encoding="utf-8") as f: + return yaml.safe_load(f) + + +_TYPE_CONFIG = _load_type_config() +ALL_ITEM_TYPES = _TYPE_CONFIG["supported"] + _TYPE_CONFIG["unsupported"] +UNSUPPORTED_ITEM_TYPES = _TYPE_CONFIG["unsupported"] + + +@handle_exceptions() +@set_command_context() +def find_command(args: Namespace) -> None: + """Search the Fabric catalog for items.""" + if args.query: + args.query = utils.process_nargs(args.query) + + is_interactive = ( + getattr(args, "fab_mode", None) == fab_constant.FAB_MODE_INTERACTIVE + ) + payload = _build_search_payload(args, is_interactive) + + utils_ui.print_grey("Searching...") + + if is_interactive: + _find_interactive(args, payload) + else: + _find_commandline(args, payload) + + +def _fetch_results( + args: Namespace, payload: dict[str, Any] +) -> tuple[list[dict], str | None]: + """Execute a catalog search request and return parsed results. + + Returns: + Tuple of (items list, continuation_token or None). + + Raises: + FabricCLIError: On API error or invalid response body. + """ + response = catalog_api.search(args, payload) + results = _parse_response(response) + + items = results.get("value", []) + continuation_token = results.get("continuationToken", "") or None + return items, continuation_token + + +def _next_page_payload(token: str, current: dict[str, Any]) -> dict[str, Any]: + """Build a continuation payload for the next page.""" + return {"continuationToken": token, "pageSize": current.get("pageSize", 50)} + + +def _print_search_summary(count: int, has_more_pages: bool = False) -> None: + """Print the search result summary line.""" + label = "item" if count == 1 else "items" + count_msg = f"{count} {label} found" + (" (more available)" if has_more_pages else "") + utils_ui.print_grey("") + utils_ui.print_grey(count_msg) + utils_ui.print_grey("") + + +def _display_page( + args: Namespace, + display_items: list[dict], + truncate_cols: list[str] | None, + has_more_pages: bool, + total_count: int, +) -> int: + """Display a page of results, returning the updated total count.""" + if display_items: + total_count += len(display_items) + _print_search_summary(total_count, has_more_pages) + _display_items(args, display_items, truncate_cols) + return total_count + + +def _find_interactive(args: Namespace, payload: dict[str, Any]) -> None: + """Fetch and display results page by page, prompting between pages.""" + total_count = 0 + items, continuation_token = _fetch_results(args, payload) + display_items, truncate_cols = _prepare_display_items(args, items) + total_count = _display_page( + args, display_items, truncate_cols, continuation_token is not None, total_count + ) + + while continuation_token is not None: + if display_items: + try: + utils_ui.print_grey("") + input("Press Enter to continue... (Ctrl+C to stop)") + except (KeyboardInterrupt, EOFError): + utils_ui.print_grey("") + break + + payload = _next_page_payload(continuation_token, payload) + items, continuation_token = _fetch_results(args, payload) + display_items, truncate_cols = _prepare_display_items(args, items) + total_count = _display_page( + args, display_items, truncate_cols, continuation_token is not None, total_count + ) + + if total_count == 0: + utils_ui.print_grey("No items found.") + + +def _find_commandline(args: Namespace, payload: dict[str, Any]) -> None: + """Fetch all results across pages and display.""" + all_items: list[dict] = [] + items, continuation_token = _fetch_results(args, payload) + all_items.extend(items) + + while continuation_token is not None: + payload = _next_page_payload(continuation_token, payload) + items, continuation_token = _fetch_results(args, payload) + all_items.extend(items) + + if not all_items: + utils_ui.print_grey("No items found.") + return + + display_items, truncate_cols = _prepare_display_items(args, all_items) + if not display_items: + utils_ui.print_grey("No items found.") + return + _print_search_summary(len(display_items)) + _display_items(args, display_items, truncate_cols) + + +def _build_search_payload(args: Namespace, is_interactive: bool) -> dict[str, Any]: + """Build the search request payload from command arguments.""" + request: dict[str, Any] = {"search": args.search_text} + request["pageSize"] = 50 if is_interactive else 1000 + + type_filter = _parse_type_from_params(args) + if type_filter: + op = type_filter["operator"] + types = type_filter["values"] + joiner = " or " if op == "eq" else " and " + clauses = [f"Type {op} '{t}'" for t in types] + request["filter"] = ( + f"({joiner.join(clauses)})" if len(clauses) > 1 else clauses[0] + ) + + return request + + +def _parse_type_from_params(args: Namespace) -> dict[str, Any] | None: + """Extract and validate item types from -P params. + + Supports: + -P type=Report → eq single + -P type=[Report,Lakehouse] → eq multiple (or) + -P type!=Dashboard → ne single + -P type!=[Dashboard,Report] → ne multiple (and) + + Returns dict with 'operator' ('eq' or 'ne') and 'values' list, or None. + """ + params_str = getattr(args, "params", None) + if not params_str: + return None + + # nargs="?" gives a string; nargs="*" gives a list (backward compat) + if isinstance(params_str, list): + params_str = ",".join(params_str) + + params_dict = utils.get_dict_from_params(params_str, max_depth=1) + + # Check for type key (with or without ! for ne operator) + type_value = None + operator = "eq" + for key, value in params_dict.items(): + # get_dict_from_params splits on first "=", so "type!=X" becomes key="type!", value="X" + clean_key = key.rstrip("!") + is_ne = key.endswith("!") + + if clean_key.lower() == "type": + type_value = value + operator = "ne" if is_ne else "eq" + else: + raise FabricCLIError( + ErrorMessages.Common.unsupported_parameter(clean_key), + fab_constant.ERROR_INVALID_INPUT, + ) + + if not type_value: + return None + + # Parse bracket syntax: [val1,val2] or plain: val1 + if type_value.startswith("[") and type_value.endswith("]"): + inner = type_value[1:-1] + types = [t.strip() for t in inner.split(",") if t.strip()] + if not types: + raise FabricCLIError( + ErrorMessages.Find.unrecognized_type( + "[]", " Specify at least one item type." + ), + fab_constant.ERROR_INVALID_INPUT, + ) + else: + types = [type_value.strip()] + + all_types_lower = {t.lower(): t for t in ALL_ITEM_TYPES} + unsupported_lower = {t.lower() for t in UNSUPPORTED_ITEM_TYPES} + normalized = [] + for t in types: + t_lower = t.lower() + if t_lower in unsupported_lower and operator == "eq": + canonical = all_types_lower.get(t_lower, t) + raise FabricCLIError( + ErrorMessages.Common.type_not_supported(canonical), + fab_constant.ERROR_UNSUPPORTED_ITEM_TYPE, + ) + if t_lower not in all_types_lower: + close = [ + v for k, v in all_types_lower.items() if t_lower in k or k in t_lower + ] + hint = ( + f" Did you mean {', '.join(close)}?" + if close + else " Run 'find --help' to see examples." + ) + raise FabricCLIError( + ErrorMessages.Find.unrecognized_type(t, hint), + fab_constant.ERROR_INVALID_ITEM_TYPE, + ) + normalized.append(all_types_lower[t_lower]) + + return {"operator": operator, "values": normalized} + + +def _parse_response(response) -> dict: + """Parse a successful API response or raise FabricCLIError on failure.""" + try: + data = json.loads(response.text) + except json.JSONDecodeError: + if response.status_code == 200: + raise FabricCLIError( + ErrorMessages.Common.invalid_json_format(), + fab_constant.ERROR_INVALID_JSON, + ) + raise FabricCLIError( + ErrorMessages.Find.search_failed(response.text), + fab_constant.ERROR_INVALID_JSON, + ) + + if response.status_code == 200: + return data + + fab_logger.log_debug(f"Catalog search error: {data}") + raise FabricCLIError( + ErrorMessages.Find.search_failed(data.get("message", response.text)), + data.get("errorCode", fab_constant.ERROR_UNEXPECTED_ERROR), + ) + + +def _get_workspace_field(item: dict, field: str) -> str | None: + """Extract workspace field, supporting both flat and hierarchy formats.""" + ws = item.get("hierarchy", {}).get("workspace", {}) + if field == "name": + return ws.get("displayName") or item.get("workspaceName") + if field == "id": + return ws.get("id") or item.get("workspaceId") + return None + + +def _prepare_display_items( + args: Namespace, items: list[dict] +) -> tuple[list[dict], list[str] | None]: + """Transform API items into display-ready dicts with optional filtering. + + Returns: + Tuple of (display items, columns_to_truncate or None). + """ + show_details = getattr(args, "long", False) + has_descriptions = any(item.get("description") for item in items) + + display_items = [] + for item in items: + if show_details: + entry = { + "name": item.get("displayName") or item.get("name"), + "id": item.get("id"), + "type": item.get("type"), + "workspace": _get_workspace_field(item, "name"), + "workspace_id": _get_workspace_field(item, "id"), + } + else: + entry = { + "name": item.get("displayName") or item.get("name"), + "type": item.get("type"), + "workspace": _get_workspace_field(item, "name"), + } + if has_descriptions: + entry["description"] = item.get("description") or "" + display_items.append(entry) + + if getattr(args, "query", None): + query_result = utils_jmespath.search(display_items, args.query) + if not isinstance(query_result, list): + return [], None + display_items = query_result + + truncate_cols = ["description", "workspace", "name"] if not show_details else None + return display_items, truncate_cols + + +def _display_items( + args: Namespace, + display_items: list[dict], + columns_to_truncate: list[str] | None = None, +) -> None: + """Render prepared display items, truncating columns for text format.""" + utils_ui.print_output_format( + args, + data=display_items, + show_headers=True, + truncate_columns=columns_to_truncate, + ) + utils_ui.print_grey("") diff --git a/src/fabric_cli/commands/find/type_supported.yaml b/src/fabric_cli/commands/find/type_supported.yaml new file mode 100644 index 000000000..e7157fcd0 --- /dev/null +++ b/src/fabric_cli/commands/find/type_supported.yaml @@ -0,0 +1,51 @@ +--- +# Item types for the find command (Catalog Search API) +# Reference: https://learn.microsoft.com/en-us/rest/api/fabric/core/catalog/search + +supported: + - AnomalyDetector + - ApacheAirflowJob + - CopyJob + - CosmosDBDatabase + - Dataflow + - Datamart + - DataPipeline + - DigitalTwinBuilder + - DigitalTwinBuilderFlow + - Environment + - Eventhouse + - EventSchemaSet + - Eventstream + - GraphModel + - GraphQLApi + - GraphQuerySet + - KQLDashboard + - KQLDatabase + - KQLQueryset + - Lakehouse + - Map + - MirroredAzureDatabricksCatalog + - MirroredDatabase + - MirroredWarehouse + - MLExperiment + - MLModel + - MountedDataFactory + - Notebook + - Ontology + - OperationsAgent + - PaginatedReport + - Reflex + - Report + - SemanticModel + - SnowflakeDatabase + - SparkJobDefinition + - SQLDatabase + - SQLEndpoint + - UserDataFunction + - VariableLibrary + - Warehouse + - WarehouseSnapshot + +unsupported: + # Types that exist in Fabric but are NOT searchable via the Catalog Search API + - Dashboard diff --git a/src/fabric_cli/core/fab_parser_setup.py b/src/fabric_cli/core/fab_parser_setup.py index c66c1747b..d87fa8530 100644 --- a/src/fabric_cli/core/fab_parser_setup.py +++ b/src/fabric_cli/core/fab_parser_setup.py @@ -14,6 +14,7 @@ from fabric_cli.parsers import fab_config_parser as config_parser from fabric_cli.parsers import fab_describe_parser as describe_parser from fabric_cli.parsers import fab_extension_parser as extension_parser +from fabric_cli.parsers import fab_find_parser as find_parser from fabric_cli.parsers import fab_fs_parser as fs_parser from fabric_cli.parsers import fab_global_params from fabric_cli.parsers import fab_jobs_parser as jobs_parser @@ -219,6 +220,7 @@ def create_parser_and_subparsers(): api_parser.register_parser(subparsers) # api auth_parser.register_parser(subparsers) # auth describe_parser.register_parser(subparsers) # desc + find_parser.register_parser(subparsers) # find extension_parser.register_parser(subparsers) # extension # version diff --git a/src/fabric_cli/errors/__init__.py b/src/fabric_cli/errors/__init__.py index 161022c8b..486124ab2 100644 --- a/src/fabric_cli/errors/__init__.py +++ b/src/fabric_cli/errors/__init__.py @@ -7,6 +7,7 @@ from .config import ConfigErrors from .context import ContextErrors from .cp import CpErrors +from .find import FindErrors from .hierarchy import HierarchyErrors from .labels import LabelsErrors from .mkdir import MkdirErrors @@ -22,6 +23,7 @@ class ErrorMessages: Config = ConfigErrors Context = ContextErrors Cp = CpErrors + Find = FindErrors Hierarchy = HierarchyErrors Labels = LabelsErrors Mkdir = MkdirErrors diff --git a/src/fabric_cli/errors/common.py b/src/fabric_cli/errors/common.py index 0896f169c..6fcfc0009 100644 --- a/src/fabric_cli/errors/common.py +++ b/src/fabric_cli/errors/common.py @@ -257,3 +257,10 @@ def invalid_definition_format(valid_formats: list[str]) -> str: message = "No formats are supported" return f"Invalid format. {message}" + @staticmethod + def unsupported_parameter(key: str) -> str: + return f"'{key}' isn't a supported parameter" + + @staticmethod + def invalid_parameter_format(param: str) -> str: + return f"Invalid parameter format: '{param}'. Use key=value or key!=value." diff --git a/src/fabric_cli/errors/config.py b/src/fabric_cli/errors/config.py index 4a393010b..5a29b22e2 100644 --- a/src/fabric_cli/errors/config.py +++ b/src/fabric_cli/errors/config.py @@ -29,10 +29,6 @@ def mode_deprecated(runtime_mode: str, interactive_mode: str) -> str: ) return msg - @staticmethod - def invalid_parameter_format(params: str) -> str: - return f"Invalid parameter format: {params}" - @staticmethod def config_not_set(config_name: str, message: str) -> str: return f"{config_name} is not set. {message}" diff --git a/src/fabric_cli/errors/find.py b/src/fabric_cli/errors/find.py new file mode 100644 index 000000000..e2dc8b58d --- /dev/null +++ b/src/fabric_cli/errors/find.py @@ -0,0 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + + +class FindErrors: + @staticmethod + def unrecognized_type(type_name: str, hint: str) -> str: + return f"'{type_name}' isn't a recognized item type.{hint}" + + @staticmethod + def search_failed(message: str) -> str: + return f"Catalog search failed: {message}" diff --git a/src/fabric_cli/parsers/fab_find_parser.py b/src/fabric_cli/parsers/fab_find_parser.py new file mode 100644 index 000000000..4162a1b7d --- /dev/null +++ b/src/fabric_cli/parsers/fab_find_parser.py @@ -0,0 +1,83 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Parser for the find command.""" + +from argparse import Namespace, _SubParsersAction + +from fabric_cli.commands.find import fab_find as find +from fabric_cli.utils import fab_error_parser as utils_error_parser +from fabric_cli.utils import fab_ui as utils_ui + + +COMMAND_FIND_DESCRIPTION = "Search the Fabric catalog for items." + +commands = { + "Description": { + "find": "Search across all workspaces by name, description, or workspace name.", + }, +} + + +def register_parser(subparsers: _SubParsersAction) -> None: + """Register the find command parser.""" + examples = [ + "# search for items by name or description", + "$ find 'sales report'\n", + "# search for lakehouses only", + "$ find 'data' -P type=Lakehouse\n", + "# search for multiple item types (bracket syntax)", + "$ find 'dashboard' -P type=[Report,SemanticModel]\n", + "# exclude a type", + "$ find 'data' -P type!=Dashboard\n", + "# exclude multiple types", + "$ find 'data' -P type!=[Dashboard,Datamart]\n", + "# show detailed output with IDs", + "$ find 'sales' -l\n", + "# combine filters", + "$ find 'finance' -P type=[Warehouse,Lakehouse] -l\n", + "# filter results client-side with JMESPath", + "$ find 'sales' -q \"[?type=='Report']\"\n", + "# project specific fields", + "$ find 'data' -q \"[].{name: name, workspace: workspace}\"", + ] + + parser = subparsers.add_parser( + "find", + help=COMMAND_FIND_DESCRIPTION, + fab_examples=examples, + fab_learnmore=["_"], + ) + + parser.add_argument( + "search_text", + metavar="query", + help="Search text (matches display name, description, and workspace name)", + ) + parser.add_argument( + "-P", + "--params", + metavar="", + nargs="?", + help="Parameters in key=value or key!=value format. Use brackets for multiple values: type=[Lakehouse,Notebook]. Use != to exclude: type!=Dashboard", + ) + parser.add_argument( + "-l", + "--long", + action="store_true", + help="Show detailed output. Optional", + ) + parser.add_argument( + "-q", + "--query", + nargs="+", + help="JMESPath query to filter. Optional", + ) + + parser.usage = f"{utils_error_parser.get_usage_prog(parser)}" + parser.set_defaults(func=find.find_command) + + +def show_help(args: Namespace) -> None: + """Display help for the find command.""" + utils_ui.display_help(commands, custom_header=COMMAND_FIND_DESCRIPTION) diff --git a/src/fabric_cli/utils/fab_ui.py b/src/fabric_cli/utils/fab_ui.py index 708f75075..128d75b16 100644 --- a/src/fabric_cli/utils/fab_ui.py +++ b/src/fabric_cli/utils/fab_ui.py @@ -14,6 +14,7 @@ from fabric_cli.core.fab_output import FabricCLIOutput, OutputStatus from fabric_cli.errors import ErrorMessages from fabric_cli.utils import fab_lazy_load +from fabric_cli.utils import fab_util def get_common_style(): @@ -95,6 +96,7 @@ def print_output_format( hidden_data: Optional[Any] = None, show_headers: bool = False, show_key_value_list: bool = False, + truncate_columns: Optional[list[str]] = None, ) -> None: """Create a FabricCLIOutput instance and print it depends on the format. @@ -105,6 +107,9 @@ def print_output_format( hidden_data: Optional hidden data to include in output show_headers: Whether to show headers in the output (default: False) show_key_value_list: Whether to show output in key-value list format (default: False) + truncate_columns: Column names (in shrink priority) to truncate so a table + fits within terminal width. Only applied for text output; JSON output + is not modified. (default: None) Returns: FabricCLIOutput: Configured output instance ready for printing @@ -132,6 +137,13 @@ def print_output_format( case "json": _print_output_format_json(output.to_json()) case "text": + if ( + truncate_columns + and isinstance(output.result.data, list) + and output.result.data + and isinstance(output.result.data[0], dict) + ): + fab_util.truncate_columns(output.result.data, truncate_columns) _print_output_format_result_text(output) case _: raise FabricCLIError( diff --git a/src/fabric_cli/utils/fab_util.py b/src/fabric_cli/utils/fab_util.py index 793243d03..d06bacee6 100644 --- a/src/fabric_cli/utils/fab_util.py +++ b/src/fabric_cli/utils/fab_util.py @@ -20,6 +20,7 @@ import json import platform import re +import shutil from typing import Any from fabric_cli.core import fab_constant, fab_state_config @@ -67,6 +68,9 @@ def get_dict_from_params(params: str | list[str], max_depth: int = 2) -> dict: Convert args to dict with a specified max nested level. Example: args.params = "key1.key2=value2,key1.key3=value3,key4=value4" -> {"key1": {"key2": "value2", "key3": "value3"}, "key4": "value4"} + + Supports != operator for negation. The trailing '!' is kept in the key: + args.params = "key!=value" -> {"key!": "value"} """ params_dict: dict = {} @@ -75,7 +79,7 @@ def get_dict_from_params(params: str | list[str], max_depth: int = 2) -> dict: # Result ['key1.key2=hello', 'key2={"hello":"testing","bye":2}', 'key3=[1,2,3]', 'key4={"key5":"value5"}'] # Example key1.key2=hello # Result ['key1.key=hello'] - pattern = r"((?:[\w\.]+=.+?)(?=(?:,\s*[\w\.]+=)|$))" + pattern = r"((?:[\w\.]+!?=.+?)(?=(?:,\s*[\w\.]+!?=)|$))" if params: if isinstance(params, list): @@ -89,7 +93,7 @@ def get_dict_from_params(params: str | list[str], max_depth: int = 2) -> dict: matches = re.findall(pattern, norm_params) if not matches: raise FabricCLIError( - ErrorMessages.Config.invalid_parameter_format(norm_params), + ErrorMessages.Common.invalid_parameter_format(norm_params), fab_constant.ERROR_INVALID_INPUT, ) @@ -242,3 +246,64 @@ def get_capacity_settings( az_resource_group, sku, ) + + +def truncate_columns( + items: list[dict], + columns_to_truncate: list[str], + min_width: int = 20, + max_col_width: int = 50, +) -> None: + """Truncate columns in priority order so a table fits within terminal width. + + Shrinks columns one at a time in the order given. Each column is reduced + just enough to make the total fit. Columns not listed are never truncated. + + Args: + items: List of dicts to truncate in place. + columns_to_truncate: Column names in shrink priority (first = shrink first). + min_width: Minimum width for any truncated column. + max_col_width: Absolute max width for any truncatable column. + """ + if not items: + return + + term_width = shutil.get_terminal_size((120, 24)).columns + # Use first item's keys — matches the text table renderer (get_data_keys), + # which prints columns based on the first item's keys and order. + all_fields = list(items[0].keys()) + # Table renderer adds +2 width per column and 1 space between columns + padding_per_col = 3 + total_padding = padding_per_col * len(all_fields) - 1 + + col_widths = {} + for f in all_fields: + col_widths[f] = max( + len(f), + max((len(str(item.get(f, ""))) for item in items), default=0), + ) + + # Apply absolute max width cap first + for col in columns_to_truncate: + if col in col_widths and col_widths[col] > max_col_width: + col_widths[col] = max_col_width + for item in items: + val = str(item.get(col, "")) + if len(val) > max_col_width: + item[col] = val[: max_col_width - 1].rstrip() + "…" + + # Then shrink further to fit terminal width + for col in columns_to_truncate: + if col not in col_widths: + continue + total = sum(col_widths[f] for f in all_fields) + total_padding + overflow = total - term_width + if overflow <= 0: + break + + max_col = max(col_widths[col] - overflow, min_width) + col_widths[col] = max_col + for item in items: + val = str(item.get(col, "")) + if len(val) > max_col: + item[col] = val[: max_col - 1].rstrip() + "…" diff --git a/tests/test_commands/api_processors/api_processor_handler.py b/tests/test_commands/api_processors/api_processor_handler.py index 58afb6c4d..33f758a21 100644 --- a/tests/test_commands/api_processors/api_processor_handler.py +++ b/tests/test_commands/api_processors/api_processor_handler.py @@ -14,6 +14,9 @@ WorkspaceAPIProcessor, ) from tests.test_commands.api_processors.domains_api_processor import DomainsAPIProcessor +from tests.test_commands.api_processors.catalog_search_api_processor import ( + CatalogSearchAPIProcessor, +) from tests.test_commands.api_processors.connection_api_processor import ( ConnectionAPIProcessor, ) @@ -28,6 +31,7 @@ def __init__(self, generated_name_mapping): ConnectionAPIProcessor(generated_name_mapping), DomainsAPIProcessor(generated_name_mapping), SubscriptionsAPIProcessor(generated_name_mapping), + CatalogSearchAPIProcessor(generated_name_mapping), ] def handle_request(self, request): diff --git a/tests/test_commands/api_processors/catalog_search_api_processor.py b/tests/test_commands/api_processors/catalog_search_api_processor.py new file mode 100644 index 000000000..943acd0f7 --- /dev/null +++ b/tests/test_commands/api_processors/catalog_search_api_processor.py @@ -0,0 +1,44 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import json +from tests.test_commands.api_processors.base_api_processor import BaseAPIProcessor +from tests.test_commands.api_processors.utils import load_response_json_body + + +class CatalogSearchAPIProcessor(BaseAPIProcessor): + CATALOG_SEARCH_URI = "https://api.fabric.microsoft.com/v1/catalog/search" + + def __init__(self, generated_name_mapping): + self.generated_name_mapping = generated_name_mapping + + def try_process_request(self, request) -> bool: + return False + + def try_process_response(self, request, response) -> bool: + uri = request.uri + + if uri.lower() == self.CATALOG_SEARCH_URI.lower(): + method = request.method + if method == "POST": + self._handle_search_response(response) + return True + + return False + + def _handle_search_response(self, response): + data = load_response_json_body(response) + if not data or "value" not in data: + return + + new_value = [] + for item in data.get("value", []): + display_name = item.get("displayName", "") + if display_name in self.generated_name_mapping: + new_value.append(item) + + data["value"] = new_value + data.pop("continuationToken", None) + + new_body_str = json.dumps(data) + response["body"]["string"] = new_body_str.encode("utf-8") diff --git a/tests/test_commands/commands_parser.py b/tests/test_commands/commands_parser.py index 485748f94..db66f60b1 100644 --- a/tests/test_commands/commands_parser.py +++ b/tests/test_commands/commands_parser.py @@ -2,10 +2,8 @@ # Licensed under the MIT License. import platform -from prompt_toolkit import PromptSession from prompt_toolkit.input import DummyInput from prompt_toolkit.output import DummyOutput -from prompt_toolkit.history import InMemoryHistory from fabric_cli.core.fab_interactive import InteractiveCLI from fabric_cli.core.fab_parser_setup import CustomArgumentParser @@ -34,6 +32,9 @@ register_stop_parser, register_unassign_parser, ) +from fabric_cli.parsers.fab_find_parser import ( + register_parser as register_find_parser, +) from fabric_cli.parsers.fab_jobs_parser import register_parser as register_jobs_parser from fabric_cli.parsers.fab_labels_parser import ( register_parser as register_labels_parser, @@ -50,6 +51,7 @@ register_export_parser, register_import_parser, register_assign_parser, + register_find_parser, register_ln_parser, register_ls_parser, register_mv_parser, @@ -72,19 +74,30 @@ def __init__(self): self._parser = customArgumentParser.add_subparsers() for register_parser_handler in parserHandlers: register_parser_handler(self._parser) - self._interactiveCLI = InteractiveCLI(customArgumentParser, self._parser) - - # Override init_session for Windows compatibility + + # On Windows without a console, PromptSession() raises + # NoConsoleScreenBufferError. Patch PromptSession in the interactive + # module to inject DummyInput/DummyOutput before the singleton is created. if platform.system() == "Windows": - def test_init_session(session_history: InMemoryHistory) -> PromptSession: - # DummyInput and DummyOutput are test classes of prompt_toolkit to - # solve the NoConsoleScreenBufferError issue - return PromptSession( - history=session_history, input=DummyInput(), output=DummyOutput() + import fabric_cli.core.fab_interactive as _interactive_mod + + _orig_ps = _interactive_mod.PromptSession + + def _safe_prompt_session(*args, **kwargs): + kwargs.setdefault("input", DummyInput()) + kwargs.setdefault("output", DummyOutput()) + return _orig_ps(*args, **kwargs) + + _interactive_mod.PromptSession = _safe_prompt_session + + try: + self._interactiveCLI = InteractiveCLI( + customArgumentParser, self._parser ) - self._interactiveCLI.init_session = test_init_session - # Reinitialize the session with test-friendly settings - self._interactiveCLI.session = self._interactiveCLI.init_session(self._interactiveCLI.history) + finally: + _interactive_mod.PromptSession = _orig_ps + else: + self._interactiveCLI = InteractiveCLI(customArgumentParser, self._parser) def exec_command(self, command: str) -> None: self._interactiveCLI.handle_command(command) diff --git a/tests/test_commands/processors.py b/tests/test_commands/processors.py index 9780fb19e..a5bfa6bba 100644 --- a/tests/test_commands/processors.py +++ b/tests/test_commands/processors.py @@ -89,6 +89,11 @@ def process_request(request): global generated_name_mapping global current_request + # Normalize API endpoint so cassettes always use the production URI + request.uri = request.uri.replace( + "dailyapi.fabric.microsoft.com", "api.fabric.microsoft.com" + ) + current_request = request if is_record_mode(): api_processor_handler.handle_request(request) diff --git a/tests/test_commands/recordings/test_commands/test_find/class_setup.yaml b/tests/test_commands/recordings/test_commands/test_find/class_setup.yaml new file mode 100644 index 000000000..a45c13d61 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/class_setup.yaml @@ -0,0 +1,325 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (None; Windows/11; Python/3.12.10) + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1358' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:33 GMT + Pragma: + - no-cache + RequestId: + - 6917ea09-8a83-429e-87af-8530e77f34d6 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (None; Windows/11; Python/3.12.10) + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1358' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:35 GMT + Pragma: + - no-cache + RequestId: + - a52ea9f9-860f-4618-aee7-d580c27ec924 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (None; Windows/11; Python/3.12.10) + method: GET + uri: https://api.fabric.microsoft.com/v1/capacities + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-000000000004", "displayName": + "mocked_fabriccli_capacity_name", "sku": "FT1", "region": "East US 2 EUAP", + "state": "Active"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '513' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:36 GMT + Pragma: + - no-cache + RequestId: + - 1fc66c75-7ba0-4908-ab0a-b9ebc1f10125 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "capacityId": "00000000-0000-0000-0000-000000000004"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '157' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (None; Windows/11; Python/3.12.10) + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '188' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:38 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f + Pragma: + - no-cache + RequestId: + - 6005eff4-638f-4ac7-9d8c-fe44057dea9d + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (find; Windows/11; Python/3.12.10) + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:03:03 GMT + Pragma: + - no-cache + RequestId: + - 2f5ce1ab-9561-4ab4-b2f7-a93cce19c885 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (find; Windows/11; Python/3.12.10) + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:03:04 GMT + Pragma: + - no-cache + RequestId: + - bace61a4-bae2-41bb-b824-7229a72a997e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli/1.5.0 (find; Windows/11; Python/3.12.10) + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 11:03:06 GMT + Pragma: + - no-cache + RequestId: + - 6c1826cb-30ff-4aa0-b044-728a1edbffff + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_basic_search_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_basic_search_success.yaml new file mode 100644 index 000000000..22af46faa --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_basic_search_success.yaml @@ -0,0 +1,479 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:38 GMT + Pragma: + - no-cache + RequestId: + - fe1b26f8-8751-40ca-8083-b4c80f24162d + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:40 GMT + Pragma: + - no-cache + RequestId: + - 48089434-7347-4455-a119-25a7b30a4e3c + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:42 GMT + Pragma: + - no-cache + RequestId: + - 5a62a4d7-bb7c-4848-b26c-bad0487239cc + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:46 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/2f0d4e59-9688-4b10-9239-0ce58b39434c + Pragma: + - no-cache + RequestId: + - 3ea01fcf-4ad8-41e4-a8cb-0fe365bd555e + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 2f0d4e59-9688-4b10-9239-0ce58b39434c + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/2f0d4e59-9688-4b10-9239-0ce58b39434c + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T10:53:46.2561218", + "lastUpdatedTimeUtc": "2026-04-19T10:53:47.8649898", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '131' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:08 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/2f0d4e59-9688-4b10-9239-0ce58b39434c/result + Pragma: + - no-cache + RequestId: + - 96af02dc-5148-403f-a88a-11feee37f3eb + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 2f0d4e59-9688-4b10-9239-0ce58b39434c + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/2f0d4e59-9688-4b10-9239-0ce58b39434c/result + response: + body: + string: '{"id": "e62d5950-895c-4731-9165-f7fb226471df", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 10:54:10 GMT + Pragma: + - no-cache + RequestId: + - dc9eb4f8-9d95-4c53-8c9c-731ad340e7eb + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "Type eq ''Notebook''"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '78' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "e62d5950-895c-4731-9165-f7fb226471df", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1278' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:42 GMT + Pragma: + - no-cache + RequestId: + - ed8fa807-799b-4758-879d-9aa863815923 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:45 GMT + Pragma: + - no-cache + RequestId: + - da2edced-0393-4eb5-9f08-03a876eeddad + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "e62d5950-895c-4731-9165-f7fb226471df", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '223' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:47 GMT + Pragma: + - no-cache + RequestId: + - 3c9bdd42-0e53-4f05-8530-bda50fcc35cd + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/e62d5950-895c-4731-9165-f7fb226471df + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:54:50 GMT + Pragma: + - no-cache + RequestId: + - fab7771e-5e71-45f5-8256-3a7f40d94c50 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_jmespath_skips_empty_page_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_jmespath_skips_empty_page_success.yaml new file mode 100644 index 000000000..8c9030218 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_jmespath_skips_empty_page_success.yaml @@ -0,0 +1,134 @@ +interactions: +- request: + body: '{"search": "jmespathskip", "pageSize": 50}' + headers: + Accept: &id001 + - '*/*' + Accept-Encoding: &id002 + - gzip, deflate + Connection: &id003 + - keep-alive + Content-Type: &id004 + - application/json + User-Agent: &id005 + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '42' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-065134249370", "type": "Notebook", + "displayName": "NB-SK-0", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-846917334185", + "type": "Notebook", "displayName": "NB-SK-1", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-437223391280", + "type": "Notebook", "displayName": "NB-SK-2", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": "token-skip2"}' + headers: + Access-Control-Expose-Headers: &id006 + - RequestId + Cache-Control: &id007 + - no-store, must-revalidate, no-cache + Content-Encoding: &id008 + - gzip + Content-Type: &id009 + - application/json; charset=utf-8 + Date: &id010 + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: &id011 + - no-cache + RequestId: &id012 + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: &id013 + - max-age=31536000; includeSubDomains + X-Content-Type-Options: &id014 + - nosniff + X-Frame-Options: &id015 + - deny + Content-Length: + - '839' + status: + code: 200 + message: OK +- request: + body: '{"continuationToken": "token-skip2", "pageSize": 50}' + headers: + Accept: *id001 + Accept-Encoding: *id002 + Connection: *id003 + Content-Type: *id004 + User-Agent: *id005 + Content-Length: + - '52' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-766725051571", "type": "Lakehouse", + "displayName": "LH-SK-0", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-421954067748", + "type": "Lakehouse", "displayName": "LH-SK-1", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-641502960160", + "type": "Lakehouse", "displayName": "LH-SK-2", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": "token-skip3"}' + headers: + Access-Control-Expose-Headers: *id006 + Cache-Control: *id007 + Content-Encoding: *id008 + Content-Type: *id009 + Date: *id010 + Pragma: *id011 + RequestId: *id012 + Strict-Transport-Security: *id013 + X-Content-Type-Options: *id014 + X-Frame-Options: *id015 + Content-Length: + - '842' + status: + code: 200 + message: OK +- request: + body: '{"continuationToken": "token-skip3", "pageSize": 50}' + headers: + Accept: *id001 + Accept-Encoding: *id002 + Connection: *id003 + Content-Type: *id004 + User-Agent: *id005 + Content-Length: + - '52' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-139661754670", "type": "Notebook", + "displayName": "NB-SK-3", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-471761962560", + "type": "Notebook", "displayName": "NB-SK-4", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: *id006 + Cache-Control: *id007 + Content-Encoding: *id008 + Content-Type: *id009 + Date: *id010 + Pragma: *id011 + RequestId: *id012 + Strict-Transport-Security: *id013 + X-Content-Type-Options: *id014 + X-Frame-Options: *id015 + Content-Length: + - '564' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_json_output_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_json_output_success.yaml new file mode 100644 index 000000000..eb3dc8fa9 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_json_output_success.yaml @@ -0,0 +1,479 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:57 GMT + Pragma: + - no-cache + RequestId: + - 8d54f585-1b65-42f7-83e7-96b791df42ab + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:59 GMT + Pragma: + - no-cache + RequestId: + - cb70fa65-cce9-4c76-ad35-9182a81cf942 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:02:01 GMT + Pragma: + - no-cache + RequestId: + - 6842212d-dc4c-4f14-a609-5185f5721715 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:02:04 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/4a6dfda4-7d04-46a5-889b-4fb29e1d81ee + Pragma: + - no-cache + RequestId: + - 6c68d3f9-98ef-4b73-ab8b-eac487b9e5e9 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 4a6dfda4-7d04-46a5-889b-4fb29e1d81ee + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/4a6dfda4-7d04-46a5-889b-4fb29e1d81ee + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T11:02:04.0954636", + "lastUpdatedTimeUtc": "2026-04-19T11:02:05.6837302", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '132' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:02:25 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/4a6dfda4-7d04-46a5-889b-4fb29e1d81ee/result + Pragma: + - no-cache + RequestId: + - ba534f2a-5c72-4f91-acca-6b98a6c58469 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 4a6dfda4-7d04-46a5-889b-4fb29e1d81ee + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/4a6dfda4-7d04-46a5-889b-4fb29e1d81ee/result + response: + body: + string: '{"id": "493fe96d-d818-42e5-89c8-eb1adc76c48f", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 11:02:26 GMT + Pragma: + - no-cache + RequestId: + - 4cefd66c-c1d1-4d83-a05f-a3197b7afbd5 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '46' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "493fe96d-d818-42e5-89c8-eb1adc76c48f", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '2677' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:02:57 GMT + Pragma: + - no-cache + RequestId: + - 9321dbba-37bd-4559-9a11-5b55f1265fb6 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:02:59 GMT + Pragma: + - no-cache + RequestId: + - 3ad6b938-d179-4e0e-935b-eaa3e9c56791 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "493fe96d-d818-42e5-89c8-eb1adc76c48f", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '222' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:03:01 GMT + Pragma: + - no-cache + RequestId: + - 75ef2fe2-015b-4ef8-89ac-7f94e2ffeb3f + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/493fe96d-d818-42e5-89c8-eb1adc76c48f + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 11:03:01 GMT + Pragma: + - no-cache + RequestId: + - c0d80ca6-3f2d-420f-a97f-3b57a773abb3 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_details_not_truncated_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_details_not_truncated_success.yaml new file mode 100644 index 000000000..c033897a0 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_details_not_truncated_success.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"search": "longname", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '38' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-000000000001", "type": "Notebook", "displayName": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "description": "A notebook with a very long display name for truncation testing", "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: + - no-cache + RequestId: + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + Content-Length: + - '603' + status: + code: 200 + message: OK +version: 1 \ No newline at end of file diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_json_not_truncated_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_json_not_truncated_success.yaml new file mode 100644 index 000000000..c033897a0 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_json_not_truncated_success.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"search": "longname", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '38' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-000000000001", "type": "Notebook", "displayName": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "description": "A notebook with a very long display name for truncation testing", "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: + - no-cache + RequestId: + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + Content-Length: + - '603' + status: + code: 200 + message: OK +version: 1 \ No newline at end of file diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_truncated_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_truncated_success.yaml new file mode 100644 index 000000000..c033897a0 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_long_name_truncated_success.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"search": "longname", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '38' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-000000000001", "type": "Notebook", "displayName": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "description": "A notebook with a very long display name for truncation testing", "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: + - no-cache + RequestId: + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + Content-Length: + - '603' + status: + code: 200 + message: OK +version: 1 \ No newline at end of file diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_multi_page_interactive_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_multi_page_interactive_success.yaml new file mode 100644 index 000000000..4ee2c60f4 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_multi_page_interactive_success.yaml @@ -0,0 +1,94 @@ +interactions: +- request: + body: '{"search": "multipage", "pageSize": 50}' + headers: + Accept: &id001 + - '*/*' + Accept-Encoding: &id002 + - gzip, deflate + Connection: &id003 + - keep-alive + Content-Type: &id004 + - application/json + User-Agent: &id005 + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '39' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-031833810413", "type": "Notebook", + "displayName": "NB-P1-0", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-977430163345", + "type": "Notebook", "displayName": "NB-P1-1", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-972104337521", + "type": "Notebook", "displayName": "NB-P1-2", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": "token-page2"}' + headers: + Access-Control-Expose-Headers: &id006 + - RequestId + Cache-Control: &id007 + - no-store, must-revalidate, no-cache + Content-Encoding: &id008 + - gzip + Content-Type: &id009 + - application/json; charset=utf-8 + Date: &id010 + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: &id011 + - no-cache + RequestId: &id012 + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: &id013 + - max-age=31536000; includeSubDomains + X-Content-Type-Options: &id014 + - nosniff + X-Frame-Options: &id015 + - deny + Content-Length: + - '839' + status: + code: 200 + message: OK +- request: + body: '{"continuationToken": "token-page2", "pageSize": 50}' + headers: + Accept: *id001 + Accept-Encoding: *id002 + Connection: *id003 + Content-Type: *id004 + User-Agent: *id005 + Content-Length: + - '52' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-186429331592", "type": "Notebook", + "displayName": "NB-P2-0", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-679042946985", + "type": "Notebook", "displayName": "NB-P2-1", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: *id006 + Cache-Control: *id007 + Content-Encoding: *id008 + Content-Type: *id009 + Date: *id010 + Pragma: *id011 + RequestId: *id012 + Strict-Transport-Security: *id013 + X-Content-Type-Options: *id014 + X-Frame-Options: *id015 + Content-Length: + - '564' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_multi_type_eq_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_multi_type_eq_success.yaml new file mode 100644 index 000000000..0e7a239c9 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_multi_type_eq_success.yaml @@ -0,0 +1,480 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:47 GMT + Pragma: + - no-cache + RequestId: + - 8cf697e9-aa9e-4961-8d46-158f856c45da + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:49 GMT + Pragma: + - no-cache + RequestId: + - d2f13356-6333-4fd7-9517-62b770f7ec92 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:52 GMT + Pragma: + - no-cache + RequestId: + - cc8a0b0f-6ed4-489d-a7ff-e43525b96ce0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:56 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/cb2817d5-da7b-4e22-b918-4c85357d9f25 + Pragma: + - no-cache + RequestId: + - bc9cfaf5-c715-4aff-a433-339678974baa + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - cb2817d5-da7b-4e22-b918-4c85357d9f25 + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/cb2817d5-da7b-4e22-b918-4c85357d9f25 + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T11:00:56.0034909", + "lastUpdatedTimeUtc": "2026-04-19T11:00:57.6785391", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '131' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:18 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/cb2817d5-da7b-4e22-b918-4c85357d9f25/result + Pragma: + - no-cache + RequestId: + - 9fa7e164-a432-4317-bb50-f2c5a8b45d41 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - cb2817d5-da7b-4e22-b918-4c85357d9f25 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/cb2817d5-da7b-4e22-b918-4c85357d9f25/result + response: + body: + string: '{"id": "16263eed-22d6-4cd2-9c63-4a752c2e8bed", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 11:01:20 GMT + Pragma: + - no-cache + RequestId: + - f6cf0db5-4518-46f8-8db9-753b7043cbfe + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "(Type eq ''Notebook'' + or Type eq ''Report'')"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '100' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "16263eed-22d6-4cd2-9c63-4a752c2e8bed", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1381' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:52 GMT + Pragma: + - no-cache + RequestId: + - 63047529-7835-4cd0-a8ab-a4e9bd3b0718 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:53 GMT + Pragma: + - no-cache + RequestId: + - 0f954e66-8074-47af-85c7-4730a43b43c7 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "16263eed-22d6-4cd2-9c63-4a752c2e8bed", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '222' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:01:54 GMT + Pragma: + - no-cache + RequestId: + - 63ff31bf-ea8f-49a4-90a3-09cbc8938f17 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/16263eed-22d6-4cd2-9c63-4a752c2e8bed + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 11:01:56 GMT + Pragma: + - no-cache + RequestId: + - fe841b62-e803-4669-8df6-47eb77999602 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_ne_multi_type_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_ne_multi_type_success.yaml new file mode 100644 index 000000000..f31e8c9e5 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_ne_multi_type_success.yaml @@ -0,0 +1,477 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:17 GMT + Pragma: + - no-cache + RequestId: + - 5431f972-3869-4058-a1e3-286918ed9e68 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:19 GMT + Pragma: + - no-cache + RequestId: + - 2eb7ad8b-4532-4887-b33a-0bdc2471fd4e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:20 GMT + Pragma: + - no-cache + RequestId: + - 84693f22-9400-4709-9e2b-913a4c371015 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:23 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/d679a059-2d06-445e-8e53-6a49fe43301e + Pragma: + - no-cache + RequestId: + - 643c15fb-010d-40b1-a2c2-38e472fa5013 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - d679a059-2d06-445e-8e53-6a49fe43301e + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/d679a059-2d06-445e-8e53-6a49fe43301e + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T10:58:22.9901436", + "lastUpdatedTimeUtc": "2026-04-19T10:58:24.1718728", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '131' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:45 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/d679a059-2d06-445e-8e53-6a49fe43301e/result + Pragma: + - no-cache + RequestId: + - bcc93428-4bac-49f4-a2fc-dd7e1b155b72 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - d679a059-2d06-445e-8e53-6a49fe43301e + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/d679a059-2d06-445e-8e53-6a49fe43301e/result + response: + body: + string: '{"id": "b4490bcd-0cec-4459-9cc5-8cc5fae10041", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 10:58:51 GMT + Pragma: + - no-cache + RequestId: + - 9d398aaf-c0e7-4789-b63a-cffab39bd8e0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "(Type ne ''Notebook'' + and Type ne ''Report'')"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '101' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '324' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:23 GMT + Pragma: + - no-cache + RequestId: + - 183e423d-ac7c-49e9-b30a-336f3a338f75 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:25 GMT + Pragma: + - no-cache + RequestId: + - 57107c47-e46a-413d-b1fe-3304f191bdad + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "b4490bcd-0cec-4459-9cc5-8cc5fae10041", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '223' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:28 GMT + Pragma: + - no-cache + RequestId: + - 9ba40583-1d93-4da7-b57d-fd146152d8a9 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/b4490bcd-0cec-4459-9cc5-8cc5fae10041 + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:59:31 GMT + Pragma: + - no-cache + RequestId: + - db71aa29-5fb6-47ae-8453-e31fcba206a1 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_no_items_display_after_jmespath_filters_all_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_no_items_display_after_jmespath_filters_all_success.yaml new file mode 100644 index 000000000..bbd2ad2f6 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_no_items_display_after_jmespath_filters_all_success.yaml @@ -0,0 +1,57 @@ +interactions: +- request: + body: '{"search": "jmespathempty", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '43' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-766504176237", "type": "Notebook", + "displayName": "NB-JM-0", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-381321519693", + "type": "Notebook", "displayName": "NB-JM-1", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-293582438515", + "type": "Notebook", "displayName": "NB-JM-2", "description": "Test item", + "catalogEntryType": "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: + - no-cache + RequestId: + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + Content-Length: + - '828' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_no_results_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_no_results_success.yaml new file mode 100644 index 000000000..b12a73270 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_no_results_success.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: '{"search": "xyznonexistent98765zzz", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '52' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '55' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:56:58 GMT + Pragma: + - no-cache + RequestId: + - cbe47fd6-7a83-4a7d-a9c9-cb0b880a0619 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_single_page_no_prompt_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_single_page_no_prompt_success.yaml new file mode 100644 index 000000000..79860017f --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_single_page_no_prompt_success.yaml @@ -0,0 +1,57 @@ +interactions: +- request: + body: '{"search": "singlepage", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.3.1 + Content-Length: + - '40' + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "00000000-0000-0000-0000-954402814734", "type": "Notebook", + "displayName": "NB-0", "description": "Test item", "catalogEntryType": "FabricItem", + "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-797063891274", + "type": "Notebook", "displayName": "NB-1", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}, {"id": "00000000-0000-0000-0000-046371880096", + "type": "Notebook", "displayName": "NB-2", "description": "Test item", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "11111111-1111-1111-1111-111111111111", + "displayName": "TestWorkspace"}}}], "continuationToken": ""}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 14 Apr 2026 10:00:00 GMT + Pragma: + - no-cache + RequestId: + - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + Content-Length: + - '819' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_type_case_insensitive_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_type_case_insensitive_success.yaml new file mode 100644 index 000000000..a2f67a300 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_type_case_insensitive_success.yaml @@ -0,0 +1,379 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:53 GMT + Pragma: + - no-cache + RequestId: + - f9567142-3fe5-4236-bfec-32ed653aa53f + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:55 GMT + Pragma: + - no-cache + RequestId: + - 5d38797e-3e3a-4587-8cab-536054ff333b + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:54:58 GMT + Pragma: + - no-cache + RequestId: + - 9cfe733f-afa8-49a0-9839-1548498fc261 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Lakehouse", "folderId": null}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '107' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/lakehouses + response: + body: + string: '{"id": "614d485f-9011-4741-b373-4df3a98971ae", "type": "Lakehouse", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId,ETag + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '166' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:04 GMT + ETag: + - '""' + Pragma: + - no-cache + RequestId: + - afb795d0-f83a-4643-9bdc-995801028cd6 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 201 + message: Created +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "Type eq ''Lakehouse''"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '79' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "614d485f-9011-4741-b373-4df3a98971ae", "type": "Lakehouse", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '264' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:36 GMT + Pragma: + - no-cache + RequestId: + - bee07f3c-01d6-49e6-8a31-1c26670ec254 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:36 GMT + Pragma: + - no-cache + RequestId: + - 77f2492d-6862-4ab1-8fec-80da9faa6cc5 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "04481fa8-c2f9-4342-8e71-810eb3a51485", "type": "SQLEndpoint", + "displayName": "fabcli000001", "description": "", "workspaceId": "75e11421-85ce-411e-8673-1edc859aeb8f", + "sensitivityLabel": {"sensitivityLabelId": "9fbde396-1a24-4c79-8edf-9254a0f35055"}}, + {"id": "614d485f-9011-4741-b373-4df3a98971ae", "type": "Lakehouse", "displayName": + "fabcli000001", "description": "Created by fab", "workspaceId": "75e11421-85ce-411e-8673-1edc859aeb8f", + "sensitivityLabel": {"sensitivityLabelId": "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '273' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:37 GMT + Pragma: + - no-cache + RequestId: + - 9716af73-910d-4a3e-aa4a-fb7632f1642b + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/614d485f-9011-4741-b373-4df3a98971ae + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:55:38 GMT + Pragma: + - no-cache + RequestId: + - 3f21af63-d033-4080-8115-9193ab094cda + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_with_jmespath_query_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_with_jmespath_query_success.yaml new file mode 100644 index 000000000..fa8b1852c --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_with_jmespath_query_success.yaml @@ -0,0 +1,479 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:34 GMT + Pragma: + - no-cache + RequestId: + - 9b575060-def9-4d9f-8c95-e536b24d48a2 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:36 GMT + Pragma: + - no-cache + RequestId: + - 867dd52a-aba3-4c5b-927c-b74cdd9a2c20 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:38 GMT + Pragma: + - no-cache + RequestId: + - f6320ab1-3096-41d5-9f82-e47ce4f60c9a + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:59:42 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/48be2061-e6f1-4322-a653-035f059a864c + Pragma: + - no-cache + RequestId: + - 54216f9c-0351-4685-9a6e-397e5cea062a + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 48be2061-e6f1-4322-a653-035f059a864c + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/48be2061-e6f1-4322-a653-035f059a864c + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T10:59:42.1540503", + "lastUpdatedTimeUtc": "2026-04-19T10:59:43.2897286", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '131' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:04 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/48be2061-e6f1-4322-a653-035f059a864c/result + Pragma: + - no-cache + RequestId: + - 36bea129-26a2-48c0-8cd6-7222740b23ad + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 48be2061-e6f1-4322-a653-035f059a864c + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/48be2061-e6f1-4322-a653-035f059a864c/result + response: + body: + string: '{"id": "85fe8cbe-e2cc-48ad-a3f4-70590e9d34cb", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 11:00:06 GMT + Pragma: + - no-cache + RequestId: + - 02597371-1da8-4ca6-9dd4-d232ae2c7c5c + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '46' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "85fe8cbe-e2cc-48ad-a3f4-70590e9d34cb", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '263' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:39 GMT + Pragma: + - no-cache + RequestId: + - 91214aef-7100-4895-a724-1c06ae85909f + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:41 GMT + Pragma: + - no-cache + RequestId: + - 7f81b981-f941-4ae5-8bab-00f176fe0ec2 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "85fe8cbe-e2cc-48ad-a3f4-70590e9d34cb", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '222' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 11:00:43 GMT + Pragma: + - no-cache + RequestId: + - 57b3de9d-7987-4417-a756-a41de23f5ffe + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/85fe8cbe-e2cc-48ad-a3f4-70590e9d34cb + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 11:00:44 GMT + Pragma: + - no-cache + RequestId: + - 8fc3cdd0-a48d-4383-baec-92d0afed002d + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_with_long_output_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_with_long_output_success.yaml new file mode 100644 index 000000000..5d79bf0d3 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_with_long_output_success.yaml @@ -0,0 +1,479 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:41 GMT + Pragma: + - no-cache + RequestId: + - 2b2b3b5a-7737-46d1-ab89-bc5555c68085 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:43 GMT + Pragma: + - no-cache + RequestId: + - 7ea680ea-569b-43d8-8319-c59a91205965 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:46 GMT + Pragma: + - no-cache + RequestId: + - 746b5825-4d16-472f-b898-54c5f17acc6a + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:55:49 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/345f16d5-428a-4ebb-b102-511827536e41 + Pragma: + - no-cache + RequestId: + - 5c65a00c-e41a-4204-9dfb-9aeb713790e1 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 345f16d5-428a-4ebb-b102-511827536e41 + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/345f16d5-428a-4ebb-b102-511827536e41 + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T10:55:49.7103165", + "lastUpdatedTimeUtc": "2026-04-19T10:55:51.3608117", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '132' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:56:12 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/345f16d5-428a-4ebb-b102-511827536e41/result + Pragma: + - no-cache + RequestId: + - e6085bdf-4d55-4b41-9cb3-fc9c83592cb1 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 345f16d5-428a-4ebb-b102-511827536e41 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/345f16d5-428a-4ebb-b102-511827536e41/result + response: + body: + string: '{"id": "491e3e05-160f-4884-984e-4671f969e986", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 10:56:15 GMT + Pragma: + - no-cache + RequestId: + - 2a8cf996-618b-435c-b780-526d036903d5 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '46' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "491e3e05-160f-4884-984e-4671f969e986", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '602' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:56:47 GMT + Pragma: + - no-cache + RequestId: + - 611676d7-9ceb-4392-afb5-ec3452884729 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:56:50 GMT + Pragma: + - no-cache + RequestId: + - e3280cba-7ecb-4178-854a-fe1bee331e7e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "491e3e05-160f-4884-984e-4671f969e986", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '224' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:56:53 GMT + Pragma: + - no-cache + RequestId: + - 30900760-b317-4f46-b6ec-0faf629d9137 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/491e3e05-160f-4884-984e-4671f969e986 + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:56:56 GMT + Pragma: + - no-cache + RequestId: + - 9ee27a9f-192e-4536-90cb-2e3da3c72d66 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_with_ne_filter_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_with_ne_filter_success.yaml new file mode 100644 index 000000000..539d6cc82 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_with_ne_filter_success.yaml @@ -0,0 +1,476 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:57:02 GMT + Pragma: + - no-cache + RequestId: + - b1e2adfa-20b4-499e-843f-e86a01331054 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:57:05 GMT + Pragma: + - no-cache + RequestId: + - 1e5ad797-5944-4eac-9b9b-172d29817711 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:57:07 GMT + Pragma: + - no-cache + RequestId: + - 1243827e-84e0-471e-b7f7-c6b3c6da299f + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Notebook", "folderId": null, "definition": {"parts": [{"path": "notebook-content.py", + "payload": "IyBGYWJyaWMgbm90ZWJvb2sgc291cmNlCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAia2VybmVsX2luZm8iOiB7CiMgTUVUQSAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgojIE1FVEEgICB9LAojIE1FVEEgICAiZGVwZW5kZW5jaWVzIjoge30KIyBNRVRBIH0KCiMgQ0VMTCAqKioqKioqKioqKioqKioqKioqKgoKIyBXZWxjb21lIHRvIHlvdXIgbmV3IG5vdGVib29rCiMgVHlwZSBoZXJlIGluIHRoZSBjZWxsIGVkaXRvciB0byBhZGQgY29kZSEKCgojIE1FVEFEQVRBICoqKioqKioqKioqKioqKioqKioqCgojIE1FVEEgewojIE1FVEEgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKIyBNRVRBICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKIyBNRVRBIH0K", + "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '764' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/notebooks + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:57:11 GMT + ETag: + - '""' + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/09506b41-2b7b-406e-9b29-9ff60eaa2fd2 + Pragma: + - no-cache + RequestId: + - e6baa4ca-cdb0-4205-8944-02e2bb8b57a2 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 09506b41-2b7b-406e-9b29-9ff60eaa2fd2 + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/09506b41-2b7b-406e-9b29-9ff60eaa2fd2 + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2026-04-19T10:57:11.1587658", + "lastUpdatedTimeUtc": "2026-04-19T10:57:12.63963", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '130' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:57:33 GMT + Location: + - https://dailyapi.fabric.microsoft.com/v1/operations/09506b41-2b7b-406e-9b29-9ff60eaa2fd2/result + Pragma: + - no-cache + RequestId: + - cb783306-dad3-46d3-853c-415d1944b81c + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - 09506b41-2b7b-406e-9b29-9ff60eaa2fd2 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/operations/09506b41-2b7b-406e-9b29-9ff60eaa2fd2/result + response: + body: + string: '{"id": "88c91de0-e4e9-4cfe-a3ce-10eed3b81b8a", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 19 Apr 2026 10:57:36 GMT + Pragma: + - no-cache + RequestId: + - e0e0a580-0630-4318-893d-0f568e0b4e78 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "Type ne ''Notebook''"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '78' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '312' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:08 GMT + Pragma: + - no-cache + RequestId: + - 86453cf0-9441-41d5-9ebf-90ac56c8abeb + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:11 GMT + Pragma: + - no-cache + RequestId: + - e020a842-25c4-4ad3-a90a-28d9416dbdfc + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "88c91de0-e4e9-4cfe-a3ce-10eed3b81b8a", "type": "Notebook", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f", "sensitivityLabel": {"sensitivityLabelId": + "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '222' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:58:14 GMT + Pragma: + - no-cache + RequestId: + - 916e5bc7-04bc-452f-a77e-3bb3b896ffc5 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/88c91de0-e4e9-4cfe-a3ce-10eed3b81b8a + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:58:15 GMT + Pragma: + - no-cache + RequestId: + - 5f76d9db-1680-4d25-ba73-17a515f1829f + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_find/test_find_with_type_filter_success.yaml b/tests/test_commands/recordings/test_commands/test_find/test_find_with_type_filter_success.yaml new file mode 100644 index 000000000..6ae4cf6ae --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_find/test_find_with_type_filter_success.yaml @@ -0,0 +1,379 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:41 GMT + Pragma: + - no-cache + RequestId: + - 6536f44a-cce8-4049-8ce8-07b01e1ee63b + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:43 GMT + Pragma: + - no-cache + RequestId: + - bbab5c82-3e87-4a59-aed8-8ce0d022e599 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:46 GMT + Pragma: + - no-cache + RequestId: + - 1e2671d0-4a02-4a86-953c-81c7b9aa642c + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: '{"description": "Created by fab", "displayName": "fabcli000001", "type": + "Lakehouse", "folderId": null}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '107' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/lakehouses + response: + body: + string: '{"id": "ca02d6e2-3938-4889-8199-6d60b2f86393", "type": "Lakehouse", + "displayName": "fabcli000001", "description": "Created by fab", "workspaceId": + "75e11421-85ce-411e-8673-1edc859aeb8f"}' + headers: + Access-Control-Expose-Headers: + - RequestId,ETag + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '166' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:52:55 GMT + ETag: + - '""' + Pragma: + - no-cache + RequestId: + - 73f13f6b-a963-4cc8-9ee9-a525327a69f7 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 201 + message: Created +- request: + body: '{"search": "fabcli000001", "pageSize": 50, "filter": "Type eq ''Lakehouse''"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '79' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: POST + uri: https://api.fabric.microsoft.com/v1/catalog/search + response: + body: + string: '{"value": [{"id": "ca02d6e2-3938-4889-8199-6d60b2f86393", "type": "Lakehouse", + "displayName": "fabcli000001", "description": "Created by fab", "catalogEntryType": + "FabricItem", "hierarchy": {"workspace": {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", + "displayName": "fabriccli_WorkspacePerTestclass_000001"}}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '263' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:28 GMT + Pragma: + - no-cache + RequestId: + - 39e1d756-bd16-429a-8314-e5e9438ac68d + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "29490b32-2d1c-4f65-aa77-711b366ca219", "displayName": + "My workspace", "description": "", "type": "Personal", "capacityId": "00000000-0000-0000-0000-000000000004"}, + {"id": "75e11421-85ce-411e-8673-1edc859aeb8f", "displayName": "fabriccli_WorkspacePerTestclass_000001", + "description": "Created by fab", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '1391' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:30 GMT + Pragma: + - no-cache + RequestId: + - 48a20c18-9a53-47a0-b93f-99d7fc115c52 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items + response: + body: + string: '{"value": [{"id": "a667d4d6-b378-4667-8b58-6d0ab1e99aed", "type": "SQLEndpoint", + "displayName": "fabcli000001", "description": "", "workspaceId": "75e11421-85ce-411e-8673-1edc859aeb8f", + "sensitivityLabel": {"sensitivityLabelId": "9fbde396-1a24-4c79-8edf-9254a0f35055"}}, + {"id": "ca02d6e2-3938-4889-8199-6d60b2f86393", "type": "Lakehouse", "displayName": + "fabcli000001", "description": "Created by fab", "workspaceId": "75e11421-85ce-411e-8673-1edc859aeb8f", + "sensitivityLabel": {"sensitivityLabelId": "9fbde396-1a24-4c79-8edf-9254a0f35055"}}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '272' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 19 Apr 2026 10:53:32 GMT + Pragma: + - no-cache + RequestId: + - fd28ce00-bf01-41fa-ac7c-da3d2a0faa7a + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.5.0 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/75e11421-85ce-411e-8673-1edc859aeb8f/items/ca02d6e2-3938-4889-8199-6d60b2f86393 + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 19 Apr 2026 10:53:35 GMT + Pragma: + - no-cache + RequestId: + - 742ff8df-8797-4cec-a06d-03010e1c0aed + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/test_find.py b/tests/test_commands/test_find.py new file mode 100644 index 000000000..b326a23df --- /dev/null +++ b/tests/test_commands/test_find.py @@ -0,0 +1,520 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Tests for the find command — e2e (VCR) tests.""" + +import json +import time + +import pytest + +from fabric_cli.core.fab_types import ItemType +from fabric_cli.errors import ErrorMessages +from tests.test_commands.commands_parser import CLIExecutor + + +def _assert_strings_in_mock_calls( + strings: list[str], + should_exist: bool, + mock_calls, + require_all_in_same_args: bool = False, +): + """Assert that specified strings are present or absent in mock calls.""" + if require_all_in_same_args: + match_found = any( + all(string in str(call) for string in strings) for call in mock_calls + ) + else: + match_found = all( + any(string in str(call) for call in mock_calls) for string in strings + ) + + if should_exist: + assert ( + match_found + ), f"Expected strings {strings} to {'all be present together' if require_all_in_same_args else 'be present'} in mock calls, but not found." + else: + assert ( + not match_found + ), f"Expected strings {strings} to {'not all be present together' if require_all_in_same_args else 'not be present'} in mock calls, but found." + + +# --------------------------------------------------------------------------- +# E2E tests (VCR-recorded) +# +# These tests use the CLIExecutor to run actual find commands through the +# full CLI pipeline, with HTTP calls recorded/played back via VCR cassettes. +# +# To record cassettes: +# 1. Set env vars: +# $env:FAB_TOKEN = "" +# $env:FAB_TOKEN_ONELAKE = $env:FAB_TOKEN +# $env:FAB_API_ENDPOINT_FABRIC = "dailyapi.fabric.microsoft.com" +# 2. Run: +# pytest tests/test_commands/test_find.py::TestFindE2E --record -v +# --------------------------------------------------------------------------- + + +class TestFindE2E: + """End-to-end tests for the find command with VCR cassettes.""" + + @pytest.fixture(autouse=True) + def _mock_input(self, monkeypatch): + """Raise EOFError on input() to stop pagination after the first page.""" + monkeypatch.setattr( + "builtins.input", lambda *args: (_ for _ in ()).throw(EOFError) + ) + + def test_find_with_type_filter_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Lakehouse, search with -P type=Lakehouse, verify found.""" + lakehouse = item_factory(ItemType.LAKEHOUSE) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command(f"find '{lakehouse.display_name}' -P type=Lakehouse") + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [lakehouse.display_name, "Lakehouse"], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_basic_search_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Notebook, search by name with type filter, verify in results and summary.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command(f"find '{notebook.display_name}' -P type=Notebook") + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [notebook.display_name], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "found" in output + + def test_find_type_case_insensitive_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Lakehouse, search with lowercase type=lakehouse.""" + lakehouse = item_factory(ItemType.LAKEHOUSE) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command(f"find '{lakehouse.display_name}' -P type=lakehouse") + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [lakehouse.display_name, "Lakehouse"], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_with_long_output_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Notebook, search with -l, verify IDs in output.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command(f"find '{notebook.display_name}' -l") + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [notebook.display_name, "id"], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_no_results_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_print_grey, + ): + """Search for nonexistent term shows 'No items found'.""" + cli_executor.exec_command("find 'xyznonexistent98765zzz'") + + grey_output = " ".join(str(c) for c in mock_print_grey.call_args_list) + assert "No items found" in grey_output + + def test_find_with_ne_filter_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_print_grey, + mock_time_sleep, + ): + """Create a Notebook, search excluding Notebook type.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + mock_print_grey.reset_mock() + time.sleep(30) + + cli_executor.exec_command(f"find '{notebook.display_name}' -P type!=Notebook") + + all_output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "Notebook" not in all_output or "No items found" in " ".join( + str(c) for c in mock_print_grey.call_args_list + ) + + def test_find_ne_multi_type_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_print_grey, + mock_time_sleep, + ): + """Create a Notebook, search excluding Notebook and Report.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + mock_print_grey.reset_mock() + time.sleep(30) + + cli_executor.exec_command( + f"find '{notebook.display_name}' -P type!=[Notebook,Report]" + ) + + all_output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "Notebook" not in all_output or "No items found" in " ".join( + str(c) for c in mock_print_grey.call_args_list + ) + + def test_find_unknown_type_failure( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_fab_ui_print_error, + ): + """Search with unknown type shows error.""" + cli_executor.exec_command("find 'data' -P type=FakeType123") + + error_output = str(mock_fab_ui_print_error.call_args_list) + assert ErrorMessages.Find.unrecognized_type("FakeType123", "") in error_output + + def test_find_unsupported_type_failure( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_fab_ui_print_error, + ): + """Search with unsupported type shows error.""" + cli_executor.exec_command("find 'data' -P type=Dashboard") + + error_output = str(mock_fab_ui_print_error.call_args_list) + assert ErrorMessages.Common.type_not_supported("Dashboard") in error_output + + def test_find_invalid_param_format_failure( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_fab_ui_print_error, + ): + """Search with malformed -P value shows error.""" + cli_executor.exec_command("find 'data' -P notakeyvalue") + + error_output = str(mock_fab_ui_print_error.call_args_list) + assert ( + ErrorMessages.Common.invalid_parameter_format("notakeyvalue") + in error_output + ) + + def test_find_unsupported_param_failure( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_fab_ui_print_error, + ): + """Search with unknown param key shows error.""" + cli_executor.exec_command("find 'data' -P foo=bar") + + error_output = str(mock_fab_ui_print_error.call_args_list) + assert ErrorMessages.Common.unsupported_parameter("foo") in error_output + + def test_find_unsupported_param_ne_failure( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_fab_ui_print_error, + ): + """Search with unknown param key using != shows error.""" + cli_executor.exec_command("find 'data' -P foo!=bar") + + error_output = str(mock_fab_ui_print_error.call_args_list) + assert ErrorMessages.Common.unsupported_parameter("foo") in error_output + + def test_find_with_jmespath_query_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Notebook, search with JMESPath query.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command( + f"""find '{notebook.display_name}' -q "[?type=='Notebook']" """ + ) + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [notebook.display_name], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_multi_type_eq_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Notebook, search for Notebook and Report types.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command( + f"find '{notebook.display_name}' -P type=[Notebook,Report]" + ) + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + ["Notebook"], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_json_output_success( + self, + item_factory, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_time_sleep, + ): + """Create a Notebook, search with JSON output.""" + notebook = item_factory(ItemType.NOTEBOOK) + mock_questionary_print.reset_mock() + time.sleep(30) + + cli_executor.exec_command( + f"find '{notebook.display_name}' --output_format json" + ) + + mock_questionary_print.assert_called() + json_output = None + for call in mock_questionary_print.call_args_list: + try: + json_output = json.loads(call.args[0]) + break + except (json.JSONDecodeError, IndexError): + continue + assert json_output is not None, "No valid JSON found in output" + assert "result" in json_output + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) > 0 + + +class TestFindTruncation: + """Tests for column truncation with long display names. + + Uses handcrafted VCR cassettes (not recordable) because the test harness + normalizes display names to short monikers during recording, which would + defeat the purpose of testing truncation on long names. + """ + + LONG_NAME = "A" * 256 + + @pytest.fixture(autouse=True) + def _skip_on_record(self, vcr_mode): + if vcr_mode == "all": + pytest.skip("Synthetic cassettes — not recordable") + + @pytest.fixture(autouse=True) + def _mock_input(self, monkeypatch): + """Raise EOFError on input() to stop pagination after the first page.""" + monkeypatch.setattr( + "builtins.input", lambda *args: (_ for _ in ()).throw(EOFError) + ) + + def test_find_long_name_truncated_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + ): + """Text output truncates a 256-char display name.""" + cli_executor.exec_command(f"find 'longname'") + + mock_questionary_print.assert_called() + full_name_found = any( + self.LONG_NAME in str(call) + for call in mock_questionary_print.call_args_list + ) + assert not full_name_found, "Full 256-char name should be truncated in text output" + _assert_strings_in_mock_calls( + ["…"], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_long_name_details_not_truncated_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + ): + """Detail mode (-l) shows the full 256-char name without truncation.""" + cli_executor.exec_command(f"find 'longname' -l") + + mock_questionary_print.assert_called() + _assert_strings_in_mock_calls( + [self.LONG_NAME], + should_exist=True, + mock_calls=mock_questionary_print.call_args_list, + ) + + def test_find_long_name_json_not_truncated_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + ): + """JSON output preserves the full 256-char name without truncation.""" + cli_executor.exec_command(f"find 'longname' --output_format json") + + mock_questionary_print.assert_called() + json_output = None + for call in mock_questionary_print.call_args_list: + try: + json_output = json.loads(call.args[0]) + break + except (json.JSONDecodeError, IndexError): + continue + assert json_output is not None, "No valid JSON found in output" + names = [item.get("name", "") for item in json_output["result"]["data"]] + assert self.LONG_NAME in names, "Full 256-char name not found in JSON output" + + +class TestFindPagination: + """E2E tests for pagination, JMESPath filtering, and edge cases. + + Uses handcrafted VCR cassettes (not recordable) to exercise + the full CLI pipeline through cli_executor → find → _find_interactive. + """ + + @pytest.fixture(autouse=True) + def _skip_on_record(self, vcr_mode): + if vcr_mode == "all": + pytest.skip("Synthetic cassettes — not recordable") + + def test_find_single_page_no_prompt_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + monkeypatch, + ): + """Single page of results — items displayed, no pagination prompt.""" + prompt_called = False + + def _fail_on_prompt(*args): + nonlocal prompt_called + prompt_called = True + + monkeypatch.setattr("builtins.input", _fail_on_prompt) + + cli_executor.exec_command("find 'singlepage'") + + assert not prompt_called, "Prompt should not appear for single page" + output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "NB-0" in output + assert "3 items found" in output + + def test_find_multi_page_interactive_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + monkeypatch, + ): + """Two pages — user presses Enter to continue, sees all items.""" + monkeypatch.setattr("builtins.input", lambda *a: "") + + cli_executor.exec_command("find 'multipage'") + + output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "NB-P1-0" in output + assert "NB-P2-0" in output + assert "5 items found" in output + + def test_find_no_items_display_after_jmespath_filters_all_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + mock_print_grey, + monkeypatch, + ): + """JMESPath filter empties all results → 'No items found.'""" + monkeypatch.setattr( + "builtins.input", lambda *a: (_ for _ in ()).throw(EOFError) + ) + + cli_executor.exec_command( + """find 'jmespathempty' -q "[?type=='Lakehouse']" """ + ) + + grey_output = " ".join(str(c) for c in mock_print_grey.call_args_list) + assert "No items found" in grey_output + + def test_find_jmespath_skips_empty_page_success( + self, + cli_executor: CLIExecutor, + mock_questionary_print, + monkeypatch, + ): + """Three pages — middle page emptied by JMESPath, prompt skipped for it.""" + prompt_count = 0 + + def _count_prompt(*a): + nonlocal prompt_count + prompt_count += 1 + return "" + + monkeypatch.setattr("builtins.input", _count_prompt) + + cli_executor.exec_command( + """find 'jmespathskip' -q "[?type=='Notebook']" """ + ) + + # Prompt shown once (after page 1 with items), NOT after page 2 (empty) + assert prompt_count == 1, f"Expected 1 prompt, got {prompt_count}" + output = " ".join(str(c) for c in mock_questionary_print.call_args_list) + assert "NB-" in output + assert "LH-" not in output