diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md index 3b60ac0f48edd2..9f9613a5a68f7c 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md @@ -9,7 +9,7 @@ Constructs a new instance of the `FieldList` class Signature: ```typescript -constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: () => void); +constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: OnNotification); ``` ## Parameters @@ -19,5 +19,5 @@ constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: b | indexPattern | IndexPattern | | | specs | FieldSpec[] | | | shortDotsEnable | boolean | | -| onNotification | () => void | | +| onNotification | OnNotification | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.intervalname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.intervalname.md new file mode 100644 index 00000000000000..762b4a37bfd289 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.intervalname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [intervalName](./kibana-plugin-plugins-data-public.indexpattern.intervalname.md) + +## IndexPattern.intervalName property + +Signature: + +```typescript +intervalName: string | undefined; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md index 649f8ef077e3f6..c15cb3358f689e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md @@ -27,9 +27,12 @@ export declare class IndexPattern implements IIndexPattern | [formatField](./kibana-plugin-plugins-data-public.indexpattern.formatfield.md) | | any | | | [formatHit](./kibana-plugin-plugins-data-public.indexpattern.formathit.md) | | any | | | [id](./kibana-plugin-plugins-data-public.indexpattern.id.md) | | string | | +| [intervalName](./kibana-plugin-plugins-data-public.indexpattern.intervalname.md) | | string | undefined | | | [metaFields](./kibana-plugin-plugins-data-public.indexpattern.metafields.md) | | string[] | | +| [sourceFilters](./kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md) | | SourceFilter[] | | | [timeFieldName](./kibana-plugin-plugins-data-public.indexpattern.timefieldname.md) | | string | undefined | | | [title](./kibana-plugin-plugins-data-public.indexpattern.title.md) | | string | | +| [type](./kibana-plugin-plugins-data-public.indexpattern.type.md) | | string | undefined | | | [typeMeta](./kibana-plugin-plugins-data-public.indexpattern.typemeta.md) | | TypeMeta | | ## Methods diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.prepbody.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.prepbody.md index 5c9f017b571da7..1d77b2a55860e2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.prepbody.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.prepbody.md @@ -8,12 +8,26 @@ ```typescript prepBody(): { - [key: string]: any; + title: string; + timeFieldName: string | undefined; + intervalName: string | undefined; + sourceFilters: string | undefined; + fields: string | undefined; + fieldFormatMap: string | undefined; + type: string | undefined; + typeMeta: string | undefined; }; ``` Returns: `{ - [key: string]: any; + title: string; + timeFieldName: string | undefined; + intervalName: string | undefined; + sourceFilters: string | undefined; + fields: string | undefined; + fieldFormatMap: string | undefined; + type: string | undefined; + typeMeta: string | undefined; }` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md new file mode 100644 index 00000000000000..10ccf8e137627a --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [sourceFilters](./kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md) + +## IndexPattern.sourceFilters property + +Signature: + +```typescript +sourceFilters?: SourceFilter[]; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.type.md new file mode 100644 index 00000000000000..7a10d058b9c656 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [type](./kibana-plugin-plugins-data-public.indexpattern.type.md) + +## IndexPattern.type property + +Signature: + +```typescript +type: string | undefined; +``` diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index e1fb1802b2a210..4a931aabd3646d 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -592,7 +592,7 @@ The `server.xsrf.whitelist` setting requires the following format: [cols="2*<"] |=== -| [[settings-xsrf-disableProtection]] `status.xsrf.disableProtection:` +| [[settings-xsrf-disableProtection]] `server.xsrf.disableProtection:` | Setting this to `true` will completely disable Cross-site request forgery protection in Kibana. This is not recommended. *Default: `false`* | `status.allowAnonymous:` diff --git a/src/plugins/data/common/index_patterns/fields/field_list.ts b/src/plugins/data/common/index_patterns/fields/field_list.ts index 34bd69230a2e46..d2489a5d1f7e33 100644 --- a/src/plugins/data/common/index_patterns/fields/field_list.ts +++ b/src/plugins/data/common/index_patterns/fields/field_list.ts @@ -64,7 +64,7 @@ export class FieldList extends Array implements IIndexPattern indexPattern: IndexPattern, specs: FieldSpec[] = [], shortDotsEnable = false, - onNotification = () => {} + onNotification: OnNotification = () => {} ) { super(); this.indexPattern = indexPattern; diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts index 09b79cae4aac2a..f7e1156170f032 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts @@ -43,8 +43,21 @@ jest.mock('../../field_mapping', () => { id: true, title: true, fieldFormatMap: { + _serialize: jest.fn().mockImplementation(() => {}), _deserialize: jest.fn().mockImplementation(() => []), }, + fields: { + _serialize: jest.fn().mockImplementation(() => {}), + _deserialize: jest.fn().mockImplementation((fields) => fields), + }, + sourceFilters: { + _serialize: jest.fn().mockImplementation(() => {}), + _deserialize: jest.fn().mockImplementation(() => undefined), + }, + typeMeta: { + _serialize: jest.fn().mockImplementation(() => {}), + _deserialize: jest.fn().mockImplementation(() => undefined), + }, })), }; }); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index e81ef1d6b2482e..5d6ae61a77e00d 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -56,14 +56,14 @@ interface IndexPatternDeps { } export class IndexPattern implements IIndexPattern { - [key: string]: any; - public id?: string; public title: string = ''; public fieldFormatMap: any; public typeMeta?: TypeMeta; public fields: IIndexPatternFieldList & { toSpec: () => FieldSpec[] }; public timeFieldName: string | undefined; + public intervalName: string | undefined; + public type: string | undefined; public formatHit: any; public formatField: any; public flattenHit: any; @@ -72,7 +72,7 @@ export class IndexPattern implements IIndexPattern { private version: string | undefined; private savedObjectsClient: SavedObjectsClientCommon; private patternCache: PatternCache; - private sourceFilters?: SourceFilter[]; + public sourceFilters?: SourceFilter[]; private originalBody: { [key: string]: any } = {}; public fieldsFetcher: any; // probably want to factor out any direct usage and change to private private shortDotsEnable: boolean = false; @@ -126,7 +126,7 @@ export class IndexPattern implements IIndexPattern { this.shortDotsEnable = shortDotsEnable; this.metaFields = metaFields; - this.fields = new FieldList(this, [], this.shortDotsEnable, this.onUnknownType); + this.fields = new FieldList(this, [], this.shortDotsEnable, this.onNotification); this.apiClient = apiClient; this.fieldsFetcher = createFieldsFetcher(this, apiClient, metaFields); @@ -226,10 +226,13 @@ export class IndexPattern implements IIndexPattern { response[name] = fieldMapping._deserialize(response[name]); }); - // give index pattern all of the values - const fieldList = this.fields; - _.assign(this, response); - this.fields = fieldList; + this.title = response.title; + this.timeFieldName = response.timeFieldName; + this.intervalName = response.intervalName; + this.sourceFilters = response.sourceFilters; + this.fieldFormatMap = response.fieldFormatMap; + this.type = response.type; + this.typeMeta = response.typeMeta; if (!this.title && this.id) { this.title = this.id; @@ -430,18 +433,16 @@ export class IndexPattern implements IIndexPattern { } prepBody() { - const body: { [key: string]: any } = {}; - - // serialize json fields - _.forOwn(this.mapping, (fieldMapping, fieldName) => { - if (!fieldName || this[fieldName] == null) return; - - body[fieldName] = fieldMapping._serialize - ? fieldMapping._serialize(this[fieldName]) - : this[fieldName]; - }); - - return body; + return { + title: this.title, + timeFieldName: this.timeFieldName, + intervalName: this.intervalName, + sourceFilters: this.mapping.sourceFilters._serialize!(this.sourceFilters), + fields: this.mapping.fields._serialize!(this.fields), + fieldFormatMap: this.mapping.fieldFormatMap._serialize!(this.fieldFormatMap), + type: this.type, + typeMeta: this.mapping.typeMeta._serialize!(this.mapping), + }; } getFormatterForField(field: IndexPatternField | IndexPatternField['spec']): FieldFormat { @@ -485,10 +486,14 @@ export class IndexPattern implements IIndexPattern { async save(saveAttempts: number = 0): Promise { if (!this.id) return; const body = this.prepBody(); - // What keys changed since they last pulled the index pattern - const originalChangedKeys = Object.keys(body).filter( - (key) => body[key] !== this.originalBody[key] - ); + + const originalChangedKeys: string[] = []; + Object.entries(body).forEach(([key, value]) => { + if (value !== this.originalBody[key]) { + originalChangedKeys.push(key); + } + }); + return this.savedObjectsClient .update(savedObjectType, this.id, body, { version: this.version }) .then((resp) => { @@ -519,8 +524,12 @@ export class IndexPattern implements IIndexPattern { // and ensure we ignore the key if the server response // is the same as the original response (since that is expected // if we made a change in that key) - const serverChangedKeys = Object.keys(updatedBody).filter((key) => { - return updatedBody[key] !== body[key] && this.originalBody[key] !== updatedBody[key]; + + const serverChangedKeys: string[] = []; + Object.entries(updatedBody).forEach(([key, value]) => { + if (value !== (body as any)[key] && value !== this.originalBody[key]) { + serverChangedKeys.push(key); + } }); let unresolvedCollision = false; @@ -545,7 +554,7 @@ export class IndexPattern implements IIndexPattern { // Set the updated response on this object serverChangedKeys.forEach((key) => { - this[key] = samePattern[key]; + (this as any)[key] = (samePattern as any)[key]; }); this.version = samePattern.version; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 261f16229460ac..9a2a82e8ed2069 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -604,7 +604,8 @@ export type FieldFormatsGetConfigFn = GetConfigFn; // @public (undocumented) export class FieldList extends Array implements IIndexPatternFieldList { // Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts - constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: () => void); + // Warning: (ae-forgotten-export) The symbol "OnNotification" needs to be exported by the entry point index.d.ts + constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: OnNotification); // (undocumented) readonly add: (field: FieldSpec) => void; // (undocumented) @@ -946,8 +947,6 @@ export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts constructor(id: string | undefined, { savedObjectsClient, apiClient, patternCache, fieldFormats, onNotification, onError, shortDotsEnable, metaFields, }: IndexPatternDeps); // (undocumented) - [key: string]: any; - // (undocumented) addScriptedField(name: string, script: string, fieldType: string | undefined, lang: string): Promise; // (undocumented) create(allowOverride?: boolean): Promise; @@ -1008,6 +1007,8 @@ export class IndexPattern implements IIndexPattern { // (undocumented) initFromSpec(spec: IndexPatternSpec): this; // (undocumented) + intervalName: string | undefined; + // (undocumented) isTimeBased(): boolean; // (undocumented) isTimeBasedWildcard(): boolean; @@ -1021,7 +1022,14 @@ export class IndexPattern implements IIndexPattern { popularizeField(fieldName: string, unit?: number): Promise; // (undocumented) prepBody(): { - [key: string]: any; + title: string; + timeFieldName: string | undefined; + intervalName: string | undefined; + sourceFilters: string | undefined; + fields: string | undefined; + fieldFormatMap: string | undefined; + type: string | undefined; + typeMeta: string | undefined; }; // (undocumented) refreshFields(): Promise; @@ -1029,6 +1037,10 @@ export class IndexPattern implements IIndexPattern { removeScriptedField(fieldName: string): Promise; // (undocumented) save(saveAttempts?: number): Promise; + // Warning: (ae-forgotten-export) The symbol "SourceFilter" needs to be exported by the entry point index.d.ts + // + // (undocumented) + sourceFilters?: SourceFilter[]; // (undocumented) timeFieldName: string | undefined; // (undocumented) @@ -1040,6 +1052,8 @@ export class IndexPattern implements IIndexPattern { // (undocumented) toString(): string; // (undocumented) + type: string | undefined; + // (undocumented) typeMeta?: IndexPatternTypeMeta; } @@ -1081,7 +1095,6 @@ export interface IndexPatternAttributes { // // @public (undocumented) export class IndexPatternField implements IFieldType { - // Warning: (ae-forgotten-export) The symbol "OnNotification" needs to be exported by the entry point index.d.ts constructor(indexPattern: IndexPattern, spec: FieldSpec, displayName: string, onNotification: OnNotification); // (undocumented) get aggregatable(): boolean; diff --git a/x-pack/plugins/maps/public/routing/maps_router.js b/x-pack/plugins/maps/public/routing/maps_router.js index 9b7900d032f5a6..f0f5234e3f9898 100644 --- a/x-pack/plugins/maps/public/routing/maps_router.js +++ b/x-pack/plugins/maps/public/routing/maps_router.js @@ -7,7 +7,14 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { Router, Switch, Route, Redirect } from 'react-router-dom'; -import { getCoreI18n, getToasts, getEmbeddableService } from '../kibana_services'; +import { i18n } from '@kbn/i18n'; +import { + getCoreChrome, + getCoreI18n, + getMapsCapabilities, + getToasts, + getEmbeddableService, +} from '../kibana_services'; import { createKbnUrlStateStorage, withNotifyOnErrors, @@ -44,6 +51,18 @@ const App = ({ history, appBasePath, onAppLeave }) => { const { originatingApp } = stateTransfer?.getIncomingEditorState({ keysToRemoveAfterFetch: ['originatingApp'] }) || {}; + if (!getMapsCapabilities().save) { + getCoreChrome().setBadge({ + text: i18n.translate('xpack.maps.badge.readOnly.text', { + defaultMessage: 'Read only', + }), + tooltip: i18n.translate('xpack.maps.badge.readOnly.tooltip', { + defaultMessage: 'Unable to save maps', + }), + iconType: 'glasses', + }); + } + return ( diff --git a/x-pack/test/functional/apps/maps/add_layer_panel.js b/x-pack/test/functional/apps/maps/add_layer_panel.js index 3902b616cf1ee1..9eb560ed42c312 100644 --- a/x-pack/test/functional/apps/maps/add_layer_panel.js +++ b/x-pack/test/functional/apps/maps/add_layer_panel.js @@ -9,17 +9,23 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['maps']); + const security = getService('security'); describe('Add layer panel', () => { const LAYER_NAME = 'World Countries'; before(async () => { + await security.testUser.setRoles(['global_maps_all']); await PageObjects.maps.openNewMap(); await PageObjects.maps.clickAddLayer(); await PageObjects.maps.selectEMSBoundariesSource(); await PageObjects.maps.selectVectorLayer(LAYER_NAME); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); + it('should show unsaved layer in layer TOC', async () => { const vectorLayerExists = await PageObjects.maps.doesLayerExist(LAYER_NAME); expect(vectorLayerExists).to.be(true); diff --git a/x-pack/test/functional/apps/maps/blended_vector_layer.js b/x-pack/test/functional/apps/maps/blended_vector_layer.js index 9658cb37291343..9793d4b8f03d3c 100644 --- a/x-pack/test/functional/apps/maps/blended_vector_layer.js +++ b/x-pack/test/functional/apps/maps/blended_vector_layer.js @@ -9,12 +9,22 @@ import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['maps']); const inspector = getService('inspector'); + const security = getService('security'); describe('blended vector layer', () => { before(async () => { + await security.testUser.setRoles(['test_logstash_reader', 'global_maps_all']); await PageObjects.maps.loadSavedMap('blended document example'); }); + afterEach(async () => { + await inspector.close(); + }); + + after(async () => { + await security.testUser.restoreDefaults(); + }); + it('should request documents when zoomed to smaller regions showing less data', async () => { const hits = await PageObjects.maps.getHits(); expect(hits).to.equal('33'); diff --git a/x-pack/test/functional/apps/maps/feature_controls/maps_security.ts b/x-pack/test/functional/apps/maps/feature_controls/maps_security.ts index f480f1f0ae24af..ae9b0f095fc44c 100644 --- a/x-pack/test/functional/apps/maps/feature_controls/maps_security.ts +++ b/x-pack/test/functional/apps/maps/feature_controls/maps_security.ts @@ -181,8 +181,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.missingOrFail('checkboxSelectAll'); }); - // This behavior was removed when the Maps app was migrated to NP - it.skip(`shows read-only badge`, async () => { + it(`shows read-only badge`, async () => { await globalNav.badgeExistsOrFail('Read only'); }); diff --git a/x-pack/test/functional/apps/maps/full_screen_mode.js b/x-pack/test/functional/apps/maps/full_screen_mode.js index b4ea2b0baf255c..a114826f564bb6 100644 --- a/x-pack/test/functional/apps/maps/full_screen_mode.js +++ b/x-pack/test/functional/apps/maps/full_screen_mode.js @@ -9,13 +9,16 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['maps', 'common']); const retry = getService('retry'); - const esArchiver = getService('esArchiver'); + const security = getService('security'); describe('maps full screen mode', () => { before(async () => { - await esArchiver.loadIfNeeded('maps/data'); + await security.testUser.setRoles(['global_maps_all']); await PageObjects.maps.openNewMap(); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); it('full screen button should exist', async () => { const exists = await PageObjects.maps.fullScreenModeMenuItemExists(); diff --git a/x-pack/test/functional/apps/maps/layer_visibility.js b/x-pack/test/functional/apps/maps/layer_visibility.js index 22cff6de416c1f..dd9b93c995695b 100644 --- a/x-pack/test/functional/apps/maps/layer_visibility.js +++ b/x-pack/test/functional/apps/maps/layer_visibility.js @@ -9,14 +9,17 @@ import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['maps']); const inspector = getService('inspector'); + const security = getService('security'); describe('layer visibility', () => { before(async () => { + await security.testUser.setRoles(['test_logstash_reader', 'global_maps_all']); await PageObjects.maps.loadSavedMap('document example hidden'); }); afterEach(async () => { await inspector.close(); + await security.testUser.restoreDefaults(); }); it('should not make any requests when layer is hidden', async () => { diff --git a/x-pack/test/functional/apps/maps/saved_object_management.js b/x-pack/test/functional/apps/maps/saved_object_management.js index 810df8e9950643..277a8a5651453d 100644 --- a/x-pack/test/functional/apps/maps/saved_object_management.js +++ b/x-pack/test/functional/apps/maps/saved_object_management.js @@ -12,6 +12,7 @@ export default function ({ getPageObjects, getService }) { const filterBar = getService('filterBar'); const browser = getService('browser'); const inspector = getService('inspector'); + const security = getService('security'); describe('map saved object management', () => { const MAP_NAME_PREFIX = 'saved_object_management_test_'; @@ -20,8 +21,16 @@ export default function ({ getPageObjects, getService }) { describe('read', () => { before(async () => { + await security.testUser.setRoles([ + 'global_maps_all', + 'geoshape_data_reader', + 'test_logstash_reader', + ]); await PageObjects.maps.loadSavedMap('join example'); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); it('should update global Kibana time to value stored with map', async () => { const timeConfig = await PageObjects.timePicker.getTimeConfig(); diff --git a/x-pack/test/functional/apps/maps/vector_styling.js b/x-pack/test/functional/apps/maps/vector_styling.js index 29c01918165cf1..1def542982dd8e 100644 --- a/x-pack/test/functional/apps/maps/vector_styling.js +++ b/x-pack/test/functional/apps/maps/vector_styling.js @@ -6,13 +6,18 @@ import expect from '@kbn/expect'; -export default function ({ getPageObjects }) { +export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['maps']); + const security = getService('security'); describe('vector styling', () => { before(async () => { + await security.testUser.setRoles(['test_logstash_reader', 'global_maps_all']); await PageObjects.maps.loadSavedMap('document example'); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); describe('categorical styling', () => { before(async () => {