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

Make org picker functional #530

Merged
merged 4 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions __tests__/components/OrgPicker/OrgPicker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@
*/
import { describe, expect, it } from '@jest/globals';
import { render, screen } from '@testing-library/react';
// eslint-disable-next-line no-unused-vars
import { usePathname } from 'next/navigation';
import userEvent from '@testing-library/user-event';
import { OrgPicker } from '@/components/OrgPicker/OrgPicker';

/* global jest */
/* eslint no-undef: "off" */
jest.mock('next/navigation', () => ({
usePathname: jest.fn(() => '/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd'),
}));
/* eslint no-undef: "error" */

describe('<OrgPicker />', () => {
const mockOrgs = [
{ name: 'foobar org 1', guid: 'baz' },
{ name: 'foobar org 2', guid: 'baz2' },
];
describe('on initial load', () => {
it('content is collapsed', () => {
// act
render(<OrgPicker />);
render(<OrgPicker orgs={mockOrgs} currentOrgId="baz" />);
// assert
const content = screen.queryByText('View all organizations');
expect(content).not.toBeInTheDocument();
Expand All @@ -21,7 +34,7 @@ describe('<OrgPicker />', () => {
it('content expands', async () => {
// setup
const user = userEvent.setup();
render(<OrgPicker />);
render(<OrgPicker orgs={mockOrgs} currentOrgId="baz" />);
// act
const button = screen.getByRole('button', { expanded: false });
await user.click(button);
Expand All @@ -30,4 +43,43 @@ describe('<OrgPicker />', () => {
expect(content).toBeInTheDocument();
});
});

describe('when only one org', () => {
it('only shows org name instead of the dropdown', () => {
// setup
render(<OrgPicker orgs={mockOrgs.slice(0, 1)} currentOrgId="baz" />);
// act
const orgName = screen.getByText(/foobar org 1/);
const button = screen.queryByRole('button');
// assert
expect(orgName).toBeInTheDocument();
expect(button).not.toBeInTheDocument();
});
});

describe('when no orgs at all', () => {
it('shows nothing', () => {
// setup
render(<OrgPicker orgs={[]} currentOrgId="baz" />);
// act
const orgName = screen.queryByText(/foobar org 1/);
const button = screen.queryByRole('button');
// assert
expect(orgName).not.toBeInTheDocument();
expect(button).not.toBeInTheDocument();
});
});

describe('when no current org', () => {
it('shows nothing', () => {
// setup
render(<OrgPicker orgs={mockOrgs} />);
// act
const orgName = screen.queryByText(/foobar org 1/);
const button = screen.queryByRole('button');
// assert
expect(orgName).not.toBeInTheDocument();
expect(button).not.toBeInTheDocument();
});
});
});
52 changes: 52 additions & 0 deletions __tests__/helpers/text.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
emailIsValid,
underscoreToText,
pluralize,
newOrgPathname,
} from '@/helpers/text';

describe('text helpers', () => {
Expand Down Expand Up @@ -47,4 +48,55 @@ describe('text helpers', () => {
expect(pluralize('role', -1)).toBe('role');
});
});

describe('newOrgPathname', () => {
const newGUID = 'foobar';

describe('when last GUID starts with an a-z character', () => {
it('removes last GUID from pathname', () => {
const path =
'/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd/users/add/b70bd8ff-ed0e-4d11-95c4-cf765202cebd'; // last GUID starts with an a-z character
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar/users/add/');
});
});

describe('last GUID starts with an a-z character, but then keeps going with more path sections', () => {
it('removes last GUID and beyond from pathname', () => {
const path =
'/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd/users/add/b70bd8ff-ed0e-4d11-95c4-cf765202cebd/keeps-going'; // last GUID starts with an a-z character, but then keeps going with more path sections
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar/users/add/');
});
});

describe('when last GUID starts with a digit', () => {
it('removes last GUID from pathname', () => {
const path =
'/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd/users/add/470bd8ff-ed0e-4d11-95c4-cf765202cebd/'; // next GUID starts with a digit
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar/users/add/');
});
});

describe('when no other GUID but the org GUID', () => {
it('just replaces the org guid with new guid', () => {
const path = '/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd'; // without trailing slash
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar');
});

it('just replaces the org guid with new guid', () => {
const path = '/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd/'; // with trailing slash
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar/');
});

it('just replaces the org guid with new guid', () => {
const path = '/orgs/470bd8ff-ed0e-4d11-95c4-cf765202cebd/users/add'; // with trailing slash
const result = newOrgPathname(path, newGUID);
expect(result).toEqual('/orgs/foobar/users/add');
});
});
});
});
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
16 changes: 7 additions & 9 deletions src/app/orgs/[orgId]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import Link from 'next/link';
import { LayoutHeader } from '@/components/LayoutHeader';
import { getOrg } from '@/controllers/controllers';
import { OrgPicker } from '@/components/OrgPicker/OrgPicker';
import { getOrgs } from '@/api/cf/cloudfoundry';

export default async function OrgLayout({
children,
Expand All @@ -10,15 +9,14 @@ export default async function OrgLayout({
children: React.ReactNode;
params: { orgId: string };
}) {
const { payload, meta } = await getOrg(params.orgId);
const orgsRes = await getOrgs();
const orgResJson = await orgsRes.json();
const orgs = orgResJson.resources;

return (
<>
<LayoutHeader>
{meta.status === 'success' ? payload.name : 'Org name not found'}
</LayoutHeader>
<div className="display-block padding-bottom-2">
<Link href="/orgs">Back to all organizations</Link>
<div className="display-flex flex-column flex-align-end width-full desktop:height-10 margin-top-3">
<OrgPicker orgs={orgs} currentOrgId={params.orgId} />
</div>
{children}
</>
Expand Down
6 changes: 0 additions & 6 deletions src/app/prototype/design-guide/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Button } from '@/components/uswds/Button';
import { Banner } from '@/components/uswds/Banner';
import Checkbox from '@/components/uswds/Checkbox';
import { useState } from 'react';
import { OrgPicker } from '@/components/OrgPicker/OrgPicker';

export default function DesignGuidePage() {
const initialCheckboxes = {
Expand Down Expand Up @@ -37,11 +36,6 @@ export default function DesignGuidePage() {
<h2>USA banner</h2>
<Banner />

<section className="position-relative padding-y-6">
<h2>Org Picker</h2>
<OrgPicker single={false} />
</section>

<h2>Headers in prose:</h2>

<div className="usa-prose">
Expand Down
7 changes: 7 additions & 0 deletions src/assets/stylesheets/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@
// 3. Load any custom SASS

/* Custom utilities classes */

// Flex

.flex-shrink-0 {
flex-shrink: 0;
}

// text styling
.text-capitalize {
text-transform: capitalize;
Expand Down
Loading