Skip to content

Commit

Permalink
Merge pull request #1644 from notaphplover/refactor/add-use-url-like-…
Browse files Browse the repository at this point in the history
…location

Add useUrlLikeLocation
  • Loading branch information
notaphplover authored Sep 16, 2024
2 parents 63459b5 + e3d2fbb commit acf7b9c
Show file tree
Hide file tree
Showing 9 changed files with 842 additions and 686 deletions.
781 changes: 394 additions & 387 deletions packages/frontend/web-ui/src/auth/hooks/useRegisterConfirm.spec.ts

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions packages/frontend/web-ui/src/auth/hooks/useRegisterConfirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { selectAuthenticatedAuth } from '../../app/store/features/authSlice';
import { AuthenticatedAuthState } from '../../app/store/helpers/models/AuthState';
import { useAppDispatch, useAppSelector } from '../../app/store/hooks';
import { createAuthByToken } from '../../app/store/thunk/createAuthByToken';
import { useUrlLikeLocation } from '../../common/hooks/useUrlLikeLocation';
import { buildSerializableResponse } from '../../common/http/helpers/buildSerializableResponse';
import { OK, UNAUTHORIZED } from '../../common/http/helpers/httpCodes';
import { RegisterConfirmResponse } from '../../common/http/models/RegisterConfirmResponse';
import { RegisterConfirmSerializedResponse } from '../../common/http/models/RegisterConfirmSerializedResponse';
import { httpClient } from '../../common/http/services/httpClient';
import { UrlLikeLocation } from '../../common/models/UrlLikeLocation';
import { RegisterConfirmStatus } from '../models/RegisterConfirmStatus';
import { UseRegisterConfirmResult } from '../models/UseRegisterConfirmResult';

Expand All @@ -22,8 +24,8 @@ export const useRegisterConfirm = (): UseRegisterConfirmResult => {
RegisterConfirmStatus.idle,
);

const url: URL = new URL(window.location.href);
const codeParam: string | null = url.searchParams.get(CODE_QUERY_PARAM);
const location: UrlLikeLocation = useUrlLikeLocation();
const codeParam: string | null = location.searchParams.get(CODE_QUERY_PARAM);

const dispatch = useAppDispatch();
const auth: AuthenticatedAuthState | null = useAppSelector(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { beforeAll, describe, expect, it, jest } from '@jest/globals';

jest.mock('react-router-dom');

jest.mock('../models/UrlLikeLocation');

import { Location, useLocation } from 'react-router-dom';

import { UrlLikeLocation } from '../models/UrlLikeLocation';
import { Writable } from '../models/Writable';
import { useUrlLikeLocation } from './useUrlLikeLocation';

describe(UrlLikeLocation.name, () => {
describe('when called', () => {
let locationFixture: Location;
let pathNameFixture: string;

let result: unknown;

beforeAll(() => {
locationFixture = Symbol() as unknown as Location;
pathNameFixture = 'pathname-fixture';

(useLocation as jest.Mock<typeof useLocation>).mockReturnValueOnce(
locationFixture,
);

(
UrlLikeLocation as unknown as jest.Mock<
(this: Writable<UrlLikeLocation>) => void
>
).mockImplementationOnce(function (this: Writable<UrlLikeLocation>) {
this.pathname = pathNameFixture;
});

result = useUrlLikeLocation();
});

it('should call useLocation', () => {
expect(useLocation).toHaveBeenCalledTimes(1);
expect(useLocation).toHaveBeenCalledWith();
});

it('should call UrlLikeLocation()', () => {
expect(UrlLikeLocation).toHaveBeenCalledTimes(1);
expect(UrlLikeLocation).toHaveBeenCalledWith(locationFixture);
});

it('should return expected result', () => {
const expectedProperties: Partial<UrlLikeLocation> = {
pathname: pathNameFixture,
};

expect(result).toStrictEqual(expect.objectContaining(expectedProperties));
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useLocation } from 'react-router-dom';

import { UrlLikeLocation } from '../models/UrlLikeLocation';

export const useUrlLikeLocation = (): UrlLikeLocation => {
return new UrlLikeLocation(useLocation());
};
81 changes: 81 additions & 0 deletions packages/frontend/web-ui/src/common/models/UrlLikeLocation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { beforeAll, describe, expect, it } from '@jest/globals';

import { Location } from 'react-router-dom';

import { UrlLikeLocation } from './UrlLikeLocation';

describe(UrlLikeLocation.name, () => {
describe.each<
[string, Location, (locationFixture: Location) => Partial<UrlLikeLocation>]
>([
[
'with empty query',
{
hash: '',
key: 'sample-key',
pathname: '/',
search: '',
state: undefined,
},
(locationFixture: Location): Partial<UrlLikeLocation> => ({
pathname: locationFixture.pathname,
searchParams: new URLSearchParams(),
}),
],
[
'with query with single value',
{
hash: '',
key: 'sample-key',
pathname: '/foo',
search: '?bar=baz',
state: undefined,
},
(locationFixture: Location): Partial<UrlLikeLocation> => ({
pathname: locationFixture.pathname,
searchParams: new URLSearchParams([['bar', 'baz']]),
}),
],
[
'with query with multiple values',
{
hash: '',
key: 'sample-key',
pathname: '/foo',
search: '?bar=baz&bar=baz2',
state: undefined,
},
(locationFixture: Location): Partial<UrlLikeLocation> => ({
pathname: locationFixture.pathname,
searchParams: new URLSearchParams([
['bar', 'baz'],
['bar', 'baz2'],
]),
}),
],
])(
'having a Location %s',
(
_: string,
locationFixture: Location,
buildExpectedUrlLikeLocation: (
locationFixture: Location,
) => Partial<UrlLikeLocation>,
) => {
describe('when called', () => {
let result: UrlLikeLocation;

beforeAll(() => {
result = new UrlLikeLocation(locationFixture);
});

it('should return expected UrlLikeLocation', () => {
const expected: Partial<UrlLikeLocation> =
buildExpectedUrlLikeLocation(locationFixture);

expect(result).toStrictEqual(expect.objectContaining(expected));
});
});
},
);
});
19 changes: 19 additions & 0 deletions packages/frontend/web-ui/src/common/models/UrlLikeLocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Location } from 'react-router-dom';

export class UrlLikeLocation {
readonly #pathname: string;
readonly #searchParams: URLSearchParams;

constructor(location: Location) {
this.#pathname = location.pathname;
this.#searchParams = new URLSearchParams(location.search);
}

public get pathname(): string {
return this.#pathname;
}

public get searchParams(): URLSearchParams {
return this.#searchParams;
}
}
3 changes: 3 additions & 0 deletions packages/frontend/web-ui/src/common/models/Writable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type Writable<T> = {
-readonly [TKey in keyof T]: T[TKey];
};
Loading

0 comments on commit acf7b9c

Please sign in to comment.