Skip to content

Commit 6902f86

Browse files
committed
Added field mapping support for members import CSVs
no issue - This is a precursor work allowing client to send csv to JSON field mapping hash as a `mapping` field parameter in the incoming request.
1 parent f6f22fc commit 6902f86

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

core/server/api/canary/utils/serializers/input/members.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ module.exports = {
4747

4848
async importCSV(apiConfig, frame) {
4949
debug('importCSV');
50-
frame.data.members = await parse(frame.file.path);
50+
frame.data.members = await parse(frame.file.path, frame.data.mapping);
5151
}
5252
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"@tryghost/kg-mobiledoc-html-renderer": "3.0.1",
5454
"@tryghost/magic-link": "0.4.9",
5555
"@tryghost/members-api": "0.23.0",
56-
"@tryghost/members-csv": "0.1.2",
56+
"@tryghost/members-csv": "0.2.0",
5757
"@tryghost/members-ssr": "0.8.1",
5858
"@tryghost/mw-session-from-token": "0.1.4",
5959
"@tryghost/session-service": "0.1.4",

test/regression/api/canary/admin/members_spec.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ describe('Members API', function () {
136136
});
137137
});
138138

139-
it('Can import CSV with minimum one field', function () {
139+
it('Can import CSV with minimum one field and labels', function () {
140140
return request
141141
.post(localUtils.API.getApiQuery(`members/upload/`))
142142
.field('labels', ['global-label-1', 'global-label-1'])
@@ -184,6 +184,55 @@ describe('Members API', function () {
184184
});
185185
});
186186

187+
it('Can import CSV with mapped fields', function () {
188+
return request
189+
.post(localUtils.API.getApiQuery(`members/upload/`))
190+
.field('mapping[email]', 'correo_electrpnico')
191+
.field('mapping[name]', 'nombre')
192+
.attach('membersfile', path.join(__dirname, '/../../../../utils/fixtures/csv/members-with-mappings.csv'))
193+
.set('Origin', config.get('url'))
194+
.expect('Content-Type', /json/)
195+
.expect('Cache-Control', testUtils.cacheRules.private)
196+
.expect(201)
197+
.then((res) => {
198+
should.not.exist(res.headers['x-cache-invalidate']);
199+
const jsonResponse = res.body;
200+
201+
should.exist(jsonResponse);
202+
should.exist(jsonResponse.meta);
203+
should.exist(jsonResponse.meta.stats);
204+
205+
jsonResponse.meta.stats.imported.count.should.equal(1);
206+
jsonResponse.meta.stats.invalid.count.should.equal(0);
207+
})
208+
.then(() => {
209+
return request
210+
.get(localUtils.API.getApiQuery(`members/?search=${encodeURIComponent('[email protected]')}`))
211+
.set('Origin', config.get('url'))
212+
.expect('Content-Type', /json/)
213+
.expect('Cache-Control', testUtils.cacheRules.private)
214+
.expect(200);
215+
})
216+
.then((res) => {
217+
should.not.exist(res.headers['x-cache-invalidate']);
218+
const jsonResponse = res.body;
219+
220+
should.exist(jsonResponse);
221+
should.exist(jsonResponse.members);
222+
should.exist(jsonResponse.members[0]);
223+
224+
const importedMember1 = jsonResponse.members[0];
225+
should(importedMember1.email).equal('[email protected]');
226+
should(importedMember1.name).equal('Hannah');
227+
should(importedMember1.note).equal('no need to map me');
228+
importedMember1.subscribed.should.equal(true);
229+
importedMember1.comped.should.equal(false);
230+
importedMember1.stripe.should.not.be.undefined();
231+
importedMember1.stripe.subscriptions.length.should.equal(0);
232+
importedMember1.labels.length.should.equal(0);
233+
});
234+
});
235+
187236
it('Can import CSV with labels and provide additional labels', function () {
188237
return request
189238
.post(localUtils.API.getApiQuery(`members/upload/`))
@@ -274,7 +323,7 @@ describe('Members API', function () {
274323
should.exist(jsonResponse.new_today);
275324

276325
// 3 from fixtures and 5 imported in previous tests
277-
jsonResponse.total.should.equal(7);
326+
jsonResponse.total.should.equal(8);
278327
});
279328
});
280329

@@ -298,7 +347,7 @@ describe('Members API', function () {
298347
should.exist(jsonResponse.new_today);
299348

300349
// 3 from fixtures and 5 imported in previous tests
301-
jsonResponse.total.should.equal(7);
350+
jsonResponse.total.should.equal(8);
302351
});
303352
});
304353

@@ -322,7 +371,7 @@ describe('Members API', function () {
322371
should.exist(jsonResponse.new_today);
323372

324373
// 3 from fixtures and 5 imported in previous tests
325-
jsonResponse.total.should.equal(7);
374+
jsonResponse.total.should.equal(8);
326375
});
327376
});
328377

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
correo_electrpnico,nombre,note
2+
[email protected],Hannah,"no need to map me"

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,10 @@
503503
node-jose "^1.1.3"
504504
stripe "^7.4.0"
505505

506-
"@tryghost/members-csv@0.1.2":
507-
version "0.1.2"
508-
resolved "https://registry.yarnpkg.com/@tryghost/members-csv/-/members-csv-0.1.2.tgz#c543125ed4cf3e02a2fcb3d98d365dd2e1796047"
509-
integrity sha512-KJgtgbDQbgRS4K3OmulqZ64jIvm4+66f/RNhK0vwkf3HGgW5JEv5PVJJbVCu5IbwubwCYUjz/0K3oyl+BqIh0w==
506+
"@tryghost/members-csv@0.2.0":
507+
version "0.2.0"
508+
resolved "https://registry.yarnpkg.com/@tryghost/members-csv/-/members-csv-0.2.0.tgz#33b65b9a5be79df38df9b0f18eb35f009df570e7"
509+
integrity sha512-48B2DwKLq+xjpsinHYcgBO5ZHfJ6tQ3jwugu0ZhvAoSqB+v/QMrK82tYINvkaSGx03pLg4ft/PIpjhWzTipATg==
510510
dependencies:
511511
csv-parser "2.3.3"
512512
papaparse "5.2.0"

0 commit comments

Comments
 (0)