Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Static Banner #799

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ module.exports = withPlugins([
HS_REPORTS_SUGGESTIONS: process.env.HS_REPORTS_SUGGESTIONS,
HS_TASKS_SUGGESTIONS: process.env.HS_TASKS_SUGGESTIONS,
ALERT_MESSAGE: process.env.ALERT_MESSAGE,
SHOW_BANNER: process.env.SHOW_BANNER,
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
},
experimental: {
modularizeImports: {
Expand Down
46 changes: 46 additions & 0 deletions src/components/Dashboard/Dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,49 @@ describe('Dashboard', () => {
).toEqual('Committed $700');
});
});

describe('Static Banner', () => {
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules(); // Most important - it clears the cache
process.env = { ...OLD_ENV }; // Make a copy
beforeTestResizeObserver();
});

afterAll(() => {
process.env = OLD_ENV; // Restore old environment
afterTestResizeObserver();
});

it('should show the banner if the env variable is true', () => {
process.env.SHOW_BANNER = 'true';

const { getByTestId } = render(
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
<ThemeProvider theme={theme}>
<SnackbarProvider>
<MockedProvider mocks={GetThisWeekDefaultMocks()} addTypename={false}>
<Dashboard accountListId="abc" data={data} />
</MockedProvider>
</SnackbarProvider>
</ThemeProvider>,
);

expect(getByTestId('staticBanner')).toBeInTheDocument();
});

it('should NOT show the banner if the env variable is false', () => {
process.env.SHOW_BANNER = 'false';

const { queryByTestId } = render(
<ThemeProvider theme={theme}>
<SnackbarProvider>
<MockedProvider mocks={GetThisWeekDefaultMocks()} addTypename={false}>
<Dashboard accountListId="abc" data={data} />
</MockedProvider>
</SnackbarProvider>
</ThemeProvider>,
);

expect(queryByTestId('staticBanner')).not.toBeInTheDocument();
});
});
7 changes: 7 additions & 0 deletions src/components/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import MonthlyGoal from './MonthlyGoal/MonthlyGoal';
import Balance from './Balance';
import DonationHistories from './DonationHistories';
import ThisWeek from './ThisWeek';
import { StaticBanner } from '../Shared/staticBanner/StaticBanner';

interface Props {
data: GetDashboardQuery;
Expand All @@ -26,6 +27,7 @@ const variants = {
},
},
};
const shouldShowBanner = process.env.SHOW_BANNER === 'true';

const Dashboard = ({ data, accountListId }: Props): ReactElement => {
return (
Expand All @@ -39,6 +41,11 @@ const Dashboard = ({ data, accountListId }: Props): ReactElement => {
exit="exit"
variants={variants}
>
{shouldShowBanner && (
<div data-testid="staticBanner">
<StaticBanner />
</div>
)}
<Grid container spacing={3} alignItems="stretch">
<Grid xs={12} sm={8} item>
<MonthlyGoal
Expand Down
81 changes: 81 additions & 0 deletions src/components/Shared/staticBanner/StaticBanner.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { render, waitFor } from '@testing-library/react';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { GetUsersOrganizationsQuery } from './getOrganizationType.generated';
import { StaticBanner } from './StaticBanner';

const mockResponseNonCru = {
GetUsersOrganizations: {
userOrganizationAccounts: [
{
__typename: 'OrganizationAccount',
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
organization: {
__typename: 'Organization',
organizationType: 'Non-Cru',
},
},
{
__typename: 'OrganizationAccount',
organization: {
__typename: 'Organization',
organizationType: 'Non-Cru',
},
},
],
},
};
const mockResponseCru = {
GetUsersOrganizations: {
userOrganizationAccounts: [
{
__typename: 'OrganizationAccount',
organization: {
__typename: 'Organization',
organizationType: 'Cru',
},
},
{
__typename: 'OrganizationAccount',
organization: {
__typename: 'Organization',
organizationType: 'Non-Cru',
},
},
],
},
};

test('static banner displays for user in Non-Cru org', async () => {
const { queryByTestId } = render(
<GqlMockedProvider<{
GetUsersOrganizations: GetUsersOrganizationsQuery;
}>
mocks={{
mockResponseNonCru,
}}
>
<StaticBanner />
</GqlMockedProvider>,
);

await waitFor(() =>
expect(queryByTestId('nonCruOrgReminder')).toBeInTheDocument(),
);
});

test('static banner does not display for user in a Cru org', async () => {
const { queryByTestId } = render(
<GqlMockedProvider<{
GetUsersOrganizations: GetUsersOrganizationsQuery;
}>
mocks={{
mockResponseCru,
}}
>
<StaticBanner />
</GqlMockedProvider>,
);

await waitFor(() =>
expect(queryByTestId('nonCruOrgReminder')).not.toBeInTheDocument(),
);
});
41 changes: 41 additions & 0 deletions src/components/Shared/staticBanner/StaticBanner.tsx
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import Alert from '@mui/material/Alert';
import { Link } from '@mui/material';
import { useGetUsersOrganizationsQuery } from './getOrganizationType.generated';

interface StaticBannerProps {
severity?: 'error' | 'info' | 'success' | 'warning';
}

export const StaticBanner: React.FC<StaticBannerProps> = ({
severity = 'warning',
}) => {
const { t } = useTranslation();

const { data, loading } = useGetUsersOrganizationsQuery();
const nonCruUser = useMemo(() => {
const foundCruOrg = data?.userOrganizationAccounts.find(
(org) =>
org.organization.organizationType === 'Cru-International' ||
org.organization.organizationType === 'Cru',
);
return !foundCruOrg;
}, [data]);

return !loading && nonCruUser ? (
<Alert severity={severity}>
{t(
`Due to data privacy regulations and costs, Cru will no longer be able to host MPDX data for non-Cru/non-CCCI ministries. This means that MPDX will no longer be available for use outside of Cru/CCCI. Your data in MPDX will be deleted if you don't export it from MPDX by January 31, 2024 or let us know why you might need an extension. For more information and to take action, `,
)}
<Link
data-testid="nonCruOrgReminder"
href="https://docs.google.com/document/d/18TnQGmshg71l3J9Gd-4ltjIjhK2PLtuG_Vc94bt6xzE/"
target="_blank"
rel="noreferrer"
>
{t('read this communication.')}
</Link>
</Alert>
) : null;
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
query GetUsersOrganizations {
userOrganizationAccounts {
organization {
organizationType
}
}
}