mirror of
https://github.com/larksuite/cli.git
synced 2026-09-14 18:42:53 +08:00
d289566ad0
* feat(base): require --fields on +table-create A table created without --fields gets the platform default schema. Those default fields then sit in the table alongside every field the caller adds afterwards, and no field command removes them all, so the only clean recovery is to drop the table and start over. Make --fields required so the schema is declared up front, the way +base-create already recommends via --table-name + --fields. - Mark --fields Required on +table-create, and reject blank / non-array / empty-array values in Validate: cobra's MarkFlagRequired only checks that the flag was set, so --fields "" and --fields "[]" would still reach the API with no fields body and fall back to the default schema. - Validate runs ahead of the dry-run branch, so --dry-run can no longer preview an invocation the real call would reject. - Update the lark-base skill, e2e coverage notes and the live e2e helper. BREAKING CHANGE: `lark-cli base +table-create --base-token <t> --name <n>` without --fields now fails with a validation error instead of creating a default-schema table. Callers that relied on create-empty-then-add-fields must pass the schema to --fields. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(base): pin typed metadata on the invalid-schema rejection Address review feedback on the +table-create schema validation. - The invalid-fields-JSON rejection now asserts category, subtype and param through assertInvalidArgumentValidation, plus the preserved *json.SyntaxError cause, instead of only asserting that some error came back. - Document why the missing-flag test asserts cobra's text rather than errs metadata, and pin that layer boundary: cobra's ValidateRequiredFlags emits a plain error and the dispatcher types it later (cmd/root_test.go). The test now fails if that boundary moves, so the weaker assertion cannot silently outlive its reason. - Reword the --fields tip and the lark-base skill note: both described the fieldless path as if it were still reachable through +table-create. They now say the command rejects omitted / blank / empty schemas up front, while keeping why the schema must be declared here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(base): enrich +table-create field example and drop redundant tips The cobra Required declaration and flag Desc already advertise the --fields requirement, so the tips paragraph restating it (and its SKILL.md / coverage.md echoes) is dropped. The select-field example now carries multiple/hue/lightness so agents copy a complete option shape. * chore: remove useless example --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
13 KiB
13 KiB
Base CLI E2E Coverage
Metrics
- Denominator: 89 leaf commands
- Covered: 30
- Coverage: 33.7%
Summary
- TestBase_BasicWorkflow: proves
+base-create,+base-get,+table-create,+table-get, and+table-list; keyt.Run(...)proof points areget base as bot,get table as bot, andlist tables and find created table as bot. - TestBaseBlockDryRun: proves the five
+base-block-*shortcuts request shapes without touching live data. - TestBaseFieldCreateDryRunArrayCompat: proves
+field-createdry-run request shape for the internal JSON-array compatibility path. - TestBaseFormQuestionsCreateDryRun: proves
+form-questions-createpreserves its POST body and renders the existing-question guard in command help. - TestBaseFormDetailDryRun / TestBaseFormSubmitDryRun: prove shared-form detail and submission request shapes.
- TestBaseDashboardBlockGetDataDryRun: proves dashboard block data request shapes and identifier handling.
- TestBaseRecordBatchUpdatePerRecordDryRun: proves
+record-batch-updatepreserves the per-recordupdate_recordsrequest shape. - TestBaseRecordBatchUpdatePerRecordWorkflow: creates two records, updates different field types in one request, asserts the minimal response contract, reads both records back, verifies a missing record ID is not prevalidated, and cleans up the temporary Base.
- TestBase_RoleWorkflow: proves
+advperm-enable,+role-create,+role-list,+role-get, and+role-update; keyt.Run(...)proof points arelist as bot,get as bot, andupdate as bot. - TestBaseFormListDryRun_UsesBaseAndTableIdentifiers: proves
+form-listdry-run request shape uses Base and table identifiers in the endpoint. - TestBaseFormQuestionsCreateVisibleRuleDryRun / TestBaseFormQuestionsUpdateVisibleRuleDryRun: prove
+form-questions-create/+form-questions-updatedry-run request shape and that the optionalvisible_ruledisplay condition is transcribed verbatim into the request body. - TestBaseTableCopyDryRun: proves
+table-copyand+table-copy-statusrequest shapes, including the schema-safe default, table-name path escaping, explicit all+wait orchestration, Cobra duration parsing, and the opaque task ID body. - TestBaseTableCopyWorkflow: feature-gated by
LARK_CLI_E2E_BASE_TABLE_COPY_READY=1until the OpenAPI is deployed; creates a source table and record, proves schema-only copy, all no-wait plus status, all wait, record inclusion, and cleanup. - Cleanup note:
+table-deleteand+role-deleteonly run in cleanup and are intentionally left uncovered. - Blocked area: table-copy live integration remains deployment-gated; dashboard, field, most record operations, most form operations, view, and workflow operations still lack deterministic create/read/update workflows in this suite.
Command Table
| Status | Cmd | Type | Testcase | Key parameter shapes | Notes / uncovered reason |
|---|---|---|---|---|---|
| ✕ | base +advperm-disable | shortcut | none | no disable workflow yet | |
| ✓ | base +advperm-enable | shortcut | base_role_workflow_test.go::TestBase_RoleWorkflow | --base-token |
|
| ✕ | base +base-copy | shortcut | none | no copy workflow yet | |
| ✓ | base +base-create | shortcut | base/helpers_test.go::createBaseWithRetry | --name; --time-zone |
helper asserts created base token |
| ✓ | base +base-get | shortcut | base_basic_workflow_test.go::TestBase_BasicWorkflow/get base as bot | --base-token |
|
| ✓ | base +base-block-create | shortcut | base_block_dryrun_test.go::TestBaseBlockDryRun/create | --base-token; --type; --name; --parent-id; dry-run only |
request shape only |
| ✓ | base +base-block-delete | shortcut | base_block_dryrun_test.go::TestBaseBlockDryRun/delete | --base-token; --block-id; dry-run only |
request shape only |
| ✓ | base +base-block-list | shortcut | base_block_dryrun_test.go::TestBaseBlockDryRun/list all,list folder | --base-token; optional --parent-id; optional --type; dry-run only |
request shape only |
| ✓ | base +base-block-move | shortcut | base_block_dryrun_test.go::TestBaseBlockDryRun/move root,move after | --base-token; --block-id; optional --parent-id; --after-id; dry-run only |
request shape only |
| ✓ | base +base-block-rename | shortcut | base_block_dryrun_test.go::TestBaseBlockDryRun/rename | --base-token; --block-id; --name; dry-run only |
request shape only |
| ✕ | base +dashboard-arrange | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-block-create | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-block-delete | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-block-get | shortcut | none | dashboard workflows not covered | |
| ✓ | base +dashboard-block-get-data | shortcut | base_dashboard_block_get_data_dryrun_test.go | --base-token; --dashboard-id; --block-id; dry-run only |
request shape and identifier handling |
| ✕ | base +dashboard-block-list | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-block-update | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-create | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-delete | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-get | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-list | shortcut | none | dashboard workflows not covered | |
| ✕ | base +dashboard-update | shortcut | none | dashboard workflows not covered | |
| ✕ | base +data-query | shortcut | none | no data-query assertions yet | |
| ✓ | base +field-create | shortcut | base_field_dryrun_test.go::TestBaseFieldCreateDryRunArrayCompat | --base-token; --table-id; --json; dry-run only |
request shape only |
| ✕ | base +field-delete | shortcut | none | field workflows not covered | |
| ✕ | base +field-get | shortcut | none | field workflows not covered | |
| ✕ | base +field-list | shortcut | none | field workflows not covered | |
| ✕ | base +field-search-options | shortcut | none | field workflows not covered | |
| ✕ | base +field-update | shortcut | none | field workflows not covered | |
| ✕ | base +form-create | shortcut | none | form workflows not covered | |
| ✕ | base +form-delete | shortcut | none | form workflows not covered | |
| ✓ | base +form-detail | shortcut | base_form_detail_dryrun_test.go::TestBaseFormDetailDryRun | --share-token; dry-run only |
shared-form request shape |
| ✕ | base +form-get | shortcut | none | form workflows not covered | |
| ✓ | base +form-list | shortcut | base_form_detail_dryrun_test.go::TestBaseFormListDryRun_UsesBaseAndTableIdentifiers | --base-token; --table-id; dry-run only |
request shape only |
| ✓ | base +form-questions-create | shortcut | TestBaseFormQuestionsCreateVisibleRuleDryRun; base_form_questions_create_dryrun_test.go | questions[].visible_rule; dry-run | request body, visible_rule passthrough, and help guard covered |
| ✕ | base +form-questions-delete | shortcut | none | form workflows not covered | |
| ✕ | base +form-questions-list | shortcut | none | form workflows not covered | |
| ✓ | base +form-questions-update | shortcut | TestBaseFormQuestionsUpdateVisibleRuleDryRun | questions[].visible_rule | dry-run: request shape + visible_rule body passthrough |
| ✓ | base +form-submit | shortcut | base_form_submit_dryrun_test.go::TestBaseFormSubmitDryRun | --share-token; --json; dry-run only |
submission request shape |
| ✕ | base +form-update | shortcut | none | form workflows not covered | |
| ✓ | base +record-batch-create | shortcut | base_record_batch_update_workflow_test.go::TestBaseRecordBatchUpdatePerRecordWorkflow | --base-token; --table-id; --json.create_records |
seeds heterogeneous live workflow records |
| ✓ | base +record-batch-update | shortcut | base_record_batch_update_dryrun_test.go::TestBaseRecordBatchUpdatePerRecordDryRun; base_record_batch_update_workflow_test.go::TestBaseRecordBatchUpdatePerRecordWorkflow | --base-token; --table-id; --json.update_records; dry-run + live |
heterogeneous select/number update with write-back verification |
| ✕ | base +record-delete | shortcut | none | record workflows not covered | |
| ✓ | base +record-get | shortcut | base_record_batch_update_workflow_test.go::TestBaseRecordBatchUpdatePerRecordWorkflow | --record-id; repeated --field-id; --format json |
reads back select and number values after batch update |
| ✕ | base +record-history-list | shortcut | none | record workflows not covered | |
| ✕ | base +record-list | shortcut | none | record workflows not covered | |
| ✕ | base +record-search | shortcut | none | record workflows not covered | |
| ✕ | base +record-share-link-create | shortcut | none | record workflows not covered | |
| ✓ | base +record-upload-attachment | shortcut | base_attachment_dryrun_test.go::TestBase_AttachmentDryRun/upload | dry-run only | request shape only |
| ✓ | base +record-download-attachment | shortcut | base_attachment_dryrun_test.go::TestBase_AttachmentDryRun/download | dry-run only | request shape only |
| ✓ | base +record-remove-attachment | shortcut | base_attachment_dryrun_test.go::TestBase_AttachmentDryRun/remove | dry-run only | request shape only |
| ✕ | base +record-upsert | shortcut | none | record workflows not covered | |
| ✓ | base +role-create | shortcut | base/helpers_test.go::createRole | --base-token; --json |
helper asserts created role id |
| ✕ | base +role-delete | shortcut | none | cleanup only | |
| ✓ | base +role-get | shortcut | base_role_workflow_test.go::TestBase_RoleWorkflow/get as bot | --base-token; --role-id |
|
| ✓ | base +role-list | shortcut | base_role_workflow_test.go::TestBase_RoleWorkflow/list as bot | --base-token |
|
| ✓ | base +role-update | shortcut | base_role_workflow_test.go::TestBase_RoleWorkflow/update as bot | --base-token; --role-id; --json |
|
| ✓ | base +table-create | shortcut | base/helpers_test.go::createTableWithRetry | --base-token; --name; --fields; optional --view |
helper asserts table id |
| ✓ | base +table-copy | shortcut | base_table_copy_dryrun_test.go::TestBaseTableCopyDryRun; base_table_copy_workflow_test.go::TestBaseTableCopyWorkflow | --table-id ID/name; default --range schema; explicit --range all --wait --timeout |
dry-run covered; live workflow is deployment-gated and not yet verified |
| ✓ | base +table-copy-status | shortcut | base_table_copy_dryrun_test.go::TestBaseTableCopyDryRun/status; base_table_copy_workflow_test.go::TestBaseTableCopyWorkflow/all no-wait and status | opaque --task-id |
dry-run covered; live polling is deployment-gated and not yet verified |
| ✕ | base +table-delete | shortcut | none | cleanup only | |
| ✓ | base +table-get | shortcut | base_basic_workflow_test.go::TestBase_BasicWorkflow/get table as bot | --base-token; --table-id |
|
| ✓ | base +table-list | shortcut | base_basic_workflow_test.go::TestBase_BasicWorkflow/list tables and find created table as bot | --base-token |
|
| ✕ | base +table-update | shortcut | none | no rename workflow yet | |
| ✕ | base +title-resolve | shortcut | none | resolver workflow not covered | |
| ✕ | base +url-resolve | shortcut | none | resolver workflow not covered | |
| ✕ | base +view-create | shortcut | none | view workflows not covered | |
| ✕ | base +view-delete | shortcut | none | view workflows not covered | |
| ✕ | base +view-get | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-card | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-filter | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-group | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-sort | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-timebar | shortcut | none | view workflows not covered | |
| ✕ | base +view-get-visible-fields | shortcut | none | view workflows not covered | |
| ✕ | base +view-list | shortcut | none | view workflows not covered | |
| ✕ | base +view-rename | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-card | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-filter | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-group | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-sort | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-timebar | shortcut | none | view workflows not covered | |
| ✕ | base +view-set-visible-fields | shortcut | none | view workflows not covered | |
| ✕ | base +workflow-create | shortcut | none | workflow CRUD not covered | |
| ✕ | base +workflow-disable | shortcut | none | workflow CRUD not covered | |
| ✕ | base +workflow-enable | shortcut | none | workflow CRUD not covered | |
| ✕ | base +workflow-get | shortcut | none | workflow CRUD not covered | |
| ✕ | base +workflow-list | shortcut | none | workflow CRUD not covered | |
| ✕ | base +workflow-update | shortcut | none | workflow CRUD not covered |