From c0682706f97465d33967a38bfe4ffd4a7100f5c9 Mon Sep 17 00:00:00 2001 From: Nguyen Thai Hung <59815499+hung-cybo@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:06:36 +0900 Subject: [PATCH] test: add e2e test cases for upsert command (#597) Co-authored-by: tuan-pham-cybozu <41720778+tuanphamcybozu@users.noreply.github.com> --- features/delete.feature | 2 +- features/import.feature | 237 +++++++++++++++++++++------- features/step_definitions/common.ts | 19 ++- features/step_definitions/delete.ts | 2 +- features/step_definitions/import.ts | 58 ++++--- features/utils/helper.ts | 29 ++++ features/utils/world.ts | 25 ++- 7 files changed, 283 insertions(+), 89 deletions(-) diff --git a/features/delete.feature b/features/delete.feature index 2d4d2b07a4..5a8bbb16d1 100644 --- a/features/delete.feature +++ b/features/delete.feature @@ -12,4 +12,4 @@ Feature: cli-kintone delete command And Load app token of the app "app_for_delete" with exact permissions "view,delete" as env var: "API_TOKEN" When I run the command with args "record delete --app $APP_ID --base-url $$TEST_KINTONE_BASE_URL --api-token $API_TOKEN --yes" Then I should get the exit code is zero - And The app "app_for_delete" should has no records + And The app "app_for_delete" should have no records diff --git a/features/import.feature b/features/import.feature index e50c7827ad..72812edbdb 100644 --- a/features/import.feature +++ b/features/import.feature @@ -3,7 +3,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-23 Should import the records with API Token successfully. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-23.csv" with content as below: + And The CSV file "CliKintoneTest-23.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -12,14 +12,14 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --file-path CliKintoneTest-23.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | | Jenny | 30 | Scenario: CliKintoneTest-20 Should return the error message when the user has no privilege to add records. - Given The csv file "CliKintoneTest-20.csv" with content as below: + Given The CSV file "CliKintoneTest-20.csv" with content as below: | Text | Number | | Alice | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" @@ -30,7 +30,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-21 Should import records to app in space successfully. Given The app "app_in_space" has no records - And The csv file "CliKintoneTest-21.csv" with content as below: + And The CSV file "CliKintoneTest-21.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -39,7 +39,7 @@ Feature: cli-kintone import command And Load app token of the app "app_in_space" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --file-path CliKintoneTest-21.csv" Then I should get the exit code is zero - And The app "app_in_space" should has records as below: + And The app "app_in_space" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -47,7 +47,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-22 Should import records to app with --api-token and --username, --password successfully. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-22.csv" with content as below: + And The CSV file "CliKintoneTest-22.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -56,14 +56,14 @@ Feature: cli-kintone import command And Load username and password of the app "app_for_import" with exact permissions "add" as env vars: "USERNAME" and "PASSWORD" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token INVALID_API_TOKEN --username $USERNAME --password $PASSWORD --file-path CliKintoneTest-22.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | | Jenny | 30 | Scenario: CliKintoneTest-24 Should return the error message when importing records with draft API Token. - Given The csv file "CliKintoneTest-24.csv" with content as below: + Given The CSV file "CliKintoneTest-24.csv" with content as below: | Text | Number | | Alice | 10 | And Load app ID of the app "app_for_draft_token" as env var: "APP_ID" @@ -73,7 +73,7 @@ Feature: cli-kintone import command And The output error message should match with the pattern: "\[520] \[GAIA_IA02] The specified API token does not match the API token generated via an app." Scenario: CliKintoneTest-25 Should return the error message when importing records with two valid API Token. - Given The csv file "CliKintoneTest-25.csv" with content as below: + Given The CSV file "CliKintoneTest-25.csv" with content as below: | Text | Number | | Alice | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" @@ -85,7 +85,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-26 Should import the records successfully with two valid API Token in different apps. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-26.csv" with content as below: + And The CSV file "CliKintoneTest-26.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -95,14 +95,14 @@ Feature: cli-kintone import command And Load app token of the app "app_for_export" with exact permissions "view" as env var: "API_TOKEN_EXPORT" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN_IMPORT,$API_TOKEN_EXPORT --file-path CliKintoneTest-26.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | | Jenny | 30 | Scenario: CliKintoneTest-27 Should return the error message when importing records with valid and invalid API Tokens. - Given The csv file "CliKintoneTest-27.csv" with content as below: + Given The CSV file "CliKintoneTest-27.csv" with content as below: | Text | Number | | Alice | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" @@ -112,7 +112,7 @@ Feature: cli-kintone import command And The output error message should match with the pattern: "\[520] \[GAIA_IA02] The specified API token does not match the API token generated via an app." Scenario: CliKintoneTest-28 Should return the error message when importing records with an API Token without Add permission. - Given The csv file "CliKintoneTest-28.csv" with content as below: + Given The CSV file "CliKintoneTest-28.csv" with content as below: | Text | Number | | Alice | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" @@ -122,7 +122,7 @@ Feature: cli-kintone import command And The output error message should match with the pattern: "\[403] \[GAIA_NO01] Using this API token, you cannot run the specified API." Scenario: CliKintoneTest-29 Should return the error message when updating records with an API Token without View/Edit permission. - Given The csv file "CliKintoneTest-29.csv" with content as below: + Given The CSV file "CliKintoneTest-29.csv" with content as below: | Text | Number | | Alice | 11 | And The app "app_for_import" has some records as below: @@ -136,7 +136,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-30 Should import the records successfully with username and password. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-30.csv" with content as below: + And The CSV file "CliKintoneTest-30.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -145,7 +145,7 @@ Feature: cli-kintone import command And Load username and password of the app "app_for_import" with exact permissions "add" as env vars: "USERNAME" and "PASSWORD" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --username $USERNAME --password $PASSWORD --file-path CliKintoneTest-30.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -153,7 +153,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-31 Should import the records successfully with username (-u option) and password. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-31.csv" with content as below: + And The CSV file "CliKintoneTest-31.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -162,7 +162,7 @@ Feature: cli-kintone import command And Load username and password of the app "app_for_import" with exact permissions "add" as env vars: "USERNAME" and "PASSWORD" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID -u $USERNAME --password $PASSWORD --file-path CliKintoneTest-31.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -170,7 +170,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-32 Should import the records successfully with username and password (-p option). Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-32.csv" with content as below: + And The CSV file "CliKintoneTest-32.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -179,14 +179,14 @@ Feature: cli-kintone import command And Load username and password of the app "app_for_import" with exact permissions "add" as env vars: "USERNAME" and "PASSWORD" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --username $USERNAME -p $PASSWORD --file-path CliKintoneTest-32.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | | Jenny | 30 | Scenario: CliKintoneTest-33 Should import the records successfully with --attachments-dir specified and no attachment field. - Given The csv file "CliKintoneTest-33.csv" with content as below: + Given The CSV file "CliKintoneTest-33.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -195,14 +195,14 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN_IMPORT" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN_IMPORT --attachments-dir ./ --file-path CliKintoneTest-33.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | | Jenny | 30 | Scenario: CliKintoneTest-34 Should return the error message when importing non-existent attachment. - Given The csv file "CliKintoneTest-34.csv" with content as below: + Given The CSV file "CliKintoneTest-34.csv" with content as below: | Text | Number | Attachment | | Alice | 10 | non_exist_file.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" @@ -214,22 +214,22 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-35 Should import the records successfully with attachment. Given The app "app_for_import_attachments" has no records And I have a file "attachments/file1.txt" with content: "123" - And The csv file "CliKintoneTest-35.csv" with content as below: + And The CSV file "CliKintoneTest-35.csv" with content as below: | Text | Number | Attachment | | Alice | 10 | file1.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" And Load app token of the app "app_for_import_attachments" with exact permissions "add" as env var: "API_TOKEN_IMPORT" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN_IMPORT --attachments-dir ./attachments --file-path CliKintoneTest-35.csv" Then I should get the exit code is zero - And The app "app_for_import_attachments" should has records as below: + And The app "app_for_import_attachments" should have records as below: | Text | Number | Attachment | | Alice | 10 | file1.txt | - And The app "app_for_import_attachments" should has attachments as below: + And The app "app_for_import_attachments" should have attachments as below: | RecordIndex | AttachmentFieldCode | File | Content | | 0 | Attachment | file1.txt | 123 | Scenario: CliKintoneTest-36 Should return the error message when importing records with a non-existent directory. - Given The csv file "CliKintoneTest-36.csv" with content as below: + Given The CSV file "CliKintoneTest-36.csv" with content as below: | Text | Number | Attachment | | Alice | 10 | no_exist_file.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" @@ -242,17 +242,17 @@ Feature: cli-kintone import command Given The app "app_for_import_attachments" has no records And I have a file "attachments/file1.txt" with content: "123" And I have a file "attachments/file2.txt" with content: "abc" - And The csv file "CliKintoneTest-37.csv" with content as below: + And The CSV file "CliKintoneTest-37.csv" with content as below: | Text | Attachment | | Alice | file1.txt\nfile2.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" And Load app token of the app "app_for_import_attachments" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir ./attachments --file-path CliKintoneTest-37.csv" Then I should get the exit code is zero - And The app "app_for_import_attachments" should has records as below: + And The app "app_for_import_attachments" should have records as below: | Text | Attachment | | Alice | file1.txt\nfile2.txt | - And The app "app_for_import_attachments" should has attachments as below: + And The app "app_for_import_attachments" should have attachments as below: | RecordIndex | AttachmentFieldCode | File | Content | | 0 | Attachment | file1.txt | 123 | | 0 | Attachment | file2.txt | abc | @@ -263,17 +263,17 @@ Feature: cli-kintone import command And I have a file "attachments/file2.txt" with content: "456" And I have a file "attachments/file3.txt" with content: "abc" And I have a file "attachments/file4.txt" with content: "xyz" - And The csv file "CliKintoneTest-38.csv" with content as below: + And The CSV file "CliKintoneTest-38.csv" with content as below: | Text | Attachment | Attachment_0 | | Alice | file1.txt\nfile2.txt | file3.txt\nfile4.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" And Load app token of the app "app_for_import_attachments" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir ./attachments --file-path CliKintoneTest-38.csv" Then I should get the exit code is zero - And The app "app_for_import_attachments" should has records as below: + And The app "app_for_import_attachments" should have records as below: | Text | Attachment | Attachment_0 | | Alice | file1.txt\nfile2.txt | file3.txt\nfile4.txt | - And The app "app_for_import_attachments" should has attachments as below: + And The app "app_for_import_attachments" should have attachments as below: | RecordIndex | AttachmentFieldCode | File | Content | | 0 | Attachment | file1.txt | 123 | | 0 | Attachment | file2.txt | 456 | @@ -286,7 +286,7 @@ Feature: cli-kintone import command And I have a file "attachments/file2.txt" with content: "456" And I have a file "attachments/file3.txt" with content: "abc" And I have a file "attachments/file4.txt" with content: "xyz" - And The csv file "CliKintoneTest-39.csv" with content as below: + And The CSV file "CliKintoneTest-39.csv" with content as below: | Text | Attachment | | Alice | file1.txt\nfile2.txt | | Lisa | file3.txt\nfile4.txt | @@ -294,11 +294,11 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import_attachments" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir ./attachments --file-path CliKintoneTest-39.csv" Then I should get the exit code is zero - And The app "app_for_import_attachments" should has records as below: + And The app "app_for_import_attachments" should have records as below: | Text | Attachment | | Alice | file1.txt\nfile2.txt | | Lisa | file3.txt\nfile4.txt | - And The app "app_for_import_attachments" should has attachments as below: + And The app "app_for_import_attachments" should have attachments as below: | RecordIndex | AttachmentFieldCode | File | Content | | 0 | Attachment | file1.txt | 123 | | 0 | Attachment | file2.txt | 456 | @@ -308,17 +308,17 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-40 Should import the records successfully with .txt attachment. Given The app "app_for_import_attachments" has no records And I have a file "attachments/file.txt" with content: "G3Gef76wJ5u1mPuh14QhwgeLd5eC0OHU" - And The csv file "CliKintoneTest-40.csv" with content as below: + And The CSV file "CliKintoneTest-40.csv" with content as below: | Text | Attachment | | Alice | file.txt | And Load app ID of the app "app_for_import_attachments" as env var: "APP_ID" And Load app token of the app "app_for_import_attachments" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir ./attachments --file-path CliKintoneTest-40.csv" Then I should get the exit code is zero - And The app "app_for_import_attachments" should has records as below: + And The app "app_for_import_attachments" should have records as below: | Text | Attachment | | Alice | file.txt | - And The app "app_for_import_attachments" should has attachments as below: + And The app "app_for_import_attachments" should have attachments as below: | RecordIndex | AttachmentFieldCode | File | Content | | 0 | Attachment | file.txt | G3Gef76wJ5u1mPuh14QhwgeLd5eC0OHU | @@ -343,9 +343,136 @@ Feature: cli-kintone import command Then I should get the exit code is non-zero And The output error message should match with the pattern: "Error: ENOENT: no such file or directory" + Scenario: CliKintoneTest-44 Should upsert the records successfully with --update-key, a Record_number field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Number | + | Alice | 10 | + | Bob | 20 | + And Load the record numbers of the app "app_for_upsert" as variable: "RECORD_NUMBERS" + And The CSV file "CliKintoneTest-44.csv" with content as below: + | Record_number | Text | Number | + | $RECORD_NUMBERS[0] | Lisa | 30 | + | $RECORD_NUMBERS[1] | Rose | 40 | + | | Jenny | 50 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Record_number --file-path CliKintoneTest-44.csv" + Then I should get the exit code is zero + And The app "app_for_upsert" should have 3 records + And The app "app_for_upsert" should have records as below: + | Record_number | Text | Number | + | $RECORD_NUMBERS[0] | Lisa | 30 | + | $RECORD_NUMBERS[1] | Rose | 40 | + | \d+ | Jenny | 50 | + + Scenario: CliKintoneTest-45 Should upsert the records successfully with --update-key is a Text field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Number | + | Alice | 10 | + | Bob | 20 | + And Load the record numbers of the app "app_for_upsert" as variable: "RECORD_NUMBERS" + And The CSV file "CliKintoneTest-45.csv" with content as below: + | Record_number | Text | Number | + | | Alice | 30 | + | | Bob | 40 | + | | Jenny | 50 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Text --file-path CliKintoneTest-45.csv" + Then I should get the exit code is zero + And The app "app_for_upsert" should have 3 records + And The app "app_for_upsert" should have records as below: + | Record_number | Text | Number | + | $RECORD_NUMBERS[0] | Alice | 30 | + | $RECORD_NUMBERS[1] | Bob | 40 | + | \d+ | Jenny | 50 | + + Scenario: CliKintoneTest-46 Should return the error message when upserting with a non-prohibit duplicate values Text field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text_Non_Prohibit_Duplicate_Values | Number | + | Alice | 10 | + And The CSV file "CliKintoneTest-46.csv" with content as below: + | Text_Non_Prohibit_Duplicate_Values | Number | + | Alice | 20 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Text_Non_Prohibit_Duplicate_Values --file-path CliKintoneTest-46.csv" + Then I should get the exit code is non-zero + And The output error message should match with the pattern: "ERROR: Error: update key field should set to unique" + + Scenario: CliKintoneTest-47 Should upsert the records successfully with --update-key is a Number field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Number | + | Alice | 10 | + | Bob | 20 | + And Load the record numbers of the app "app_for_upsert" as variable: "RECORD_NUMBERS" + And The CSV file "CliKintoneTest-47.csv" with content as below: + | Record_number | Text | Number | + | | Lisa | 10 | + | | Rose | 20 | + | | Jenny | 30 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Number --file-path CliKintoneTest-47.csv" + Then I should get the exit code is zero + And The app "app_for_upsert" should have 3 records + And The app "app_for_upsert" should have records as below: + | Record_number | Text | Number | + | $RECORD_NUMBERS[0] | Lisa | 10 | + | $RECORD_NUMBERS[1] | Rose | 20 | + | \d+ | Jenny | 30 | + + Scenario: CliKintoneTest-48 Should return the error message when upserting with a non-prohibit duplicate values Number field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Number_Non_Prohibit_Duplicate_Values | + | Alice | 10 | + And The CSV file "CliKintoneTest-48.csv" with content as below: + | Text | Number_Non_Prohibit_Duplicate_Values | + | Bob | 10 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Number_Non_Prohibit_Duplicate_Values --file-path CliKintoneTest-48.csv" + Then I should get the exit code is non-zero + And The output error message should match with the pattern: "ERROR: Error: update key field should set to unique" + + Scenario: CliKintoneTest-49 Should return the error message when upserting with an unsupported field. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Date | + | Alice | 2024-01-01 | + And The CSV file "CliKintoneTest-49.csv" with content as below: + | Text | Date | + | Bob | 2024-01-01 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "view,add,edit" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Date --file-path CliKintoneTest-49.csv" + Then I should get the exit code is non-zero + And The output error message should match with the pattern: "ERROR: Error: unsupported field type for update key" + + Scenario: CliKintoneTest-50 Should return the error message when upserting with an API Token without Edit permission. + Given The app "app_for_upsert" has no records + And The app "app_for_upsert" has some records as below: + | Text | Number | + | Alice | 10 | + | Bob | 20 | + And The CSV file "CliKintoneTest-50.csv" with content as below: + | Text | Number | + | Alice | 30 | + | Bob | 40 | + And Load app ID of the app "app_for_upsert" as env var: "APP_ID" + And Load app token of the app "app_for_upsert" with exact permissions "add" as env var: "API_TOKEN" + When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --update-key Text --file-path CliKintoneTest-50.csv" + Then I should get the exit code is non-zero + And The output error message should match with the pattern: "\[403\] \[GAIA_NO01\] Using this API token, you cannot run the specified API." + Scenario: CliKintoneTest-51 Should import the records successfully with --fields specified. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-51.csv" with content as below: + And The CSV file "CliKintoneTest-51.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -354,7 +481,7 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --fields Text --file-path CliKintoneTest-51.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | | | Bob | | @@ -362,7 +489,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-52 Should import the records successfully with --fields specified multiple existent field codes. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-52.csv" with content as below: + And The CSV file "CliKintoneTest-52.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -371,7 +498,7 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --fields Text,Number --file-path CliKintoneTest-52.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -379,7 +506,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-53 Should return the error message when importing records with --fields specified, including existent and non-existent field codes. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-53.csv" with content as below: + And The CSV file "CliKintoneTest-53.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -392,7 +519,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-54 Should return the error message when importing records with --fields specified, including fields within a table. Given The app "app_for_import_table" has no records - And The csv file "CliKintoneTest-54.csv" with content as below: + And The CSV file "CliKintoneTest-54.csv" with content as below: | * | Text_0 | Number_0 | Table | Text | Number | | * | Alice | 10 | 1 | Alice_1 | 100 | | | Alice | 10 | 2 | Alice_2 | 200 | @@ -407,7 +534,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-55 Should import the records successfully with --fields specified, including field code of the table. Given The app "app_for_import_table" has no records - And The csv file "CliKintoneTest-55.csv" with content as below: + And The CSV file "CliKintoneTest-55.csv" with content as below: | * | Text_0 | Number_0 | Table | Text | Number | | * | Alice | 10 | 1 | Alice_1 | 100 | | | Alice | 10 | 2 | Alice_2 | 200 | @@ -418,7 +545,7 @@ Feature: cli-kintone import command And Load app token of the app "app_for_import_table" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --fields Table --file-path CliKintoneTest-55.csv" Then I should get the exit code is zero - And The app "app_for_import_table" with table field should has records as below: + And The app "app_for_import_table" with table field should have records as below: | * | Text_0 | Number_0 | Table | (Table.Text) | (Table.Number) | | * | | | \d+ | Alice_1 | 100 | | | | | \d+ | Alice_2 | 200 | @@ -428,7 +555,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-60 Should import the records successfully with the correct guest space id. Given The app "app_in_guest_space" has no records - And The csv file "CliKintoneTest-60.csv" with content as below: + And The CSV file "CliKintoneTest-60.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -438,7 +565,7 @@ Feature: cli-kintone import command And Load guest space ID of the app "app_in_guest_space" as env var: "GUEST_SPACE_ID" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --guest-space-id $GUEST_SPACE_ID --file-path CliKintoneTest-60.csv" Then I should get the exit code is zero - And The app "app_in_guest_space" should has records as below: + And The app "app_in_guest_space" should have records as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -446,7 +573,7 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-61 Should return the error message when the guest space does not exist. Given The app "app_in_guest_space" has no records - And The csv file "CliKintoneTest-61.csv" with content as below: + And The CSV file "CliKintoneTest-61.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | @@ -459,33 +586,33 @@ Feature: cli-kintone import command Scenario: CliKintoneTest-62 Should import the records successfully with --encoding option is utf8. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-62.csv" with "utf8" encoded content as below: + And The CSV file "CliKintoneTest-62.csv" with "utf8" encoded content as below: | Text | Number | | レコード番号 | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --encoding utf8 --file-path CliKintoneTest-62.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | レコード番号 | 10 | Scenario: CliKintoneTest-63 Should import the records successfully with --encoding option is sjis. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-63.csv" with "sjis" encoded content as below: + And The CSV file "CliKintoneTest-63.csv" with "sjis" encoded content as below: | Text | Number | | 作成日時 | 10 | And Load app ID of the app "app_for_import" as env var: "APP_ID" And Load app token of the app "app_for_import" with exact permissions "add" as env var: "API_TOKEN" When I run the command with args "record import --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --encoding sjis --file-path CliKintoneTest-63.csv" Then I should get the exit code is zero - And The app "app_for_import" should has records as below: + And The app "app_for_import" should have records as below: | Text | Number | | 作成日時 | 10 | Scenario: CliKintoneTest-64 Should return the error message when importing records with an unsupported character code. Given The app "app_for_import" has no records - And The csv file "CliKintoneTest-64.csv" with content as below: + And The CSV file "CliKintoneTest-64.csv" with content as below: | Text | Number | | Alice | 10 | | Bob | 20 | diff --git a/features/step_definitions/common.ts b/features/step_definitions/common.ts index fc665d280a..8e28c26ba1 100644 --- a/features/step_definitions/common.ts +++ b/features/step_definitions/common.ts @@ -37,6 +37,14 @@ Given( }, ); +Given( + "Load the record numbers of the app {string} as variable: {string}", + function (appKey: string, destVar: string) { + const recordNumbers = this.getRecordNumbersByAppKey(appKey); + this.replacements = { [destVar]: recordNumbers, ...this.replacements }; + }, +); + Given( "Load app token of the app {string} with exact permissions {string} as env var: {string}", function (appKey: string, permission: string, destEnvVar: string) { @@ -125,7 +133,8 @@ Given( async function (appKey, table) { const appCredential = this.getAppCredentialByAppKey(appKey); const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["add"]); - const tempFilePath = await this.generateCsvFile(table.raw()); + const csvObject = this.replacePlaceholdersInDataTables(table.raw()); + const tempFilePath = await this.generateCsvFile(csvObject); const command = `record import --file-path ${tempFilePath} --app ${appCredential.appId} --base-url $$TEST_KINTONE_BASE_URL --api-token ${apiToken}`; this.execCliKintoneSync(command); if (this.response.status !== 0) { @@ -182,3 +191,11 @@ Then( assert.match(this.response.stdout, reg); }, ); + +Then( + "The app {string} should have {int} records", + function (appKey, numberOfRecords: number) { + const recordNumbers = this.getRecordNumbersByAppKey(appKey); + assert.equal(recordNumbers.length, numberOfRecords); + }, +); diff --git a/features/step_definitions/delete.ts b/features/step_definitions/delete.ts index acf4e03921..1c75424e95 100644 --- a/features/step_definitions/delete.ts +++ b/features/step_definitions/delete.ts @@ -4,7 +4,7 @@ import { Then } from "../utils/world"; const NO_RECORDS_WARNING = "No records exist in the app or match the condition."; -Then("The app {string} should has no records", function (appKey) { +Then("The app {string} should have no records", function (appKey) { const appCredential = this.getAppCredentialByAppKey(appKey); const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["view"]); const command = `record export --app ${appCredential.appId} --base-url $$TEST_KINTONE_BASE_URL --api-token ${apiToken}`; diff --git a/features/step_definitions/import.ts b/features/step_definitions/import.ts index 0f1b6780be..704adc85c5 100644 --- a/features/step_definitions/import.ts +++ b/features/step_definitions/import.ts @@ -5,14 +5,15 @@ import type { SupportedEncoding } from "../utils/helper"; import { SUPPORTED_ENCODING } from "../utils/helper"; Given( - "The csv file {string} with content as below:", + "The CSV file {string} with content as below:", async function (filePath: string, table) { - await this.generateCsvFile(table.raw(), { filePath }); + const csvObject = this.replacePlaceholdersInDataTables(table.raw()); + await this.generateCsvFile(csvObject, { filePath }); }, ); Given( - "The csv file {string} with {string} encoded content as below:", + "The CSV file {string} with {string} encoded content as below:", async function (filePath: string, encoding: SupportedEncoding, table) { if (!SUPPORTED_ENCODING.includes(encoding)) { throw new Error(`The encoding ${encoding} is not supported`); @@ -29,31 +30,36 @@ Given( }, ); -Then("The app {string} should has records as below:", function (appKey, table) { - const appCredential = this.getAppCredentialByAppKey(appKey); - const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["view"]); - const fields = table.raw()[0].join(","); - let command = `record export --app ${appCredential.appId} --base-url $$TEST_KINTONE_BASE_URL --api-token ${apiToken} --fields ${fields}`; - if (appCredential.guestSpaceId && appCredential.guestSpaceId.length > 0) { - command += ` --guest-space-id ${appCredential.guestSpaceId}`; - } - this.execCliKintoneSync(command); - if (this.response.status !== 0) { - throw new Error(`Getting records failed. Error: \n${this.response.stderr}`); - } +Then( + "The app {string} should have records as below:", + function (appKey, table) { + const appCredential = this.getAppCredentialByAppKey(appKey); + const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["view"]); + const fields = table.raw()[0].join(","); + let command = `record export --app ${appCredential.appId} --base-url $$TEST_KINTONE_BASE_URL --api-token ${apiToken} --fields ${fields}`; + if (appCredential.guestSpaceId && appCredential.guestSpaceId.length > 0) { + command += ` --guest-space-id ${appCredential.guestSpaceId}`; + } + this.execCliKintoneSync(command); + if (this.response.status !== 0) { + throw new Error( + `Getting records failed. Error: \n${this.response.stderr}`, + ); + } - const records = table.raw(); - records.shift(); - records.forEach((record: string[]) => { - const values = record - .map((field: string) => (field ? `"${field}"` : "")) - .join(","); - assert.match(this.response.stdout, new RegExp(`${values}`)); - }); -}); + const records = this.replacePlaceholdersInDataTables(table.raw()); + records.shift(); + records.forEach((record: string[]) => { + const values = record + .map((field: string) => (field ? `"${field}"` : "")) + .join(","); + assert.match(this.response.stdout, new RegExp(`${values}`)); + }); + }, +); Then( - "The app {string} with table field should has records as below:", + "The app {string} with table field should have records as below:", function (appKey, table) { const appCredential = this.getAppCredentialByAppKey(appKey); const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["view"]); @@ -92,7 +98,7 @@ Then( ); Then( - "The app {string} should has attachments as below:", + "The app {string} should have attachments as below:", function (appKey, table) { const columns: string[] = table.raw()[0]; const requiredColumns = [ diff --git a/features/utils/helper.ts b/features/utils/helper.ts index db66145b81..01570ff9d7 100644 --- a/features/utils/helper.ts +++ b/features/utils/helper.ts @@ -7,6 +7,10 @@ export const SUPPORTED_ENCODING = ["utf8", "sjis"]; export type SupportedEncoding = (typeof SUPPORTED_ENCODING)[number]; +export type ReplacementValue = string | string[] | number | number[] | boolean; + +export type Replacements = { [key: string]: ReplacementValue }; + export const execCliKintoneSync = ( args: string, options?: { env?: { [key: string]: string }; cwd?: string }, @@ -137,3 +141,28 @@ export const getRecordNumbers = (appId: string, apiToken: string): string[] => { return recordNumbers.filter((recordNumber) => recordNumber.length > 0); }; + +export const replacePlaceholders = ( + str: string, + replacements: Replacements, +): string => { + return str.replace( + /\$([a-zA-Z0-9_]*)(?:\[(\d+)])?/g, + (match: string, placeholder: string, index?: number) => { + if (replacements[placeholder] === undefined) { + return match; + } + + const replacementValue = replacements[placeholder]; + if ( + Array.isArray(replacementValue) && + index && + replacementValue[index] !== undefined + ) { + return replacementValue[index].toString(); + } + + return replacementValue.toString(); + }, + ); +}; diff --git a/features/utils/world.ts b/features/utils/world.ts index 66322ae256..2d44318326 100644 --- a/features/utils/world.ts +++ b/features/utils/world.ts @@ -2,12 +2,13 @@ import type { SpawnSyncReturns } from "child_process"; import type { Credentials, AppCredential, Permission } from "./credentials"; import * as cucumber from "@cucumber/cucumber"; import { World } from "@cucumber/cucumber"; -import type { SupportedEncoding } from "./helper"; +import type { SupportedEncoding, Replacements } from "./helper"; import { generateCsvFile, execCliKintoneSync, generateFile, getRecordNumbers, + replacePlaceholders, } from "./helper"; import { getAppCredentialByAppKey, @@ -18,6 +19,7 @@ import { export class OurWorld extends World { public env: { [key: string]: string } = {}; + public replacements: Replacements = {}; private _workingDir?: string; private _credentials?: Credentials; private _response?: SpawnSyncReturns; @@ -62,10 +64,13 @@ export class OurWorld extends World { } public execCliKintoneSync(args: string) { - this.response = execCliKintoneSync(args, { - env: this.env, - cwd: this.workingDir, - }); + this.response = execCliKintoneSync( + replacePlaceholders(args, this.replacements), + { + env: this.env, + cwd: this.workingDir, + }, + ); } public async generateCsvFile( @@ -163,6 +168,16 @@ export class OurWorld extends World { const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["view"]); return getRecordNumbers(credential.appId, apiToken); } + + public replacePlaceholdersInDataTables(table: string[][]): string[][] { + if (Object.keys(this.replacements).length === 0) { + return table; + } + + return table.map((row) => + row.map((cell) => replacePlaceholders(cell, this.replacements)), + ); + } } // Helpers to avoid having to specify generics every time