diff --git a/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.spec.tsx b/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.spec.tsx index 3f931ef8542..7e6b8a7bfd3 100644 --- a/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.spec.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.spec.tsx @@ -1,103 +1,155 @@ import React from 'react'; import type { ComponentProps } from 'react'; -import { render, screen } from '@testing-library/react'; +import { cleanup, render, screen } from '@testing-library/react'; import { expect } from 'chai'; -import { Provider } from 'react-redux'; - -import configureStore from '../../../test/configure-store'; +import preferencesAccess from 'compass-preferences-model'; import { OutputStage } from './output-stage-preview'; const renderOutputStage = ( props: Partial> = {} ) => { render( - - {}} - onRunOutputStage={() => {}} - {...props} - /> - + {}} + onRunOutputStage={() => {}} + {...props} + /> ); }; describe('OutputStagePreview', function () { - (['$out', '$merge'] as const).forEach(function (operator) { + let enableAggregationBuilderRunPipeline: boolean; + + afterEach(cleanup); + + it('renders nothing for a non-out stage', function () { + renderOutputStage({ operator: '$match' }); + expect(screen.queryAllByText(/./)).to.have.lengthOf(0); + }); + + for (const operator of ['$out', '$merge']) { describe(`${operator} stage`, function () { - context('renders loader when stage is loading', function () { - it('renders loader with namespace', function () { - renderOutputStage({ - operator, - isLoading: true, - destinationNamespace: 'test.out', + describe('with enableAggregationBuilderRunPipeline set to `true`', function () { + before(async function () { + enableAggregationBuilderRunPipeline = + preferencesAccess.getPreferences() + .enableAggregationBuilderRunPipeline; + await preferencesAccess.savePreferences({ + enableAggregationBuilderRunPipeline: true, }); + }); + + after(async function () { + await preferencesAccess.savePreferences({ + enableAggregationBuilderRunPipeline, + }); + }); + + it('shows stage description in default state', function () { + renderOutputStage({ operator }); expect( - screen.getByText(/Persisting documents to test.out/i) + screen.getByText( + new RegExp(`The \\${operator} operator will cause the pipeline`) + ) ).to.exist; }); - it('renders loader with generic text', function () { + it('does not show the "run" button', function () { + renderOutputStage({ operator }); + expect( + screen.queryByRole('button', { + name: + operator === '$merge' ? 'Merge Documents' : 'Save Documents', + }) + ).to.eq(null); + }); + + it('shows stage description in error state', function () { + renderOutputStage({ operator, hasServerError: true }); + expect( + screen.getByText( + new RegExp(`The \\${operator} operator will cause the pipeline`) + ) + ).to.exist; + }); + + it('shows stage description in loading state', function () { renderOutputStage({ operator, isLoading: true }); - expect(screen.getByText(/Persisting documents .../i)).to.exist; + expect( + screen.getByText( + new RegExp(`The \\${operator} operator will cause the pipeline`) + ) + ).to.exist; }); - }); - it('renders nothing on server error', function () { - renderOutputStage({ operator, hasServerError: true }); - expect(() => { - screen.getByTestId('output-stage-text'); - }).to.throw; + it('shows stage description in finished state', function () { + renderOutputStage({ operator, isFinishedPersistingDocuments: true }); + expect( + screen.getByText( + new RegExp(`The \\${operator} operator will cause the pipeline`) + ) + ).to.exist; + }); }); - context('when documents have been persisted', function () { - context('renders the out stage preview', function () { - it('with namespace', function () { - renderOutputStage({ - operator, - isFinishedPersistingDocuments: true, - destinationNamespace: 'test.out', - }); - expect( - screen.getByText(/Documents persisted to collection: test.out/i) - ).to.exist; + describe('with enableAggregationBuilderRunPipeline set to `false`', function () { + before(async function () { + enableAggregationBuilderRunPipeline = + preferencesAccess.getPreferences() + .enableAggregationBuilderRunPipeline; + await preferencesAccess.savePreferences({ + enableAggregationBuilderRunPipeline: false, }); + }); - it('without namespace', function () { - renderOutputStage({ - operator, - isFinishedPersistingDocuments: true, - }); - expect( - screen.getByText(/Documents persisted to specified collection/i) - ).to.exist; + after(async function () { + await preferencesAccess.savePreferences({ + enableAggregationBuilderRunPipeline, }); }); - it('renders go to collection button', function () { - renderOutputStage({ operator, isFinishedPersistingDocuments: true }); - expect(screen.getByTestId('goto-output-collection')).to.exist; + it('shows stage description in default state', function () { + renderOutputStage({ operator }); + expect( + screen.getByText( + new RegExp(`The \\${operator} operator will cause the pipeline`) + ) + ).to.exist; }); - }); - context('default stage of component', function () { - it('renders the out stage preview', function () { + it('shows the "run" button', function () { renderOutputStage({ operator }); - expect(screen.getByTestId('output-stage-text')).to.exist; + expect( + screen.getByRole('button', { + name: + operator === '$merge' ? 'Merge Documents' : 'Save Documents', + }) + ).to.exist; }); - it('renders save documents button on atlas', function () { - renderOutputStage({ operator }); - expect(screen.getByTestId('save-output-documents')).to.exist; + + it('shows nothing in error state', function () { + renderOutputStage({ operator, hasServerError: true }); + expect(screen.queryAllByText(/./)).to.have.lengthOf(0); + }); + + it('shows loader in loading state', function () { + renderOutputStage({ operator, isLoading: true }); + expect(screen.getByText(/Persisting Documents to foo.bar/)).to.exist; + }); + + it('shows "Documents persisted ..." in finished state', function () { + renderOutputStage({ operator, isFinishedPersistingDocuments: true }); + expect(screen.getByText(/Documents persisted to collection: foo.bar/)) + .to.exist; + expect(screen.getByRole('button', { name: 'Go to collection.' })).to + .exist; }); }); }); - }); + } }); diff --git a/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.tsx b/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.tsx index a5d4614b1ee..e64407ed0d3 100644 --- a/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/output-stage-preview.tsx @@ -89,7 +89,9 @@ export const OutputStage = ({ onRunOutputStage, onGoToOutputResults, }: OutputStageProps) => { - const enableAggregationBuilderRunPipeline = usePreference( + // When explicit pipeline run is not enabled, we allow to run output stage + // from the preview + const showOutputActions = !usePreference( 'enableAggregationBuilderRunPipeline', React ); @@ -98,31 +100,35 @@ export const OutputStage = ({ return null; } - if (isLoading) { - return ; - } - - // Stage editor show the error message. - if (hasServerError) { - return null; - } - - if (isFinishedPersistingDocuments) { - return ( -
- - {documentsPersistedText(destinationNamespace)} - - - Go to collection. - -
- ); + // Following states are only allowed when running out stage from the preview + // card is enabled + if (showOutputActions) { + // Stage editor show the error message. + if (hasServerError) { + return null; + } + + if (isLoading) { + return ; + } + + if (isFinishedPersistingDocuments) { + return ( +
+ + {documentsPersistedText(destinationNamespace)} + + + Go to collection. + +
+ ); + } } return ( @@ -132,7 +138,7 @@ export const OutputStage = ({ ? MERGE_STAGE_PREVIEW_TEXT : OUT_STAGE_PREVIEW_TEXT} - {enableAggregationBuilderRunPipeline && ( + {showOutputActions && (