Skip to content

Commit

Permalink
fix: avoid unmounting of elements in children render function when fe…
Browse files Browse the repository at this point in the history
…ature app is loaded (#604)
  • Loading branch information
stemey authored Oct 26, 2020
1 parent ec1210f commit 1709b7d
Show file tree
Hide file tree
Showing 5 changed files with 376 additions and 311 deletions.
28 changes: 28 additions & 0 deletions packages/react/src/__tests__/feature-app-container.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
FeatureAppContainer,
FeatureHubContextProvider
} from '..';
import {InternalFeatureAppContainer} from '../internal/internal-feature-app-container';
import {logger} from './logger';
import {TestErrorBoundary} from './test-error-boundary';

Expand Down Expand Up @@ -394,6 +395,19 @@ describe('FeatureAppContainer', () => {
expect(testRenderer.toJSON()).toBe('Custom Error UI');
});

it('renders what the children function returns if feature app definition is undefined', () => {
const testRenderer = renderWithFeatureHubContext(
<InternalFeatureAppContainer
featureAppId="testId"
children={() => 'loading UI'}
logger={logger}
featureAppManager={mockFeatureAppManager}
/>
);

expect(testRenderer.toJSON()).toBe('loading UI');
});

describe('when children throws an error', () => {
let childrenMockError: Error;

Expand Down Expand Up @@ -708,6 +722,20 @@ describe('FeatureAppContainer', () => {
});

describe('when no children function is passed', () => {
describe('when no feature app definition is passed', () => {
it('renders null', () => {
const testRenderer = renderWithFeatureHubContext(
<InternalFeatureAppContainer
featureAppId="testId"
logger={logger}
featureAppManager={mockFeatureAppManager}
/>
);

expect(testRenderer.getInstance()).toBeNull();
});
});

describe('when the promise resolves', () => {
it('renders the feature app', async () => {
const testRenderer = renderWithFeatureHubContext(
Expand Down
63 changes: 16 additions & 47 deletions packages/react/src/__tests__/feature-app-loader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ import {
} from '@feature-hub/core';
import * as React from 'react';
import TestRenderer from 'react-test-renderer';
import {
CustomFeatureAppRenderingParams,
FeatureAppContainer,
FeatureAppLoader
} from '..';
import {CustomFeatureAppRenderingParams, FeatureAppLoader} from '..';
import {FeatureHubContextProvider} from '../feature-hub-context';
import {InternalFeatureAppContainer} from '../internal/internal-feature-app-container';
import {logger} from './logger';
import {TestErrorBoundary} from './test-error-boundary';

interface MockAsyncSsrManager extends AsyncSsrManagerV1 {
scheduleRerender: ((promise: Promise<unknown>) => void) & jest.Mock;
}

jest.mock('../feature-app-container', () => ({
FeatureAppContainer: jest.fn(() => 'mocked FeatureAppContainer')
jest.mock('../internal/internal-feature-app-container', () => ({
InternalFeatureAppContainer: jest.fn(
() => 'mocked InternalFeatureAppContainer'
)
}));

describe('FeatureAppLoader', () => {
Expand Down Expand Up @@ -151,41 +150,6 @@ describe('FeatureAppLoader', () => {
expect(testRenderer.toJSON()).toBeNull();
});
});

describe('when given a children function', () => {
it('calls children with only loading=true', () => {
const children = jest.fn().mockReturnValue(null);

renderWithFeatureHubContext(
<FeatureAppLoader
featureAppId="testId"
src="example.js"
children={children}
/>
);

const expectedParameter: CustomFeatureAppRenderingParams = {
featureAppNode: undefined,
error: undefined,
loading: true
};

expect(children.mock.calls).toEqual([[expectedParameter]]);
});
it('renders what children function returns', () => {
const children = jest.fn(() => 'Custom Loading UI');

const testRenderer = renderWithFeatureHubContext(
<FeatureAppLoader
featureAppId="testId"
src="example.js"
children={children}
/>
);

expect(testRenderer.toJSON()).toBe('Custom Loading UI');
});
});
});

describe('without a css prop', () => {
Expand Down Expand Up @@ -328,7 +292,7 @@ describe('FeatureAppLoader', () => {
});
});

it('renders a FeatureAppContainer', () => {
it('renders an InternalFeatureAppContainer', () => {
const onError = jest.fn();
const renderError = jest.fn();
const beforeCreate = jest.fn();
Expand All @@ -349,7 +313,7 @@ describe('FeatureAppLoader', () => {
/>
);

expect(testRenderer.toJSON()).toBe('mocked FeatureAppContainer');
expect(testRenderer.toJSON()).toBe('mocked InternalFeatureAppContainer');

const expectedProps = {
baseUrl: '/base',
Expand All @@ -360,10 +324,15 @@ describe('FeatureAppLoader', () => {
featureAppId: 'testId',
onError,
renderError,
children
children,
featureAppManager: mockFeatureAppManager,
logger
};

expect(FeatureAppContainer).toHaveBeenCalledWith(expectedProps, {});
expect(InternalFeatureAppContainer).toHaveBeenCalledWith(
expectedProps,
{}
);
});

it('does not schedule a rerender on the Async SSR Manager', () => {
Expand Down Expand Up @@ -814,7 +783,7 @@ describe('FeatureAppLoader', () => {

await mockAsyncFeatureAppDefinition.promise;

expect(testRenderer.toJSON()).toBe('mocked FeatureAppContainer');
expect(testRenderer.toJSON()).toBe('mocked InternalFeatureAppContainer');
});

it('does not schedule a rerender on the Async SSR Manager', () => {
Expand Down
Loading

0 comments on commit 1709b7d

Please sign in to comment.