diff --git a/ui/src/app/about/_components/GeneralInfoSection.tsx b/ui/src/app/about/_components/GeneralInfoSection.tsx new file mode 100644 index 00000000..ea78f0aa --- /dev/null +++ b/ui/src/app/about/_components/GeneralInfoSection.tsx @@ -0,0 +1,55 @@ +const GeneralInfoSection = () => { + const generalInfoItems = [ + { + question: 'How do I request a new grouping?', + answer: ( + + A request form is available. + + ) + }, + { + question: 'What is the Include members list?', + answer: 'A grouping\'s Include is the portion of the grouping membership that is manually updated. It may be empty.' + }, + { + question: 'Exactly what is a grouping?', + answer: ( + <> + + General information about groupings is available. + {' '} + A grouping's components include the Basis, Include, and Exclude lists. + + ) + }, + { + question: 'What is the Exclude members list?', + answer: 'A grouping\'s Exclude overrides automatic and manual membership by explicitly not including anyone listed here. It may be empty.' + }, + { + question: 'What is the Basis?', + answer: 'A grouping\'s Basis is the portion of the grouping membership that is automatically updated. It may be empty.' + } + ]; + + return ( +
+

GENERAL INFORMATION

+
+ {generalInfoItems.map((generalInfoItem, index) => ( +
+

{generalInfoItem.question}

+

{generalInfoItem.answer}

+
+ ))} +
+
+ ); +}; + +export default GeneralInfoSection; diff --git a/ui/src/app/about/_components/TechnicalInfoSection.tsx b/ui/src/app/about/_components/TechnicalInfoSection.tsx new file mode 100644 index 00000000..8bc68315 --- /dev/null +++ b/ui/src/app/about/_components/TechnicalInfoSection.tsx @@ -0,0 +1,47 @@ +const TechnicalInfoSection = () => { + const technicalInfoItems = [ + { name: 'React.js', url: 'https://react.dev/learn', description: '(Quickstart)' }, + { name: 'shadcn/ui', url: 'https://ui.shadcn.com/docs', description: '(Guide)' }, + { name: 'Jest', url: 'https://jestjs.io/docs/getting-started', description: '(Introduction)' }, + { name: 'Next.js', url: 'https://nextjs.org/docs', description: '(Introduction)' }, + { name: 'Tanstack Table', url: 'https://tanstack.com/table/v8/docs/introduction', description: '(Introduction)' }, + { name: 'React Testing Library', url: 'https://testing-library.com/', description: '(Documentation)' }, + { name: 'Typescript', url: 'https://www.typescriptlang.org/docs/', description: '(Guide)' }, + { name: 'Tanstack Query', url: 'https://tanstack.com/query/latest/docs/framework/react/overview', description: '(Guide)' }, + { name: '', url: '', description: ''}, + { name: 'Tailwind CSS', url: 'https://v2.tailwindcss.com/docs', description: '(Guide)' }, + { name: 'Iron Session', url: 'https://github.com/vvo/iron-session', description: '(GitHub)' } + ]; + + return ( +
+

TECHNICAL INFORMATION

+
+
+

Resources

+

Source code is available on GitHub +

+
+
+

Technologies

+
+ {technicalInfoItems.map((item, index) => ( +
+

+ {item.name}  + + {item.description} + +

+
+ ))} +
+
+
+
+ ); +}; + +export default TechnicalInfoSection; diff --git a/ui/src/app/about/_components/WhatHappensIfSection.tsx b/ui/src/app/about/_components/WhatHappensIfSection.tsx new file mode 100644 index 00000000..11c5c8f4 --- /dev/null +++ b/ui/src/app/about/_components/WhatHappensIfSection.tsx @@ -0,0 +1,34 @@ +const WhatHappensIfSection = () => { + const whatHappensIfItems = [ + { + question: 'I was an owner of just one grouping and someone (me or another owner) deleted my ownership while I was still logged in.', + answer: 'You will still see the Groupings menu option, but you will get an error message when you click on it. Next time you log in, the Groupings menu option will no longer appear, assuming that you don\'t reacquire the ownership of a grouping before then.' + }, + { + question: 'I was not an owner of any groupings and someone made me an owner while I was still logged in.', + answer: 'You will have to log out and then log back in again to see the Groupings menu option.' + }, + { + question: 'I was an admin and someone (me or another admin) deleted my admin role while I was still logged in.', + answer: 'You will still see the Admin menu option, but you will get an error message when you click on it. Next time you log in, the Admin menu option will no longer appear, assuming that you don\'t reacquire the Admin role before then.' + } + ]; + + return ( +
+
+

WHAT HAPPENS IF

+
+ {whatHappensIfItems.map((item, index) => ( +
+

Q: {item.question}

+

A: {item.answer}

+
+ ))} +
+
+
+ ); +}; + +export default WhatHappensIfSection; diff --git a/ui/src/app/about/page.tsx b/ui/src/app/about/page.tsx index 92d02ce0..a2ecbcc7 100644 --- a/ui/src/app/about/page.tsx +++ b/ui/src/app/about/page.tsx @@ -1,154 +1,14 @@ import UHGroupingsInfo from '@/components/UHGroupingsInfo'; +import GeneralInfoSection from '@/app/about/_components/GeneralInfoSection'; +import WhatHappensIfSection from '@/app/about/_components/WhatHappensIfSection'; +import TechnicalInfoSection from '@/app/about/_components/TechnicalInfoSection'; const About = () => (
- -
-

GENERAL INFO

-
-
-

How do I request a new grouping?

-

- A request form is available - . -

- -

Exactly what is a grouping?

-

- General information about - groupings is available. - A grouping's components include the Basis, Include, and Exclude lists.

- -

What is the Basis?

-

A grouping's Basis is the portion of the grouping membership that - is automatically updated. It may be empty.

-
-
-

What is the Include members list?

-

A grouping's Include is the portion of the grouping - membership that is - manually updated. - It may be empty.

-

What is the Exclude members list?

-

A grouping's Exclude overrides automatic - and manual membership by explicitly not including anyone listed here. It may be empty.

-
-
-
- -
-
-

WHAT HAPPENS IF

-
-
-

Q: I was an owner of just one grouping and - someone (me or another owner) deleted my ownership while I was still logged in.

-

A: You will still see the Groupings menu option, but you will get an error message when - you click on it. Next time you log in, the Groupings menu option will no longer appear, - assuming that you don't reacquire the ownership of a grouping before then.

-
-
-

Q: I was not an owner of any groupings and - someone made me an owner while I was still logged in.

-

A: You will have to log out and then log back in again to see the - Groupings menu option.

-
-
-

Q: I was an admin and someone - (me or another admin) deleted my admin role while I was still logged in.

-

A: You will still see the Admin menu option, but you will get an error - message when you click on it. Next time you log in, the Admin menu option will no longer - appear, assuming that you don't reacquire the Admin role before then.

-
-
-
-
-
-

TECHNICAL INFORMATION

-
-
-

Resources

-

Source code is available on GitHub -

-
- -
-

Technologies

-
-
-

React.js  - (Quickstart)

-

Next.js  - (Introduction)

-

Typescript  - (Guide) -

-

Tailwind CSS  - (Guide) -

-
-
-

shadcn/ui  - (Guide)

-

Tanstack Table  - (Introduction) -

-

Tanstack Query  - (Guide) -

-

Iron Session  - (GitHub) -

-
-
-

Jest  - (Introduction) -

-

React Testing Library  - (Documentation) -

-
-
-
-
-
+ + + +
); diff --git a/ui/tests/app/about/_components/GeneralInfoSection.test.tsx b/ui/tests/app/about/_components/GeneralInfoSection.test.tsx new file mode 100644 index 00000000..a35c186a --- /dev/null +++ b/ui/tests/app/about/_components/GeneralInfoSection.test.tsx @@ -0,0 +1,24 @@ +import { render, screen } from '@testing-library/react'; +import GeneralInfoSection from '@/app/about/_components/GeneralInfoSection'; + +describe('GeneralInfoSection', () => { + it('should render with question and answer', () => { + render(); + + expect(screen.getByText('How do I request a new grouping?')).toBeInTheDocument(); + expect(screen.getByText('A request form is available.')).toBeInTheDocument(); + + expect(screen.getByText('What is the Include members list?')).toBeInTheDocument(); + expect(screen.getByText('A grouping\'s Include is the portion of the grouping membership that is manually updated. It may be empty.')).toBeInTheDocument(); + + expect(screen.getByText('Exactly what is a grouping?')).toBeInTheDocument(); + expect(screen.getByText('General information about groupings is available.')).toBeInTheDocument(); + expect(screen.getByText('A grouping\'s components include the Basis, Include, and Exclude lists.')).toBeInTheDocument(); + + expect(screen.getByText('What is the Exclude members list?')).toBeInTheDocument(); + expect(screen.getByText('A grouping\'s Exclude overrides automatic and manual membership by explicitly not including anyone listed here. It may be empty.')).toBeInTheDocument(); + + expect(screen.getByText('What is the Basis?')).toBeInTheDocument(); + expect(screen.getByText('A grouping\'s Basis is the portion of the grouping membership that is automatically updated. It may be empty.')).toBeInTheDocument(); + }); +}); diff --git a/ui/tests/app/about/_components/TechnicalInfoSection.test.tsx b/ui/tests/app/about/_components/TechnicalInfoSection.test.tsx new file mode 100644 index 00000000..8eb0dcef --- /dev/null +++ b/ui/tests/app/about/_components/TechnicalInfoSection.test.tsx @@ -0,0 +1,51 @@ +import { render, screen } from '@testing-library/react'; +import TechnicalInfoSection from '@/app/about/_components/TechnicalInfoSection'; + +describe('TechnicalInfoSection', () => { + it('should render with name, url, and description', () => { + render(); + + const guideLinks = screen.getAllByText('(Guide)'); + const introductionLinks = screen.getAllByText('(Introduction)'); + + expect(screen.getByText('React.js')).toBeInTheDocument(); + expect(screen.getByText('(Quickstart)')).toBeInTheDocument(); + expect(screen.getByText('(Quickstart)')).toHaveAttribute('href', 'https://react.dev/learn'); + + expect(screen.getByText('shadcn/ui')).toBeInTheDocument(); + expect(guideLinks[0]).toBeInTheDocument(); + expect(guideLinks[0]).toHaveAttribute('href', 'https://ui.shadcn.com/docs'); + + expect(screen.getByText('Jest')).toBeInTheDocument(); + expect(introductionLinks[0]).toBeInTheDocument(); + expect(introductionLinks[0]).toHaveAttribute('href', 'https://jestjs.io/docs/getting-started'); + + expect(screen.getByText('Next.js')).toBeInTheDocument(); + expect(introductionLinks[1]).toBeInTheDocument(); + expect(introductionLinks[1]).toHaveAttribute('href', 'https://nextjs.org/docs'); + + expect(screen.getByText('Tanstack Table')).toBeInTheDocument(); + expect(introductionLinks[2]).toBeInTheDocument(); + expect(introductionLinks[2]).toHaveAttribute('href', 'https://tanstack.com/table/v8/docs/introduction'); + + expect(screen.getByText('React Testing Library')).toBeInTheDocument(); + expect(screen.getByText('(Documentation)')).toBeInTheDocument(); + expect(screen.getByText('(Documentation)')).toHaveAttribute('href', 'https://testing-library.com/'); + + expect(screen.getByText('Typescript')).toBeInTheDocument(); + expect(guideLinks[1]).toBeInTheDocument(); + expect(guideLinks[1]).toHaveAttribute('href', 'https://www.typescriptlang.org/docs/'); + + expect(screen.getByText('Tanstack Query')).toBeInTheDocument(); + expect(guideLinks[2]).toBeInTheDocument(); + expect(guideLinks[2]).toHaveAttribute('href', 'https://tanstack.com/query/latest/docs/framework/react/overview'); + + expect(screen.getByText('Tailwind CSS')).toBeInTheDocument(); + expect(guideLinks[3]).toBeInTheDocument(); + expect(guideLinks[3]).toHaveAttribute('href', 'https://v2.tailwindcss.com/docs'); + + expect(screen.getByText('Iron Session')).toBeInTheDocument(); + expect(screen.getByText('(GitHub)')).toBeInTheDocument(); + expect(screen.getByText('(GitHub)')).toHaveAttribute('href', 'https://github.com/vvo/iron-session'); + }); +}); diff --git a/ui/tests/app/about/_components/WhatHappensIfSection.test.tsx b/ui/tests/app/about/_components/WhatHappensIfSection.test.tsx new file mode 100644 index 00000000..6256a7b0 --- /dev/null +++ b/ui/tests/app/about/_components/WhatHappensIfSection.test.tsx @@ -0,0 +1,17 @@ +import { render, screen } from '@testing-library/react'; +import WhatHappensIfSection from '@/app/about/_components/WhatHappensIfSection'; + +describe('WhatHappensIfSection', () => { + it('should render with question and answer', () => { + render(); + + expect(screen.getByText('Q: I was an owner of just one grouping and someone (me or another owner) deleted my ownership while I was still logged in.')).toBeInTheDocument(); + expect(screen.getByText('A: You will still see the Groupings menu option, but you will get an error message when you click on it. Next time you log in, the Groupings menu option will no longer appear, assuming that you don\'t reacquire the ownership of a grouping before then.')).toBeInTheDocument(); + + expect(screen.getByText('Q: I was not an owner of any groupings and someone made me an owner while I was still logged in.')).toBeInTheDocument(); + expect(screen.getByText('A: You will have to log out and then log back in again to see the Groupings menu option.')).toBeInTheDocument(); + + expect(screen.getByText('Q: I was an admin and someone (me or another admin) deleted my admin role while I was still logged in.')).toBeInTheDocument(); + expect(screen.getByText('A: You will still see the Admin menu option, but you will get an error message when you click on it. Next time you log in, the Admin menu option will no longer appear, assuming that you don\'t reacquire the Admin role before then.')).toBeInTheDocument(); + }); +}); diff --git a/ui/tests/app/about/page.test.tsx b/ui/tests/app/about/page.test.tsx index 2d6a1af5..737166be 100644 --- a/ui/tests/app/about/page.test.tsx +++ b/ui/tests/app/about/page.test.tsx @@ -2,51 +2,10 @@ import { render, screen } from '@testing-library/react'; import About from '@/app/about/page'; describe('About', () => { - - it('should render the About page with the appropriate headers, images and links', () => { - render(); - expect(screen.getByRole('main')).toBeInTheDocument(); - - expect(screen.getByText('What is a UH Grouping?')).toBeInTheDocument(); - expect(screen.getByRole('img', {name: 'Cogs icon'})).toBeInTheDocument(); - expect(screen.getByRole('img', {name: 'Email icon'})).toBeInTheDocument(); - expect(screen.getByRole('img', {name: 'Watch icon'})).toBeInTheDocument(); - - expect(screen.getByText('GENERAL INFO')).toBeInTheDocument(); - expect(screen.getByRole('link', {name: 'A request form is available'})) - .toHaveAttribute('href', 'https://uhawaii.atlassian.net/wiki/spaces/UHIAM/pages/13402308/UH+Groupings+Request+Form'); - expect(screen.getByRole('link', {name: 'General information about groupings is available'})) - .toHaveAttribute('href', 'https://uhawaii.atlassian.net/wiki/spaces/UHIAM/pages/13403213/UH+Groupings'); - + it('should render the headers GENERAL INFORMATION, WHAT HAPPENS IF, and TECHNICAL INFORMATION', () => { + render(); + expect(screen.getByText('GENERAL INFORMATION')).toBeInTheDocument(); expect(screen.getByText('WHAT HAPPENS IF')).toBeInTheDocument(); - expect(screen.getByText('TECHNICAL INFORMATION')).toBeInTheDocument(); - expect(screen.getByText('Resources')).toBeInTheDocument(); - expect(screen.getByRole('link', {name: 'GitHub'})) - .toHaveAttribute('href', 'https://github.com/uhawaii-system-its-ti-iam/uh-groupings'); - - expect(screen.getByText('Technologies')).toBeInTheDocument(); - expect(screen.getByRole('link', {name: 'Link to React.js Quickstart'})) - .toHaveAttribute('href', 'https://react.dev/learn'); - expect(screen.getByRole('link', {name: 'Link to Next.js Introduction'})) - .toHaveAttribute('href', 'https://nextjs.org/docs'); - expect(screen.getByRole('link', {name: 'Link to Typescript Guide'})) - .toHaveAttribute('href', 'https://www.typescriptlang.org/docs/'); - expect(screen.getByRole('link', {name: 'Link to Tailwind CSS Guide'})) - .toHaveAttribute('href', 'https://v2.tailwindcss.com/docs'); - - expect(screen.getByRole('link', {name: 'Link to shadcn/ui Guide'})) - .toHaveAttribute('href', 'https://ui.shadcn.com/docs'); - expect(screen.getByRole('link', {name: 'Link to Tanstack Table Introduction'})) - .toHaveAttribute('href', 'https://tanstack.com/table/v8/docs/introduction'); - expect(screen.getByRole('link', {name: 'Link to Tanstack Query Guide'})) - .toHaveAttribute('href', 'https://tanstack.com/query/latest/docs/framework/react/overview'); - - expect(screen.getByRole('link', {name: 'Link to Iron Session GitHub'})) - .toHaveAttribute('href', 'https://github.com/vvo/iron-session'); - expect(screen.getByRole('link', {name: 'Link to Jest Introduction'})) - .toHaveAttribute('href', 'https://jestjs.io/docs/getting-started'); - expect(screen.getByRole('link', {name: 'Link to React Testing Library Documentation'})) - .toHaveAttribute('href', 'https://testing-library.com/'); }); });