From f49f9c9d5d355e43b2548539d24afd11e63b9df0 Mon Sep 17 00:00:00 2001 From: Kengo Yamashita Date: Sat, 11 May 2024 13:17:42 +0900 Subject: [PATCH] feat: add router and login (#1) --- app/package-lock.json | 9 ++++++ app/package.json | 1 + app/src/index.tsx | 12 ++++++-- app/src/pages/login.test.tsx | 39 ++++++++++++++++++++++++ app/src/pages/login.tsx | 50 +++++++++++++++++++++++++++++++ app/src/service/auth.ts | 0 app/src/todo-list.test.tsx | 55 ---------------------------------- app/src/todo-list.tsx | 58 ------------------------------------ 8 files changed, 109 insertions(+), 115 deletions(-) create mode 100644 app/src/pages/login.test.tsx create mode 100644 app/src/pages/login.tsx create mode 100644 app/src/service/auth.ts delete mode 100644 app/src/todo-list.test.tsx delete mode 100644 app/src/todo-list.tsx diff --git a/app/package-lock.json b/app/package-lock.json index 38c8633..3018717 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { + "@solidjs/router": "^0.13.3", "solid-js": "^1.8.11" }, "devDependencies": { @@ -1022,6 +1023,14 @@ "solid-js": "^1.6.12" } }, + "node_modules/@solidjs/router": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/@solidjs/router/-/router-0.13.3.tgz", + "integrity": "sha512-p8zznlvnN3KySMXqT8irhubgDNTETNa/guaGHU/cZl7kuiPO3PmkWNYfoNCygtEpoxLmLpf62/ZKeyhFdZexsw==", + "peerDependencies": { + "solid-js": "^1.8.6" + } + }, "node_modules/@solidjs/testing-library": { "version": "0.8.7", "resolved": "https://registry.npmjs.org/@solidjs/testing-library/-/testing-library-0.8.7.tgz", diff --git a/app/package.json b/app/package.json index b8e154c..84c0347 100644 --- a/app/package.json +++ b/app/package.json @@ -27,6 +27,7 @@ "vite-plugin-solid": "^2.8.2" }, "dependencies": { + "@solidjs/router": "^0.13.3", "solid-js": "^1.8.11" } } diff --git a/app/src/index.tsx b/app/src/index.tsx index 8384ea8..5df018b 100644 --- a/app/src/index.tsx +++ b/app/src/index.tsx @@ -1,6 +1,7 @@ import { render } from 'solid-js/web'; +import { Router, Route } from '@solidjs/router'; -import { TodoList } from './todo-list'; +import { Login } from './pages/login'; const root = document.getElementById('root'); @@ -10,4 +11,11 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) { ); } -render(() => , root!); +render( + () => ( + + + + ), + document.getElementById('root')!, +) diff --git a/app/src/pages/login.test.tsx b/app/src/pages/login.test.tsx new file mode 100644 index 0000000..17736e9 --- /dev/null +++ b/app/src/pages/login.test.tsx @@ -0,0 +1,39 @@ +import { suite } from "uvu"; +import * as assert from "uvu/assert"; + +import { render, fireEvent, waitFor } from '@solidjs/testing-library'; +import { isInDocument, hasStyle } from 'solid-dom-testing'; + +import { Login } from './login'; + +const test = suite>(''); + +test.before.each((context) => { + const returnValue = render(() => ); + Object.getOwnPropertyNames(returnValue).forEach((name) => { + // @ts-expect-error + context[name] = returnValue[name]; + }); +}); + +test.after.each(({ unmount }) => unmount()); + +// test target: it will render an username input and a password input +test('it will render an username input and a password input', ({ + getByPlaceholderText, +}) => { + assert.ok(isInDocument(getByPlaceholderText('Username'))); + assert.ok(isInDocument(getByPlaceholderText('******************'))); +}); + +// test target: it will render an Sign In button +test('it will render an Sign In button', ({ getByText }) => { + assert.ok(isInDocument(getByText('Sign In'))); +}); + +// test target: it will render an Forgot Password link +test('it will render an Forgot Password link', ({ getByText }) => { + assert.ok(isInDocument(getByText('Forgot Password?'))); +}); + +test.run(); \ No newline at end of file diff --git a/app/src/pages/login.tsx b/app/src/pages/login.tsx new file mode 100644 index 0000000..ff2afb5 --- /dev/null +++ b/app/src/pages/login.tsx @@ -0,0 +1,50 @@ +// this component is a simple login page + +export const Login = () => { + return ( +
+
+

Login

+
+
+ + +
+
+ + +

Please choose a password.

+
+
+ + + Forgot Password? + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/app/src/service/auth.ts b/app/src/service/auth.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/src/todo-list.test.tsx b/app/src/todo-list.test.tsx deleted file mode 100644 index 0563c0f..0000000 --- a/app/src/todo-list.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { suite } from 'uvu'; -import * as assert from 'uvu/assert'; - -import { render, fireEvent, waitFor } from 'solid-testing-library'; -import { isInDocument, hasStyle } from 'solid-dom-testing'; - -import { TodoList } from './todo-list'; - -const test = suite>(''); - -test.before.each((context) => { - const returnValue = render(() => ); - Object.getOwnPropertyNames(returnValue).forEach((name) => { - // @ts-expect-error - context[name] = returnValue[name]; - }); -}); - -test.after.each(({ unmount }) => unmount()); - -test('it will render an text input and a button', ({ - getByPlaceholderText, - getByText, -}) => { - assert.ok(isInDocument(getByPlaceholderText('new todo here'))); - assert.ok(isInDocument(getByText('Add Todo'))); -}); - -test('it will add a new todo', async ({ getByPlaceholderText, getByText }) => { - const input = getByPlaceholderText('new todo here') as HTMLInputElement; - const button = getByText('Add Todo'); - input.value = 'test new todo'; - fireEvent.click(button as HTMLInputElement); - assert.is(input.value, ''); - await waitFor(() => assert.ok(isInDocument(getByText(/test new todo/)))); -}); - -test('it will mark a todo as completed', async ({ - getByPlaceholderText, - findByRole, - getByText, -}) => { - const input = getByPlaceholderText('new todo here') as HTMLInputElement; - const button = getByText('Add Todo') as HTMLButtonElement; - input.value = 'mark new todo as completed'; - fireEvent.click(button); - const completed = (await findByRole('checkbox')) as HTMLInputElement; - assert.is(completed?.checked, false); - fireEvent.click(completed); - assert.is(completed?.checked, true); - const text = getByText('mark new todo as completed') as HTMLSpanElement; - assert.ok(hasStyle(text, { 'text-decoration': 'line-through' })); -}); - -test.run(); diff --git a/app/src/todo-list.tsx b/app/src/todo-list.tsx deleted file mode 100644 index f470226..0000000 --- a/app/src/todo-list.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { For, createSignal } from 'solid-js'; - -type Todo = { id: number; text: string; completed: boolean }; - -export const TodoList = () => { - let input!: HTMLInputElement; - let todoId = 0; - const [todos, setTodos] = createSignal([]); - const addTodo = (text: string) => { - setTodos([...todos(), { id: ++todoId, text, completed: false }]); - }; - const toggleTodo = (id: number) => { - setTodos( - todos().map((todo) => - todo.id === id ? { ...todo, completed: !todo.completed } : todo, - ), - ); - }; - - return ( - <> -
-

Hello World

- - -
- - {(todo) => { - const { id, text } = todo; - return ( -
- - - {text} - -
- ); - }} -
- - ); -};