Skip to content

Commit

Permalink
Merge branch 'release-0.2.0' into feat/prashanth-groovy-scripts-1342-…
Browse files Browse the repository at this point in the history
…1343
  • Loading branch information
prv-proton authored Dec 10, 2024
2 parents 49b632a + 4831c4a commit c6dc4b1
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Remove notifications email from user_profile
Revision ID: cd8698fe40e6
Revises: 26ab15f8ab18
Create Date: 2024-12-09 22:33:29.554360
"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "cd8698fe40e6"
down_revision = "26ab15f8ab18"
branch_labels = None
depends_on = None


def upgrade() -> None:
# Remove notifications_email column from user_profile table
op.drop_column("user_profile", "notifications_email")


def downgrade() -> None:
# Add notifications_email column to user_profile table
op.add_column(
"user_profile",
sa.Column(
"notifications_email",
sa.String(length=255),
nullable=True,
comment="Email address used for notifications",
),
)
3 changes: 0 additions & 3 deletions backend/lcfs/db/models/user/UserProfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ class UserProfile(BaseModel, Auditable):
String(150), unique=True, nullable=False, comment="keycloak Username"
)
email = Column(String(255), nullable=True, comment="Primary email address")
notifications_email = Column(
String(255), nullable=True, comment="Email address used for notifications"
)
title = Column(String(100), nullable=True, comment="Professional Title")
phone = Column(String(50), nullable=True, comment="Primary phone number")
mobile_phone = Column(String(50), nullable=True, comment="Mobile phone number")
Expand Down
14 changes: 6 additions & 8 deletions backend/lcfs/tests/user/test_user_repo.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from unittest.mock import AsyncMock, Mock
from unittest.mock import Mock

import pytest

from lcfs.db.models import UserProfile, UserLoginHistory
from lcfs.web.api.user.repo import UserRepository
from lcfs.tests.user.user_payloads import user_orm_model
from lcfs.web.exception.exceptions import DataNotFoundException


@pytest.fixture
Expand Down Expand Up @@ -50,14 +49,13 @@ async def test_create_login_history(dbsession, user_repo):


