mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Overhaul the query history tab to allow browsing of the history and full query text. Fixes #2282
Patch by Joao and the team at Pivotal.
This commit is contained in:
committed by
Dave Page
parent
e413186d23
commit
7f55412059
68
web/regression/javascript/code_mirror_spec.jsx
Normal file
68
web/regression/javascript/code_mirror_spec.jsx
Normal file
@@ -0,0 +1,68 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import React from 'react';
|
||||
import $ from '../../pgadmin/static/vendor/jquery/jquery-1.11.2';
|
||||
import CodeMirror from '../../pgadmin/static/jsx/history/detail/code_mirror';
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
|
||||
describe('CodeMirror', () => {
|
||||
beforeEach(() => {
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
describe('#hydrateWhenBecomesVisible', () => {
|
||||
let codeMirror, isVisibleSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
codeMirror = shallow(<CodeMirror />).instance();
|
||||
isVisibleSpy = spyOn($.fn, 'is');
|
||||
spyOn(codeMirror, 'hydrate');
|
||||
});
|
||||
|
||||
describe('when component is visible', () => {
|
||||
beforeEach(() => {
|
||||
isVisibleSpy.and.returnValue(true);
|
||||
});
|
||||
|
||||
it('should hydrate the codemirror element', () => {
|
||||
codeMirror.hydrateWhenBecomesVisible();
|
||||
expect(codeMirror.hydrate).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when component is not visible', () => {
|
||||
beforeEach(() => {
|
||||
isVisibleSpy.and.returnValue(false);
|
||||
});
|
||||
|
||||
it('should not hydrate the codemirror element', () => {
|
||||
codeMirror.hydrateWhenBecomesVisible();
|
||||
expect(codeMirror.hydrate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when becomes visible', () => {
|
||||
beforeEach(() => {
|
||||
isVisibleSpy.and.returnValue(true);
|
||||
});
|
||||
|
||||
it('should hydrate the codemirror element', (done) => {
|
||||
setTimeout(() => {
|
||||
codeMirror.hydrateWhenBecomesVisible();
|
||||
expect(codeMirror.hydrate).toHaveBeenCalledTimes(1);
|
||||
done();
|
||||
}, 150);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -66,10 +66,6 @@ describe('historyCollection', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('sort', function () {
|
||||
it('doesn\'t sort');
|
||||
});
|
||||
|
||||
describe('when instantiated', function () {
|
||||
describe('from a history model', function () {
|
||||
it('has the historyModel', () => {
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import QueryHistoryEntry from '../../../pgadmin/static/jsx/history/query_history_entry';
|
||||
|
||||
import {mount} from 'enzyme';
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
|
||||
describe('QueryHistoryEntry', () => {
|
||||
let historyWrapper;
|
||||
beforeEach(() => {
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
describe('for a failed query', () => {
|
||||
beforeEach(() => {
|
||||
const historyEntry = {
|
||||
query: 'second sql statement',
|
||||
start_time: new Date(2016, 11, 11, 1, 33, 5, 99),
|
||||
status: false,
|
||||
};
|
||||
historyWrapper = mount(<QueryHistoryEntry historyEntry={historyEntry}/>);
|
||||
});
|
||||
it('displays a pink background color', () => {
|
||||
expect(historyWrapper.find('div').first()).toHaveStyle('backgroundColor', '#F7D0D5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a successful query', () => {
|
||||
beforeEach(() => {
|
||||
const historyEntry = {
|
||||
query: 'second sql statement',
|
||||
start_time: new Date(2016, 11, 11, 1, 33, 5, 99),
|
||||
status: true,
|
||||
};
|
||||
historyWrapper = mount(<QueryHistoryEntry historyEntry={historyEntry}/>);
|
||||
});
|
||||
it('does not display a pink background color', () => {
|
||||
expect(historyWrapper.find('div').first()).toHaveStyle('backgroundColor', '#FFF');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,30 +10,45 @@
|
||||
import React from 'react';
|
||||
import QueryHistory from '../../../pgadmin/static/jsx/history/query_history';
|
||||
import QueryHistoryEntry from '../../../pgadmin/static/jsx/history/query_history_entry';
|
||||
import QueryHistoryDetail from '../../../pgadmin/static/jsx/history/query_history_detail';
|
||||
import HistoryCollection from '../../../pgadmin/static/js/history/history_collection';
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
|
||||
import {mount, shallow} from 'enzyme';
|
||||
import {mount} from 'enzyme';
|
||||
|
||||
describe('QueryHistory', () => {
|
||||
let historyWrapper;
|
||||
beforeEach(() => {
|
||||
jasmineEnzyme();
|
||||
const historyCollection = new HistoryCollection([]);
|
||||
historyWrapper = shallow(<QueryHistory historyCollection={historyCollection}/>);
|
||||
});
|
||||
|
||||
describe('on construction', () => {
|
||||
describe('on construction, when there is no history', () => {
|
||||
beforeEach(function () {
|
||||
const historyCollection = new HistoryCollection([]);
|
||||
historyWrapper = mount(<QueryHistory historyCollection={historyCollection}/>);
|
||||
});
|
||||
|
||||
it('has no entries', (done) => {
|
||||
let foundChildren = historyWrapper.find(QueryHistoryEntry);
|
||||
expect(foundChildren.length).toBe(0);
|
||||
done();
|
||||
});
|
||||
|
||||
it('nothing is displayed on right panel', (done) => {
|
||||
let foundChildren = historyWrapper.find(QueryHistoryDetail);
|
||||
expect(foundChildren.length).toBe(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('does not error', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when it has history', () => {
|
||||
describe('when two SQL queries were executed', () => {
|
||||
let foundChildren;
|
||||
let queryDetail;
|
||||
let historyCollection;
|
||||
|
||||
beforeEach(() => {
|
||||
const historyObjects = [
|
||||
@@ -43,59 +58,114 @@ describe('QueryHistory', () => {
|
||||
status: false,
|
||||
row_affected: 1,
|
||||
total_time: '234 msec',
|
||||
message: 'some other message',
|
||||
message: 'message from second sql query',
|
||||
},
|
||||
{
|
||||
query: 'first sql statement',
|
||||
start_time: new Date(2017, 5, 3, 14, 3, 15, 150),
|
||||
status: true,
|
||||
row_affected: 2,
|
||||
row_affected: 12345,
|
||||
total_time: '14 msec',
|
||||
message: 'a very important message',
|
||||
message: 'message from first sql query',
|
||||
},
|
||||
];
|
||||
const historyCollection = new HistoryCollection(historyObjects);
|
||||
historyCollection = new HistoryCollection(historyObjects);
|
||||
|
||||
historyWrapper = mount(<QueryHistory historyCollection={historyCollection}/>);
|
||||
|
||||
foundChildren = historyWrapper.find(QueryHistoryEntry);
|
||||
queryDetail = historyWrapper.find(QueryHistoryDetail);
|
||||
});
|
||||
|
||||
it('has two query history entries', () => {
|
||||
expect(foundChildren.length).toBe(2);
|
||||
});
|
||||
|
||||
it('displays the SQL of the queries in order', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('first sql statement');
|
||||
expect(foundChildren.at(1).text()).toContain('second sql statement');
|
||||
});
|
||||
|
||||
it('displays the formatted timestamp of the queries in chronological order by most recent first', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('Jun 3 2017 – 14:03:15');
|
||||
expect(foundChildren.at(1).text()).toContain('Dec 11 2016 – 01:33:05');
|
||||
});
|
||||
|
||||
it('displays the number of rows affected', () => {
|
||||
expect(foundChildren.at(1).text()).toContain('1 rows affected');
|
||||
expect(foundChildren.at(0).text()).toContain('2 rows affected');
|
||||
});
|
||||
|
||||
it('displays the total time', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('total time: 14 msec');
|
||||
expect(foundChildren.at(1).text()).toContain('total time: 234 msec');
|
||||
});
|
||||
|
||||
it('displays the truncated message', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('a very important message');
|
||||
expect(foundChildren.at(1).text()).toContain('some other message');
|
||||
});
|
||||
|
||||
describe('when there are one failing and one successful query each', () => {
|
||||
it('adds a white background color for the successful query', () => {
|
||||
expect(foundChildren.at(0).find('div').first()).toHaveStyle('backgroundColor', '#FFF');
|
||||
describe('the main pane', () => {
|
||||
it('has two query history entries', () => {
|
||||
expect(foundChildren.length).toBe(2);
|
||||
});
|
||||
it('adds a red background color for the failed query', () => {
|
||||
expect(foundChildren.at(1).find('div').first()).toHaveStyle('backgroundColor', '#F7D0D5');
|
||||
|
||||
it('displays the query history entries in order', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('first sql statement');
|
||||
expect(foundChildren.at(1).text()).toContain('second sql statement');
|
||||
});
|
||||
|
||||
it('displays the formatted timestamp of the queries in chronological order by most recent first', () => {
|
||||
expect(foundChildren.at(0).text()).toContain('Jun 3 2017 – 14:03:15');
|
||||
expect(foundChildren.at(1).text()).toContain('Dec 11 2016 – 01:33:05');
|
||||
});
|
||||
|
||||
it('renders the most recent query as selected', () => {
|
||||
expect(foundChildren.at(0).nodes.length).toBe(1);
|
||||
expect(foundChildren.at(0).find('QueryHistorySelectedEntry').length).toBe(1);
|
||||
});
|
||||
|
||||
it('renders the older query as not selected', () => {
|
||||
expect(foundChildren.at(1).nodes.length).toBe(1);
|
||||
expect(foundChildren.at(1).find('QueryHistoryErrorEntry').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the details pane', () => {
|
||||
it('displays the formatted timestamp', () => {
|
||||
expect(queryDetail.at(0).text()).toContain('6-3-17 14:03:15Date');
|
||||
});
|
||||
|
||||
it('displays the number of rows affected', () => {
|
||||
if (/PhantomJS/.test(window.navigator.userAgent)) {
|
||||
expect(queryDetail.at(0).text()).toContain('12345Rows Affected');
|
||||
} else {
|
||||
expect(queryDetail.at(0).text()).toContain('12,345Rows Affected');
|
||||
}
|
||||
});
|
||||
|
||||
it('displays the total time', () => {
|
||||
expect(queryDetail.at(0).text()).toContain('14 msecDuration');
|
||||
});
|
||||
|
||||
it('displays the full message', () => {
|
||||
expect(queryDetail.at(0).text()).toContain('message from first sql query');
|
||||
});
|
||||
|
||||
it('displays first query SQL', (done) => {
|
||||
setTimeout(() => {
|
||||
expect(queryDetail.at(0).text()).toContain('first sql statement');
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the older query is clicked on', () => {
|
||||
beforeEach(() => {
|
||||
foundChildren.at(1).simulate('click');
|
||||
});
|
||||
|
||||
it('displays the query in the right pane', () => {
|
||||
expect(queryDetail.at(0).text()).toContain('second sql statement');
|
||||
});
|
||||
|
||||
it('renders the most recent query as selected in the left pane', () => {
|
||||
expect(foundChildren.at(0).nodes.length).toBe(1);
|
||||
expect(foundChildren.at(0).find('QueryHistoryVanillaEntry').length).toBe(1);
|
||||
});
|
||||
|
||||
it('renders the older query as selected in the left pane', () => {
|
||||
expect(foundChildren.at(1).nodes.length).toBe(1);
|
||||
expect(foundChildren.at(1).find('QueryHistorySelectedErrorEntry').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a third SQL query is executed', () => {
|
||||
beforeEach(() => {
|
||||
historyCollection.add({
|
||||
query: 'third sql statement',
|
||||
start_time: new Date(2017, 11, 11, 1, 33, 5, 99),
|
||||
status: false,
|
||||
row_affected: 5,
|
||||
total_time: '26 msec',
|
||||
message: 'third sql message',
|
||||
});
|
||||
});
|
||||
|
||||
it('displays third query SQL in the right pane', () => {
|
||||
expect(queryDetail.at(0).text()).toContain('third sql statement');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user