diff --git a/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.test.ts b/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.test.ts new file mode 100644 index 0000000..e2624e9 --- /dev/null +++ b/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.test.ts @@ -0,0 +1,101 @@ +import { addQuery, getHashPart, replaceKeyValue } from './minsoo-web' + +describe('getHashPart', () => { + it('case 1', () => { + expect(getHashPart('minsoo#foo')).toEqual({ + nonHash: 'minsoo', + hash: '#foo', + }) + }) + + it('case 2', () => { + expect(getHashPart('http://www.minsoo#foo')).toEqual({ + nonHash: 'http://www.minsoo', + hash: '#foo', + }) + }) + + it('case 3', () => { + expect(getHashPart('http://www.minsoo')).toEqual({ + nonHash: 'http://www.minsoo', + hash: '', + }) + }) + + it('case 4: 일반적이진 않지만, 의도치 않게 해시가 여러개 들어가있는 경우', () => { + expect(getHashPart('http://www.minsoo#foo#minsoo')).toEqual({ + nonHash: 'http://www.minsoo', + hash: '#foo#minsoo', + }) + }) +}) + +describe('replaceKeyValue', () => { + it('case 1', () => { + expect(replaceKeyValue('minsoo?key=foo', 'key', 'bar')).toBe( + 'minsoo?key=bar', + ) + }) + + it('case 2', () => { + expect(replaceKeyValue('minsoo?foo=foo', 'key', 'bar')).toBe( + 'minsoo?foo=foo', + ) + }) + + it('case 3', () => { + expect(replaceKeyValue('minsoo?key=foo&key=baz', 'key', 'bar')).toBe( + 'minsoo?key=bar&key=bar', + ) + }) +}) + +describe('addQuery', () => { + test('case 0: URL 형식이 굳이 아니여도 동작', () => { + expect(addQuery('www.linkedin.com/?name=elon#top', 'name', 'musk')).toBe( + 'www.linkedin.com/?name=musk#top', + ) + }) + + test('case 1', () => { + expect(addQuery('https://www.linkedin.com/', 'key', 'value')).toBe( + 'https://www.linkedin.com/?key=value', + ) + }) + + test('case 2: 기존 URL에 이미 쿼리가 있는 경우', () => { + expect( + addQuery('https://www.linkedin.com/?name=elon', 'key', 'value'), + ).toBe('https://www.linkedin.com/?name=elon&key=value') + }) + + test('case 3: 기존 URL에 hash가 있는 경우', () => { + expect( + addQuery('https://www.linkedin.com/?name=elon#top', 'key', 'value'), + ).toBe('https://www.linkedin.com/?name=elon&key=value#top') + }) + + test('case 4: 기존 쿼리와 추가하려는 쿼리의 key가 동일한 경우', () => { + const URL = 'https://www.linkedin.com/?name=elon#top' + + expect(addQuery(URL, 'name', 'musk')).toBe( + 'https://www.linkedin.com/?name=musk#top', + ) + + expect(addQuery(URL, 'name', 'musk')).toBe( + 'https://www.linkedin.com/?name=musk#top', + ) + }) + + test('case 5: 기존 쿼리와 추가하려는 쿼리의 key가 동일한 경우', () => { + const URL = 'https://www.linkedin.com/?name=elon&name=minsoo#top' + + expect(addQuery(URL, 'name', 'musk')).toBe( + 'https://www.linkedin.com/?name=musk&name=musk#top', + ) + + expect(addQuery(URL, 'name', 'musk')).toBe( + 'https://www.linkedin.com/?name=musk&name=musk#top', + ) + }) +}) diff --git a/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.ts b/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.ts new file mode 100644 index 0000000..46a6496 --- /dev/null +++ b/packages/example/src/1week/URL/addQuery/__submit__/minsoo-web.ts @@ -0,0 +1,65 @@ +const hasIncludes = (url: string, value: string): 'YES' | 'NO' => + url.includes(value) ? 'YES' : 'NO' + +export const getHashPart = ( + text: string, +): { nonHash: string; hash: string } => { + const indexOfHash = text.indexOf('#') + + if (indexOfHash >= 0) { + return { + nonHash: text.slice(0, indexOfHash), + hash: text.slice(indexOfHash), + } + } + + return { + nonHash: text, + hash: '', + } +} + +export const replaceKeyValue = ( + url: string, + key: string, + newValue: string | number, +) => { + const regExp = new RegExp(`${key}=([^&]*)`, 'g') + if (url.match(regExp)) { + return url.replace(regExp, `${key}=${newValue}`) + } + + return url +} + +/** + * 출제자: 예진님 (yejineee) + * URL의 쿼리스트링 관련 유틸 함수를 계산 을 최대한 이용하여 만들기 + * + * - 해쉬가 있다면, 유지해야 함 + * - 기존 쿼리가 있다면, 유지해야 함 + * - 기존 쿼리와 추가하려는 쿼리의 key가 동일하다면, 기존 쿼리가 대체됨 + */ + +export const addQuery = ( + originURL: string, + key: string, + value: string | number, +) => { + const { nonHash, hash } = getHashPart(originURL) + + let returnUrl = nonHash + let connector = '?' + + if (hasIncludes(originURL, '?') === 'YES') { + connector = '&' + } + + returnUrl += `${connector}${key}=${value}` + + if (hasIncludes(originURL, `?${key}`) === 'YES') { + returnUrl = replaceKeyValue(nonHash, key, value) + } + + return returnUrl + hash +}