@drax/crud-back 0.4.0 → 0.5.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/dist/controllers/AbstractFastifyController.js +113 -44
- package/dist/exports/AbstractExport.js +41 -0
- package/dist/exports/ExportCsv.js +86 -0
- package/dist/exports/ExportJson.js +51 -0
- package/dist/repository/AbstractMongoRepository.js +11 -0
- package/dist/services/AbstractService.js +44 -0
- package/dist/workers/ExportCsvWorker.js +12 -0
- package/package.json +8 -6
- package/src/controllers/AbstractFastifyController.ts +130 -46
- package/src/exports/AbstractExport.ts +74 -0
- package/src/exports/ExportCsv.ts +107 -0
- package/src/exports/ExportJson.ts +64 -0
- package/src/index.ts +0 -3
- package/src/repository/AbstractMongoRepository.ts +25 -5
- package/src/repository/AbstractSqliteRepository.ts +1 -1
- package/src/services/AbstractService.ts +81 -10
- package/src/workers/ExportCsvWorker.js +12 -0
- package/src/workers/ExportCsvWorker.ts +12 -0
- package/test/_mocks/MockRepository.ts +58 -0
- package/test/exports/ExportCsv.test.ts +137 -0
- package/test/services/AbstractService.test.ts +40 -0
- package/test/workers/ExportCsvWorker.test.ts +92 -0
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/AbstractFastifyController.d.ts +19 -7
- package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
- package/types/exports/AbstractExport.d.ts +23 -0
- package/types/exports/AbstractExport.d.ts.map +1 -0
- package/types/exports/ExportCsv.d.ts +13 -0
- package/types/exports/ExportCsv.d.ts.map +1 -0
- package/types/exports/ExportFsCsv.d.ts +17 -0
- package/types/exports/ExportFsCsv.d.ts.map +1 -0
- package/types/exports/ExportJson.d.ts +8 -0
- package/types/exports/ExportJson.d.ts.map +1 -0
- package/types/index.d.ts +0 -2
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/ICrudRepository.d.ts +2 -1
- package/types/interfaces/ICrudRepository.d.ts.map +1 -1
- package/types/repository/AbstractMongoRepository.d.ts +3 -3
- package/types/repository/AbstractMongoRepository.d.ts.map +1 -1
- package/types/repository/AbstractSqliteRepository.d.ts +1 -1
- package/types/repository/AbstractSqliteRepository.d.ts.map +1 -1
- package/types/services/AbstractService.d.ts +8 -5
- package/types/services/AbstractService.d.ts.map +1 -1
- package/types/workers/ExportCsvWorker.d.ts +2 -0
- package/types/workers/ExportCsvWorker.d.ts.map +1 -0
- package/src/interfaces/ICrudRepository.ts +0 -16
- package/src/interfaces/IEntityPermission.ts +0 -10
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import {ValidationError, ZodErrorToValidationError} from "@drax/common-back"
|
|
2
2
|
import {ZodError} from "zod";
|
|
3
3
|
import type {ZodSchema} from "zod";
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import type {
|
|
5
|
+
IDraxPaginateOptions,
|
|
6
|
+
IDraxPaginateResult,
|
|
7
|
+
IDraxFindOptions,
|
|
8
|
+
IDraxCrud,
|
|
9
|
+
IDraxExportOptions
|
|
10
|
+
} from "@drax/crud-share";
|
|
11
|
+
import {IDraxCrudService} from "@drax/crud-share";
|
|
12
|
+
import ExportCsv from "../exports/ExportCsv.js";
|
|
13
|
+
import ExportJson from "../exports/ExportJson.js";
|
|
14
|
+
import {IDraxExportResult} from "@drax/crud-share";
|
|
15
|
+
|
|
16
|
+
class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
17
|
+
|
|
18
|
+
_repository: IDraxCrud<T, C, U>
|
|
10
19
|
_schema?: ZodSchema | undefined
|
|
11
20
|
|
|
12
|
-
constructor(repository:
|
|
21
|
+
constructor(repository: IDraxCrud<T, C, U>, schema?: ZodSchema) {
|
|
13
22
|
this._repository = repository
|
|
14
23
|
this._schema = schema
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
async create(data: C): Promise<T> {
|
|
18
27
|
try {
|
|
19
|
-
if(this._schema){
|
|
28
|
+
if (this._schema) {
|
|
20
29
|
await this._schema.parseAsync(data)
|
|
21
30
|
}
|
|
22
31
|
const item: T = await this._repository.create(data)
|
|
@@ -32,10 +41,10 @@ class AbstractService<T,C,U> {
|
|
|
32
41
|
|
|
33
42
|
async update(id: string, data: U): Promise<T> {
|
|
34
43
|
try {
|
|
35
|
-
if(this._schema){
|
|
44
|
+
if (this._schema) {
|
|
36
45
|
await this._schema.parseAsync(data)
|
|
37
46
|
}
|
|
38
|
-
const item
|
|
47
|
+
const item: T = await this._repository.update(id, data)
|
|
39
48
|
return item
|
|
40
49
|
} catch (e) {
|
|
41
50
|
console.error("Error updating", e)
|
|
@@ -139,6 +148,68 @@ class AbstractService<T,C,U> {
|
|
|
139
148
|
|
|
140
149
|
}
|
|
141
150
|
|
|
151
|
+
async find({
|
|
152
|
+
orderBy = '',
|
|
153
|
+
order = false,
|
|
154
|
+
search = '',
|
|
155
|
+
filters = []
|
|
156
|
+
}: IDraxFindOptions): Promise<T[]> {
|
|
157
|
+
try {
|
|
158
|
+
const items = await this._repository.find({orderBy, order, search, filters});
|
|
159
|
+
return items;
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.error("Error paginating", e)
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async export({
|
|
168
|
+
format = 'JSON',
|
|
169
|
+
headers = [],
|
|
170
|
+
separator = ';',
|
|
171
|
+
orderBy = '',
|
|
172
|
+
order = false,
|
|
173
|
+
search = '',
|
|
174
|
+
filters = []
|
|
175
|
+
}: IDraxExportOptions,
|
|
176
|
+
destinationPath: string): Promise<IDraxExportResult> {
|
|
177
|
+
try {
|
|
178
|
+
|
|
179
|
+
console.log("ExportOptions", {
|
|
180
|
+
format,
|
|
181
|
+
headers,
|
|
182
|
+
separator,
|
|
183
|
+
outputPath: destinationPath,
|
|
184
|
+
orderBy,
|
|
185
|
+
order,
|
|
186
|
+
search,
|
|
187
|
+
filters
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
let cursor:any
|
|
191
|
+
let exporter:any
|
|
192
|
+
|
|
193
|
+
switch (format) {
|
|
194
|
+
case 'JSON':
|
|
195
|
+
cursor = await this._repository.find({orderBy, order, search, filters});
|
|
196
|
+
exporter = new ExportJson({cursor, destinationPath: destinationPath, headers});
|
|
197
|
+
return await exporter.process()
|
|
198
|
+
case 'CSV':
|
|
199
|
+
cursor = await this._repository.find({orderBy, order, search, filters});
|
|
200
|
+
exporter = new ExportCsv({cursor, destinationPath: destinationPath, headers, separator});
|
|
201
|
+
return await exporter.process()
|
|
202
|
+
default:
|
|
203
|
+
throw new Error(`Unsupported export format: ${format}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
} catch (e) {
|
|
207
|
+
console.error("Error exporting", e)
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
142
213
|
}
|
|
143
214
|
|
|
144
215
|
export default AbstractService
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { parentPort } from 'worker_threads';
|
|
2
|
+
import ExportCsv from '../exports/ExportCsv.js'; // Ajusta la ruta según sea necesario
|
|
3
|
+
|
|
4
|
+
parentPort.on('message', async (options) => {
|
|
5
|
+
const exporter = new ExportCsv(options);
|
|
6
|
+
try {
|
|
7
|
+
let result = await exporter.process();
|
|
8
|
+
parentPort.postMessage({result: result});
|
|
9
|
+
} catch (error) {
|
|
10
|
+
parentPort.postMessage({error: error.message});
|
|
11
|
+
}
|
|
12
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { parentPort } from 'worker_threads';
|
|
2
|
+
import ExportCsv from '../exports/ExportCsv'; // Ajusta la ruta según sea necesario
|
|
3
|
+
|
|
4
|
+
parentPort.on('message', async (options) => {
|
|
5
|
+
const exporter = new ExportCsv(options);
|
|
6
|
+
try {
|
|
7
|
+
let result = await exporter.process();
|
|
8
|
+
parentPort.postMessage({result: result});
|
|
9
|
+
} catch (error) {
|
|
10
|
+
parentPort.postMessage({error: error.message});
|
|
11
|
+
}
|
|
12
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type {IDraxCrud, IDraxPaginateOptions, IDraxPaginateResult} from "@drax/common-share";
|
|
2
|
+
|
|
3
|
+
class MockRepository implements IDraxCrud<any, any, any> {
|
|
4
|
+
async create(data: any): Promise<any> {
|
|
5
|
+
return {id: '1',...data}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async update(id: string, data: any): Promise<any> {
|
|
9
|
+
return {...data}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async delete(id: string): Promise<boolean> {
|
|
13
|
+
return true
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async findById(id: string): Promise<any | null> {
|
|
17
|
+
return {id: '1', name: 'John Doe'}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async findByIds(ids: string[]): Promise<any[]> {
|
|
21
|
+
return [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async findOneBy(field: string, value: string): Promise<any | null> {
|
|
25
|
+
return {id: '1', name: 'John Doe'}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async findBy(field: string, value: string): Promise<any[]> {
|
|
29
|
+
return [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async fetchAll(): Promise<any[]> {
|
|
33
|
+
return [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async search(value: string): Promise<any[]> {
|
|
37
|
+
return [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async find(options?: any): Promise<any[]> {
|
|
41
|
+
return [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
paginate(options: IDraxPaginateOptions): Promise<IDraxPaginateResult<any>> {
|
|
45
|
+
|
|
46
|
+
return Promise.resolve({
|
|
47
|
+
page: 1,
|
|
48
|
+
limit: 10,
|
|
49
|
+
total: 2,
|
|
50
|
+
items: [{id: '1', name: 'John Doe'}, {id: '2', name: 'Jane Doe'}]
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {MockRepository}
|
|
58
|
+
export default MockRepository
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import ExportCsv from '../../src/exports/ExportCsv';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
// Simulación de un cursor para MongoDB o SQLite
|
|
9
|
+
function createMockCursor(data: any[]) {
|
|
10
|
+
let index = 0;
|
|
11
|
+
return {
|
|
12
|
+
async *[Symbol.asyncIterator]() {
|
|
13
|
+
while (index < data.length) {
|
|
14
|
+
yield data[index++];
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//@ts-ignore
|
|
21
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const __dirname = path.dirname(__filename);
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// Utilidad para leer el contenido del CSV generado
|
|
26
|
+
function readGeneratedCSV(filePath: string): string[] {
|
|
27
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
28
|
+
return content.split('\n').filter(line => line.length > 0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Eliminar el archivo de salida después de cada prueba
|
|
32
|
+
function cleanUp(outputFilePath) {
|
|
33
|
+
if (fs.existsSync(outputFilePath)) {
|
|
34
|
+
fs.unlinkSync(outputFilePath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mockData = [
|
|
39
|
+
{
|
|
40
|
+
id: '123',
|
|
41
|
+
name: 'Cristian',
|
|
42
|
+
lastname: 'Incarnato',
|
|
43
|
+
age: 39,
|
|
44
|
+
address: {
|
|
45
|
+
street: 'Directorio',
|
|
46
|
+
number: '3935',
|
|
47
|
+
floor: '6',
|
|
48
|
+
depto: 'c'
|
|
49
|
+
},
|
|
50
|
+
phones: [
|
|
51
|
+
{ number: '1234567', type: 'personal' },
|
|
52
|
+
{ number: '87456123', type: 'laboral' },
|
|
53
|
+
],
|
|
54
|
+
hobbies: ['soccer', 'gym'],
|
|
55
|
+
pets: [
|
|
56
|
+
{name: 'capitan', colors: ['grey'], skills: [{name: 'jump', level: 2}] },
|
|
57
|
+
{name: 'indio', colors: ['grey', 'white'], skills: [{name: 'jump', level: 5}, {name: 'run', level: 4}]},
|
|
58
|
+
],
|
|
59
|
+
jobs: ['developer','devops']
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// Prueba para exportar datos con arrays de subdocumentos
|
|
65
|
+
test('Debe exportar atributos base a un archivo CSV', async () => {
|
|
66
|
+
const outputFilePath = path.resolve(__dirname, 'output_base_test.csv');
|
|
67
|
+
|
|
68
|
+
cleanUp(outputFilePath);
|
|
69
|
+
|
|
70
|
+
const mockCursor = createMockCursor(mockData);
|
|
71
|
+
const exportCsv = new ExportCsv({
|
|
72
|
+
cursor: mockCursor,
|
|
73
|
+
destinationPath: outputFilePath,
|
|
74
|
+
headers: ['name', 'lastname', 'address','phones', 'hobbies'],
|
|
75
|
+
separator: ';',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await exportCsv.process();
|
|
79
|
+
|
|
80
|
+
const output = readGeneratedCSV(outputFilePath);
|
|
81
|
+
|
|
82
|
+
// Verificar que el archivo CSV tenga las filas correctas para los arrays
|
|
83
|
+
assert.strictEqual(output[0], 'name;lastname;address;phones;hobbies');
|
|
84
|
+
assert.strictEqual(output[1], 'Cristian;Incarnato;{"street":"Directorio","number":"3935","floor":"6","depto":"c"};[{"number":"1234567","type":"personal"},{"number":"87456123","type":"laboral"}];soccer,gym');
|
|
85
|
+
|
|
86
|
+
//cleanUp(outputFilePath);
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('Debe exportar atributos de objeto a un archivo CSV', async () => {
|
|
90
|
+
const outputFilePath = path.resolve(__dirname, 'output_object_test.csv');
|
|
91
|
+
|
|
92
|
+
cleanUp(outputFilePath);
|
|
93
|
+
|
|
94
|
+
const mockCursor = createMockCursor(mockData);
|
|
95
|
+
const exportCsv = new ExportCsv({
|
|
96
|
+
cursor: mockCursor,
|
|
97
|
+
destinationPath: outputFilePath,
|
|
98
|
+
headers: ['name', 'lastname', 'address.street','address.number'],
|
|
99
|
+
separator: ';',
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await exportCsv.process();
|
|
103
|
+
|
|
104
|
+
const output = readGeneratedCSV(outputFilePath);
|
|
105
|
+
|
|
106
|
+
// Verificar que el archivo CSV tenga las filas correctas para los arrays
|
|
107
|
+
assert.strictEqual(output[0], 'name;lastname;address.street;address.number');
|
|
108
|
+
assert.strictEqual(output[1], 'Cristian;Incarnato;Directorio;3935');
|
|
109
|
+
|
|
110
|
+
//cleanUp(outputFilePath);
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
test('Debe exportar atributos de un array de objetos a un archivo CSV', async () => {
|
|
116
|
+
const outputFilePath = path.resolve(__dirname, 'output_object_test.csv');
|
|
117
|
+
|
|
118
|
+
cleanUp(outputFilePath);
|
|
119
|
+
|
|
120
|
+
const mockCursor = createMockCursor(mockData);
|
|
121
|
+
const exportCsv = new ExportCsv({
|
|
122
|
+
cursor: mockCursor,
|
|
123
|
+
destinationPath: outputFilePath,
|
|
124
|
+
headers: ['name', 'lastname', 'phones.number','phones.type'],
|
|
125
|
+
separator: ';',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
await exportCsv.process();
|
|
129
|
+
|
|
130
|
+
const output = readGeneratedCSV(outputFilePath);
|
|
131
|
+
|
|
132
|
+
// Verificar que el archivo CSV tenga las filas correctas para los arrays
|
|
133
|
+
assert.strictEqual(output[0], 'name;lastname;phones.number;phones.type');
|
|
134
|
+
assert.strictEqual(output[1], 'Cristian;Incarnato;1234567|87456123;personal|laboral');
|
|
135
|
+
|
|
136
|
+
//cleanUp(outputFilePath);
|
|
137
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import MockRepository from "../_mocks/MockRepository.js";
|
|
4
|
+
import {AbstractService} from "../../src/services/AbstractService.js";
|
|
5
|
+
import {fileURLToPath} from "url";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
//@ts-ignore
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const mockRepository = new MockRepository();
|
|
13
|
+
const abstractService = new AbstractService(mockRepository);
|
|
14
|
+
|
|
15
|
+
test('create', async () => {
|
|
16
|
+
const item: any = await abstractService.create({name: 'John Doe'})
|
|
17
|
+
assert.deepStrictEqual(item.name, 'John Doe');
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
test('export', async () => {
|
|
22
|
+
const file = 'test.csv'
|
|
23
|
+
const outputPath = path.resolve(__dirname, file);
|
|
24
|
+
|
|
25
|
+
const result:any = await abstractService.export(
|
|
26
|
+
{
|
|
27
|
+
format: 'CSV',
|
|
28
|
+
headers: ['name'],
|
|
29
|
+
separator: ';',
|
|
30
|
+
limit: 0,
|
|
31
|
+
search: '',
|
|
32
|
+
filters: [],
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
console.log("result",result)
|
|
37
|
+
|
|
38
|
+
assert.deepStrictEqual(outputPath, result.outputPath);
|
|
39
|
+
assert.deepStrictEqual(2, result.rowCount);
|
|
40
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
// Reemplazo de __dirname para ES modules
|
|
3
|
+
import {test} from "node:test";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import assert from "node:assert";
|
|
6
|
+
import {WorkerHandler} from "@drax/common-back"
|
|
7
|
+
import {fileURLToPath} from "url";
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
function createMockCursor(data: any[]) {
|
|
14
|
+
let index = 0;
|
|
15
|
+
return {
|
|
16
|
+
async *[Symbol.asyncIterator]() {
|
|
17
|
+
while (index < data.length) {
|
|
18
|
+
yield data[index++];
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Utilidad para leer el contenido del CSV generado
|
|
25
|
+
function readGeneratedCSV(filePath: string): string[] {
|
|
26
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
27
|
+
return content.split('\n').filter(line => line.length > 0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Eliminar el archivo de salida después de cada prueba
|
|
31
|
+
function cleanUp(outputFilePath) {
|
|
32
|
+
if (fs.existsSync(outputFilePath)) {
|
|
33
|
+
fs.unlinkSync(outputFilePath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const mockData = [
|
|
39
|
+
{
|
|
40
|
+
id: '123',
|
|
41
|
+
name: 'Cristian',
|
|
42
|
+
lastname: 'Incarnato',
|
|
43
|
+
age: 39,
|
|
44
|
+
address: {
|
|
45
|
+
street: 'Directorio',
|
|
46
|
+
number: '3935',
|
|
47
|
+
floor: '6',
|
|
48
|
+
depto: 'c'
|
|
49
|
+
},
|
|
50
|
+
phones: [
|
|
51
|
+
{ number: '1234567', type: 'personal' },
|
|
52
|
+
{ number: '87456123', type: 'laboral' },
|
|
53
|
+
],
|
|
54
|
+
hobbies: ['soccer', 'gym'],
|
|
55
|
+
pets: [
|
|
56
|
+
{name: 'capitan', colors: ['grey'], skills: [{name: 'jump', level: 2}] },
|
|
57
|
+
{name: 'indio', colors: ['grey', 'white'], skills: [{name: 'jump', level: 5}, {name: 'run', level: 4}]},
|
|
58
|
+
],
|
|
59
|
+
jobs: ['developer','devops']
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
test('Debe exportar atributos base a un archivo CSV', async () => {
|
|
64
|
+
const outputFilePath = path.resolve(__dirname, 'output_base_worker_test.csv');
|
|
65
|
+
|
|
66
|
+
cleanUp(outputFilePath);
|
|
67
|
+
|
|
68
|
+
const mockCursor = createMockCursor(mockData);
|
|
69
|
+
const workerFile = './src/workers/ExportCsvWorker.js'
|
|
70
|
+
const params = {
|
|
71
|
+
cursor: mockCursor,
|
|
72
|
+
outputPath: outputFilePath,
|
|
73
|
+
headers: ['name', 'lastname', 'address','phones', 'hobbies'],
|
|
74
|
+
separator: ';',
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try{
|
|
78
|
+
const result = await WorkerHandler(workerFile,params)
|
|
79
|
+
console.log("result", result)
|
|
80
|
+
}catch (error) {
|
|
81
|
+
console.log("error", error)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
const output = readGeneratedCSV(outputFilePath);
|
|
86
|
+
|
|
87
|
+
// Verificar que el archivo CSV tenga las filas correctas para los arrays
|
|
88
|
+
assert.strictEqual(output[0], 'name;lastname;address;phones;hobbies');
|
|
89
|
+
assert.strictEqual(output[1], 'Cristian;Incarnato;{"street":"Directorio","number":"3935","floor":"6","depto":"c"};[{"number":"1234567","type":"personal"},{"number":"87456123","type":"laboral"}];soccer,gym');
|
|
90
|
+
|
|
91
|
+
//cleanUp(outputFilePath);
|
|
92
|
+
})
|