import React from 'react';
import { cleanup, render, screen } from '@testing-library/react';
import { ExplainPlanView } from './explain-plan-view';
import type { Stage } from '@mongodb-js/explain-plan-helper';
import { ExplainPlan } from '@mongodb-js/explain-plan-helper';
import { expect } from 'chai';
import { Provider } from 'react-redux';
import { configureStore } from '../stores/explain-plan-modal-store';
const simpleExplain = new ExplainPlan({
queryPlanner: {
plannerVersion: 1,
namespace: 'test.test',
indexFilterSet: false,
parsedQuery: {},
optimizedPipeline: true,
winningPlan: {
stage: 'COLLSCAN',
direction: 'forward',
},
rejectedPlans: [],
},
executionStats: {
executionSuccess: true,
nReturned: 1000,
executionTimeMillis: 5,
totalKeysExamined: 0,
totalDocsExamined: 1000,
executionStages: {
stage: 'COLLSCAN',
nReturned: 1000,
executionTimeMillisEstimate: 0,
works: 1002,
advanced: 1000,
needTime: 1,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
direction: 'forward',
docsExamined: 1000,
},
allPlansExecution: [],
},
ok: 1,
} as unknown as Stage).serialize();
describe('ExplainPlanView', function () {
afterEach(cleanup);
it('should render explain plan', function () {
render(
);
expect(screen.getByText('COLLSCAN')).to.exist;
expect(screen.getByText('Query Performance Summary')).to.exist;
expect(screen.getByTestId('docsReturned'))
.to.have.property('textContent')
.match(/1000\xa0documents returned/);
expect(screen.getByTestId('docsExamined'))
.to.have.property('textContent')
.match(/1000\xa0documents examined/);
expect(screen.getByTestId('executionTimeMs'))
.to.have.property('textContent')
.match(/5\xa0ms\xa0execution time/);
expect(screen.getByTestId('sortedInMemory'))
.to.have.property('textContent')
.match(/Is not\xa0sorted in memory/);
expect(screen.getByTestId('indexKeysExamined'))
.to.have.property('textContent')
.match(/0\xa0index keys examined/);
});
it('should render error when there is no explain plan', function () {
render();
expect(screen.getByText('No explain plan')).to.exist;
});
it('should render raw explain when explain was not parsed successfully', function () {
render(
);
expect(
screen.getByText(
'Visual explain plan is not supported with this query on this collection in this Compass release',
{ exact: false }
)
).to.exist;
function parentButton(el: Node | null): Node | null {
if (!el) return null;
if (el.parentNode?.nodeName === 'BUTTON') return el.parentNode;
return parentButton(el.parentNode);
}
expect(parentButton(screen.getByText('Visual Tree'))).to.have.property(
'disabled'
);
expect(parentButton(screen.getByText('Raw Output'))).to.have.property(
'disabled'
);
const doc = (
screen.getByTestId('raw-explain-plan') as unknown as { _cm: any }
)._cm.state.sliceDoc();
expect(doc).to.eq(`{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "test.test",
"indexFilterSet": false,
"parsedQuery": {},
"optimizedPipeline": true,
"winningPlan": {
"stage": "COLLSCAN",
"direction": "forward"
},
"rejectedPlans": []
},
"executionStats": {
"executionSuccess": true,
"nReturned": 1000,
"executionTimeMillis": 5,
"totalKeysExamined": 0,
"totalDocsExamined": 1000,
"executionStages": {
"stage": "COLLSCAN",
"nReturned": 1000,
"executionTimeMillisEstimate": 0,
"works": 1002,
"advanced": 1000,
"needTime": 1,
"needYield": 0,
"saveState": 1,
"restoreState": 1,
"isEOF": 1,
"direction": "forward",
"docsExamined": 1000
},
"allPlansExecution": []
},
"ok": 1
}`);
});
});