Skip to content

Commit 06bceb6

Browse files
committed
Implementing export progress endpoint and test
1 parent 18680e1 commit 06bceb6

File tree

3 files changed

+140
-59
lines changed

3 files changed

+140
-59
lines changed

spec/ExportRouter.spec.js

Lines changed: 98 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,80 @@ const AdmZip = require('adm-zip');
44
const dd = require('deep-diff');
55

66
describe('Export router', () => {
7+
8+
const headers = {
9+
'Content-Type': 'application/json',
10+
'X-Parse-Application-Id': 'test',
11+
'X-Parse-Master-Key': 'test'
12+
};
13+
14+
const createRecords = (itemCount) => {
15+
let ExportTest = Parse.Object.extend("ExportTest");
16+
17+
let items = new Array(itemCount).fill().map((item, index) => {
18+
19+
let exportTest = new ExportTest();
20+
21+
exportTest.set('field1', `value1-${index}`);
22+
exportTest.set('field2', `value2-${index}`);
23+
24+
return exportTest;
25+
});
26+
27+
28+
return Parse.Object.saveAll(items);
29+
};
30+
31+
it_exclude_dbs(['postgres'])('should create export progress', (done) => {
32+
33+
reconfigureServer({
34+
emailAdapter: {
35+
sendMail : () => {
36+
done();
37+
}
38+
}
39+
})
40+
.then(() => {
41+
return createRecords(3000);
42+
})
43+
.then(data => {
44+
request.put(
45+
{
46+
headers: headers,
47+
url: 'http://localhost:8378/1/export_data',
48+
body: JSON.stringify({
49+
name: 'ExportTest',
50+
feedbackEmail: '[email protected]'
51+
})
52+
},
53+
() => {
54+
55+
request.get(
56+
{
57+
headers: headers,
58+
url: 'http://localhost:8378/1/export_progress'
59+
},
60+
(err, response, body) => {
61+
62+
let progress = JSON.parse(body);
63+
64+
expect(progress instanceof Array).toBe(true);
65+
expect(progress.length).toBe(1);
66+
67+
if (progress.length) {
68+
expect(progress[0].id).toBe('ExportTest');
69+
}
70+
71+
});
72+
}
73+
);
74+
}
75+
);
76+
});
77+
778
it_exclude_dbs(['postgres'])('send success export mail', (done) => {
879

980
let results = [];
10-
let headers = {
11-
'Content-Type': 'application/json',
12-
'X-Parse-Application-Id': 'test',
13-
'X-Parse-Master-Key': 'test'
14-
};
1581

1682
let emailAdapter = {
1783
sendMail: ({text, link, to, subject}) => {
@@ -42,49 +108,33 @@ describe('Export router', () => {
42108
emailAdapter: emailAdapter
43109
})
44110
.then(() => {
45-
46-
let ExportTest = Parse.Object.extend("ExportTest");
47-
48-
49-
let itemCount = 3716;//change this value if you want to test with more or less items;
50-
let items = new Array(itemCount).fill().map((item, index) => {
51-
52-
let exportTest = new ExportTest();
53-
54-
exportTest.set('field1', `value1-${index}`);
55-
exportTest.set('field2', `value2-${index}`);
56-
57-
return exportTest;
58-
});
59-
60-
Parse.Object.saveAll(items)
61-
.then(data => {
62-
request.get(
63-
{
64-
headers: headers,
65-
url: 'http://localhost:8378/1/classes/ExportTest',
66-
},
67-
(err, response, body) => {
68-
results = JSON.parse(body);
69-
70-
request.put(
71-
{
72-
headers: headers,
73-
url: 'http://localhost:8378/1/export_data',
74-
body: JSON.stringify({
75-
name: 'ExportTest',
76-
feedbackEmail: '[email protected]'
77-
})
78-
},
79-
(err, response, body) => {
80-
expect(err).toBe(null);
81-
expect(body).toEqual('"We are exporting your data. You will be notified by e-mail once it is completed."');
82-
}
83-
);
84-
}
85-
);
86-
87-
});
111+
return createRecords(2176);
112+
})
113+
.then(data => {
114+
request.get(
115+
{
116+
headers: headers,
117+
url: 'http://localhost:8378/1/classes/ExportTest',
118+
},
119+
(err, response, body) => {
120+
results = JSON.parse(body);
121+
122+
request.put(
123+
{
124+
headers: headers,
125+
url: 'http://localhost:8378/1/export_data',
126+
body: JSON.stringify({
127+
name: 'ExportTest',
128+
feedbackEmail: '[email protected]'
129+
})
130+
},
131+
(err, response, body) => {
132+
expect(err).toBe(null);
133+
expect(body).toEqual('"We are exporting your data. You will be notified by e-mail once it is completed."');
134+
}
135+
);
136+
}
137+
);
88138
});
89139
});
90140
});

src/Controllers/SchemaController.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ const defaultColumns = Object.freeze({
105105
_GlobalConfig: {
106106
"objectId": {type: 'String'},
107107
"params": {type: 'Object'}
108+
},
109+
_ExportProgress: {
110+
"objectId": {type:'String'},
111+
"id": {type:'String'},
112+
"masterKey": {type:'String'},
113+
"applicationId": {type:'String'}
108114
}
109115
});
110116

@@ -113,9 +119,9 @@ const requiredColumns = Object.freeze({
113119
_Role: ["name", "ACL"]
114120
});
115121

116-
const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus']);
122+
const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_ExportProgress' ]);
117123

118-
const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig']);
124+
const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_ExportProgress']);
119125

120126
// 10 alpha numberic chars + uppercase
121127
const userIdRegex = /^[a-zA-Z0-9]{10}$/;

src/Routers/ExportRouter.js

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,23 @@ import archiver from 'archiver';
66
import tmp from 'tmp';
77
import fs from 'fs';
88

9+
const DefaultExportExportProgressCollectionName = "_ExportProgress";
10+
911
export class ExportRouter extends PromiseRouter {
1012

1113
handleExportProgress(req) {
12-
return Promise.resolve({ response: 100 });
14+
15+
const databaseController = req.config.database;
16+
17+
let query = {
18+
masterKey: req.info.masterKey,
19+
applicationId: req.info.appId
20+
};
21+
22+
return databaseController.find(DefaultExportExportProgressCollectionName, query)
23+
.then((response) => {
24+
return { response };
25+
});
1326
}
1427

1528
handleExportPage(req, name, jsonFileStream, where, skip, limit) {
@@ -31,15 +44,31 @@ export class ExportRouter extends PromiseRouter {
3144

3245
handleExport(req) {
3346

47+
const databaseController = req.config.database;
3448
let data = req.body;
3549

3650
let tmpJsonFile = tmp.fileSync();
3751
let jsonFileStream = fs.createWriteStream(tmpJsonFile.name);
3852

3953
jsonFileStream.write('{\n"results" : [\n');
4054

55+
let exportProgress = {
56+
id: data.name,
57+
masterKey: req.info.masterKey,
58+
applicationId: req.info.appId
59+
};
60+
61+
62+
let emailControllerAdapter = req.config.emailControllerAdapter;
63+
64+
if (!emailControllerAdapter) {
65+
return Promise.reject(new Error('You have to setup a Mail Adapter.'));
66+
}
4167

42-
rest.find(req.config, req.auth, data.name, data.where, { count: true, limit: 0 })
68+
databaseController.create(DefaultExportExportProgressCollectionName, exportProgress)
69+
.then(() => {
70+
return rest.find(req.config, req.auth, data.name, data.where, { count: true, limit: 0 });
71+
})
4372
.then((result) => {
4473

4574
let i = 0;
@@ -92,12 +121,6 @@ export class ExportRouter extends PromiseRouter {
92121
})
93122
.then((fileData) => {
94123

95-
let emailControllerAdapter = req.config.emailControllerAdapter;
96-
97-
if (!emailControllerAdapter) {
98-
return Promise.reject(new Error('You have to setup a Mail Adapter.'));
99-
}
100-
101124
return emailControllerAdapter.sendMail({
102125
text: `We have successfully exported your data from the class ${data.name}.\n
103126
Please download from ${fileData.url}`,
@@ -107,12 +130,14 @@ export class ExportRouter extends PromiseRouter {
107130
});
108131
})
109132
.catch((error) => {
110-
console.log(error);
111133
return emailControllerAdapter.sendMail({
112134
text: `We could not export your data to the class ${data.name}. Error: ${error}`,
113135
to: req.body.feedbackEmail,
114136
subject: 'Export failed'
115137
});
138+
})
139+
.then(() => {
140+
return databaseController.destroy(DefaultExportExportProgressCollectionName, exportProgress);
116141
});
117142

118143
return Promise.resolve({response: 'We are exporting your data. You will be notified by e-mail once it is completed.'});

0 commit comments

Comments
 (0)