Skip to content

Commit

Permalink
Merge pull request #946 from equinor/feat/api-response-component
Browse files Browse the repository at this point in the history
✨ wrap status components into ApiResponseError
  • Loading branch information
Brynjulf authored Jan 22, 2025
2 parents 51d1e67 + 88c4278 commit cc69dbf
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/organisms/Status/collections/ApiResponseError.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { MemoryRouter } from 'react-router-dom';

import { Meta, StoryObj } from '@storybook/react';

import { ApiResponseError } from './ApiResponseError';

import styled from 'styled-components';

const Wrapper = styled.div`
height: 50vh;
`;

const meta: Meta<typeof ApiResponseError> = {
title: 'Organisms/Status/Collections/ApiResponseError',
component: ApiResponseError,
parameters: {
layout: 'centered',
design: {
type: 'figma',
url: '',
},
},
argTypes: {
statusCode: {
control: 'number',
description: 'Eg. 400, 401, 403, 404, 500',
},
},
args: {
statusCode: 400,
},
decorators: (Story) => (
<Wrapper>
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
</Wrapper>
),
};

export default meta;
type Story = StoryObj<typeof ApiResponseError>;

export const Default: Story = {
args: {},
};
80 changes: 80 additions & 0 deletions src/organisms/Status/collections/ApiResponseError.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ReactNode } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';

import { screen } from '@testing-library/dom';
import { render } from '@testing-library/react';

import { ApiResponseError } from './ApiResponseError';

describe('ApiResponseError', () => {
const renderWithRouter = (children: ReactNode) =>
render(<Router>{children}</Router>);

it('renders BadRequest for statusCode 400', () => {
renderWithRouter(<ApiResponseError statusCode={400} />);

expect(
screen.getByRole('heading', {
name: /bad request/i,
})
).toBeInTheDocument();
});

it('renders MissingAccessToApp for statusCode 401', () => {
renderWithRouter(<ApiResponseError statusCode={401} />);
expect(
screen.getByRole('heading', {
name: /you don't have access to/i,
})
).toBeInTheDocument();
});

it('renders MissingPermissions for statusCode 403', () => {
renderWithRouter(<ApiResponseError statusCode={403} />);
expect(
screen.getByRole('heading', {
name: /it looks like you don't have permission to access this page\./i,
})
).toBeInTheDocument();
});

it('renders PageNotFound for statusCode 404', () => {
renderWithRouter(<ApiResponseError statusCode={404} />);
expect(
screen.getByRole('heading', {
name: /page not found/i,
})
).toBeInTheDocument();
});

it('renders ServerError for statusCode 500', () => {
renderWithRouter(<ApiResponseError statusCode={500} />);
expect(
screen.getByRole('heading', {
name: /something is wrong on our servers/i,
})
).toBeInTheDocument();
});

it('renders GenericError for unknown statusCode', () => {
renderWithRouter(<ApiResponseError statusCode={999} />);
expect(
screen.getByRole('heading', {
name: /something went wrong/i,
})
).toBeInTheDocument();
});

it('renders GenericError when statusCode is undefined', () => {
renderWithRouter(<ApiResponseError />);
expect(
screen.getByRole('heading', {
name: /something went wrong/i,
})
).toBeInTheDocument();
});
it('renders nothing when statusCode is less than 400', () => {
renderWithRouter(<ApiResponseError statusCode={200} />);
expect(screen.queryByText(/something went wrong/i)).not.toBeInTheDocument();
});
});
48 changes: 48 additions & 0 deletions src/organisms/Status/collections/ApiResponseError.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { FC } from 'react';

import {
BadRequest,
GenericError,
MissingAccessToApp,
MissingPermissions,
PageNotFound,
ServerError,
} from './';

interface ServerErrorProps {
statusCode?: number;
}

/**
* Will determine what kind of error message to show, for non-error status code will return nothing
* @param statusCode - optional, will return generic error by default
* @returns error component corresponding to http status code
*/
const ApiResponseError: FC<ServerErrorProps> = ({ statusCode }) => {
if (statusCode! < 400) {
return null;
}
if (statusCode === 400) {
return <BadRequest />;
}

if (statusCode === 401) {
return <MissingAccessToApp />;
}

if (statusCode === 403) {
return <MissingPermissions />;
}

if (statusCode === 404) {
return <PageNotFound />;
}

if (statusCode === 500) {
return <ServerError />;
}

return <GenericError />;
};

export { ApiResponseError };
1 change: 1 addition & 0 deletions src/organisms/Status/collections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { MissingAccessToApp } from './MissingAccessToApp';
export { MissingPermissions } from './MissingPermissions';
export { PageNotFound } from './PageNotFound';
export { ServerError } from './ServerError';
export { ApiResponseError } from './ApiResponseError';

0 comments on commit cc69dbf

Please sign in to comment.