mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 13:52:10 +03:00
🎨 Support LTS imports (#8498)
refs #8141 - update importer for LTS fields - optimise for LTS export fixtures - add image/language test for LTS import - ensure post image is mapped to feature_image - create mobiledoc values from markdown and html - if mobiledoc is null, use markdown or html to create a mobiledoc markdown card - update import mapping to use locale - defaultLang in settings now maps to default_locale - language for post and user models now maps to locale - posts are not always loaded in correct same order so we select the posts we want to validate - ensure if mobiledoc field is not in export we can still import from markdown - map last_login to last_seen - for users the importer maps last_login to last_seen - add warning for legacyActiveTheme - for export with old activeTheme key provide a warning that theme is not installed - add importer test for LTS user long email - add a test for LTS export where email address could be longer than alpha - fix for importer date tests on mysql - use valueOf in moment to compare times stored in different formats - ignore warnings for not found settings in import - use a flag to ignore NotFound Entries for settings during import
This commit is contained in:
parent
9023ff0b68
commit
b081ae34b5
@ -16,7 +16,15 @@ class Base {
|
||||
|
||||
this.errorConfig = {
|
||||
allowDuplicates: true,
|
||||
returnDuplicates: true
|
||||
returnDuplicates: true,
|
||||
showNotFoundWarning: true
|
||||
};
|
||||
|
||||
this.legacyKeys = {};
|
||||
this.legacyMapper = function legacyMapper(item) {
|
||||
return _.mapKeys(item, function matchLegacyKey(value, key) {
|
||||
return self.legacyKeys[key] || key;
|
||||
});
|
||||
};
|
||||
|
||||
this.dataKeyToImport = options.dataKeyToImport;
|
||||
@ -79,12 +87,14 @@ class Base {
|
||||
}));
|
||||
}
|
||||
} else if (err instanceof errors.NotFoundError) {
|
||||
problems.push({
|
||||
message: 'Entry was not imported and ignored. Could not find entry.',
|
||||
help: self.modelName,
|
||||
context: JSON.stringify(obj),
|
||||
err: err
|
||||
});
|
||||
if (self.showNotFoundWarning) {
|
||||
problems.push({
|
||||
message: 'Entry was not imported and ignored. Could not find entry.',
|
||||
help: self.modelName,
|
||||
context: JSON.stringify(obj),
|
||||
err: err
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!errors.utils.isIgnitionError(err)) {
|
||||
err = new errors.DataImportError({
|
||||
|
@ -13,6 +13,10 @@ class PostsImporter extends BaseImporter {
|
||||
dataKeyToImport: 'posts',
|
||||
requiredData: ['tags', 'posts_tags']
|
||||
}));
|
||||
|
||||
this.legacyKeys = {
|
||||
image: 'feature_image'
|
||||
};
|
||||
}
|
||||
|
||||
sanitizeAttributes() {
|
||||
@ -99,10 +103,42 @@ class PostsImporter extends BaseImporter {
|
||||
|
||||
beforeImport() {
|
||||
debug('beforeImport');
|
||||
let mobileDocContent, self = this;
|
||||
|
||||
this.sanitizeAttributes();
|
||||
this.addTagsToPosts();
|
||||
|
||||
// Remove legacy field language
|
||||
this.dataToImport = _.filter(this.dataToImport, function (data) {
|
||||
return _.omit(data, 'language');
|
||||
});
|
||||
|
||||
this.dataToImport = this.dataToImport.map(self.legacyMapper);
|
||||
|
||||
// For legacy imports/custom imports with only html we can parse the markdown or html into a mobile doc card
|
||||
// For now we can hardcode the version
|
||||
_.each(this.dataToImport, function (model) {
|
||||
if (!model.mobiledoc) {
|
||||
if (model.markdown && model.markdown.length > 0) {
|
||||
mobileDocContent = model.markdown;
|
||||
} else if (model.html && model.html.length > 0) {
|
||||
mobileDocContent = model.html;
|
||||
} else {
|
||||
// Set mobileDocContent to null else it will affect empty posts
|
||||
mobileDocContent = null;
|
||||
}
|
||||
if (mobileDocContent) {
|
||||
model.mobiledoc = JSON.stringify({
|
||||
version: '0.3.1',
|
||||
markups: [],
|
||||
atoms: [],
|
||||
cards: [['card-markdown',{cardName: 'card-markdown',markdown: mobileDocContent}]],
|
||||
sections:[[10,0]]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// NOTE: do after, because model properties are deleted e.g. post.id
|
||||
return super.beforeImport();
|
||||
}
|
||||
|
@ -14,9 +14,17 @@ class SettingsImporter extends BaseImporter {
|
||||
requiredData: []
|
||||
}));
|
||||
|
||||
this.legacyKeys = {
|
||||
activePlugins: 'active_apps',
|
||||
installedPlugins: 'installed_apps'
|
||||
this.errorConfig = {
|
||||
allowDuplicates: true,
|
||||
returnDuplicates: true,
|
||||
showNotFoundWarning: false
|
||||
};
|
||||
|
||||
// Map legacy keys
|
||||
this.legacySettingsKeyValues = {
|
||||
isPrivate: 'is_private',
|
||||
activeTimezone: 'active_timezone',
|
||||
cover: 'cover_image'
|
||||
};
|
||||
}
|
||||
|
||||
@ -27,14 +35,25 @@ class SettingsImporter extends BaseImporter {
|
||||
beforeImport() {
|
||||
debug('beforeImport');
|
||||
|
||||
let self = this;
|
||||
let self = this,
|
||||
ltsActiveTheme = _.find(this.dataToImport, {key: 'activeTheme'});
|
||||
|
||||
// If there is an lts we want to warn user that theme is not imported
|
||||
if (ltsActiveTheme) {
|
||||
self.problems.push({
|
||||
message: 'Theme not imported, please upload in Settings - Design',
|
||||
help: self.modelName,
|
||||
context: JSON.stringify(ltsActiveTheme)
|
||||
});
|
||||
}
|
||||
|
||||
// Remove core and theme data types
|
||||
this.dataToImport = _.filter(this.dataToImport, function (data) {
|
||||
return ['core', 'theme'].indexOf(data.type) === -1;
|
||||
});
|
||||
|
||||
_.each(this.dataToImport, function (obj) {
|
||||
obj.key = self.legacyKeys[obj.key] || obj.key;
|
||||
obj.key = self.legacySettingsKeyValues[obj.key] || obj.key;
|
||||
});
|
||||
|
||||
return super.beforeImport();
|
||||
|
@ -13,6 +13,11 @@ class TagsImporter extends BaseImporter {
|
||||
dataKeyToImport: 'tags',
|
||||
requiredData: []
|
||||
}));
|
||||
|
||||
// Map legacy keys
|
||||
this.legacyKeys = {
|
||||
image: 'feature_image'
|
||||
};
|
||||
}
|
||||
|
||||
beforeImport() {
|
||||
@ -32,6 +37,8 @@ class TagsImporter extends BaseImporter {
|
||||
|
||||
let self = this, ops = [];
|
||||
|
||||
this.dataToImport = this.dataToImport.map(self.legacyMapper);
|
||||
|
||||
_.each(this.dataToImport, function (obj) {
|
||||
ops.push(models[self.modelName].findOne({name: obj.name}, options).then(function (tag) {
|
||||
if (tag) {
|
||||
|
@ -12,6 +12,13 @@ class UsersImporter extends BaseImporter {
|
||||
dataKeyToImport: 'users',
|
||||
requiredData: ['roles', 'roles_users']
|
||||
}));
|
||||
|
||||
// Map legacy keys
|
||||
this.legacyKeys = {
|
||||
image: 'profile_image',
|
||||
cover: 'cover_image',
|
||||
last_login: 'last_seen'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,6 +32,13 @@ class UsersImporter extends BaseImporter {
|
||||
|
||||
let self = this, role;
|
||||
|
||||
// Remove legacy field language
|
||||
this.dataToImport = _.filter(this.dataToImport, function (data) {
|
||||
return _.omit(data, 'language');
|
||||
});
|
||||
|
||||
this.dataToImport = this.dataToImport.map(self.legacyMapper);
|
||||
|
||||
_.each(this.dataToImport, function (model) {
|
||||
model.password = globalUtils.uid(50);
|
||||
model.status = 'locked';
|
||||
|
@ -39,7 +39,7 @@ describe('Import', function () {
|
||||
it('import results have data and problems', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importResult) {
|
||||
@ -54,14 +54,13 @@ describe('Import', function () {
|
||||
it('removes duplicate posts', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003',{lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importResult) {
|
||||
should.exist(importResult.data.posts);
|
||||
|
||||
importResult.data.posts.length.should.equal(1);
|
||||
importResult.problems.length.should.eql(8);
|
||||
importResult.problems.length.should.eql(2);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
@ -70,7 +69,7 @@ describe('Import', function () {
|
||||
it('removes duplicate tags and updates associations', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-duplicate-tags').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-duplicate-tags', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importResult) {
|
||||
@ -87,7 +86,9 @@ describe('Import', function () {
|
||||
return postTag.tag_id !== 2;
|
||||
});
|
||||
|
||||
importResult.problems.length.should.equal(9);
|
||||
importResult.problems.length.should.equal(3);
|
||||
|
||||
importResult.problems[2].message.should.equal('Theme not imported, please upload in Settings - Design');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
@ -100,7 +101,7 @@ describe('Import', function () {
|
||||
it('imports data from 000', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-000').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-000', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -146,7 +147,7 @@ describe('Import', function () {
|
||||
it('safely imports data, from 001', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-001').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-001', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -203,7 +204,7 @@ describe('Import', function () {
|
||||
it('doesn\'t import invalid settings data from 001', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-001-invalid-setting').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-001-invalid-setting', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -244,7 +245,7 @@ describe('Import', function () {
|
||||
it('safely imports data from 002', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-002').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-002', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -305,7 +306,7 @@ describe('Import', function () {
|
||||
it('safely imports data from 003 (single user)', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -344,7 +345,7 @@ describe('Import', function () {
|
||||
it('handles validation errors nicely', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-badValidation').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-badValidation', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -368,7 +369,7 @@ describe('Import', function () {
|
||||
it('handles database errors nicely: duplicated tag slugs', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-dbErrors').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-dbErrors', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importedData) {
|
||||
@ -386,7 +387,7 @@ describe('Import', function () {
|
||||
it('does import posts with an invalid author', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-mu-unknownAuthor').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-mu-unknownAuthor', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importedData) {
|
||||
@ -436,7 +437,7 @@ describe('Import', function () {
|
||||
it('doesn\'t import invalid tags data from 003', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-nullTags').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-nullTags', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -454,7 +455,7 @@ describe('Import', function () {
|
||||
it('doesn\'t import invalid posts data from 003', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-nullPosts').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-nullPosts', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -475,7 +476,7 @@ describe('Import', function () {
|
||||
it('correctly sanitizes incorrect UUIDs', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-wrongUUID').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-wrongUUID', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -499,7 +500,7 @@ describe('Import', function () {
|
||||
it('ensure post tag order is correct', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-004').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-004', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
@ -547,7 +548,7 @@ describe('Import', function () {
|
||||
it('doesn\'t import a title which is too long', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-001').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-001', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
|
||||
// change title to 1001 characters
|
||||
@ -596,7 +597,7 @@ describe('Import (new test structure)', function () {
|
||||
|
||||
before(function doImport(done) {
|
||||
testUtils.initFixtures('roles', 'owner', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu');
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu', {lts:true});
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
@ -818,7 +819,7 @@ describe('Import (new test structure)', function () {
|
||||
|
||||
before(function doImport(done) {
|
||||
testUtils.initFixtures('roles', 'owner', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu-noOwner');
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu-noOwner', {lts:true});
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
@ -1041,7 +1042,7 @@ describe('Import (new test structure)', function () {
|
||||
before(function doImport(done) {
|
||||
// initialise the blog with some data
|
||||
testUtils.initFixtures('users:roles', 'posts', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu');
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu', {lts:true});
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
@ -1270,7 +1271,7 @@ describe('Import (new test structure)', function () {
|
||||
before(function doImport(done) {
|
||||
// initialise the blog with some data
|
||||
testUtils.initFixtures('users:roles', 'posts', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu-multipleOwner');
|
||||
return testUtils.fixtures.loadExportFixture('export-003-mu-multipleOwner', {lts: true});
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
@ -1334,4 +1335,221 @@ describe('Import (new test structure)', function () {
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lts: legacy fields', function () {
|
||||
var exportData;
|
||||
|
||||
before(function doImport(done) {
|
||||
// initialise the blog with some data
|
||||
testUtils.initFixtures('roles', 'owner', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-lts-legacy-fields', {lts: true});
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
after(testUtils.teardown);
|
||||
|
||||
it('ensure data is still imported and mapped correctly', function (done) {
|
||||
var fetchImported = Promise.join(
|
||||
knex('users').select(),
|
||||
knex('posts').select(),
|
||||
knex('tags').select(),
|
||||
knex('settings').select()
|
||||
);
|
||||
|
||||
fetchImported
|
||||
.then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
importedData.length.should.equal(4);
|
||||
|
||||
var users = importedData[0],
|
||||
posts = importedData[1],
|
||||
tags = importedData[2],
|
||||
settings = importedData[3],
|
||||
firstPost = _.find(posts, {slug: exportData.data.posts[0].slug});
|
||||
|
||||
// Check length of of posts, tags and users
|
||||
posts.length.should.equal(exportData.data.posts.length);
|
||||
tags.length.should.equal(exportData.data.tags.length);
|
||||
// Users include original user + joe bloggs' brother
|
||||
users.length.should.equal(exportData.data.users.length + 1);
|
||||
|
||||
// Check feature image is correctly mapped for a post
|
||||
firstPost.feature_image.should.eql('/content/images/2017/05/post-image.jpg');
|
||||
// Check logo and cover images are correctly mapped for a user
|
||||
users[1].cover_image.should.eql(exportData.data.users[0].cover);
|
||||
users[1].profile_image.should.eql(exportData.data.users[0].image);
|
||||
// Check feature image is correctly mapped for a tag
|
||||
tags[0].feature_image.should.eql(exportData.data.tags[0].image);
|
||||
// Check logo image is correctly mapped for a blog
|
||||
settings[6].key.should.eql('logo');
|
||||
settings[6].value.should.eql('/content/images/2017/05/bloglogo.jpeg');
|
||||
// Check cover image is correctly mapped for a blog
|
||||
settings[7].key.should.eql('cover_image');
|
||||
settings[7].value.should.eql('/content/images/2017/05/blogcover.jpeg');
|
||||
|
||||
// Check default settings locale is not overwritten by defaultLang
|
||||
settings[9].key.should.eql('default_locale');
|
||||
settings[9].value.should.eql('en');
|
||||
|
||||
// Check post language is null
|
||||
should(firstPost.locale).equal(null);
|
||||
// Check user language is null
|
||||
should(users[1].locale).equal(null);
|
||||
|
||||
// Check mobiledoc is populated from markdown
|
||||
JSON.parse(firstPost.mobiledoc).cards[0][1].markdown.should.eql(exportData.data.posts[0].markdown);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lts: style import with missing markdown or html values', function () {
|
||||
var exportData;
|
||||
|
||||
before(function doImport(done) {
|
||||
// initialise the blog with some data
|
||||
testUtils.initFixtures('roles', 'owner', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-lts-style-bad-markdown-html',
|
||||
{lts: true}
|
||||
);
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
after(testUtils.teardown);
|
||||
|
||||
it('ensure images are mapped correctly and language is null', function (done) {
|
||||
var fetchImported = Promise.join(
|
||||
knex('users').select(),
|
||||
knex('posts').select(),
|
||||
knex('tags').select(),
|
||||
knex('settings').select()
|
||||
);
|
||||
|
||||
fetchImported.then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
importedData.length.should.equal(4);
|
||||
|
||||
var users = importedData[0],
|
||||
posts = importedData[1],
|
||||
tags = importedData[2],
|
||||
settings = importedData[3],
|
||||
firstPost = _.find(posts, {slug: exportData.data.posts[0].slug}),
|
||||
secondPost = _.find(posts, {slug: exportData.data.posts[1].slug}),
|
||||
thirdPost = _.find(posts, {slug: exportData.data.posts[2].slug}),
|
||||
fourthPost = _.find(posts, {slug: exportData.data.posts[3].slug});
|
||||
|
||||
// Check length of of posts, tags and users
|
||||
posts.length.should.equal(exportData.data.posts.length);
|
||||
tags.length.should.equal(exportData.data.tags.length);
|
||||
// Users include original user + joe bloggs' brother
|
||||
users.length.should.equal(exportData.data.users.length + 1);
|
||||
|
||||
// Check feature image is correctly mapped for a post
|
||||
should(firstPost.feature_image).equal(null);
|
||||
// Check logo and cover images are correctly mapped for a user
|
||||
users[1].cover_image.should.eql(exportData.data.users[0].cover);
|
||||
users[1].profile_image.should.eql(exportData.data.users[0].image);
|
||||
// Check feature image is correctly mapped for a tag
|
||||
tags[0].feature_image.should.eql(exportData.data.tags[0].image);
|
||||
// Check logo image is correctly mapped for a blog
|
||||
settings[6].key.should.eql('logo');
|
||||
settings[6].value.should.eql('/content/images/2017/05/bloglogo.jpeg');
|
||||
// Check cover image is correctly mapped for a blog
|
||||
settings[7].key.should.eql('cover_image');
|
||||
settings[7].value.should.eql('/content/images/2017/05/blogcover.jpeg');
|
||||
|
||||
// Check default settings locale is not overwritten by defaultLang
|
||||
settings[9].key.should.eql('default_locale');
|
||||
settings[9].value.should.eql('en');
|
||||
|
||||
// Check post language is set to null
|
||||
should(firstPost.locale).equal(null);
|
||||
// Check user language is set to null
|
||||
should(users[1].locale).equal(null);
|
||||
|
||||
// Check last_seen is mapped from last_login for user
|
||||
assert.equal(
|
||||
moment(users[1].last_seen).valueOf(),
|
||||
moment(exportData.data.users[0].last_login).valueOf()
|
||||
);
|
||||
// Check mobiledoc is populated from from html when mobiledoc is null & markdown is empty string
|
||||
JSON.parse(firstPost.mobiledoc).cards[0][1].markdown.should.eql(exportData.data.posts[0].html);
|
||||
// Check mobiledoc is populated from from html when mobiledoc is null & markdown is null
|
||||
JSON.parse(secondPost.mobiledoc).cards[0][1].markdown.should.eql(exportData.data.posts[1].html);
|
||||
// Check mobiledoc is null when markdown and mobiledoc are null and html is empty string
|
||||
should(thirdPost.mobiledoc).equal(null);
|
||||
// Check mobiledoc is null when markdown, mobiledoc are html are null
|
||||
should(fourthPost.mobiledoc).equal(null);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('ensure post without mobiledoc key uses markdown', function (done) {
|
||||
var fetchImported = Promise.resolve(knex('posts').select());
|
||||
|
||||
fetchImported.then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
importedData.length.should.equal(5);
|
||||
|
||||
var posts = importedData,
|
||||
fifthPost = _.find(posts, {slug: exportData.data.posts[4].slug});
|
||||
|
||||
// Check mobiledoc is populated from from html when mobiledoc is null & markdown is empty string
|
||||
JSON.parse(fifthPost.mobiledoc).cards[0][1].markdown.should.eql(exportData.data.posts[4].markdown);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lts: style import for user with a very long email address', function () {
|
||||
var exportData;
|
||||
|
||||
before(function doImport(done) {
|
||||
// initialise the blog with some data
|
||||
testUtils.initFixtures('roles', 'owner', 'settings').then(function () {
|
||||
return testUtils.fixtures.loadExportFixture('export-lts-style-user-long-email',
|
||||
{lts: true}
|
||||
);
|
||||
}).then(function (exported) {
|
||||
exportData = exported;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
after(testUtils.teardown);
|
||||
|
||||
it('provides error message and does not import where lts email address is longer that 1.0.0 constraint', function (done) {
|
||||
testUtils.fixtures.loadExportFixture('export-lts-style-user-long-email', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function () {
|
||||
(1).should.eql(0, 'Data import should not resolve promise.');
|
||||
}).catch(function (error) {
|
||||
error[0].message.should.eql('Value in [users.email] exceeds maximum length of 191 characters.');
|
||||
error[0].errorType.should.eql('ValidationError');
|
||||
|
||||
Promise.resolve(knex('users').select()).then(function (users) {
|
||||
should.exist(users);
|
||||
|
||||
users.length.should.equal(1, 'Did not get data successfully');
|
||||
users[0].email.should.not.equal(exportData.data.users[0].email);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -313,7 +313,7 @@ describe('Importer', function () {
|
||||
|
||||
it('correctly handles a valid db api wrapper', function (done) {
|
||||
var file = [{
|
||||
path: testUtils.fixtures.getExportFixturePath('export-003-api-wrapper'),
|
||||
path: testUtils.fixtures.getExportFixturePath('export-003-api-wrapper', {lts: true}),
|
||||
name: 'export-003-api-wrapper.json'
|
||||
}];
|
||||
JSONHandler.loadFile(file).then(function (result) {
|
||||
@ -325,7 +325,7 @@ describe('Importer', function () {
|
||||
|
||||
it('correctly errors when given a bad db api wrapper', function (done) {
|
||||
var file = [{
|
||||
path: testUtils.fixtures.getExportFixturePath('export-003-api-wrapper-bad'),
|
||||
path: testUtils.fixtures.getExportFixturePath('export-003-api-wrapper-bad', {lts: true}),
|
||||
name: 'export-003-api-wrapper-bad.json'
|
||||
}];
|
||||
|
||||
|
1630
core/test/utils/fixtures/export/lts/export-lts-legacy-fields.json
Normal file
1630
core/test/utils/fixtures/export/lts/export-lts-legacy-fields.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,37 @@
|
||||
{
|
||||
"meta": {
|
||||
"exported_on": 1496145843289,
|
||||
"version": "009"
|
||||
},
|
||||
"data": {
|
||||
"users": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "1e2a7354-f580-4deb-9801-ca286628125a",
|
||||
"name": "Joe Blogg's long email Brother",
|
||||
"slug": "joe-bloggs-long-email-brother",
|
||||
"password": "$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKABC",
|
||||
"email": "thisisareallylongemailaddressIamhappytobeusingacharactercounterbutIhavealongwaytogoyetImeanserioulsywhohasemailaddressthislongthereisnowaythiswillpassvalidationsonghost100andisarealedgecase@example.com",
|
||||
"image": "/content/images/2017/05/authorlogo.jpeg",
|
||||
"cover": "/content/images/2017/05/authorcover.jpeg",
|
||||
"bio": "I'm Joe's brother, the good looking one!",
|
||||
"website": "http://joebloggslongemailbrother.com",
|
||||
"location": null,
|
||||
"facebook": null,
|
||||
"twitter": null,
|
||||
"accessibility": null,
|
||||
"status": "active",
|
||||
"language": "en_US",
|
||||
"visibility": "public",
|
||||
"meta_title": null,
|
||||
"meta_description": null,
|
||||
"tour": null,
|
||||
"last_login": "2017-05-30T10:39:32.000Z",
|
||||
"created_at": "2016-10-28T13:43:36.000Z",
|
||||
"created_by": 1,
|
||||
"updated_at": "2017-05-30T12:02:35.000Z",
|
||||
"updated_by": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -313,12 +313,15 @@ fixtures = {
|
||||
return path.resolve(__dirname + '/fixtures/import/' + filename);
|
||||
},
|
||||
|
||||
getExportFixturePath: function (filename) {
|
||||
return path.resolve(__dirname + '/fixtures/export/' + filename + '.json');
|
||||
getExportFixturePath: function (filename, options) {
|
||||
options = options || {lts: false};
|
||||
var relativePath = options.lts ? '/fixtures/export/lts/' : '/fixtures/export/';
|
||||
return path.resolve(__dirname + relativePath + filename + '.json');
|
||||
},
|
||||
|
||||
loadExportFixture: function loadExportFixture(filename) {
|
||||
var filePath = this.getExportFixturePath(filename),
|
||||
loadExportFixture: function loadExportFixture(filename, options) {
|
||||
options = options || {lts: false};
|
||||
var filePath = this.getExportFixturePath(filename, options),
|
||||
readFile = Promise.promisify(fs.readFile);
|
||||
|
||||
return readFile(filePath).then(function (fileContents) {
|
||||
|
Loading…
Reference in New Issue
Block a user