Skip to content

Commit

Permalink
🎯 merge pull request #5 from lachlanshoesmith/bugfix/handle-duplicate…
Browse files Browse the repository at this point in the history
…-phone-numbers

📱 bugfix - handle duplicate phone numbers
  • Loading branch information
lachlanshoesmith authored Jan 23, 2024
2 parents 51b377f + cab72f6 commit 5313f33
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 11 deletions.
15 changes: 10 additions & 5 deletions backend/backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from jose import JWTError, jwt
from passlib.context import CryptContext
from psycopg import DataError, IntegrityError, AsyncConnection, sql
from psycopg.errors import UniqueViolation
from psycopg_pool import AsyncConnectionPool

from .models import (TokenData, ProposedWebsite, RegisteringStudentRequest,
Expand Down Expand Up @@ -375,11 +376,15 @@ async def create_account(user_data: RegisteringUser, conn: AsyncConnection):

async def register_full_account(user_data: RegisteringFullUserRequest, conn: AsyncConnection):
async with conn.cursor() as cur:
await cur.execute('''
insert into Full_Account (id, email, phone_number)
values (%(id)s, %(email)s, %(phone_number)s)
''', {'id': user_data['id'], 'email': user_data['user'].email, 'phone_number': user_data['user'].phone_number})
await conn.commit()
try:
await cur.execute('''
insert into Full_Account (id, email, phone_number)
values (%(id)s, %(email)s, %(phone_number)s)
''', {'id': user_data['id'], 'email': user_data['user'].email, 'phone_number': user_data['user'].phone_number})
await conn.commit()
except UniqueViolation:
raise HTTPException(
status_code=400, detail='Phone number taken.')


@app.post('/register')
Expand Down
14 changes: 14 additions & 0 deletions backend/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ async def test_register_administrator_with_same_email(test_db):
assert res.json()['detail'] == 'User already exists.'


@pytest.mark.anyio
async def test_register_administrator_with_same_phone_number(test_db):
res = await register_administrator()
assert res.status_code == 200

administrator = deepcopy(d.registering_administrator_data)
administrator['username'] = 'different_username'
administrator['email'] = 'different_email@gmail.com'

res = await register_administrator(administrator)
assert res.status_code == 400, res.text
assert res.json()['detail'] == 'Phone number taken.'


@pytest.mark.anyio
async def test_register_student(test_db):
res = await register_administrator()
Expand Down
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.49.3",
"react-router-dom": "^6.21.3"
},
"devDependencies": {
Expand Down
12 changes: 12 additions & 0 deletions frontend/pnpm-lock.yaml

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

5 changes: 5 additions & 0 deletions frontend/src/components/Root/Root.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@
margin: 0 0.5rem;
}
}

.smallText {
color: #999;
font-size: 0.5rem;
}
4 changes: 4 additions & 0 deletions frontend/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ function Root() {
<p>
By <a href="https://github.com/lachlanshoesmith">Lachlan Shoesmith</a>
</p>
<p className={classes.smallText}>
webdevcamp is not associated with Skill Samurai Rouse Hill or Skill
Samurai as a broader company.
</p>
</footer>
</>
);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
color-scheme: light dark;
color: #dbdbdb;
background-color: #222;
max-width: 480px;
margin: 0 auto;
}
5 changes: 5 additions & 0 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Root from './components/Root/Root.tsx';
import ErrorPage from './routes/ErrorPage.tsx';
import Login from './routes/Login.tsx';
import Register from './routes/Register.tsx';
import Home from './routes/Home.tsx';
import './index.css';

Expand All @@ -21,6 +22,10 @@ const router = createBrowserRouter([
path: '/login',
element: <Login />,
},
{
path: '/register',
element: <Register />,
},
],
},
]);
Expand Down
61 changes: 55 additions & 6 deletions frontend/src/routes/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,64 @@
import { Form } from 'react-router-dom';
import Button from '../components/Button/Button';
import { useForm, SubmitHandler } from 'react-hook-form';
import { useState } from 'react';

function login() {
type Inputs = {
username: string;
password: string;
};

export default function Login() {
const {
register,
formState: { errors },
handleSubmit,
} = useForm<Inputs>();
const [loginErrors, setLoginErrors] = useState('');

const onSubmit: SubmitHandler<Inputs> = async (data) => {
const res = await fetch('https://webdevcamp.fly.dev/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});

const responseJSON = await res.json();
const responseDetail: string = responseJSON.detail;

if (!res.ok) {
setLoginErrors(responseDetail);
} else {
console.log(responseDetail);
}
};
return (
<>
<h1>Login Page</h1>
<Form method="get">
<form onSubmit={handleSubmit(onSubmit)}>
<input
type="text"
{...register('username', {
required: true,
minLength: 3,
maxLength: 20,
})}
aria-invalid={errors.username ? 'true' : 'false'}
placeholder="Username"
/>
<input
type="password"
{...register('password', {
required: true,
minLength: 8,
})}
aria-invalid={errors.password ? 'true' : 'false'}
placeholder="Password"
/>
<Button type="submit">Login</Button>
</Form>
</form>
{loginErrors && <p>{loginErrors}</p>}
</>
);
}

export default login;
101 changes: 101 additions & 0 deletions frontend/src/routes/Register.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import Button from '../components/Button/Button';
import { useForm, SubmitHandler } from 'react-hook-form';
import { useState } from 'react';

type Inputs = {
given_name: string;
family_name: string;
username: string;
hashed_password: string;
account_type: string;
email: string;
phone_number: string;
};

export default function Register() {
const {
register,
formState: { errors },
handleSubmit,
} = useForm<Inputs>();
const [registerErrors, setRegisterErrors] = useState('');

const onSubmit: SubmitHandler<Inputs> = async (data) => {
data.account_type = 'administrator';
const res = await fetch('https://webdevcamp.fly.dev/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});

const responseJSON = await res.json();

if (!res.ok) {
setRegisterErrors(responseJSON.detail);
} else {
console.log(res.json());
}
};
return (
<>
<h1>Register new administrator</h1>
<form onSubmit={handleSubmit(onSubmit)}>
<input
type="text"
{...register('given_name', {
required: true,
})}
aria-invalid={errors.given_name ? 'true' : 'false'}
placeholder="Given name"
/>
<input
type="text"
{...register('family_name', {
required: true,
})}
aria-invalid={errors.family_name ? 'true' : 'false'}
placeholder="Family name"
/>
<input
type="text"
{...register('username', {
required: true,
minLength: 3,
maxLength: 20,
})}
aria-invalid={errors.username ? 'true' : 'false'}
placeholder="Username"
/>
<input
type="password"
{...register('hashed_password', {
required: true,
minLength: 8,
})}
aria-invalid={errors.hashed_password ? 'true' : 'false'}
placeholder="Password"
/>
<input
type="email"
{...register('email', {
required: true,
})}
aria-invalid={errors.email ? 'true' : 'false'}
placeholder="Email"
/>
<input
type="text"
{...register('phone_number', {
required: false,
})}
aria-invalid={errors.phone_number ? 'true' : 'false'}
placeholder="Phone number"
/>
<Button type="submit">Register</Button>
</form>
{registerErrors && <p>{registerErrors}</p>}
</>
);
}

0 comments on commit 5313f33

Please sign in to comment.