mirror of
https://github.com/larksuite/cli.git
synced 2026-09-14 18:42:53 +08:00
2f8d816512
* fix(sheets): repair the build after the local-office detection move main does not compile: shortcuts/sheets/lark_sheet_workbook.go references isOfficeSpreadsheet and officePrefixes, which no longer exist in the package. Neither PR was wrong on its own. #2531 (merged 10:39) moved local-office token detection into common.IsLocalOfficeToken and deleted the sheets-local copies; #2533 (merged 12:48) added errLocalOfficeExportUnsupported, which calls them. #2533's branch predated the move, so its CI was green against a base that still had the symbols, and merging it left main broken. Repoints both references at the moved API. Behaviour is unchanged: common.IsLocalOfficeToken is the same predicate #2531 moved, and the prefix pair is the exported form of the same two constants. #2533's own coverage — TestWorkbookExport_LocalOfficeTokenRejected across the local_office_ prefix, the fake_office_ prefix, and an interleaved OFL0X token, plus the wiki-node and dry-run cases — passes unchanged, which is what pins the equivalence. * fix(sheets): derive dry-run image parent_type from the ref kind, not the token A `/wiki/` URL reaches a DryRun hook as the wiki node_token: resolving it to the backing spreadsheet needs the get_node call a preview must not make. Both image-upload previews fed that node_token straight to sheetMediaParentType, so the parent_type they showed was derived from a token that is not the one Execute uploads against. A node_token shaped like an imported office token previewed office_sheet_file for a spreadsheet that will upload as sheet_image. sheetsDryRunParentType decides from the ref's kind instead. A wiki ref is native by construction, not by default: resolveWikiNodeToSpreadsheetToken rejects any node whose obj_type is not "sheet", and a spreadsheet backed by an imported office file sits in drive as a "file" node, so it never survives that gate to reach an upload. Execute is unaffected either way — it derives from the resolved token. This mirrors slidesDryRunParentType, which the slides domain already applies for the same reason. The hooks now hold the parsed ref rather than re-deriving the token from it, so the kind is visible where the preview is built. Also records, at uploadSheetMediaFile, that office_sheet_file survives the multipart path. Slides caps image uploads at 20 MB because upload_prepare rejects its parent types outright, which raised the question for sheets, whose deprecated +media-upload has no such cap. Verified against the live API: upload_prepare accepts both sheet_image and office_sheet_file, and a 20.6 MB file uploaded with office_sheet_file completes prepare -> 6 x upload_part -> upload_finish and returns a file_token a float image then accepts. Tests: sheetsDryRunParentType over both ref kinds, including wiki refs carrying office-shaped and office-prefixed node tokens; dry-run coverage through the public flags for +cells-set-image and +float-image-create, each checked against the identical token as a /wiki/ URL and as a raw spreadsheet token so the two rows differ only in kind; the same pair added to the e2e dry-run lane. All four fail against the previous behaviour. * fix(sheets): send oversized images through the chunked upload, not upload_all uploadSheetImage always used the single-part endpoint, so an image past the 20 MB ceiling failed with a bare 1061002 "upload media failed: params error" naming neither the size nor the limit. The capability was already in the domain: the deprecated sheets +media-upload has dispatched by size since it was written (backward.uploadSheetMediaFile), which left the same image succeeding through the old shortcut and failing through +cells-set-image and +float-image-create, the ones meant to replace it. uploadSheetImage now picks the endpoint by size the way doc and the deprecated shortcut already do. The parent_type is unchanged and still comes from sheetMediaParentType, so the office/native split rides along either branch. The preview follows the same branch. appendSheetImageUploadDryRun renders one upload_all under the ceiling and the upload_prepare / upload_part / upload_finish trio above it, and both image-write hooks now build their upload step through it rather than each spelling out an upload_all. A preview that promised a single-part upload for a file the CLI will send in chunks is a preview of a different request. Verified against the live API with a 20.6 MB PNG: +cells-set-image and +float-image-create both complete, the cell reads back holding the uploaded image_token at the file's real 3000x2400 dimensions, and the dry-run shows the three chunked steps Execute hits. The same file failed with 1061002 before. Tests: the chunked branch at exactly one byte past the ceiling, asserted through upload_prepare's parent_type with upload_all deliberately left unstubbed so a regression fails loudly; the preview's step list on both sides of the boundary, as a unit test and in the e2e dry-run lane. All fail against the previous behaviour.
7.8 KiB
7.8 KiB
Sheets CLI E2E Coverage
Metrics
- Denominator: 30 leaf commands
- Covered: 18
- Coverage: 60.0%
Summary
- TestSheets_CRUDE2EWorkflow: proves
+create,+info,+write,+read,+append,+find, and+export; keyt.Run(...)proof points arecreate spreadsheet with +create as bot,read data with +read as bot,find cells with +find as bot, andexport spreadsheet with +export as bot. - TestSheets_CreateWorkflowAsUser: proves the UAT path for
sheets +createandsheets +infothroughcreate spreadsheet with +create as userandget spreadsheet info with +info as user. - TestSheets_SpreadsheetsResource: proves direct
spreadsheets create,spreadsheets get, andspreadsheets patch. - TestSheets_FilterWorkflow: proves
spreadsheet.sheet.filters create,get,update, anddelete, with supporting sheet setup through+create,+info, and+write. - TestSheets_SheetShortcutsDryRun: proves request shapes for
+create-sheet,+copy-sheet,+delete-sheet, and+update-sheetwithout hitting live APIs. - TestSheets_SheetShortcutsWorkflow: proves live
+create-sheet,+copy-sheet,+update-sheet, and+delete-sheetflows against a real spreadsheet, with verification through+info. - TestSheets_ImageUploadDryRunParentType: dry-run coverage for the drive
parent_typean image upload carries, across every surface a local file enters through —+media-upload,+cells-set-image, and+float-image-create. A native spreadsheet must upload assheet_imageand one backed by an imported office file asoffice_sheet_file; a/wiki/ref must stay native, because a preview cannot resolve the node and so must not read the split out of the node_token. The negative half matters most: the backend does not validateparent_nodeagainstparent_type, so a wrong value uploads successfully and only surfaces later as an image that will not render. - TestSheets_ImageUploadDryRunChunked: dry-run coverage for the 20 MB branch in
+cells-set-image. Under the ceiling the preview shows oneupload_all; one byte past it, theupload_prepare/upload_part/upload_finishtrio Execute actually sends. Before that dispatch existed, an oversized image failed onupload_allwith a bare1061002naming neither the size nor the limit. - Cleanup note: workflow-created spreadsheets are cleaned up via
drive +delete --type sheet; those cleanup-only executions are not counted as command coverage because no testcase asserts delete behavior as the primary proof surface.
Command Table
| Status | Cmd | Type | Testcase | Key parameter shapes | Notes / uncovered reason |
|---|---|---|---|---|---|
| ✕ | sheets +add-dimension | shortcut | none | no dimension workflow yet | |
| ✓ | sheets +append | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/append rows with +append as bot | --spreadsheet-token; --sheet-id; --range; --values |
|
| ✕ | sheets +batch-set-style | shortcut | none | no style workflow yet | |
| ✓ | sheets +create | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/create spreadsheet with +create as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/create spreadsheet with initial data as bot; sheets_create_workflow_test.go::TestSheets_CreateWorkflowAsUser/create spreadsheet with +create as user | --title |
|
| ✓ | sheets +create-sheet | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/create sheet with +create-sheet as bot | --spreadsheet-token; optional --title; optional --index |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +copy-sheet | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/copy sheet with +copy-sheet as bot | --spreadsheet-token; --sheet-id; optional --title; optional --index |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✕ | sheets +delete-dimension | shortcut | none | no dimension workflow yet | |
| ✓ | sheets +delete-sheet | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/delete sheet with +delete-sheet as bot | --spreadsheet-token; --sheet-id |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +export | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/export spreadsheet with +export as bot | --spreadsheet-token; --file-extension |
|
| ✓ | sheets +find | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/find cells with +find as bot | --spreadsheet-token; --sheet-id; --find; --range |
|
| ✓ | sheets +info | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/get spreadsheet info with +info as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/get sheet info as bot; sheets_create_workflow_test.go::TestSheets_CreateWorkflowAsUser/get spreadsheet info with +info as user | --spreadsheet-token |
|
| ✕ | sheets +insert-dimension | shortcut | none | no dimension workflow yet | |
| ✕ | sheets +merge-cells | shortcut | none | no merge workflow yet | |
| ✕ | sheets +move-dimension | shortcut | none | no dimension workflow yet | |
| ✓ | sheets +read | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/read data with +read as bot | --spreadsheet-token; --sheet-id; --range |
|
| ✕ | sheets +replace | shortcut | none | no replace workflow yet | |
| ✕ | sheets +set-style | shortcut | none | no style workflow yet | |
| ✕ | sheets +unmerge-cells | shortcut | none | no merge workflow yet | |
| ✕ | sheets +update-dimension | shortcut | none | no dimension workflow yet | |
| ✓ | sheets +update-sheet | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/update sheet with +update-sheet as bot | --spreadsheet-token; --sheet-id; scalar update flags; optional protect fields |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +write | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/write data with +write as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/write test data for filtering as bot | --spreadsheet-token; --sheet-id; --range; --values |
|
| ✕ | sheets +write-image | shortcut | none | no image workflow yet | |
| ✓ | sheets spreadsheet.sheet.filters create | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/create filter with spreadsheet.sheet.filters create as bot | spreadsheet_token; sheet_id in --params; filter JSON in --data |
|
| ✓ | sheets spreadsheet.sheet.filters delete | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/delete filter with spreadsheet.sheet.filters delete as bot | spreadsheet_token; sheet_id in --params |
|
| ✓ | sheets spreadsheet.sheet.filters get | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/get filter with spreadsheet.sheet.filters get as bot | spreadsheet_token; sheet_id in --params |
|
| ✓ | sheets spreadsheet.sheet.filters update | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/update filter with spreadsheet.sheet.filters update as bot | spreadsheet_token; sheet_id in --params; filter JSON in --data |
|
| ✕ | sheets spreadsheet.sheets find | api | none | no direct API workflow yet | |
| ✓ | sheets spreadsheets create | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/create spreadsheet with spreadsheets create as bot | title in --data |
|
| ✓ | sheets spreadsheets get | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/get spreadsheet with spreadsheets get as bot | spreadsheet_token in --params |
|
| ✓ | sheets spreadsheets patch | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/patch spreadsheet with spreadsheets patch as bot | spreadsheet_token in --params; title patch in --data |