Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add test cases for the export command with attachments #602

Merged
merged 4 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions features/export.feature
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,100 @@ Feature: cli-kintone export command
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN_1,INVALID_API_TOKEN"
Then I should get the exit code is non-zero
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-90 Should return the record contents and download attachments successfully with an existing directory.
Given The app "app_for_export_attachments" has no records
And I have a file "attachments/file1.txt" with content: "123"
And The app "app_for_export_attachments" has some records with attachments in directory "attachments" as below:
| Text | Attachment |
| Alice | file1.txt |
And Load the record numbers of the app "app_for_export_attachments" as variable: "RECORD_NUMBERS"
And Load app ID of the app "app_for_export_attachments" as env var: "APP_ID"
And Load app token of the app "app_for_export_attachments" with exact permissions "view" as env var: "API_TOKEN"
And I have a directory "exported-attachments"
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir exported-attachments"
Then I should get the exit code is zero
And The output message should match with the data below:
| Record_number | Text | Attachment |
| $RECORD_NUMBERS[0] | Alice | Attachment-$RECORD_NUMBERS[0][\/\\\\]file1.txt |
Copy link
Contributor

Choose a reason for hiding this comment

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

@hung-cybo
Do we need a comment to explain about the regular expression for slash and backslash?

And The directory "exported-attachments" should contain files as below:
| FilePath | FileName | Content |
| Attachment-$RECORD_NUMBERS[0] | file1.txt | 123 |

Scenario: CliKintoneTest-91 Should return the record contents and download attachments successfully with a non-existent directory.
Given The app "app_for_export_attachments" has no records
And I have a file "attachments/file1.txt" with content: "123"
And The app "app_for_export_attachments" has some records with attachments in directory "attachments" as below:
| Text | Attachment |
| Alice | file1.txt |
And Load the record numbers of the app "app_for_export_attachments" as variable: "RECORD_NUMBERS"
And Load app ID of the app "app_for_export_attachments" as env var: "APP_ID"
And Load app token of the app "app_for_export_attachments" with exact permissions "view" as env var: "API_TOKEN"
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir new-directory"
Then I should get the exit code is zero
And The output message should match with the data below:
| Record_number | Text | Attachment |
| $RECORD_NUMBERS[0] | Alice | Attachment-$RECORD_NUMBERS[0][\/\\\\]file1.txt |
And The directory "new-directory" should contain files as below:
| FilePath | FileName | Content |
| Attachment-$RECORD_NUMBERS[0] | file1.txt | 123 |

Scenario: CliKintoneTest-92 Should return the record contents and download attachments successfully with attachments in different records.
Given The app "app_for_export_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 app "app_for_export_attachments" has some records with attachments in directory "attachments" as below:
| Text | Attachment |
| Alice | file1.txt |
| Bob | file2.txt |
And Load the record numbers of the app "app_for_export_attachments" as variable: "RECORD_NUMBERS"
And Load app ID of the app "app_for_export_attachments" as env var: "APP_ID"
And Load app token of the app "app_for_export_attachments" with exact permissions "view" as env var: "API_TOKEN"
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir exported-attachments"
Then I should get the exit code is zero
And The output message should match with the data below:
| Record_number | Text | Attachment |
| $RECORD_NUMBERS[0] | Alice | Attachment-$RECORD_NUMBERS[0][\/\\\\]file1.txt |
| $RECORD_NUMBERS[1] | Bob | Attachment-$RECORD_NUMBERS[1][\/\\\\]file2.txt |
And The directory "exported-attachments" should contain files as below:
| FilePath | FileName | Content |
| Attachment-$RECORD_NUMBERS[0] | file1.txt | 123 |
| Attachment-$RECORD_NUMBERS[1] | file2.txt | abc |

Scenario: CliKintoneTest-93 Should return the record contents and download attachments successfully with attachments in a record.
Given The app "app_for_export_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 app "app_for_export_attachments" has some records with attachments in directory "attachments" as below:
| Text | Attachment |
| Alice | file1.txt\nfile2.txt |
And Load the record numbers of the app "app_for_export_attachments" as variable: "RECORD_NUMBERS"
And Load app ID of the app "app_for_export_attachments" as env var: "APP_ID"
And Load app token of the app "app_for_export_attachments" with exact permissions "view" as env var: "API_TOKEN"
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir exported-attachments"
Then I should get the exit code is zero
And The output message should match with the data below:
| Record_number | Text | Attachment |
| $RECORD_NUMBERS[0] | Alice | Attachment-$RECORD_NUMBERS[0][\/\\\\]file1.txt\nAttachment-$RECORD_NUMBERS[0][\/\\\\]file2.txt |
And The directory "exported-attachments" should contain files as below:
| FilePath | FileName | Content |
| Attachment-$RECORD_NUMBERS[0] | file1.txt | 123 |
| Attachment-$RECORD_NUMBERS[0] | file2.txt | abc |