@pytest.mark.anyio
async def test_update_notifications_email_success(dbsession, user_repo):
async def test_update_email_success(dbsession, user_repo):
# Arrange: Create a user in the database
user = UserProfile(
keycloak_user_id="user_id_1",
keycloak_email="[email protected]",
keycloak_username="username1",
email="[email protected]",
notifications_email=None,
title="Developer",
phone="1234567890",
mobile_phone="0987654321",
Expand All @@ -70,10 +68,10 @@ async def test_update_notifications_email_success(dbsession, user_repo):
await dbsession.commit()
await dbsession.refresh(user)

# Act: Update the notifications email
updated_user = await user_repo.update_notifications_email(
# Act: Update the email
updated_user = await user_repo.update_email(
user_profile_id=1, email="[email protected]"
)

# Assert: Check if the notifications email was updated
assert updated_user.notifications_email == "[email protected]"
# Assert: Check if the email was updated
assert updated_user.email == "[email protected]"
7 changes: 3 additions & 4 deletions backend/lcfs/tests/user/test_user_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,19 +468,18 @@ async def test_track_logged_in_success(client: AsyncClient, fastapi_app, set_moc


@pytest.mark.anyio
async def test_update_notifications_email_success(
async def test_update_email_success(
client: AsyncClient,
fastapi_app,
set_mock_user,
add_models,
):
set_mock_user(fastapi_app, [RoleEnum.GOVERNMENT])

# Prepare request data
request_data = {"notifications_email": "[email protected]"}
request_data = {"email": "[email protected]"}

# Act: Send POST request to the endpoint
url = fastapi_app.url_path_for("update_notifications_email")
url = fastapi_app.url_path_for("update_email")
response = await client.post(url, json=request_data)

# Assert: Check response status and content
Expand Down
1 change: 0 additions & 1 deletion backend/lcfs/tests/user/user_payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
keycloak_email="[email protected]",
keycloak_username="username",
email="[email protected]",
notifications_email=None,
title="Developer",
phone="1234567890",
mobile_phone="0987654321",
Expand Down
5 changes: 2 additions & 3 deletions backend/lcfs/web/api/user/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ async def create_login_history(self, user: UserProfile):
self.db.add(login_history)

@repo_handler
async def update_notifications_email(
async def update_email(
self, user_profile_id: int, email: str
) -> UserProfile:
# Fetch the user profile
Expand All @@ -679,8 +679,7 @@ async def update_notifications_email(
result = await self.db.execute(query)
user_profile = result.scalar_one_or_none()

# Update the notifications_email field
user_profile.notifications_email = email
user_profile.email = email

# Flush and refresh without committing
await self.db.flush()
Expand Down
5 changes: 2 additions & 3 deletions backend/lcfs/web/api/user/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class UserBaseSchema(BaseSchema):
keycloak_username: str
keycloak_email: EmailStr
email: Optional[EmailStr] = None
notifications_email: Optional[EmailStr] = None
title: Optional[str] = None
phone: Optional[str] = None
first_name: Optional[str] = None
Expand Down Expand Up @@ -97,5 +96,5 @@ class UserLoginHistoryResponseSchema(BaseSchema):
pagination: PaginationResponseSchema


class UpdateNotificationsEmailSchema(BaseSchema):
notifications_email: EmailStr
class UpdateEmailSchema(BaseSchema):
email: EmailStr
9 changes: 3 additions & 6 deletions backend/lcfs/web/api/user/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,12 @@ async def track_user_login(self, user: UserProfile):
await self.repo.create_login_history(user)

@service_handler
async def update_notifications_email(self, user_id: int, email: str):
async def update_email(self, user_id: int, email: str):
try:
# Update the notifications_email field of the user
return await self.repo.update_notifications_email(user_id, email)
# Return the updated user
return UserBaseSchema.model_validate(user)
return await self.repo.update_email(user_id, email)
except DataNotFoundException as e:
logger.error(f"User not found: {e}")
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
logger.error(f"Error updating notifications email: {e}")
logger.error(f"Error updating email: {e}")
raise HTTPException(status_code=500, detail="Internal Server Error")
27 changes: 9 additions & 18 deletions backend/lcfs/web/api/user/views.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
from typing import List

import structlog
from fastapi import (
APIRouter,
Body,
status,
Request,
Response,
Depends,
Query,
HTTPException,
)
from fastapi import APIRouter, Body, status, Request, Response, Depends, Query
from fastapi.responses import StreamingResponse

from lcfs.db import dependencies
Expand All @@ -23,7 +14,7 @@
UserLoginHistoryResponseSchema,
UsersSchema,
UserActivitiesResponseSchema,
UpdateNotificationsEmailSchema,
UpdateEmailSchema,
)
from lcfs.web.api.user.services import UserServices
from lcfs.web.core.decorators import view_handler
Expand Down Expand Up @@ -255,18 +246,18 @@ async def get_all_user_login_history(


@router.post(
"/update-notifications-email",
response_model=UpdateNotificationsEmailSchema,
"/update-email",
response_model=UpdateEmailSchema,
status_code=status.HTTP_200_OK,
)
@view_handler(["*"])
async def update_notifications_email(
async def update_email(
request: Request,
email_data: UpdateNotificationsEmailSchema = Body(...),
email_data: UpdateEmailSchema = Body(...),
service: UserServices = Depends(),
):
user_id = request.user.user_profile_id
email = email_data.notifications_email
email = email_data.email

user = await service.update_notifications_email(user_id, email)
return user
user = await service.update_email(user_id, email)
return UpdateEmailSchema(email=user.email)
2 changes: 1 addition & 1 deletion frontend/src/constants/routes/apiRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,5 @@ export const apiRoutes = {
getNotificationsCount: '/notifications/count',
getNotificationSubscriptions: '/notifications/subscriptions',
saveNotificationSubscriptions: '/notifications/subscriptions/save',
updateNotificationsEmail: '/users/update-notifications-email'
updateNotificationsEmail: '/users/update-email'
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const BCeIDNotificationSettings = () => {
<NotificationSettingsForm
categories={categories}
showEmailField
initialEmail={currentUser.notificationsEmail}
initialEmail={currentUser.email}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import {
notificationTypes,
notificationChannels
} from '@/constants/notificationTypes'
import { useNavigate } from 'react-router-dom'
import { ROUTES } from '@/constants/routes'
import MailIcon from '@mui/icons-material/Mail'
import NotificationsIcon from '@mui/icons-material/Notifications'
import BCButton from '@/components/BCButton'
Expand All @@ -40,19 +38,18 @@ const NotificationSettingsForm = ({
initialEmail
}) => {
const { t } = useTranslation(['notifications'])
const navigate = useNavigate()
const [isFormLoading, setIsFormLoading] = useState(false)
const [message, setMessage] = useState('')
const { data: subscriptionsData, isLoading: isSubscriptionsLoading } =
useNotificationSubscriptions()
const createSubscription = useCreateSubscription()
const deleteSubscription = useDeleteSubscription()
const updateNotificationsEmail = useUpdateNotificationsEmail()
const updateEmail = useUpdateNotificationsEmail()

// Validation schema
const validationSchema = Yup.object().shape({
...(showEmailField && {
notificationEmail: Yup.string()
email: Yup.string()
.email(t('errors.invalidEmail'))
.required(t('errors.emailRequired'))
})
Expand All @@ -75,7 +72,7 @@ const NotificationSettingsForm = ({
})
}
if (showEmailField && initialEmail) {
setValue('notificationEmail', initialEmail)
setValue('email', initialEmail)
}
}, [subscriptionsData, showEmailField, initialEmail, setValue])

Expand Down Expand Up @@ -122,8 +119,8 @@ const NotificationSettingsForm = ({
try {
if (showEmailField) {
// BCeID user, save the email address
await updateNotificationsEmail.mutateAsync({
notifications_email: data.notificationEmail
await updateEmail.mutateAsync({
email: data.email
})
setMessage(t('messages.emailSaved'))
}
Expand Down Expand Up @@ -423,11 +420,11 @@ const NotificationSettingsForm = ({
>
{showEmailField && (
<BCBox sx={{ marginTop: 2 }}>
<InputLabel htmlFor="notificationEmail" sx={{ pb: 1 }}>
{t('notificationsEmail')}:
<InputLabel htmlFor="email" sx={{ pb: 1 }}>
{t('email')}:
</InputLabel>
<Controller
name="notificationEmail"
name="email"
control={control}
render={({ field, fieldState: { error } }) => (
<TextField
Expand Down

0 comments on commit c6dc4b1

Please sign in to comment.