Ensure migrations run on saved object import (#34793)
* Ensure migrations run on saved object import * Fix broken tests * Fix ESLint errors
This commit is contained in:
parent
d259e1f258
commit
fcd60ca0d9
|
@ -43,6 +43,7 @@ describe('collectSavedObjects()', () => {
|
|||
Array [
|
||||
Object {
|
||||
"foo": true,
|
||||
"migrationVersion": Object {},
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
@ -60,6 +61,7 @@ Array [
|
|||
Array [
|
||||
Object {
|
||||
"foo": true,
|
||||
"migrationVersion": Object {},
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
|
|
@ -44,6 +44,10 @@ export async function collectSavedObjects(
|
|||
createFilterStream<SavedObject>(obj => !!obj),
|
||||
createLimitStream(objectLimit),
|
||||
createFilterStream<SavedObject>(obj => (filter ? filter(obj) : true)),
|
||||
createMapStream((obj: SavedObject) => {
|
||||
// Ensure migrations execute on every saved object
|
||||
return Object.assign({ migrationVersion: {} }, obj);
|
||||
}),
|
||||
createConcatStream([]),
|
||||
])) as SavedObject[];
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ Object {
|
|||
"title": "My Index Pattern",
|
||||
},
|
||||
"id": "1",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "index-pattern",
|
||||
},
|
||||
|
@ -132,6 +133,7 @@ Object {
|
|||
"title": "My Search",
|
||||
},
|
||||
"id": "2",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "search",
|
||||
},
|
||||
|
@ -140,6 +142,7 @@ Object {
|
|||
"title": "My Visualization",
|
||||
},
|
||||
"id": "3",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "visualization",
|
||||
},
|
||||
|
@ -148,6 +151,7 @@ Object {
|
|||
"title": "My Dashboard",
|
||||
},
|
||||
"id": "4",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "dashboard",
|
||||
},
|
||||
|
@ -200,6 +204,7 @@ Object {
|
|||
"title": "My Index Pattern",
|
||||
},
|
||||
"id": "1",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "index-pattern",
|
||||
},
|
||||
|
@ -208,6 +213,7 @@ Object {
|
|||
"title": "My Search",
|
||||
},
|
||||
"id": "2",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "search",
|
||||
},
|
||||
|
@ -216,6 +222,7 @@ Object {
|
|||
"title": "My Visualization",
|
||||
},
|
||||
"id": "3",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "visualization",
|
||||
},
|
||||
|
@ -224,6 +231,7 @@ Object {
|
|||
"title": "My Dashboard",
|
||||
},
|
||||
"id": "4",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "dashboard",
|
||||
},
|
||||
|
|
|
@ -141,6 +141,7 @@ Object {
|
|||
"title": "My Visualization",
|
||||
},
|
||||
"id": "3",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "visualization",
|
||||
},
|
||||
|
@ -196,6 +197,7 @@ Object {
|
|||
"title": "My Index Pattern",
|
||||
},
|
||||
"id": "1",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [],
|
||||
"type": "index-pattern",
|
||||
},
|
||||
|
@ -260,6 +262,7 @@ Object {
|
|||
"title": "My Dashboard",
|
||||
},
|
||||
"id": "4",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [
|
||||
Object {
|
||||
"id": "13",
|
||||
|
|
|
@ -77,6 +77,47 @@ describe('POST /api/saved_objects/_import', () => {
|
|||
expect(savedObjectsClient.bulkCreate).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('defaults migrationVersion to empty object', async () => {
|
||||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_import',
|
||||
payload: [
|
||||
'--EXAMPLE',
|
||||
'Content-Disposition: form-data; name="file"; filename="export.ndjson"',
|
||||
'Content-Type: application/ndjson',
|
||||
'',
|
||||
'{"type":"index-pattern","id":"my-pattern","attributes":{"title":"my-pattern-*"}}',
|
||||
'--EXAMPLE--',
|
||||
].join('\r\n'),
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data; boundary=EXAMPLE',
|
||||
},
|
||||
};
|
||||
savedObjectsClient.find.mockResolvedValueOnce({ saved_objects: [] });
|
||||
savedObjectsClient.bulkCreate.mockResolvedValueOnce({
|
||||
saved_objects: [
|
||||
{
|
||||
type: 'index-pattern',
|
||||
id: 'my-pattern',
|
||||
attributes: {
|
||||
title: 'my-pattern-*',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const { payload, statusCode } = await server.inject(request);
|
||||
const response = JSON.parse(payload);
|
||||
expect(statusCode).toBe(200);
|
||||
expect(response).toEqual({
|
||||
success: true,
|
||||
successCount: 1,
|
||||
});
|
||||
expect(savedObjectsClient.bulkCreate.mock.calls).toHaveLength(1);
|
||||
const firstBulkCreateCallArray = savedObjectsClient.bulkCreate.mock.calls[0][0];
|
||||
expect(firstBulkCreateCallArray).toHaveLength(1);
|
||||
expect(firstBulkCreateCallArray[0].migrationVersion).toEqual({});
|
||||
});
|
||||
|
||||
test('imports an index pattern and dashboard', async () => {
|
||||
// NOTE: changes to this scenario should be reflected in the docs
|
||||
const request = {
|
||||
|
|
|
@ -77,7 +77,48 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => {
|
|||
expect(savedObjectsClient.bulkCreate).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('retries importin a dashboard', async () => {
|
||||
test('defaults migrationVersion to empty object', async () => {
|
||||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_resolve_import_errors',
|
||||
payload: [
|
||||
'--EXAMPLE',
|
||||
'Content-Disposition: form-data; name="file"; filename="export.ndjson"',
|
||||
'Content-Type: application/ndjson',
|
||||
'',
|
||||
'{"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"}}',
|
||||
'--EXAMPLE',
|
||||
'Content-Disposition: form-data; name="retries"',
|
||||
'',
|
||||
'[{"type":"dashboard","id":"my-dashboard"}]',
|
||||
'--EXAMPLE--',
|
||||
].join('\r\n'),
|
||||
headers: {
|
||||
'content-Type': 'multipart/form-data; boundary=EXAMPLE',
|
||||
},
|
||||
};
|
||||
savedObjectsClient.bulkCreate.mockResolvedValueOnce({
|
||||
saved_objects: [
|
||||
{
|
||||
type: 'dashboard',
|
||||
id: 'my-dashboard',
|
||||
attributes: {
|
||||
title: 'Look at my dashboard',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const { payload, statusCode } = await server.inject(request);
|
||||
const response = JSON.parse(payload);
|
||||
expect(statusCode).toBe(200);
|
||||
expect(response).toEqual({ success: true, successCount: 1 });
|
||||
expect(savedObjectsClient.bulkCreate.mock.calls).toHaveLength(1);
|
||||
const firstBulkCreateCallArray = savedObjectsClient.bulkCreate.mock.calls[0][0];
|
||||
expect(firstBulkCreateCallArray).toHaveLength(1);
|
||||
expect(firstBulkCreateCallArray[0].migrationVersion).toEqual({});
|
||||
});
|
||||
|
||||
test('retries importing a dashboard', async () => {
|
||||
// NOTE: changes to this scenario should be reflected in the docs
|
||||
const request = {
|
||||
method: 'POST',
|
||||
|
@ -123,6 +164,7 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => {
|
|||
"title": "Look at my dashboard",
|
||||
},
|
||||
"id": "my-dashboard",
|
||||
"migrationVersion": Object {},
|
||||
"type": "dashboard",
|
||||
},
|
||||
],
|
||||
|
@ -185,6 +227,7 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => {
|
|||
"title": "Look at my dashboard",
|
||||
},
|
||||
"id": "my-dashboard",
|
||||
"migrationVersion": Object {},
|
||||
"type": "dashboard",
|
||||
},
|
||||
],
|
||||
|
@ -266,6 +309,7 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => {
|
|||
"title": "Look at my visualization",
|
||||
},
|
||||
"id": "my-vis",
|
||||
"migrationVersion": Object {},
|
||||
"references": Array [
|
||||
Object {
|
||||
"id": "existing",
|
||||
|
|
|
@ -113,6 +113,7 @@ export default function ({ getService }) {
|
|||
type: 'visualization',
|
||||
attributes: {
|
||||
title: 'My favorite vis',
|
||||
visState: '{}',
|
||||
},
|
||||
references: [
|
||||
{
|
||||
|
@ -230,6 +231,7 @@ export default function ({ getService }) {
|
|||
type: 'visualization',
|
||||
attributes: {
|
||||
title: 'My favorite vis',
|
||||
visState: '{}',
|
||||
},
|
||||
references: [
|
||||
{
|
||||
|
|
|
@ -112,7 +112,11 @@ export function importTestSuiteFactory(es: any, esArchiver: any, supertest: Supe
|
|||
await supertest
|
||||
.post(`${getUrlPrefix(spaceId)}/api/saved_objects/_import`)
|
||||
.auth(user.username, user.password)
|
||||
.attach('file', Buffer.from(JSON.stringify(data), 'utf8'), 'export.ndjson')
|
||||
.attach(
|
||||
'file',
|
||||
Buffer.from(data.map(obj => JSON.stringify(obj)).join('\n'), 'utf8'),
|
||||
'export.ndjson'
|
||||
)
|
||||
.expect(tests.default.statusCode)
|
||||
.then(tests.default.response);
|
||||
});
|
||||
|
@ -131,7 +135,11 @@ export function importTestSuiteFactory(es: any, esArchiver: any, supertest: Supe
|
|||
.post(`${getUrlPrefix(spaceId)}/api/saved_objects/_import`)
|
||||
.query({ overwrite: true })
|
||||
.auth(user.username, user.password)
|
||||
.attach('file', Buffer.from(JSON.stringify(data), 'utf8'), 'export.ndjson')
|
||||
.attach(
|
||||
'file',
|
||||
Buffer.from(data.map(obj => JSON.stringify(obj)).join('\n'), 'utf8'),
|
||||
'export.ndjson'
|
||||
)
|
||||
.expect(tests.unknownType.statusCode)
|
||||
.then(tests.unknownType.response);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue