airbyte-faros-destination 0.15.4 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -14,3 +14,4 @@ export declare function mainCommand(options?: {
14
14
  export { Edition, InvalidRecordStrategy } from './common/types';
15
15
  export { Converter, DestinationRecord, DestinationModel, StreamContext, StreamName, } from './converters/converter';
16
16
  export { FarosDestinationRunner } from './destination-runner';
17
+ export * from './testing-tools/testing-tools';
package/lib/index.js CHANGED
@@ -1,4 +1,18 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
17
  exports.FarosDestinationRunner = exports.StreamName = exports.StreamContext = exports.Converter = exports.InvalidRecordStrategy = exports.Edition = void 0;
4
18
  exports.mainCommand = mainCommand;
@@ -36,4 +50,5 @@ Object.defineProperty(exports, "StreamContext", { enumerable: true, get: functio
36
50
  Object.defineProperty(exports, "StreamName", { enumerable: true, get: function () { return converter_1.StreamName; } });
37
51
  var destination_runner_2 = require("./destination-runner");
38
52
  Object.defineProperty(exports, "FarosDestinationRunner", { enumerable: true, get: function () { return destination_runner_2.FarosDestinationRunner; } });
53
+ __exportStar(require("./testing-tools/testing-tools"), exports);
39
54
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAYA,kCAoBC;AA9BD,6DAA4D;AAE5D;;;;;;;GAOG;AACH,SAAgB,WAAW,CAAC,OAG3B;IACC,MAAM,iBAAiB,GAAG,IAAI,2CAAsB,EAAE,CAAC;IACvD,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAEhD,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,cAAc,EAAE,CAAC;QAC5B,OAAO,CAAC,eAAe,CAAC;YACtB,gEAAgE;YAChE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;YAClB,gEAAgE;YAChE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wCAA8D;AAAtD,gGAAA,OAAO,OAAA;AAAE,8GAAA,qBAAqB,OAAA;AACtC,oDAMgC;AAL9B,sGAAA,SAAS,OAAA;AAGT,0GAAA,aAAa,OAAA;AACb,uGAAA,UAAU,OAAA;AAEZ,2DAA4D;AAApD,4HAAA,sBAAsB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAYA,kCAoBC;AA9BD,6DAA4D;AAE5D;;;;;;;GAOG;AACH,SAAgB,WAAW,CAAC,OAG3B;IACC,MAAM,iBAAiB,GAAG,IAAI,2CAAsB,EAAE,CAAC;IACvD,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAEhD,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,cAAc,EAAE,CAAC;QAC5B,OAAO,CAAC,eAAe,CAAC;YACtB,gEAAgE;YAChE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;YAClB,gEAAgE;YAChE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wCAA8D;AAAtD,gGAAA,OAAO,OAAA;AAAE,8GAAA,qBAAqB,OAAA;AACtC,oDAMgC;AAL9B,sGAAA,SAAS,OAAA;AAGT,0GAAA,aAAa,OAAA;AACb,uGAAA,UAAU,OAAA;AAEZ,2DAA4D;AAApD,4HAAA,sBAAsB,OAAA;AAE9B,gEAA8C"}
@@ -0,0 +1,37 @@
1
+ import { ChildProcess } from 'child_process';
2
+ import { Readable, Writable } from 'stream';
3
+ export declare function read(s: Readable): Promise<string>;
4
+ export declare function readLines(s: Readable): Promise<ReadonlyArray<string>>;
5
+ export interface CLIOptions {
6
+ env?: {
7
+ [key: string]: string;
8
+ };
9
+ }
10
+ /** A convenience class for testing CLI inputs and outputs. */
11
+ export declare class CLI {
12
+ private readonly cp;
13
+ constructor(cp: ChildProcess);
14
+ get stderr(): Readable;
15
+ get stdout(): Readable;
16
+ get stdin(): Writable;
17
+ /** Waits for the child process to terminate and returns the exit code. */
18
+ wait(): Promise<number>;
19
+ /**
20
+ * Checks stdin for the given prompt string, then writes the given response to
21
+ * stdout.
22
+ */
23
+ respondToPrompt(prompt: string, response: string): void;
24
+ /**
25
+ * Runs CLI as a subprocess with the given arguments.
26
+ *
27
+ * If a home directory is not provided, the CLI's home directory will be set
28
+ * to an empty, unique, and temporary directory. In particular, this means
29
+ * that runs created by this function have separate caches and can run
30
+ * concurrently without interference.
31
+ *
32
+ * If a home diectory is not provided, the newly generated temporary directory
33
+ * will be deleted after the CLI command has returned. Otherwise, it is the
34
+ * caller's responsibility to clean up their chosen home directory.
35
+ */
36
+ static runWith(args: string[], opts?: CLIOptions, bin?: string): Promise<CLI>;
37
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CLI = void 0;
7
+ exports.read = read;
8
+ exports.readLines = readLines;
9
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const consumers_1 = __importDefault(require("stream/consumers"));
12
+ async function read(s) {
13
+ return await consumers_1.default.text(s);
14
+ }
15
+ async function readLines(s) {
16
+ return (await read(s)).split('\n');
17
+ }
18
+ /** A convenience class for testing CLI inputs and outputs. */
19
+ class CLI {
20
+ constructor(cp) {
21
+ this.cp = cp;
22
+ }
23
+ get stderr() {
24
+ // `stderr` is always defined with the options in `runWith`.
25
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
26
+ return this.cp.stderr;
27
+ }
28
+ get stdout() {
29
+ // `stdout` is always defined with the options in `runWith`.
30
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31
+ return this.cp.stdout;
32
+ }
33
+ get stdin() {
34
+ // `stdin` is always defined with the options in `runWith`.
35
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
+ return this.cp.stdin;
37
+ }
38
+ /** Waits for the child process to terminate and returns the exit code. */
39
+ async wait() {
40
+ if (this.cp.exitCode !== null) {
41
+ return this.cp.exitCode;
42
+ }
43
+ return new Promise((ok) => {
44
+ this.cp.on('exit', ok);
45
+ });
46
+ }
47
+ /**
48
+ * Checks stdin for the given prompt string, then writes the given response to
49
+ * stdout.
50
+ */
51
+ respondToPrompt(prompt, response) {
52
+ // Use flag to only write to stdin once, since the Enquirer library prompt
53
+ // triggers stdout.on() multiple times.
54
+ let shouldRespond = true;
55
+ this.stdout.on('data', (data) => {
56
+ if (shouldRespond && data.toString().includes(prompt)) {
57
+ this.stdin.write(response, 'utf8');
58
+ shouldRespond = false;
59
+ }
60
+ });
61
+ }
62
+ /**
63
+ * Runs CLI as a subprocess with the given arguments.
64
+ *
65
+ * If a home directory is not provided, the CLI's home directory will be set
66
+ * to an empty, unique, and temporary directory. In particular, this means
67
+ * that runs created by this function have separate caches and can run
68
+ * concurrently without interference.
69
+ *
70
+ * If a home diectory is not provided, the newly generated temporary directory
71
+ * will be deleted after the CLI command has returned. Otherwise, it is the
72
+ * caller's responsibility to clean up their chosen home directory.
73
+ */
74
+ static async runWith(args, opts = {}, bin = 'main') {
75
+ const spawnOpts = {
76
+ env: {
77
+ ...process.env,
78
+ ...opts.env,
79
+ },
80
+ };
81
+ const cp = (0, cross_spawn_1.default)(path_1.default.resolve('bin', bin), args, spawnOpts);
82
+ return new CLI(cp);
83
+ }
84
+ }
85
+ exports.CLI = CLI;
86
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/testing-tools/cli.ts"],"names":[],"mappings":";;;;;;AAMA,oBAEC;AAED,8BAEC;AAXD,8DAAgC;AAChC,gDAAwB;AAExB,iEAAyC;AAElC,KAAK,UAAU,IAAI,CAAC,CAAW;IACpC,OAAO,MAAM,mBAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,CAAW;IACzC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAMD,8DAA8D;AAC9D,MAAa,GAAG;IACd,YAA6B,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAEjD,IAAI,MAAM;QACR,4DAA4D;QAC5D,oEAAoE;QACpE,OAAO,IAAI,CAAC,EAAE,CAAC,MAAO,CAAC;IACzB,CAAC;IAED,IAAI,MAAM;QACR,4DAA4D;QAC5D,oEAAoE;QACpE,OAAO,IAAI,CAAC,EAAE,CAAC,MAAO,CAAC;IACzB,CAAC;IAED,IAAI,KAAK;QACP,2DAA2D;QAC3D,oEAAoE;QACpE,OAAO,IAAI,CAAC,EAAE,CAAC,KAAM,CAAC;IACxB,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,EAAE,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YACxB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,MAAc,EAAE,QAAgB;QAC9C,0EAA0E;QAC1E,uCAAuC;QACvC,IAAI,aAAa,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAS,EAAE,EAAE;YACnC,IAAI,aAAa,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACnC,aAAa,GAAG,KAAK,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAClB,IAAc,EACd,OAAmB,EAAE,EACrB,GAAG,GAAG,MAAM;QAEZ,MAAM,SAAS,GAAG;YAChB,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,GAAG,IAAI,CAAC,GAAG;aACZ;SACF,CAAC;QACF,MAAM,EAAE,GAAG,IAAA,qBAAK,EAAC,cAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAC5D,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;CACF;AAzED,kBAyEC"}
@@ -0,0 +1,3 @@
1
+ export * from './cli';
2
+ export * from './testing-tools';
3
+ export * from './utils';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./cli"), exports);
18
+ __exportStar(require("./testing-tools"), exports);
19
+ __exportStar(require("./utils"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing-tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wCAAsB;AACtB,kDAAgC;AAChC,0CAAwB"}
@@ -0,0 +1,36 @@
1
+ import { Mockttp } from 'mockttp';
2
+ import pino from 'pino';
3
+ import { Dictionary } from 'ts-essentials';
4
+ import { Edition, InvalidRecordStrategy } from '../common/types';
5
+ /**
6
+ * Read a test resource by name
7
+ */
8
+ export declare function readTestResourceFile(fileName: string): string;
9
+ /**
10
+ * Parse a test resource into JSON
11
+ */
12
+ export declare function readTestResourceAsJSON(fileName: string): any;
13
+ /**
14
+ * Creates a temporary file
15
+ * @return path to the temporary file
16
+ */
17
+ export declare function tempFile(data: string, postfix: string): Promise<string>;
18
+ export interface TempConfigOptions {
19
+ readonly api_url: string;
20
+ readonly invalid_record_strategy?: InvalidRecordStrategy;
21
+ readonly edition?: Edition;
22
+ readonly edition_configs?: Dictionary<any>;
23
+ readonly source_specific_configs?: Dictionary<any>;
24
+ readonly replace_origin_map?: Dictionary<any>;
25
+ readonly exclude_fields_map?: Dictionary<any>;
26
+ readonly log_records?: boolean;
27
+ }
28
+ /**
29
+ * Creates a temporary file with testing configuration
30
+ * @return path to the temporary config file to delete
31
+ */
32
+ export declare function tempConfig(options: TempConfigOptions): Promise<string>;
33
+ export declare function getConf(options: TempConfigOptions): any;
34
+ export declare function sourceSpecificTempConfig(url: string, source_specific_configs: Dictionary<any>): Promise<string>;
35
+ export declare function initMockttp(mockttp: Mockttp): Promise<void>;
36
+ export declare function testLogger(name?: string): pino.Logger;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readTestResourceFile = readTestResourceFile;
7
+ exports.readTestResourceAsJSON = readTestResourceAsJSON;
8
+ exports.tempFile = tempFile;
9
+ exports.tempConfig = tempConfig;
10
+ exports.getConf = getConf;
11
+ exports.sourceSpecificTempConfig = sourceSpecificTempConfig;
12
+ exports.initMockttp = initMockttp;
13
+ exports.testLogger = testLogger;
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const pino_1 = __importDefault(require("pino"));
16
+ const tmp_promise_1 = __importDefault(require("tmp-promise"));
17
+ const util_1 = __importDefault(require("util"));
18
+ const types_1 = require("../common/types");
19
+ const TEST_SOURCE_ID = 'mytestsource';
20
+ // Remove all controlled temporary objects on process exit
21
+ tmp_promise_1.default.setGracefulCleanup();
22
+ /**
23
+ * Read a test resource by name
24
+ */
25
+ function readTestResourceFile(fileName) {
26
+ return fs_1.default.readFileSync(`test/resources/${fileName}`, 'utf8');
27
+ }
28
+ const writeFile = util_1.default.promisify(fs_1.default.write);
29
+ /**
30
+ * Parse a test resource into JSON
31
+ */
32
+ function readTestResourceAsJSON(fileName) {
33
+ return JSON.parse(readTestResourceFile(fileName));
34
+ }
35
+ /**
36
+ * Creates a temporary file
37
+ * @return path to the temporary file
38
+ */
39
+ async function tempFile(data, postfix) {
40
+ const file = await tmp_promise_1.default.file({ postfix });
41
+ await writeFile(file.fd, data, null, 'utf-8');
42
+ return file.path;
43
+ }
44
+ /**
45
+ * Creates a temporary file with testing configuration
46
+ * @return path to the temporary config file to delete
47
+ */
48
+ async function tempConfig(options) {
49
+ const conf = getConf(options);
50
+ return tempFile(JSON.stringify(conf), '.json');
51
+ }
52
+ function getConf(options) {
53
+ const { api_url, invalid_record_strategy = types_1.InvalidRecordStrategy.FAIL, edition = types_1.Edition.CLOUD, edition_configs = {}, source_specific_configs = {}, replace_origin_map = {}, exclude_fields_map = {}, log_records = false, } = options;
54
+ const edition_configs_defaults = edition === types_1.Edition.CLOUD
55
+ ? {
56
+ edition,
57
+ api_url,
58
+ api_key: 'test-api-key',
59
+ graph: 'test-graph',
60
+ }
61
+ : {
62
+ edition,
63
+ hasura_url: api_url,
64
+ segment_user_id: 'bacaf6e6-41d8-4102-a3a4-5d28100e642f',
65
+ segment_test_host: api_url,
66
+ };
67
+ const conf = {
68
+ edition_configs: { ...edition_configs_defaults, ...edition_configs },
69
+ invalid_record_strategy,
70
+ origin: 'test-origin',
71
+ jsonata_destination_models: ['generic_Record'],
72
+ jsonata_expression: `
73
+ data.{
74
+ "model": "generic_Record",
75
+ "record": {
76
+ "uid": foo
77
+ }
78
+ }`,
79
+ source_specific_configs,
80
+ replace_origin_map: JSON.stringify(replace_origin_map),
81
+ exclude_fields_map: JSON.stringify(exclude_fields_map),
82
+ faros_source_id: TEST_SOURCE_ID,
83
+ log_records,
84
+ };
85
+ return conf;
86
+ }
87
+ function sourceSpecificTempConfig(url, source_specific_configs) {
88
+ return tempConfig({ api_url: url, source_specific_configs });
89
+ }
90
+ async function initMockttp(mockttp) {
91
+ await mockttp.start({ startPort: 30000, endPort: 50000 });
92
+ // Faros GraphQL auth check
93
+ await mockttp
94
+ .forGet('/users/me')
95
+ .once()
96
+ .thenReply(200, JSON.stringify({ tenantId: '1' }));
97
+ // Faros GraphQL graph stats
98
+ await mockttp
99
+ .forGet('/graphs/test-graph/statistics')
100
+ .once()
101
+ .thenReply(200, JSON.stringify({}));
102
+ // Hasura health check
103
+ await mockttp.forGet('/healthz').once().thenReply(200, JSON.stringify({}));
104
+ // Get Faros Account
105
+ await mockttp
106
+ .forGet(`/accounts/${TEST_SOURCE_ID}`)
107
+ .once()
108
+ .thenReply(200, JSON.stringify({ account: { accountId: TEST_SOURCE_ID } }));
109
+ // Faros Account Sync
110
+ const mockSyncResult = {
111
+ sync: {
112
+ syncId: '1',
113
+ logId: '1',
114
+ startedAt: new Date().toISOString(),
115
+ status: 'running',
116
+ },
117
+ };
118
+ await mockttp
119
+ .forPut(`/accounts/${TEST_SOURCE_ID}/syncs`)
120
+ .once()
121
+ .thenReply(200, JSON.stringify(mockSyncResult));
122
+ await mockttp
123
+ .forPatch(`/accounts/${TEST_SOURCE_ID}/syncs/1`)
124
+ .once()
125
+ .thenReply(200, JSON.stringify(mockSyncResult));
126
+ }
127
+ function testLogger(name = 'test') {
128
+ var _a, _b;
129
+ return (0, pino_1.default)({
130
+ name,
131
+ level: (_a = process.env.LOG_LEVEL) !== null && _a !== void 0 ? _a : 'info',
132
+ // pino-pretty leaves threads open which can prevent Jest from exiting properly
133
+ transport: ((_b = process.env.LOG_LEVEL) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'debug'
134
+ ? { target: 'pino-pretty', options: { levelFirst: true } }
135
+ : undefined,
136
+ });
137
+ }
138
+ //# sourceMappingURL=testing-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing-tools.js","sourceRoot":"","sources":["../../src/testing-tools/testing-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Dictionary } from 'ts-essentials';
2
+ export interface DestinationWriteTestOptions {
3
+ configPath: string;
4
+ catalogPath: string;
5
+ inputRecordsPath: string;
6
+ checkRecordsData?: (records: ReadonlyArray<Dictionary<any>>) => void;
7
+ }
8
+ export interface GenerateBasicTestSuiteOptions {
9
+ sourceName: string;
10
+ catalogPath?: string;
11
+ inputRecordsPath?: string;
12
+ checkRecordsData?: (records: ReadonlyArray<Dictionary<any>>) => void;
13
+ }
14
+ export declare const destinationWriteTest: (options: DestinationWriteTestOptions) => Promise<void>;
15
+ export declare function generateBasicTestSuite({ sourceName, catalogPath, inputRecordsPath, checkRecordsData, }: GenerateBasicTestSuiteOptions): void;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.destinationWriteTest = void 0;
4
+ exports.generateBasicTestSuite = generateBasicTestSuite;
5
+ const faros_airbyte_cdk_1 = require("faros-airbyte-cdk");
6
+ const mockttp_1 = require("mockttp");
7
+ const cli_1 = require("./cli");
8
+ const testing_tools_1 = require("./testing-tools");
9
+ // Executes the destination write command in dry-run mode and optionally checks:
10
+ // - The processed and written records count
11
+ // - The records data
12
+ const destinationWriteTest = async (options) => {
13
+ const { configPath, catalogPath, inputRecordsPath, checkRecordsData = undefined, } = options;
14
+ const cli = await cli_1.CLI.runWith([
15
+ 'write',
16
+ '--config',
17
+ configPath,
18
+ '--catalog',
19
+ catalogPath,
20
+ '--dry-run',
21
+ ]);
22
+ cli.stdin.end((0, testing_tools_1.readTestResourceFile)(inputRecordsPath), 'utf8');
23
+ const stdoutLines = await (0, cli_1.readLines)(cli.stdout);
24
+ const matches = [];
25
+ stdoutLines.forEach((line) => {
26
+ const regexes = [
27
+ /Processed (\d+) records/,
28
+ /Would write (\d+) records/,
29
+ /Errored (\d+) records/,
30
+ /Skipped (\d+) records/,
31
+ /Processed records by stream: {(.*)}/,
32
+ /Would write records by model: {(.*)}/,
33
+ ];
34
+ const matchedLine = regexes.find((regex) => regex.test(line));
35
+ if (matchedLine) {
36
+ matches.push(matchedLine.exec(line)[0]);
37
+ }
38
+ });
39
+ expect(matches).toMatchSnapshot();
40
+ if (checkRecordsData) {
41
+ const records = readRecordData(stdoutLines);
42
+ checkRecordsData(records);
43
+ }
44
+ expect(await (0, cli_1.read)(cli.stderr)).toBe('');
45
+ expect(await cli.wait()).toBe(0);
46
+ };
47
+ exports.destinationWriteTest = destinationWriteTest;
48
+ function readRecordData(lines) {
49
+ const records = [];
50
+ for (const line of lines) {
51
+ try {
52
+ const msg = (0, faros_airbyte_cdk_1.parseAirbyteMessage)(line);
53
+ if (msg.type === faros_airbyte_cdk_1.AirbyteMessageType.RECORD) {
54
+ const recordMessage = msg;
55
+ records.push(recordMessage.record.data);
56
+ }
57
+ }
58
+ catch (error) {
59
+ // Not a record message. Ignore.
60
+ }
61
+ }
62
+ return records;
63
+ }
64
+ function generateBasicTestSuite({ sourceName, catalogPath = `test/resources/${sourceName}/catalog.json`, inputRecordsPath = `${sourceName}/all-streams.log`, checkRecordsData, }) {
65
+ describe(`${sourceName} basic test`, () => {
66
+ const mockttp = (0, mockttp_1.getLocal)({ debug: false, recordTraffic: false });
67
+ let configPath;
68
+ beforeEach(async () => {
69
+ await (0, testing_tools_1.initMockttp)(mockttp);
70
+ configPath = await (0, testing_tools_1.tempConfig)({
71
+ api_url: mockttp.url,
72
+ log_records: !!checkRecordsData,
73
+ });
74
+ });
75
+ afterEach(async () => {
76
+ await mockttp.stop();
77
+ });
78
+ test('process records from all streams', async () => {
79
+ await (0, exports.destinationWriteTest)({
80
+ configPath,
81
+ catalogPath,
82
+ inputRecordsPath,
83
+ checkRecordsData,
84
+ });
85
+ });
86
+ });
87
+ }
88
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/testing-tools/utils.ts"],"names":[],"mappings":"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"}