Testing
Testing is a way to maintain reliability of your Flatfile integrations as it evolves.
Highlights:
Environments
Flatfile provides a developer mode and production environment.
Developer mode is an easy way to get up and running without securing user imports. Useful during an initial integration of a Portal into your own application.
Deploying to developer mode (test
) or production (prod
) is based on the variable set in the .env
file with the Platform SDK.
Production:
FLATFILE_ENV=prod
Developer mode:
FLATFILE_ENV=test
See example:
# An access and a secret key are required to use the Flatfile API
FLATFILE_ACCESS_KEY_ID=
FLATFILE_SECRET=
# Add your targetted env here, it defaults to `test`. Switch to `prod` when ready
FLATFILE_ENV=prod
# The team ID associated with the schema thats being deployed
FLATFILE_TEAM_ID=
# Optional - if it is not set this will default to https://api.us.flatfile.io
FLATFILE_API_URL=
Testing in code
In order to be confident that your configuration is working properly, it's good practice to write tests for your code. If you are using the starter project, you can include Jest tests by adding a .spec.ts
file to your project, typically in the same directory as the file that you are testing. So to test my-workbook.ts
, add a file in the same directory called my-workbook.spec.ts
and import your Workbook into that file for testing.
Use the following command to run your tests:
npm run test
SheetTester
The @flatfile/configure
package provides a SheetTester
utility with convenient functions for testing your code:
transformField(fieldName: string, value: string)
Takes a field name and value and returns the transformed value based on all sheet operations:
- Test
- Workbook
import { SheetTester } from "@flatfile/configure";
import { MyWorkbook } from "./MyWorkbook";
describe("Workbook tests ->", () => {
const testSheet = new SheetTester(MyWorkbook, "MySheet");
test("field transformations work", async () => {
expect(await testSheet.transformField("firstName", "alex")).toEqual("ALEX");
expect(await testSheet.transformField("age", "10")).toEqual(20);
expect(await testSheet.transformField("active", "true")).toEqual(true);
});
});
import { BooleanField, NumberField, Sheet, TextField, Workbook } from "@flatfile/configure";
const MySheet = new Sheet(
"MySheet",
{
firstName: TextField({
required: true,
description: "foo",
compute: (v) => v.toUpperCase(),
}),
age: NumberField(),
active: BooleanField({ default: false }),
},
{
recordCompute: (record, _session, _logger) => {
const age = record.get("age");
const newAge = typeof age === "number" ? age * 2 : 0;
record.set("age", newAge);
},
},
);
export default new Workbook({
name: `MyWorkbook`,
namespace: "test",
sheets: { MySheet },
});
testRecord(record: object)
This takes a full record and returns the transformed record based on all sheet operations:
- Test
- Workbook
import { SheetTester } from "@flatfile/configure";
import { MyWorkbook } from "./MyWorkbook";
describe("Workbook tests ->", () => {
const testSheet = new SheetTester(MyWorkbook, "MySheet");
test("single record is processed correctly", async () => {
const inputRow = { firstName: "alex", age: "10", active: "true" };
const expectedOutputRow = { age: 20, firstName: "ALEX", active: true };
const res = await testSheet.testRecord(inputRow);
expect(res).toMatchObject(expectedOutputRow);
});
});
import { BooleanField, NumberField, Sheet, TextField, Workbook } from "@flatfile/configure";
const MySheet = new Sheet(
"MySheet",
{
firstName: TextField({
required: true,
description: "foo",
compute: (v) => v.toUpperCase(),
}),
age: NumberField(),
active: BooleanField({ default: false }),
},
{
recordCompute: (record, _session, _logger) => {
const age = record.get("age");
const newAge = typeof age === "number" ? age * 2 : 0;
record.set("age", newAge);
},
},
);
export default new Workbook({
name: `MyWorkbook`,
namespace: "test",
sheets: { MySheet },
});
testRecords(record: object[])
This takes an array of full records and returns the transformed records based on all sheet operations:
- Test
- Workbook
import { SheetTester } from "@flatfile/configure";
import { MyWorkbook } from "./MyWorkbook";
describe("Workbook tests ->", () => {
const testSheet = new SheetTester(MyWorkbook, "MySheet");
test("multiple records are processed correctly", async () => {
const inputRows = [
{ firstName: "alex", age: "10", active: "true" },
{ firstName: "ashley", age: "8", active: "false" },
];
const expectedOutputRows = [
{ age: 20, firstName: "ALEX", active: true },
{ age: 16, firstName: "ASHLEY", active: false },
];
const results = await testSheet.testRecords(inputRows);
expect(results).toMatchObject(expectedOutputRows);
});
});
import { BooleanField, NumberField, Sheet, TextField, Workbook } from "@flatfile/configure";
const MySheet = new Sheet(
"MySheet",
{
firstName: TextField({
required: true,
description: "foo",
compute: (v) => v.toUpperCase(),
}),
age: NumberField(),
active: BooleanField({ default: false }),
},
{
recordCompute: (record, _session, _logger) => {
const age = record.get("age");
const newAge = typeof age === "number" ? age * 2 : 0;
record.set("age", newAge);
},
},
);
export default new Workbook({
name: `MyWorkbook`,
namespace: "test",
sheets: { MySheet },
});
Full example
- Test
- Workbook
import { SheetTester } from "@flatfile/configure";
import { MyWorkbook } from "./MyWorkbook";
describe("Workbook tests ->", () => {
const testSheet = new SheetTester(MyWorkbook, "MySheet");
test("single record is processed correctly", async () => {
const inputRow = { firstName: "alex", age: "10", active: "true" };
const expectedOutputRow = { age: 20, firstName: "ALEX", active: true };
const res = await testSheet.testRecord(inputRow);
expect(res).toMatchObject(expectedOutputRow);
});
test("multiple records are processed correctly", async () => {
const inputRows = [
{ firstName: "Alex", age: "10", active: "true" },
{ firstName: "Ashley", age: "8", active: "false" },
];
const expectedOutputRows = [
{ age: 20, firstName: "ALEX", active: true },
{ age: 16, firstName: "ASHLEY", active: false },
];
const results = await testSheet.testRecords(inputRows);
expect(results).toMatchObject(expectedOutputRows);
});
test("transformField() work", async () => {
expect(await testSheet.transformField("firstName", "alex")).toEqual("ALEX");
expect(await testSheet.transformField("age", "10")).toEqual(20);
expect(await testSheet.transformField("active", "true")).toEqual(true);
});
});
import { BooleanField, NumberField, Sheet, TextField, Workbook } from "@flatfile/configure";
const MySheet = new Sheet(
"MySheet",
{
firstName: TextField({
required: true,
description: "foo",
compute: (v) => v.toUpperCase(),
}),
age: NumberField(),
active: BooleanField({ default: false }),
},
{
recordCompute: (record, _session, _logger) => {
const age = record.get("age");
const newAge = typeof age === "number" ? age * 2 : 0;
record.set("age", newAge);
},
},
);
export default new Workbook({
name: `MyWorkbook`,
namespace: "test",
sheets: { MySheet },
});