Scenario: CliKintoneTest-94 Should return the record contents and download attachments successfully with a TXT file.
Given The app "app_for_export_attachments" has no records
And I have a file "attachments/file1.txt" with content: "123"
And The app "app_for_export_attachments" has some records with attachments in directory "attachments" as below:
| Text | Attachment |
| Alice | file1.txt |
And Load the record numbers of the app "app_for_export_attachments" as variable: "RECORD_NUMBERS"
And Load app ID of the app "app_for_export_attachments" as env var: "APP_ID"
And Load app token of the app "app_for_export_attachments" with exact permissions "view" as env var: "API_TOKEN"
When I run the command with args "record export --base-url $$TEST_KINTONE_BASE_URL --app $APP_ID --api-token $API_TOKEN --attachments-dir exported-attachments"
Then I should get the exit code is zero
And The output message should match with the data below:
| Record_number | Text | Attachment |
| $RECORD_NUMBERS[0] | Alice | Attachment-$RECORD_NUMBERS[0][\/\\\\]file1.txt |
And The directory "exported-attachments" should contain files as below:
| FilePath | FileName | Content |
| Attachment-$RECORD_NUMBERS[0] | file1.txt | 123 |
6 changes: 3 additions & 3 deletions features/step_definitions/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Given(
async function (appKey, table) {
const appCredential = this.getAppCredentialByAppKey(appKey);
const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["add"]);
const csvObject = this.replacePlaceholdersInDataTables(table.raw());
const csvObject = this.replacePlaceholdersInRawDataTables(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);
Expand All @@ -148,7 +148,7 @@ Given(
async function (appKey: string, attachmentDir: string, table) {
const appCredential = this.getAppCredentialByAppKey(appKey);
const apiToken = this.getAPITokenByAppAndPermissions(appKey, ["add"]);
const csvObject = this.replacePlaceholdersInDataTables(table.raw());
const csvObject = this.replacePlaceholdersInRawDataTables(table.raw());
const tempFilePath = await this.generateCsvFile(csvObject);
const command = `record import --file-path ${tempFilePath} --app ${appCredential.appId} --base-url $$TEST_KINTONE_BASE_URL --attachments-dir ${attachmentDir} --api-token ${apiToken}`;
this.execCliKintoneSync(command);
Expand Down Expand Up @@ -189,7 +189,7 @@ Then(
Then(
"The output message should match with the data below:",
async function (table) {
const records = table.raw();
const records = this.replacePlaceholdersInRawDataTables(table.raw());
records.forEach((record: string[]) => {
const values = record
.map((field: string) => (field ? `"${field}"` : ""))
Expand Down
40 changes: 40 additions & 0 deletions features/step_definitions/export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as assert from "assert";
import { Given, Then } from "../utils/world";
import fs from "fs";
import path from "path";

Given("I have a directory {string}", function (directory: string) {
fs.mkdirSync(path.join(this.workingDir, directory));
});

Then(
"The directory {string} should contain files as below:",
function (attachmentDir, table) {
const columns: string[] = table.raw()[0];
const requiredColumns = ["FilePath", "FileName", "Content"];
requiredColumns.forEach((requiredColumn) => {
if (!columns.includes(requiredColumn)) {
throw new Error(`The table should have ${requiredColumn} column.`);
}
});

const records: Array<{ [key: string]: string }> =
this.replacePlaceholdersInHashesDataTables(table.hashes());
for (let index = 0; index < records.length; index++) {
const record = records[index];
const actualFilePath = `${this.workingDir}/${attachmentDir}/${record.FilePath}/${record.FileName}`;

assert.ok(
fs.existsSync(actualFilePath),
`The file "${actualFilePath}" is not found`,
);

const actualContent = fs.readFileSync(actualFilePath, "utf8");
assert.equal(
actualContent,
record.Content,
`The content of the file "${actualFilePath}" does not matched.`,
);
}
},
);
17 changes: 13 additions & 4 deletions features/step_definitions/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import path from "path";
Given(
"The CSV file {string} with content as below:",
async function (filePath: string, table) {
const csvObject = this.replacePlaceholdersInDataTables(table.raw());
const csvObject = this.replacePlaceholdersInRawDataTables(table.raw());
await this.generateCsvFile(csvObject, { filePath });
},
);
Expand Down Expand Up @@ -48,7 +48,7 @@ Then(
);
}

const records = this.replacePlaceholdersInDataTables(table.raw());
const records = this.replacePlaceholdersInRawDataTables(table.raw());
records.shift();
records.forEach((record: string[]) => {
const values = record
Expand Down Expand Up @@ -133,8 +133,17 @@ Then(
recordNumbers[record.RecordIndex as unknown as number];
const actualFilePath = `${this.workingDir}/${attachmentDir}/${record.AttachmentFieldCode}-${recordNumber}/${record.File}`;

assert.ok(fs.existsSync(actualFilePath));
assert.equal(fs.readFileSync(actualFilePath, "utf8"), record.Content);
assert.ok(
fs.existsSync(actualFilePath),
`The file "${actualFilePath}" is not found`,
);

const actualContent = fs.readFileSync(actualFilePath, "utf8");
assert.equal(
actualContent,
record.Content,
`The content of the file "${actualFilePath}" does not matched.`,
);
}
},
);
Expand Down
18 changes: 17 additions & 1 deletion features/utils/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class OurWorld extends World {
return getRecordNumbers(credential.appId, apiToken);
}

public replacePlaceholdersInDataTables(table: string[][]): string[][] {
public replacePlaceholdersInRawDataTables(table: string[][]): string[][] {
if (Object.keys(this.replacements).length === 0) {
return table;
}
Expand All @@ -178,6 +178,22 @@ export class OurWorld extends World {
row.map((cell) => replacePlaceholders(cell, this.replacements)),
);
}

public replacePlaceholdersInHashesDataTables(
table: Array<{ [key: string]: string }>,
): Array<{ [key: string]: string }> {
if (Object.keys(this.replacements).length === 0) {
return table;
}

return table.map((row) => {
const newRow: { [key: string]: string } = {};
Object.keys(row).forEach((key) => {
newRow[key] = replacePlaceholders(row[key], this.replacements);
});
return newRow;
});
}
}

// Helpers to avoid having to specify generics every time
Expand Down