blob: 7326073b77a8bfeb16d9233cc485870f4a2027c8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import { isFeatureEnabled } from '@superset-ui/core';
import {
render,
screen,
act,
userEvent,
waitFor,
} from 'spec/helpers/testing-library';
import ShareSqlLabQuery from 'src/SqlLab/components/ShareSqlLabQuery';
import { initialState } from 'src/SqlLab/fixtures';
import { omit } from 'lodash';
const mockStore = configureStore([thunk]);
const defaultProps = {
queryEditorId: 'qe1',
addDangerToast: jest.fn(),
};
const mockQueryEditor = {
id: defaultProps.queryEditorId,
dbId: 0,
name: 'query title',
schema: 'query_schema',
autorun: false,
sql: 'SELECT * FROM ...',
remoteId: 999,
};
const disabled = {
id: 'disabledEditorId',
remoteId: undefined,
};
const mockState = {
...initialState,
sqlLab: {
...initialState.sqlLab,
queryEditors: [mockQueryEditor, disabled],
},
};
const store = mockStore(mockState);
jest.mock('@superset-ui/core', () => ({
...jest.requireActual('@superset-ui/core'),
isFeatureEnabled: jest.fn(),
}));
const mockedIsFeatureEnabled = isFeatureEnabled as jest.Mock;
const unsavedQueryEditor = {
id: defaultProps.queryEditorId,
dbId: 9888,
name: 'query title changed',
schema: 'query_schema_updated',
sql: 'SELECT * FROM Updated Limit 100',
autorun: true,
templateParams: '{ "my_value": "foo" }',
};
describe('ShareSqlLabQuery', () => {
const storeQueryUrl = 'glob:*/api/v1/sqllab/permalink';
const storeQueryMockId = 'ci39c3';
beforeEach(async () => {
fetchMock.post(
storeQueryUrl,
() => ({ key: storeQueryMockId, url: `/p/${storeQueryMockId}` }),
{
overwriteRoutes: true,
},
);
fetchMock.resetHistory();
jest.clearAllMocks();
});
afterAll(() => fetchMock.reset());
describe('via permalink api', () => {
beforeAll(() => {
mockedIsFeatureEnabled.mockImplementation(() => true);
});
afterAll(() => {
mockedIsFeatureEnabled.mockReset();
});
it('calls storeQuery() with the query when getCopyUrl() is called', async () => {
await act(async () => {
render(<ShareSqlLabQuery {...defaultProps} />, {
useRedux: true,
store,
});
});
const button = screen.getByRole('button');
const expected = omit(mockQueryEditor, ['id', 'remoteId']);
userEvent.click(button);
await waitFor(() =>
expect(fetchMock.calls(storeQueryUrl)).toHaveLength(1),
);
expect(
JSON.parse(fetchMock.calls(storeQueryUrl)[0][1]?.body as string),
).toEqual(expected);
});
it('calls storeQuery() with unsaved changes', async () => {
await act(async () => {
render(<ShareSqlLabQuery {...defaultProps} />, {
useRedux: true,
store: mockStore({
...initialState,
sqlLab: {
...initialState.sqlLab,
unsavedQueryEditor,
},
}),
});
});
const button = screen.getByRole('button');
const expected = omit(unsavedQueryEditor, ['id']);
userEvent.click(button);
await waitFor(() =>
expect(fetchMock.calls(storeQueryUrl)).toHaveLength(1),
);
expect(
JSON.parse(fetchMock.calls(storeQueryUrl)[0][1]?.body as string),
).toEqual(expected);
});
});
});