Skip to content

Commit

Permalink
Merge 4713a2d into e96fca2
Browse files Browse the repository at this point in the history
  • Loading branch information
setchy committed May 17, 2024
2 parents e96fca2 + 4713a2d commit 7ceeb04
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 36 deletions.
19 changes: 18 additions & 1 deletion src/routes/LoginEnterprise.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import * as TestRenderer from 'react-test-renderer';
const { ipcRenderer } = require('electron');
import { shell } from 'electron';
import { mockedEnterpriseAccounts } from '../__mocks__/mockedData';
import { AppContext } from '../context/App';
import type { AuthState } from '../types';
Expand All @@ -14,6 +15,8 @@ jest.mock('react-router-dom', () => ({
}));

describe('routes/LoginEnterprise.tsx', () => {
const openExternalMock = jest.spyOn(shell, 'openExternal');

const mockAccounts: AuthState = {
enterpriseAccounts: [],
user: null,
Expand Down Expand Up @@ -123,10 +126,24 @@ describe('routes/LoginEnterprise.tsx', () => {
target: { value: 'abc' },
});

fireEvent.submit(screen.getByTitle('Login Button'));
fireEvent.submit(screen.getByTitle('Login'));

expect(screen.getByText('Invalid hostname.')).toBeTruthy();
expect(screen.getByText('Invalid client id.')).toBeTruthy();
expect(screen.getByText('Invalid client secret.')).toBeTruthy();
});

it('should open help docs in the browser', async () => {
render(
<AppContext.Provider value={{ accounts: mockAccounts }}>
<MemoryRouter>
<LoginEnterpriseRoute />
</MemoryRouter>
</AppContext.Provider>,
);

fireEvent.click(screen.getByLabelText('GitHub Docs'));

expect(openExternalMock).toHaveBeenCalledTimes(1);
});
});
43 changes: 34 additions & 9 deletions src/routes/LoginEnterprise.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const ipcRenderer = require('electron').ipcRenderer;

import { ArrowLeftIcon } from '@primer/octicons-react';
import { ArrowLeftIcon, BookIcon, SignInIcon } from '@primer/octicons-react';

import { type FC, useCallback, useContext, useEffect } from 'react';
import { Form, type FormRenderProps } from 'react-final-form';
Expand All @@ -9,6 +9,10 @@ import { useNavigate } from 'react-router-dom';
import { FieldInput } from '../components/fields/FieldInput';
import { AppContext } from '../context/App';
import type { AuthOptions } from '../types';
import { openExternalLink } from '../utils/comms';

const GITHUB_DOCS_URL =
'https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app';

interface IValues {
hostname?: string;
Expand Down Expand Up @@ -65,9 +69,16 @@ export const LoginEnterpriseRoute: FC = () => {
}
}, [enterpriseAccounts]);

const openLink = useCallback((url: string) => {
openExternalLink(url);
}, []);

const renderForm = (formProps: FormRenderProps) => {
const { handleSubmit, submitting, pristine } = formProps;

const buttonClasses =
'rounded bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none cursor-pointer';

return (
<form onSubmit={handleSubmit}>
<FieldInput
Expand All @@ -84,14 +95,28 @@ export const LoginEnterpriseRoute: FC = () => {
placeholder="ABC123DEF456"
/>

<button
className="float-right px-4 py-2 my-4 bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none"
title="Login Button"
disabled={submitting || pristine}
type="submit"
>
Login
</button>
<div className="flex justify-between items-center">
<div className="text-xs italic hover:text-blue-500 justify-center items-center">
<button
type="button"
aria-label="GitHub Docs"
className={`px-2 py-1 text-xs ${buttonClasses}`}
onClick={() => openLink(GITHUB_DOCS_URL)}
>
<BookIcon size={12} /> Docs
</button>
</div>
<div className="justify-center items-center">
<button
className={`float-right px-4 py-2 my-4 ${buttonClasses}`}
title="Login"
disabled={submitting || pristine}
type="submit"
>
<SignInIcon size={14} /> Login
</button>
</div>
</div>
</form>
);
};
Expand Down
20 changes: 17 additions & 3 deletions src/routes/LoginWithToken.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('routes/LoginWithToken.tsx', () => {
target: { value: 'github.com' },
});

fireEvent.submit(screen.getByTitle('Submit Button'));
fireEvent.submit(screen.getByTitle('Login'));

await waitFor(() => expect(mockValidateToken).toHaveBeenCalledTimes(1));

Expand All @@ -130,7 +130,7 @@ describe('routes/LoginWithToken.tsx', () => {
fireEvent.change(screen.getByLabelText('Hostname'), {
target: { value: 'github.com' },
});
fireEvent.submit(screen.getByTitle('Submit Button'));
fireEvent.submit(screen.getByTitle('Login'));
});

await waitFor(() => expect(mockValidateToken).toHaveBeenCalledTimes(1));
Expand All @@ -153,9 +153,23 @@ describe('routes/LoginWithToken.tsx', () => {
target: { value: '123' },
});

fireEvent.submit(screen.getByTitle('Submit Button'));
fireEvent.submit(screen.getByTitle('Login'));

expect(screen.getByText('Invalid hostname.')).toBeDefined();
expect(screen.getByText('Invalid token.')).toBeDefined();
});

it('should open help docs in the browser', async () => {
render(
<AppContext.Provider value={{ validateToken: mockValidateToken }}>
<MemoryRouter>
<LoginWithToken />
</MemoryRouter>
</AppContext.Provider>,
);

fireEvent.click(screen.getByLabelText('GitHub Docs'));

expect(openExternalMock).toHaveBeenCalledTimes(1);
});
});
35 changes: 26 additions & 9 deletions src/routes/LoginWithToken.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ArrowLeftIcon } from '@primer/octicons-react';
import { ArrowLeftIcon, BookIcon, SignInIcon } from '@primer/octicons-react';

import { type FC, useCallback, useContext, useState } from 'react';
import { Form, type FormRenderProps } from 'react-final-form';
Expand All @@ -12,6 +12,9 @@ import { Constants } from '../utils/constants';

import { format } from 'date-fns';

const GITHUB_DOCS_URL =
'https://docs.github.com/en/enterprise-server@3.13/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens';

interface IValues {
token?: string;
hostname?: string;
Expand Down Expand Up @@ -103,14 +106,28 @@ export const LoginWithToken: FC = () => {
</div>
)}

<button
className={`float-right px-4 py-2 my-4 ${buttonClasses}`}
title="Submit Button"
disabled={submitting || pristine}
type="submit"
>
Submit
</button>
<div className="flex justify-between items-center">
<div className="text-xs italic hover:text-blue-500 justify-center items-center">
<button
type="button"
aria-label="GitHub Docs"
className={`px-2 py-1 text-xs ${buttonClasses}`}
onClick={() => openLink(GITHUB_DOCS_URL)}
>
<BookIcon size={12} /> Docs
</button>
</div>
<div className="justify-center items-center">
<button
className={`float-right px-4 py-2 my-4 ${buttonClasses}`}
title="Login"
disabled={submitting || pristine}
type="submit"
>
<SignInIcon size={14} /> Login
</button>
</div>
</div>
</form>
);
};
Expand Down
76 changes: 69 additions & 7 deletions src/routes/__snapshots__/LoginEnterprise.test.tsx.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 69 additions & 7 deletions src/routes/__snapshots__/LoginWithToken.test.tsx.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ceeb04

Please sign in to comment.