diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml
index 8cce08db00329781bb30fe04f6b1490ab978b19d..a74e1d6a911805b26a95eb345be549afb55b81ee 100644
--- a/.github/workflows/sonarqube.yml
+++ b/.github/workflows/sonarqube.yml
@@ -5,10 +5,12 @@ on:
       - '*'
   pull_request:
     types: [opened, synchronize, reopened]
+
 jobs:
   build:
     name: Build and analyze
     runs-on: ubuntu-latest
+
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/Dockerfile b/Dockerfile
index 9372156b8f55652b70d6d0af1f7bde92551459ba..fcc2364a5f41ab24e97fdb0a084feb527cd94c45 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -25,6 +25,6 @@ ENV JDBC_STAGING_DATABASE_URL ${JDBC_STAGING_DATABASE_URL}
 ENV JDBC_STAGING_DATABASE_USERNAME ${JDBC_STAGING_DATABASE_USERNAME}
 
 WORKDIR /app
-COPY --from=builder /app/target/authentication-0.0.1-SNAPSHOT.jar app.jar
+COPY --from=builder /app/target/authentication-0.1.jar app.jar
 EXPOSE 8080
 CMD ["java", "-jar", "app.jar"]
diff --git a/pom.xml b/pom.xml
index 10d9861a4bf1d40b33e55f5a9675d00f045a73e3..a63ccbe75f2dd4fdd2e922b756d2fa0629cd1ae7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,13 @@
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-dependencies</artifactId>
+			<version>2023.0.0</version>
+			<type>pom</type>
+			<scope>import</scope>
+		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-devtools</artifactId>
@@ -195,11 +202,39 @@
 			<version>0.11.5</version>
 			<scope>runtime</scope>
 		</dependency>
-
 		<dependency>
-			<groupId>me.paulschwarz</groupId>
-			<artifactId>spring-dotenv</artifactId>
-			<version>4.0.0</version>
+			<groupId>com.google.api-client</groupId>
+			<artifactId>google-api-client</artifactId>
+			<version>2.6.0</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.http-client</groupId>
+			<artifactId>google-http-client-gson</artifactId>
+			<version>1.41.7</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>javax.servlet-api</artifactId>
+			<version>4.0.1</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.powermock</groupId>
+			<artifactId>powermock-module-junit4</artifactId>
+			<version>2.0.9</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.powermock</groupId>
+			<artifactId>powermock-api-mockito2</artifactId>
+			<version>2.0.9</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-inline</artifactId>
+			<version>5.2.0</version> <!-- Use the latest version -->
+			<scope>test</scope>
 		</dependency>
 
 
@@ -257,17 +292,38 @@
 				<version>0.8.12</version>
 				<executions>
 					<execution>
+						<id>prepare-agent</id>
 						<goals>
 							<goal>prepare-agent</goal>
 						</goals>
 					</execution>
 					<execution>
 						<id>report</id>
-						<phase>test</phase>
+						<phase>verify</phase>
 						<goals>
 							<goal>report</goal>
 						</goals>
 					</execution>
+					<execution>
+						<id>check</id>
+						<goals>
+							<goal>check</goal>
+						</goals>
+						<configuration>
+							<rules>
+								<rule>
+									<element>BUNDLE</element>
+									<limits>
+										<limit>
+											<counter>LINE</counter>
+											<value>COVEREDRATIO</value>
+											<minimum>1.00</minimum>
+										</limit>
+									</limits>
+								</rule>
+							</rules>
+						</configuration>
+					</execution>
 				</executions>
 			</plugin>
 		</plugins>
diff --git a/src/main/java/com/safetypin/authentication/controller/AuthenticationController.java b/src/main/java/com/safetypin/authentication/controller/AuthenticationController.java
index 21a60193446684d5ac4638584ea135e6506e2321..0869e05fe92245a14d85d5640e5c1d2a91047580 100644
--- a/src/main/java/com/safetypin/authentication/controller/AuthenticationController.java
+++ b/src/main/java/com/safetypin/authentication/controller/AuthenticationController.java
@@ -5,6 +5,9 @@ import com.safetypin.authentication.exception.InvalidCredentialsException;
 import com.safetypin.authentication.exception.UserAlreadyExistsException;
 import com.safetypin.authentication.service.AuthenticationService;
 import jakarta.validation.Valid;
+import com.safetypin.authentication.service.GoogleAuthService;
+import com.safetypin.authentication.service.JwtService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
@@ -14,9 +17,14 @@ import org.springframework.web.bind.annotation.*;
 public class AuthenticationController {
 
     private final AuthenticationService authenticationService;
+    private final GoogleAuthService googleAuthService;
+    private final JwtService jwtService;
 
-    public AuthenticationController(AuthenticationService authenticationService) {
+    @Autowired
+    public AuthenticationController(AuthenticationService authenticationService, GoogleAuthService googleAuthService, JwtService jwtService) {
         this.authenticationService = authenticationService;
+        this.googleAuthService = googleAuthService;
+        this.jwtService = jwtService;
     }
 
 
@@ -33,19 +41,6 @@ public class AuthenticationController {
 
     }
 
-    // Endpoint for social registration/login
-    @PostMapping("/register-social")
-    public ResponseEntity<AuthResponse> registerSocial(@Valid @RequestBody SocialLoginRequest request) {
-        try {
-            String jwt = authenticationService.socialLogin(request);
-            return ResponseEntity.ok().body(new AuthResponse(true, "OK", new Token(jwt)));
-        } catch (IllegalArgumentException | UserAlreadyExistsException e) {
-            AuthResponse response = new AuthResponse(false, e.getMessage(), null);
-            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
-        }
-
-    }
-
     // OTP verification endpoint
     @PostMapping("/verify-otp")
     public ResponseEntity<AuthResponse> verifyOTP(@RequestParam String email, @RequestParam String otp) {
@@ -72,17 +67,18 @@ public class AuthenticationController {
 
     }
 
-    // Endpoint for social login (DEPRECATED, use regis-social instead)
-    @PostMapping("/login-social")
-    public ResponseEntity<AuthResponse> loginSocial(@RequestParam String email) {
+    @PostMapping("/google")
+    public ResponseEntity<AuthResponse> authenticateGoogle(@Valid @RequestBody GoogleAuthDTO googleAuthData) {
         try {
-            String jwt = authenticationService.loginSocial(email);
+            String jwt = googleAuthService.authenticate(googleAuthData);
             return ResponseEntity.ok(new AuthResponse(true, "OK", new Token(jwt)));
-        } catch (InvalidCredentialsException e) {
+        } catch (UserAlreadyExistsException e) {
             AuthResponse response = new AuthResponse(false, e.getMessage(), null);
             return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
+        } catch (Exception e) {
+            AuthResponse response = new AuthResponse(false, e.getMessage(), null);
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
         }
-
     }
 
 
@@ -96,7 +92,7 @@ public class AuthenticationController {
     @PostMapping("/verify-jwt")
     public ResponseEntity<AuthResponse> verifyJwtToken(@RequestParam String token) {
         try {
-            UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
+            UserResponse userResponse = jwtService.getUserFromJwtToken(token);
             return ResponseEntity.ok(new AuthResponse(true, "OK", userResponse));
         } catch (InvalidCredentialsException e) {
             AuthResponse response = new AuthResponse(false, e.getMessage(), null);
@@ -104,13 +100,6 @@ public class AuthenticationController {
         }
     }
 
-
-    // Endpoint simulating a content post that requires a verified account (DEPRECATED, use be-post instead)
-    @PostMapping("/post")
-    public String postContent(@RequestParam String email, @RequestParam String content) {
-        return authenticationService.postContent(email, content);
-    }
-
     // On successful login, return an empty map as a placeholder for future reports
     @GetMapping("/dashboard")
     public String dashboard() {
diff --git a/src/main/java/com/safetypin/authentication/dto/GoogleAuthDTO.java b/src/main/java/com/safetypin/authentication/dto/GoogleAuthDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..e99d997d6852fee4a2c42fe022bde21a5e7c0f81
--- /dev/null
+++ b/src/main/java/com/safetypin/authentication/dto/GoogleAuthDTO.java
@@ -0,0 +1,20 @@
+package com.safetypin.authentication.dto;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Setter
+@Getter
+@EqualsAndHashCode
+@ToString
+public class GoogleAuthDTO {
+
+    @NotBlank
+    private String idToken;
+
+    @NotBlank
+    private String serverAuthCode;
+}
\ No newline at end of file
diff --git a/src/main/java/com/safetypin/authentication/exception/ApiException.java b/src/main/java/com/safetypin/authentication/exception/ApiException.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a5d80ea764d6e2cab580fdc04f864433077fd4e
--- /dev/null
+++ b/src/main/java/com/safetypin/authentication/exception/ApiException.java
@@ -0,0 +1,11 @@
+package com.safetypin.authentication.exception;
+
+import java.io.IOException;
+
+public class ApiException extends IOException {
+
+    public ApiException(String message) {
+        super(message);
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/safetypin/authentication/model/User.java b/src/main/java/com/safetypin/authentication/model/User.java
index baba8721fd0ccb144ea8e33362b1450271d7179e..7fd5f65f99ed01e7058afb07ad8b8dbb267984c2 100644
--- a/src/main/java/com/safetypin/authentication/model/User.java
+++ b/src/main/java/com/safetypin/authentication/model/User.java
@@ -52,10 +52,6 @@ public class User {
     @Getter
     private String provider;  // "EMAIL", "GOOGLE", "APPLE"
 
-    @Setter
-    @Getter
-    private String socialId;  // For social login users
-
 
     // Getters and setters
 
diff --git a/src/main/java/com/safetypin/authentication/security/SecurityConfig.java b/src/main/java/com/safetypin/authentication/security/SecurityConfig.java
index cf7421e2be4860288392ae21398d38e262c6edf7..20ab02f50ce8dd3852704388e9dda1f1ec602132 100644
--- a/src/main/java/com/safetypin/authentication/security/SecurityConfig.java
+++ b/src/main/java/com/safetypin/authentication/security/SecurityConfig.java
@@ -16,7 +16,7 @@ public class SecurityConfig {
     @Bean
     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         http
-                // CSRF protection is enabled by default, so we don't disable it here
+                .csrf(AbstractHttpConfigurer::disable)
                 .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/**").permitAll() // Allow all requests
                 )
diff --git a/src/main/java/com/safetypin/authentication/seeder/DevDataSeeder.java b/src/main/java/com/safetypin/authentication/seeder/DevDataSeeder.java
index 54da05b3adddbd15bd5708ce635c3b72d9b57084..2018c87adba7ba92f8d4c5c454b19c8348e5281a 100644
--- a/src/main/java/com/safetypin/authentication/seeder/DevDataSeeder.java
+++ b/src/main/java/com/safetypin/authentication/seeder/DevDataSeeder.java
@@ -42,7 +42,6 @@ public class DevDataSeeder implements Runnable {
             user1.setRole(Role.REGISTERED_USER);
             user1.setBirthdate(LocalDate.of(1990, 1, 1));
             user1.setProvider(EMAIL_PROVIDER);
-            user1.setSocialId("social1");
             userRepository.save(user1);
 
             User user2 = new User();
@@ -53,7 +52,6 @@ public class DevDataSeeder implements Runnable {
             user2.setRole(Role.REGISTERED_USER);
             user2.setBirthdate(LocalDate.of(1991, 2, 2));
             user2.setProvider(EMAIL_PROVIDER);
-            user2.setSocialId("social2");
             userRepository.save(user2);
 
 
@@ -65,7 +63,6 @@ public class DevDataSeeder implements Runnable {
             user3.setRole(Role.REGISTERED_USER);
             user3.setBirthdate(LocalDate.of(1992, 3, 3));
             user3.setProvider(EMAIL_PROVIDER);
-            user3.setSocialId("social3");
             userRepository.save(user3);
 
             User user4 = new User();
@@ -76,7 +73,6 @@ public class DevDataSeeder implements Runnable {
             user4.setRole(Role.REGISTERED_USER);
             user4.setBirthdate(LocalDate.of(1993, 4, 4));
             user4.setProvider(EMAIL_PROVIDER);
-            user4.setSocialId("social4");
             userRepository.save(user4);
 
             User user5 = new User();
@@ -87,7 +83,6 @@ public class DevDataSeeder implements Runnable {
             user5.setRole(Role.PREMIUM_USER);
             user5.setBirthdate(LocalDate.of(1994, 5, 5));
             user5.setProvider(EMAIL_PROVIDER);
-            user5.setSocialId("social5");
             userRepository.save(user5);
 
             User user6 = new User();
diff --git a/src/main/java/com/safetypin/authentication/service/AuthenticationService.java b/src/main/java/com/safetypin/authentication/service/AuthenticationService.java
index 48d9ea81d3edd85a241334b8fa2b7e2c8b633b8c..064d215910db7c568e17df7567b26a51c294da1e 100644
--- a/src/main/java/com/safetypin/authentication/service/AuthenticationService.java
+++ b/src/main/java/com/safetypin/authentication/service/AuthenticationService.java
@@ -1,46 +1,35 @@
 package com.safetypin.authentication.service;
 
 import com.safetypin.authentication.dto.RegistrationRequest;
-import com.safetypin.authentication.dto.SocialLoginRequest;
-import com.safetypin.authentication.dto.UserResponse;
 import com.safetypin.authentication.exception.InvalidCredentialsException;
 import com.safetypin.authentication.exception.UserAlreadyExistsException;
 import com.safetypin.authentication.model.Role;
 import com.safetypin.authentication.model.User;
-import com.safetypin.authentication.repository.UserRepository;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.Keys;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 
-import java.security.Key;
 import java.time.LocalDate;
 import java.time.Period;
-import java.util.Date;
 import java.util.Optional;
-import java.util.UUID;
 
 @Service
 public class AuthenticationService {
     public static final String EMAIL_PROVIDER = "EMAIL";
-    private static final Logger logger = LoggerFactory.getLogger(AuthenticationService.class);
-    @Value("${JWT_SECRET_KEY}")
-    private String JWT_SECRET_KEY;
-    private static final Long JWT_TOKEN_EXPIRATION_TIME = 86400000L;
-    private final UserRepository userRepository;
+
+    private final UserService userService;
     private final PasswordEncoder passwordEncoder;
     private final OTPService otpService;
 
-    public AuthenticationService(UserRepository userRepository, PasswordEncoder passwordEncoder, OTPService otpService) {
-        this.userRepository = userRepository;
+    private final JwtService jwtService;
+    private static final Logger logger = LoggerFactory.getLogger(AuthenticationService.class);
+
+    public AuthenticationService(UserService userService, PasswordEncoder passwordEncoder, OTPService otpService, JwtService jwtService) {
+        this.userService = userService;
         this.passwordEncoder = passwordEncoder;
         this.otpService = otpService;
+        this.jwtService = jwtService;
     }
 
     // Registration using email – includes birthdate and OTP generation
@@ -48,8 +37,8 @@ public class AuthenticationService {
         if (calculateAge(request.getBirthdate()) < 16) {
             throw new IllegalArgumentException("User must be at least 16 years old");
         }
-        User existingUser = userRepository.findByEmail(request.getEmail());
-        if (existingUser != null) {
+        Optional<User> existingUser = userService.findByEmail(request.getEmail());
+        if (existingUser.isPresent()) {
             throw new UserAlreadyExistsException("Email address is already registered. If you previously used social login (Google/Apple), please use that method to sign in.");
         }
         String encodedPassword = passwordEncoder.encode(request.getPassword());
@@ -63,84 +52,41 @@ public class AuthenticationService {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(request.getBirthdate());
         user.setProvider(EMAIL_PROVIDER);
-        user.setSocialId(null);
-        user = userRepository.save(user);
+        user = userService.save(user);
 
         otpService.generateOTP(request.getEmail());
         logger.info("OTP generated for user at {}", java.time.LocalDateTime.now());
 
-        return generateJwtToken(user.getId());
-    }
-
-    // Social registration/login – simulating data fetched from Google/Apple
-    public String socialLogin(SocialLoginRequest request) {
-        if (calculateAge(request.getBirthdate()) < 16) {
-            throw new IllegalArgumentException("User must be at least 16 years old");
-        }
-        User existing = userRepository.findByEmail(request.getEmail());
-
-        // login (if email is found)
-        if (existing != null) {
-            if (EMAIL_PROVIDER.equals(existing.getProvider())) {
-                // already logged in using email instead of social
-                throw new UserAlreadyExistsException("An account with this email exists. Please sign in using your email and password.");
-            }
-            generateJwtToken(existing.getId());
-        }
-
-        // register
-        User user = new User();
-        user.setEmail(request.getEmail());
-        user.setPassword(null);
-        user.setName(request.getName());
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(request.getBirthdate());
-        user.setProvider(request.getProvider().toUpperCase());
-        user.setSocialId(request.getSocialId());
-
-        user = userRepository.save(user);
-        logger.info("User registered via social login at {}", java.time.LocalDateTime.now());
-
-        return generateJwtToken(user.getId());
+        return jwtService.generateToken(user.getId());
     }
 
     // Email login with detailed error messages
     public String loginUser(String email, String rawPassword) {
-        User user = userRepository.findByEmail(email);
-        if (user == null) {
+        Optional<User> findUser = userService.findByEmail(email);
+        if (findUser.isEmpty()) {
             // email not exists
             logger.warn("Login failed: Email not found");
             throw new InvalidCredentialsException("Invalid email");
         }
+        User user = findUser.get();
         if (!passwordEncoder.matches(rawPassword, user.getPassword())) {
             // incorrect password
             logger.warn("Login failed: Incorrect password attempt");
             throw new InvalidCredentialsException("Invalid password");
         }
         logger.info("User logged in at {}", java.time.LocalDateTime.now());
-        return generateJwtToken(user.getId());
-    }
-
-    // Social login verification (assumed to be pre-verified externally)
-    public String loginSocial(String email) {
-        User user = userRepository.findByEmail(email);
-        if (user == null) {
-            throw new InvalidCredentialsException("Social login failed: Email not found");
-        }
-        logger.info("User logged in via social authentication at {}", java.time.LocalDateTime.now());
-
-        return generateJwtToken(user.getId());
+        return jwtService.generateToken(user.getId());
     }
 
     // OTP verification – marks user as verified upon success
     public boolean verifyOTP(String email, String otp) {
         boolean result = otpService.verifyOTP(email, otp);
         if (result) {
-            User user = userRepository.findByEmail(email);
-            if (user != null) {
+            Optional<User> findUser = userService.findByEmail(email);
+            if (findUser.isPresent()) {
+                User user = findUser.get();
                 user.setVerified(true);
-                userRepository.save(user);
+                userService.save(user);
                 logger.info("OTP successfully verified at {}", java.time.LocalDateTime.now());
             }
         } else {
@@ -151,73 +97,17 @@ public class AuthenticationService {
 
     // Forgot password – only applicable for email-registered users
     public void forgotPassword(String email) {
-        User user = userRepository.findByEmail(email);
-        if (user == null || !EMAIL_PROVIDER.equals(user.getProvider())) {
+
+        Optional<User> user = userService.findByEmail(email);
+        if (user.isEmpty() || !EMAIL_PROVIDER.equals(user.get().getProvider())) {
             throw new IllegalArgumentException("Password reset is only available for email-registered users.");
         }
         // In production, send a reset token via email.
         logger.info("Password reset requested at {}", java.time.LocalDateTime.now());
     }
 
-    // Example method representing posting content that requires a verified account
-    // Deprecated : moved to be-post
-    public String postContent(String email, String content) { // NOSONAR
-        User user = userRepository.findByEmail(email);
-        if (user == null) {
-            return "User not found. Please register.";
-        }
-        if (!user.isVerified()) {
-            return "Your account is not verified. Please complete OTP verification. You may request a new OTP after 2 minutes.";
-        }
-        logger.info("Content posted successfully by user");
-        // For demo purposes, we assume the post is successful.
-        return "Content posted successfully";
-    }
-
     private int calculateAge(LocalDate birthdate) {
         return Period.between(birthdate, LocalDate.now()).getYears();
     }
 
-
-    public String generateJwtToken(UUID userId) {
-        Key key = Keys.hmacShaKeyFor(JWT_SECRET_KEY.getBytes());
-        return Jwts
-                .builder()
-                .setSubject(userId.toString())
-                .setIssuedAt(new Date(System.currentTimeMillis()))
-                .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_EXPIRATION_TIME))
-                .signWith(key, SignatureAlgorithm.HS256)
-                .compact();
-    }
-
-    public UserResponse getUserFromJwtToken(String token) {
-        try {
-            Key key = Keys.hmacShaKeyFor(JWT_SECRET_KEY.getBytes());
-
-            Claims claims = Jwts.parserBuilder()
-                    .setSigningKey(key)
-                    .build()
-                    .parseClaimsJws(token)
-                    .getBody();
-
-            boolean isExpired = claims.getExpiration().before(new Date(System.currentTimeMillis()));
-            UUID userId = UUID.fromString(claims.getSubject());
-
-            if (isExpired) {
-                throw new InvalidCredentialsException("Token expired");
-            }
-
-            Optional<User> user = userRepository.findById(userId);
-            if (user.isEmpty()) {
-                throw new InvalidCredentialsException("User not found");
-            }
-            return user.get().generateUserResponse();
-
-        } catch (JwtException | IllegalArgumentException e){
-            throw new InvalidCredentialsException("Invalid token");
-        }
-
-    }
-
-
 }
diff --git a/src/main/java/com/safetypin/authentication/service/GoogleAuthService.java b/src/main/java/com/safetypin/authentication/service/GoogleAuthService.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce8ef7ad860c7fe5af0ffade7017a4dcfd264664
--- /dev/null
+++ b/src/main/java/com/safetypin/authentication/service/GoogleAuthService.java
@@ -0,0 +1,217 @@
+package com.safetypin.authentication.service;
+
+import com.google.api.client.auth.oauth2.TokenResponse;
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.gson.GsonFactory;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import com.safetypin.authentication.dto.GoogleAuthDTO;
+import com.safetypin.authentication.exception.ApiException;
+import com.safetypin.authentication.exception.InvalidCredentialsException;
+import com.safetypin.authentication.exception.UserAlreadyExistsException;
+import com.safetypin.authentication.model.Role;
+import com.safetypin.authentication.model.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.net.*;
+import java.security.GeneralSecurityException;
+import java.time.LocalDate;
+import java.time.Year;
+import java.util.Collections;
+import java.util.Optional;
+
+@Service
+public class GoogleAuthService {
+    private static final Logger logger = LoggerFactory.getLogger(GoogleAuthService.class);
+
+    private final UserService userService;
+    private final JwtService jwtService;
+
+    @Value("${google.client.id:default}")
+    private String googleClientId;
+
+    @Value("${google.client.secret:default}")
+    private String googleClientSecret;
+
+    private static final String EMAIL_PROVIDER = "GOOGLE";
+    private static final String PEOPLE_API_BASE_URL = "https://people.googleapis.com/v1/people/me";
+
+    private static final String BIRTHDAY = "birthdays";
+
+    public GoogleAuthService(UserService userService, JwtService jwtService) {
+        this.userService = userService;
+        this.jwtService = jwtService;
+    }
+
+    public String authenticate(GoogleAuthDTO googleAuthDTO) throws ApiException {
+        try {
+            GoogleIdToken.Payload payload = verifyIdToken(googleAuthDTO.getIdToken());
+            String email = payload.getEmail();
+            String name = (String) payload.get("name");
+
+            Optional<User> existingUser = userService.findByEmail(email);
+            if (existingUser.isPresent()) {
+                User user = existingUser.get();
+                String userProvider = user.getProvider();
+                if (!EMAIL_PROVIDER.equals(userProvider)) {
+                    throw new UserAlreadyExistsException("An account with this email exists. Please sign in using " + userProvider);
+                }
+                return jwtService.generateToken(user.getId());
+            }
+
+            String accessToken = getAccessToken(googleAuthDTO.getServerAuthCode());
+            LocalDate userBirthdate = getUserBirthdate(accessToken);
+
+            User newUser = new User();
+            newUser.setEmail(email);
+            newUser.setName(name);
+            newUser.setPassword(null);
+            newUser.setProvider(EMAIL_PROVIDER);
+            newUser.setVerified(true);
+            newUser.setRole(Role.REGISTERED_USER);
+            newUser.setBirthdate(userBirthdate);
+
+            User user = userService.save(newUser);
+            logger.info("New user registered via Google authentication: {}", email);
+
+            return jwtService.generateToken(user.getId());
+        } catch (UserAlreadyExistsException e) {
+            throw e;
+        } catch (Exception e) {
+            logger.error("Google authentication failed: {}", e.getMessage());
+            throw new ApiException("Authentication failed");
+        }
+    }
+
+    GoogleIdTokenVerifier createIdTokenVerifier() {
+        return new GoogleIdTokenVerifier.Builder(
+                new NetHttpTransport(), new GsonFactory())
+                .setAudience(Collections.singletonList(googleClientId))
+                .build();
+    }
+
+    GoogleAuthorizationCodeTokenRequest createAuthorizationCodeTokenRequest(String serverAuthCode) {
+        return new GoogleAuthorizationCodeTokenRequest(
+                new NetHttpTransport(),
+                GsonFactory.getDefaultInstance(),
+                "https://oauth2.googleapis.com/token",
+                googleClientId,
+                googleClientSecret,
+                serverAuthCode,
+                "");
+    }
+
+    GoogleIdToken.Payload verifyIdToken(String idTokenString) throws IllegalArgumentException, InvalidCredentialsException, GeneralSecurityException, IOException {
+        if (idTokenString == null) {
+            throw new IllegalArgumentException("ID Token cannot be null");
+        }
+
+        GoogleIdTokenVerifier verifier = createIdTokenVerifier();
+        GoogleIdToken idToken = verifier.verify(idTokenString);
+
+        if (idToken == null) {
+            throw new InvalidCredentialsException("Invalid ID Token");
+        }
+        return idToken.getPayload();
+    }
+
+    protected URL createURL(String urlString) throws IOException {
+        URI uri = URI.create(urlString);
+        return uri.toURL();
+    }
+
+    String getAccessToken(String serverAuthCode) throws IOException {
+        TokenResponse tokenResponse = createAuthorizationCodeTokenRequest(serverAuthCode)
+                .execute();
+
+        return tokenResponse.getAccessToken();
+    }
+
+    String fetchUserData(String accessToken) {
+        try {
+            String apiUrl = PEOPLE_API_BASE_URL + "?personFields=" + GoogleAuthService.BIRTHDAY;
+            URL url = createURL(apiUrl);
+
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            try {
+                conn.setRequestMethod("GET");
+                conn.setRequestProperty("Authorization", "Bearer " + accessToken);
+                conn.setRequestProperty("Accept", "application/json");
+
+                int responseCode = conn.getResponseCode();
+                if (responseCode == HttpURLConnection.HTTP_OK) {
+                    return readResponse(conn.getInputStream());
+                } else {
+                    logger.error("Error fetching data from Google API: HTTP {}", responseCode);
+                    return null;
+                }
+            } finally {
+                conn.disconnect();
+            }
+        } catch (MalformedURLException e) {
+            logger.error("Invalid API URL", e);
+            return null;
+        } catch (IOException e) {
+            logger.error("IO error when fetching user data", e);
+            return null;
+        }
+    }
+
+
+    private String readResponse(InputStream inputStream) throws IOException {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
+            StringBuilder response = new StringBuilder();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                response.append(line);
+            }
+            return response.toString();
+        }
+    }
+
+    LocalDate getUserBirthdate(String accessToken) {
+        String response = fetchUserData(accessToken);
+        return extractBirthday(response);
+    }
+
+    LocalDate extractBirthday(String jsonResponse) {
+        JsonElement rootElement = JsonParser.parseString(jsonResponse);
+        JsonObject rootObj = rootElement.getAsJsonObject();
+
+        if (!rootObj.has(BIRTHDAY)) {
+            return null;
+        }
+
+        JsonArray birthdaysArray = rootObj.getAsJsonArray(BIRTHDAY);
+        if (birthdaysArray.isEmpty()) {
+            return null;
+        }
+
+        JsonObject birthdayObj = birthdaysArray.get(0).getAsJsonObject();
+        if (!birthdayObj.has("date")) {
+            return null;
+        }
+
+        JsonObject dateObj = birthdayObj.getAsJsonObject("date");
+
+        int year = dateObj.has("year") ? dateObj.get("year").getAsInt() : 0;
+        int month = dateObj.get("month").getAsInt();
+        int day = dateObj.get("day").getAsInt();
+
+        if (year > 0) {
+            return LocalDate.of(year, month, day);
+        } else {
+            return LocalDate.of(Year.now().getValue(), month, day);
+        }
+    }
+}
diff --git a/src/main/java/com/safetypin/authentication/service/JwtService.java b/src/main/java/com/safetypin/authentication/service/JwtService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e312b56b08533522f8c47808cc1f1556ef765fa0
--- /dev/null
+++ b/src/main/java/com/safetypin/authentication/service/JwtService.java
@@ -0,0 +1,62 @@
+package com.safetypin.authentication.service;
+
+import com.safetypin.authentication.dto.UserResponse;
+import com.safetypin.authentication.exception.InvalidCredentialsException;
+import com.safetypin.authentication.model.User;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.Keys;
+import org.springframework.stereotype.Service;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.security.Key;
+import java.util.Date;
+import java.util.UUID;
+
+@Service
+public class JwtService {
+    private static final long EXPIRATION_TIME = 86400000; // 1 day
+
+    private final Key key;
+
+    private final UserService userService;
+
+    public JwtService(@Value("${jwt.secret:biggerboysandstolensweethearts}") String secretKey, UserService userService) {
+        this.key = Keys.hmacShaKeyFor(secretKey.getBytes());
+        this.userService = userService;
+    }
+
+    public String generateToken(UUID userId) {
+        return Jwts.builder()
+                .setSubject(userId.toString())
+                .setIssuedAt(new Date(System.currentTimeMillis()))
+                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
+                .signWith(key, SignatureAlgorithm.HS256)
+                .compact();
+    }
+
+    public Claims parseToken(String token) {
+        return Jwts.parserBuilder()
+                .setSigningKey(key)
+                .build()
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    public UserResponse getUserFromJwtToken(String token) throws InvalidCredentialsException {
+        Claims claims = parseToken(token);
+
+        boolean isExpired = claims.getExpiration().before(new Date(System.currentTimeMillis()));
+        UUID userId = UUID.fromString(claims.getSubject());
+
+        if (isExpired) {
+            throw new InvalidCredentialsException("Token expired");
+        } else {
+            User user = userService.findById(userId)
+                    .orElseThrow(() -> new InvalidCredentialsException("User not found"));
+
+            return user.generateUserResponse();
+        }
+    }
+}
diff --git a/src/main/java/com/safetypin/authentication/service/UserService.java b/src/main/java/com/safetypin/authentication/service/UserService.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a17e3ab4106fa5de071ca5dcae6c34143eef812
--- /dev/null
+++ b/src/main/java/com/safetypin/authentication/service/UserService.java
@@ -0,0 +1,29 @@
+package com.safetypin.authentication.service;
+
+import com.safetypin.authentication.model.User;
+import com.safetypin.authentication.repository.UserRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+public class UserService {
+    private final UserRepository userRepository;
+
+    public UserService(UserRepository userRepository) {
+        this.userRepository = userRepository;
+    }
+
+    public Optional<User> findById(UUID id) {
+        return userRepository.findById(id);
+    }
+
+    public Optional<User> findByEmail(String email) {
+        return Optional.ofNullable(userRepository.findByEmail(email));
+    }
+
+    public User save(User user) {
+        return userRepository.save(user);
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 9b8952e3e1f63f29ec58126023430b22ccad6930..1f57723b9a70ad73a3d55c4e9401aa7f9b34885a 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -10,4 +10,6 @@ spring.mail.properties.mail.smtp.auth=true
 spring.mail.properties.mail.smtp.starttls.enable=true
 spring.mail.properties.mail.smtp.starttls.required=true
 
-JWT_SECRET_KEY={$JWT_SECRET_KEY}
\ No newline at end of file
+google.client.id=${GOOGLE_CLIENT_ID:default}
+google.client.secret=${GOOGLE_CLIENT_SECRET:default}
+jwt.secret=${JWT_SECRET:biggerboysandstolensweetheartsss}
\ No newline at end of file
diff --git a/src/test/java/com/safetypin/authentication/controller/AuthenticationControllerTest.java b/src/test/java/com/safetypin/authentication/controller/AuthenticationControllerTest.java
index b847fbf259a73ddff0ab5f3e9af9aebbcd5c9a7f..3002d32c3d68eae6b6713d7fe98bd541c5838547 100644
--- a/src/test/java/com/safetypin/authentication/controller/AuthenticationControllerTest.java
+++ b/src/test/java/com/safetypin/authentication/controller/AuthenticationControllerTest.java
@@ -1,14 +1,17 @@
 package com.safetypin.authentication.controller;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.safetypin.authentication.dto.GoogleAuthDTO;
 import com.safetypin.authentication.dto.PasswordResetRequest;
 import com.safetypin.authentication.dto.RegistrationRequest;
-import com.safetypin.authentication.dto.SocialLoginRequest;
 import com.safetypin.authentication.dto.UserResponse;
 import com.safetypin.authentication.exception.InvalidCredentialsException;
 import com.safetypin.authentication.model.Role;
+import com.safetypin.authentication.exception.UserAlreadyExistsException;
 import com.safetypin.authentication.model.User;
 import com.safetypin.authentication.service.AuthenticationService;
+import com.safetypin.authentication.service.GoogleAuthService;
+import com.safetypin.authentication.service.JwtService;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,9 +43,44 @@ class AuthenticationControllerTest {
     @Autowired
     private AuthenticationService authenticationService;
 
+    @Autowired
+    private GoogleAuthService googleAuthService;
+
+    @Autowired
+    private JwtService jwtService;
+
     @Autowired
     private ObjectMapper objectMapper;
 
+    @TestConfiguration
+    static class TestConfig {
+        @Bean
+        public AuthenticationService authenticationService() {
+            return Mockito.mock(AuthenticationService.class);
+        }
+
+        @Bean
+        public GoogleAuthService googleAuthService() {
+            return Mockito.mock(GoogleAuthService.class);
+        }
+
+        @Bean
+        public JwtService jwtService() {
+            return Mockito.mock(JwtService.class);
+        }
+    }
+
+    @TestConfiguration
+    static class TestSecurityConfig {
+        @Bean
+        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+            http.csrf(AbstractHttpConfigurer::disable)
+                    .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());
+            return http.build();
+        }
+    }
+
+
     @Test
     void testRegisterEmail() throws Exception {
         RegistrationRequest request = new RegistrationRequest();
@@ -61,7 +99,7 @@ class AuthenticationControllerTest {
 
         UUID id = UUID.randomUUID();
         user.setId(id);
-        String token = authenticationService.generateJwtToken(user.getId());
+        String token = jwtService.generateToken(user.getId());
         Mockito.when(authenticationService.registerUser(any(RegistrationRequest.class))).thenReturn(token);
 
         mockMvc.perform(post("/api/auth/register-email")
@@ -71,38 +109,6 @@ class AuthenticationControllerTest {
                 .andExpect(jsonPath("$.data.tokenValue").value(token));
     }
 
-    @Test
-    void testRegisterSocial() throws Exception {
-        SocialLoginRequest request = new SocialLoginRequest();
-        request.setProvider("GOOGLE");
-        request.setSocialToken("token");
-        request.setEmail("social@example.com");
-        request.setName("Social User");
-        request.setBirthdate(LocalDate.now().minusYears(25));
-        request.setSocialId("social123");
-
-        User user = new User();
-        user.setEmail("social@example.com");
-        user.setPassword(null);
-        user.setName("Social User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(request.getBirthdate());
-        user.setProvider("GOOGLE");
-        user.setSocialId("social123");
-
-        UUID id = UUID.randomUUID();
-        user.setId(id);
-        String token = authenticationService.generateJwtToken(user.getId());
-        Mockito.when(authenticationService.socialLogin(any(SocialLoginRequest.class))).thenReturn(token);
-
-        mockMvc.perform(post("/api/auth/register-social")
-                        .contentType(MediaType.APPLICATION_JSON)
-                        .content(objectMapper.writeValueAsString(request)))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.data.tokenValue").value(token));
-    }
-
     @Test
     void testLoginEmail() throws Exception {
         User user = new User();
@@ -113,11 +119,10 @@ class AuthenticationControllerTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(20));
         user.setProvider("EMAIL");
-        user.setSocialId(null);
 
         UUID id = UUID.randomUUID();
         user.setId(id);
-        String token = authenticationService.generateJwtToken(user.getId());
+        String token = jwtService.generateToken(user.getId());
         Mockito.when(authenticationService.loginUser("email@example.com", "password")).thenReturn(token);
 
         mockMvc.perform(post("/api/auth/login-email")
@@ -129,55 +134,24 @@ class AuthenticationControllerTest {
 
     @Test
     void testLoginEmail_InvalidCredentials() throws Exception {
-        String errorMessage = "Invalid email or password";
-        Mockito.when(authenticationService.loginUser("wrong@example.com", "wrongpassword"))
-                .thenThrow(new InvalidCredentialsException(errorMessage));
+        // Prepare test data
+        String email = "email@example.com";
+        String password = "invalidPassword";
 
+        // Mock the service method to throw InvalidCredentialsException
+        Mockito.when(authenticationService.loginUser(email, password))
+                .thenThrow(new InvalidCredentialsException("Invalid email or password"));
+
+        // Perform the test
         mockMvc.perform(post("/api/auth/login-email")
-                        .param("email", "wrong@example.com")
-                        .param("password", "wrongpassword"))
+                        .param("email", email)
+                        .param("password", password))
                 .andExpect(status().isBadRequest())
                 .andExpect(jsonPath("$.success").value(false))
-                .andExpect(jsonPath("$.message").value(errorMessage))
-                .andExpect(jsonPath("$.data").isEmpty());
-    }
-
-    @Test
-    void testLoginSocial() throws Exception {
-        User user = new User();
-        user.setEmail("social@example.com");
-        user.setPassword(null);
-        user.setName("Social User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(LocalDate.now().minusYears(25));
-        user.setProvider("GOOGLE");
-        user.setSocialId("social123");
-
-        UUID id = UUID.randomUUID();
-        user.setId(id);
-        String token = authenticationService.generateJwtToken(user.getId());
-        Mockito.when(authenticationService.loginSocial("social@example.com")).thenReturn(token);
-
-        mockMvc.perform(post("/api/auth/login-social")
-                        .param("email", "social@example.com"))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.data.tokenValue").value(token));
+                .andExpect(jsonPath("$.message").value("Invalid email or password"))
+                .andExpect(jsonPath("$.data").doesNotExist()); // No data expected in case of error
     }
 
-    @Test
-    void testLoginSocial_InvalidCredentials() throws Exception {
-        String errorMessage = "User with this email not found";
-        Mockito.when(authenticationService.loginSocial("nonexistent@example.com"))
-                .thenThrow(new InvalidCredentialsException(errorMessage));
-
-        mockMvc.perform(post("/api/auth/login-social")
-                        .param("email", "nonexistent@example.com"))
-                .andExpect(status().isBadRequest())
-                .andExpect(jsonPath("$.success").value(false))
-                .andExpect(jsonPath("$.message").value(errorMessage))
-                .andExpect(jsonPath("$.data").isEmpty());
-    }
 
     @Test
     void testVerifyOTP_Success() throws Exception {
@@ -228,81 +202,178 @@ class AuthenticationControllerTest {
                 .andExpect(content().string("Password reset instructions have been sent to your email (simulated)"));
     }
 
+
     @Test
-    void testVerifyJwtToken_Success() throws Exception {
-        String validToken = "valid.jwt.token";
-        UUID userId = UUID.randomUUID();
-        UserResponse userResponse = UserResponse.builder()
-                .id(userId)
-                .email("test@example.com")
-                .name("Test User")
-                .isVerified(true)
-                .role("REGISTERED_USER")
-                .birthdate(LocalDate.now().minusYears(25))
-                .provider("EMAIL")
-                .build();
-
-        Mockito.when(authenticationService.getUserFromJwtToken(validToken)).thenReturn(userResponse);
+    void testRegisterEmail_UserAlreadyExistsException() throws Exception {
+        // Prepare registration request
+        RegistrationRequest request = new RegistrationRequest();
+        request.setEmail("existing@example.com");
+        request.setPassword("password");
+        request.setName("Test User");
+        request.setBirthdate(LocalDate.now().minusYears(20));
 
-        mockMvc.perform(post("/api/auth/verify-jwt")
-                        .param("token", validToken))
+        // Mock the service to throw UserAlreadyExistsException
+        String errorMessage = "User with email already exists";
+        Mockito.when(authenticationService.registerUser(Mockito.any(RegistrationRequest.class)))
+                .thenThrow(new UserAlreadyExistsException(errorMessage));
+
+        // Perform the POST request to /register-email endpoint
+        mockMvc.perform(post("/api/auth/register-email")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(request)))
+                .andExpect(status().isBadRequest())
+                .andExpect(jsonPath("$.success").value(false))
+                .andExpect(jsonPath("$.message").value(errorMessage))
+                .andExpect(jsonPath("$.data").doesNotExist());
+    }
+
+    @Test
+    void testDashboard() throws Exception {
+        mockMvc.perform(get("/api/auth/dashboard"))
+                .andExpect(status().isOk())
+                .andExpect(content().string("{}"));
+    }
+
+    @Test
+    void testAuthenticateGoogle_Success() throws Exception {
+        // Prepare test data
+        GoogleAuthDTO googleAuthData = new GoogleAuthDTO();
+        googleAuthData.setIdToken("validGoogleToken");
+        googleAuthData.setServerAuthCode("validServerAuthCode");
+
+        // Generate a mock JWT token
+        String mockJwt = "mockJwtToken123";
+
+        // Mock the service method to return the JWT token
+        Mockito.when(googleAuthService.authenticate(any(GoogleAuthDTO.class)))
+                .thenReturn(mockJwt);
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(googleAuthData)))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.success").value(true))
                 .andExpect(jsonPath("$.message").value("OK"))
-                .andExpect(jsonPath("$.data.email").value("test@example.com"))
-                .andExpect(jsonPath("$.data.name").value("Test User"));
+                .andExpect(jsonPath("$.data.tokenValue").value(mockJwt));
     }
 
     @Test
-    void testVerifyJwtToken_InvalidToken() throws Exception {
-        String invalidToken = "invalid.token";
-        String errorMessage = "Invalid or expired JWT token";
+    void testAuthenticateGoogle_MissingIdToken() throws Exception {
+        // Prepare test data with missing idToken
+        GoogleAuthDTO googleAuthData = new GoogleAuthDTO();
+        googleAuthData.setServerAuthCode("validServerAuthCode");
 
-        Mockito.when(authenticationService.getUserFromJwtToken(invalidToken))
-                .thenThrow(new InvalidCredentialsException(errorMessage));
+        // Perform the test
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(googleAuthData)))
+                .andExpect(status().isBadRequest());
+    }
 
-        mockMvc.perform(post("/api/auth/verify-jwt")
-                        .param("token", invalidToken))
+    @Test
+    void testAuthenticateGoogle_MissingServerAuthCode() throws Exception {
+        // Prepare test data with missing serverAuthCode
+        GoogleAuthDTO googleAuthData = new GoogleAuthDTO();
+        googleAuthData.setIdToken("validGoogleToken");
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(googleAuthData)))
+                .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    void testAuthenticateGoogle_UserAlreadyExists() throws Exception {
+        // Prepare test data
+        GoogleAuthDTO googleAuthData = new GoogleAuthDTO();
+        googleAuthData.setIdToken("existingUserToken");
+        googleAuthData.setServerAuthCode("existingUserAuthCode");
+
+        // Simulate UserAlreadyExistsException
+        String errorMessage = "User with this email already exists";
+        Mockito.when(googleAuthService.authenticate(any(GoogleAuthDTO.class)))
+                .thenThrow(new UserAlreadyExistsException(errorMessage));
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(googleAuthData)))
                 .andExpect(status().isBadRequest())
                 .andExpect(jsonPath("$.success").value(false))
                 .andExpect(jsonPath("$.message").value(errorMessage))
-                .andExpect(jsonPath("$.data").isEmpty());
+                .andExpect(jsonPath("$.data").doesNotExist());
     }
 
     @Test
-    void testPostContent() throws Exception {
-        Mockito.when(authenticationService.postContent("email@example.com", "Test Content"))
-                .thenReturn("Content posted successfully");
+    void testAuthenticateGoogle_GeneralException() throws Exception {
+        // Prepare test data
+        GoogleAuthDTO googleAuthData = new GoogleAuthDTO();
+        googleAuthData.setIdToken("invalidToken");
+        googleAuthData.setServerAuthCode("invalidAuthCode");
+
+        // Simulate a general exception
+        String errorMessage = "Authentication failed: Invalid token";
+        Mockito.when(googleAuthService.authenticate(any(GoogleAuthDTO.class)))
+                .thenThrow(new RuntimeException(errorMessage));
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(googleAuthData)))
+                .andExpect(status().isInternalServerError());
+    }
 
-        mockMvc.perform(post("/api/auth/post")
-                        .param("email", "email@example.com")
-                        .param("content", "Test Content"))
-                .andExpect(status().isOk())
-                .andExpect(content().string("Content posted successfully"));
+    @Test
+    void testAuthenticateGoogle_EmptyInput() throws Exception {
+        // Perform test with empty input
+        mockMvc.perform(post("/api/auth/google")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content("{}"))
+                .andExpect(status().isBadRequest());
     }
 
     @Test
-    void testDashboard() throws Exception {
-        mockMvc.perform(get("/api/auth/dashboard"))
-                .andExpect(status().isOk())
-                .andExpect(content().string("{}"));
+    void testVerifyJwtToken() throws Exception {
+        // Prepare test data
+        String validToken = "valid.jwt.token";
+
+        // Create a mock UserResponse
+        UserResponse userResponse = Mockito.mock(UserResponse.class);
+        UUID userId = UUID.randomUUID();
+
+        // Set up basic behavior for the mock
+        Mockito.when(userResponse.getId()).thenReturn(userId);
+        Mockito.when(userResponse.getEmail()).thenReturn("test@example.com");
+        Mockito.when(userResponse.getName()).thenReturn("Test User");
+
+        // Mock the service method to return the mocked user response
+        Mockito.when(jwtService.getUserFromJwtToken(validToken)).thenReturn(userResponse);
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/verify-jwt")
+                        .param("token", validToken))
+                .andExpect(jsonPath("$.success").value(true))
+                .andExpect(jsonPath("$.message").value("OK"));
     }
 
-    @TestConfiguration
-    static class TestConfig {
-        @Bean
-        public AuthenticationService authenticationService() {
-            return Mockito.mock(AuthenticationService.class);
-        }
+    @Test
+    void testVerifyJwtToken_InvalidToken() throws Exception {
+        // Prepare test data
+        String invalidToken = "invalid.jwt.token";
 
-        @Bean
-        public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-            http
-                    .csrf(AbstractHttpConfigurer::disable)  // Appropriate for JWT authentication
-                    .authorizeHttpRequests(auth -> auth
-                            .anyRequest().permitAll()
-                    );
-            return http.build();
-        }
+        // Mock the service method to throw InvalidCredentialsException
+        Mockito.when(jwtService.getUserFromJwtToken(invalidToken))
+                .thenThrow(new InvalidCredentialsException("Invalid token"));
+
+        // Perform the test
+        mockMvc.perform(post("/api/auth/verify-jwt")
+                        .param("token", invalidToken))
+                .andExpect(status().isBadRequest())
+                .andExpect(jsonPath("$.success").value(false))
+                .andExpect(jsonPath("$.message").value("Invalid token"))
+                .andExpect(jsonPath("$.data").doesNotExist()); // No data expected in case of error
     }
+
 }
diff --git a/src/test/java/com/safetypin/authentication/dto/GoogleAuthDTOTest.java b/src/test/java/com/safetypin/authentication/dto/GoogleAuthDTOTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9d0095f4bed6d5bba42c7710e285122dc2c5933
--- /dev/null
+++ b/src/test/java/com/safetypin/authentication/dto/GoogleAuthDTOTest.java
@@ -0,0 +1,147 @@
+package com.safetypin.authentication.dto;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
+import jakarta.validation.ValidatorFactory;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class GoogleAuthDTOTest {
+
+    private Validator validator;
+
+    @BeforeEach
+    void setUp() {
+        try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
+            validator = factory.getValidator();
+        }
+    }
+
+    @Test
+    void testAllArgsConstructor() {
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        assertNotNull(dto);
+    }
+
+    @Test
+    void testSetterAndGetterMethods() {
+        // Create DTO
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+
+        // Set values
+        dto.setIdToken("test-id-token");
+        dto.setServerAuthCode("test-server-auth-code");
+
+        // Verify getters
+        assertEquals("test-id-token", dto.getIdToken());
+        assertEquals("test-server-auth-code", dto.getServerAuthCode());
+    }
+
+    @Test
+    void testValidation_AllFieldsValid() {
+        // Create DTO with valid fields
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        dto.setIdToken("valid-id-token");
+        dto.setServerAuthCode("valid-server-auth-code");
+
+        // Validate
+        Set<ConstraintViolation<GoogleAuthDTO>> violations = validator.validate(dto);
+        assertTrue(violations.isEmpty(), "No violations expected for valid input");
+    }
+
+    @Test
+    void testValidation_IdTokenBlank() {
+        // Create DTO with blank ID token
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        dto.setIdToken("");
+        dto.setServerAuthCode("valid-server-auth-code");
+
+        // Validate
+        Set<ConstraintViolation<GoogleAuthDTO>> violations = validator.validate(dto);
+        assertFalse(violations.isEmpty(), "Violations expected for blank ID token");
+
+        // Check specific violation
+        assertTrue(violations.stream()
+                        .anyMatch(v -> v.getPropertyPath().toString().equals("idToken")),
+                "Violation should be on idToken field"
+        );
+    }
+
+    @Test
+    void testValidation_ServerAuthCodeBlank() {
+        // Create DTO with blank server auth code
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        dto.setIdToken("valid-id-token");
+        dto.setServerAuthCode("");
+
+        // Validate
+        Set<ConstraintViolation<GoogleAuthDTO>> violations = validator.validate(dto);
+        assertFalse(violations.isEmpty(), "Violations expected for blank server auth code");
+
+        // Check specific violation
+        assertTrue(violations.stream()
+                        .anyMatch(v -> v.getPropertyPath().toString().equals("serverAuthCode")),
+                "Violation should be on serverAuthCode field"
+        );
+    }
+
+    @Test
+    void testValidation_BothFieldsBlank() {
+        // Create DTO with both fields blank
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        dto.setIdToken("");
+        dto.setServerAuthCode("");
+
+        // Validate
+        Set<ConstraintViolation<GoogleAuthDTO>> violations = validator.validate(dto);
+        assertFalse(violations.isEmpty(), "Violations expected when both fields are blank");
+        assertEquals(2, violations.size(), "Should have violations for both fields");
+    }
+
+    @Test
+    void testEqualsAndHashCode() {
+        // Create two identical DTOs
+        GoogleAuthDTO dto1 = new GoogleAuthDTO();
+        dto1.setIdToken("test-token");
+        dto1.setServerAuthCode("test-code");
+
+        GoogleAuthDTO dto2 = new GoogleAuthDTO();
+        dto2.setIdToken("test-token");
+        dto2.setServerAuthCode("test-code");
+
+        GoogleAuthDTO dto3 = new GoogleAuthDTO();
+        dto3.setIdToken("different-token");
+        dto3.setServerAuthCode("different-code");
+
+        // Test equals
+        assertEquals(dto1, dto2, "Identical DTOs should be equal");
+        assertNotEquals(dto1, dto3, "Different DTOs should not be equal");
+        assertNotEquals(null, dto1, "Should not be equal to null");
+        assertNotEquals(new Object(), dto1, "Should not be equal to different object type");
+
+        // Test hashCode
+        assertEquals(dto1.hashCode(), dto2.hashCode(), "Identical DTOs should have same hashCode");
+        assertNotEquals(dto1.hashCode(), dto3.hashCode(), "Different DTOs should have different hashCodes");
+    }
+
+    @Test
+    void testToString() {
+        // Create DTO
+        GoogleAuthDTO dto = new GoogleAuthDTO();
+        dto.setIdToken("test-token");
+        dto.setServerAuthCode("test-code");
+
+        // Check toString
+        String toString = dto.toString();
+        assertNotNull(toString);
+        assertTrue(toString.contains("idToken"));
+        assertTrue(toString.contains("serverAuthCode"));
+        assertTrue(toString.contains("test-token"));
+        assertTrue(toString.contains("test-code"));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/com/safetypin/authentication/model/UserTest.java b/src/test/java/com/safetypin/authentication/model/UserTest.java
index 84891ec12ef5619a680cf7f4c37419b64794a001..cfc7b2a3711b22d2ecbe63e87b40e355072e60c9 100644
--- a/src/test/java/com/safetypin/authentication/model/UserTest.java
+++ b/src/test/java/com/safetypin/authentication/model/UserTest.java
@@ -21,7 +21,6 @@ class UserTest {
         assertNull(user.getRole(), "Default role should be null");
         assertNull(user.getBirthdate(), "Default birthdate should be null");
         assertNull(user.getProvider(), "Default provider should be null");
-        assertNull(user.getSocialId(), "Default socialId should be null");
     }
 
     @Test
@@ -35,7 +34,6 @@ class UserTest {
         Role role = Role.REGISTERED_USER;
         LocalDate birthdate = LocalDate.of(2000, 1, 1);
         String provider = "GOOGLE";
-        String socialId = "social123";
 
         user.setId(id);
         user.setEmail(email);
@@ -45,7 +43,6 @@ class UserTest {
         user.setRole(role);
         user.setBirthdate(birthdate);
         user.setProvider(provider);
-        user.setSocialId(socialId);
 
         assertEquals(id, user.getId());
         assertEquals(email, user.getEmail());
@@ -55,7 +52,6 @@ class UserTest {
         assertEquals(role, user.getRole());
         assertEquals(birthdate, user.getBirthdate());
         assertEquals(provider, user.getProvider());
-        assertEquals(socialId, user.getSocialId());
     }
 
     @Test
@@ -67,7 +63,6 @@ class UserTest {
         Role role = Role.MODERATOR;
         LocalDate birthdate = LocalDate.of(1995, 5, 15);
         String provider = "EMAIL";
-        String socialId = null;
 
         User user = new User();
         user.setEmail(email);
@@ -77,7 +72,6 @@ class UserTest {
         user.setRole(role);
         user.setBirthdate(birthdate);
         user.setProvider(provider);
-        user.setSocialId(socialId);
 
 
         // id remains null until set (by the persistence layer)
@@ -89,7 +83,6 @@ class UserTest {
         assertEquals(role, user.getRole());
         assertEquals(birthdate, user.getBirthdate());
         assertEquals(provider, user.getProvider());
-        assertNull(user.getSocialId(), "SocialId should be null");
     }
 
     @Test
diff --git a/src/test/java/com/safetypin/authentication/seeder/DevDataSeederTest.java b/src/test/java/com/safetypin/authentication/seeder/DevDataSeederTest.java
index 1df2e3a1bdba993fb6f828b37938977bec1f861d..33caa25146cd47b6cf90e9390774cae75f7c6c83 100644
--- a/src/test/java/com/safetypin/authentication/seeder/DevDataSeederTest.java
+++ b/src/test/java/com/safetypin/authentication/seeder/DevDataSeederTest.java
@@ -51,7 +51,6 @@ class DevDataSeederTest {
         user.setRole(Role.MODERATOR);
         user.setBirthdate(LocalDate.of(1990, 1, 1));
         user.setProvider("EMAIL");
-        user.setSocialId("social_9999");
         userRepository.save(user);
 
         long countBefore = userRepository.count();
diff --git a/src/test/java/com/safetypin/authentication/service/AuthenticationServiceTest.java b/src/test/java/com/safetypin/authentication/service/AuthenticationServiceTest.java
index fe61c0e89fe629324ec3b48d980f31ed9c6f6d21..67358617ca0adcb807c47c55c196c98b43e77452 100644
--- a/src/test/java/com/safetypin/authentication/service/AuthenticationServiceTest.java
+++ b/src/test/java/com/safetypin/authentication/service/AuthenticationServiceTest.java
@@ -1,32 +1,18 @@
 package com.safetypin.authentication.service;
 
 import com.safetypin.authentication.dto.RegistrationRequest;
-import com.safetypin.authentication.dto.SocialLoginRequest;
-import com.safetypin.authentication.dto.UserResponse;
 import com.safetypin.authentication.exception.InvalidCredentialsException;
 import com.safetypin.authentication.exception.UserAlreadyExistsException;
 import com.safetypin.authentication.model.Role;
 import com.safetypin.authentication.model.User;
-import com.safetypin.authentication.repository.UserRepository;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.Keys;
-import jakarta.annotation.PostConstruct;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.test.context.TestPropertySource;
 
-import java.security.Key;
 import java.time.LocalDate;
-import java.util.Date;
 import java.util.Optional;
 import java.util.UUID;
 
@@ -38,7 +24,7 @@ import static org.mockito.Mockito.*;
 class AuthenticationServiceTest {
 
     @Mock
-    private UserRepository userRepository;
+    private UserService userService;
 
     @Mock
     private PasswordEncoder passwordEncoder;
@@ -46,18 +32,25 @@ class AuthenticationServiceTest {
     @Mock
     private OTPService otpService;
 
-    @InjectMocks
+    @Mock
+    private JwtService jwtService;
+
     private AuthenticationService authenticationService;
 
+    @BeforeEach
+    void setUp() {
+        authenticationService = new AuthenticationService(userService, passwordEncoder, otpService, jwtService);
+    }
+
     // registerUser tests
-    
+
     @Test
     void testRegisterUser_UnderAge() {
         RegistrationRequest request = new RegistrationRequest();
         request.setEmail("test@example.com");
         request.setPassword("password");
         request.setName("Test User");
-        // set birthdate to 17 years old
+        // set birthdate to 15 years old
         request.setBirthdate(LocalDate.now().minusYears(15));
 
         Exception exception = assertThrows(IllegalArgumentException.class, () ->
@@ -74,7 +67,8 @@ class AuthenticationServiceTest {
         request.setName("Test User");
         request.setBirthdate(LocalDate.now().minusYears(20));
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(new User());
+        User existingUser = new User();
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(existingUser));
 
         Exception exception = assertThrows(UserAlreadyExistsException.class, () ->
                 authenticationService.registerUser(request)
@@ -90,8 +84,9 @@ class AuthenticationServiceTest {
         request.setName("Test User");
         request.setBirthdate(LocalDate.now().minusYears(20));
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(null);
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.empty());
         when(passwordEncoder.encode("password")).thenReturn("encodedPassword");
+
         User savedUser = new User();
         savedUser.setEmail("test@example.com");
         savedUser.setPassword("encodedPassword");
@@ -100,165 +95,36 @@ class AuthenticationServiceTest {
         savedUser.setRole(Role.REGISTERED_USER);
         savedUser.setBirthdate(request.getBirthdate());
         savedUser.setProvider("EMAIL");
-        savedUser.setSocialId(null);
 
         UUID id = UUID.randomUUID();
         savedUser.setId(id);
-        when(userRepository.save(any(User.class))).thenReturn(savedUser);
-        when(userRepository.findById(id)).thenReturn(Optional.of(savedUser));
-
-        String token = authenticationService.registerUser(request);
-        assertNotNull(token);
-        UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
-        assertEquals("test@example.com", userResponse.getEmail());
-        // OTPService should be invoked to generate OTP.
-        verify(otpService, times(1)).generateOTP("test@example.com");
-    }
-
-    // socialLogin tests
-
-    @Test
-    void testSocialLogin_UnderAge() {
-        SocialLoginRequest request = new SocialLoginRequest();
-        request.setEmail("social@example.com");
-        request.setName("Social User");
-        request.setBirthdate(LocalDate.now().minusYears(15));
-        request.setProvider("GOOGLE");
-        request.setSocialId("social123");
-        request.setSocialToken("token");
-
-        Exception exception = assertThrows(IllegalArgumentException.class, () ->
-                authenticationService.socialLogin(request)
-        );
-        assertEquals("User must be at least 16 years old", exception.getMessage());
-    }
 
-    @Test
-    void testSocialLogin_DuplicateEmailWithEmailProvider() {
-        SocialLoginRequest request = new SocialLoginRequest();
-        request.setEmail("social@example.com");
-        request.setName("Social User");
-        request.setBirthdate(LocalDate.now().minusYears(25));
-        request.setProvider("APPLE");
-        request.setSocialId("social123");
-        request.setSocialToken("token");
-
-        User existingUser = new User();
-        existingUser.setEmail("social@example.com");
-        existingUser.setPassword("encodedPassword");
-        existingUser.setName("Existing User");
-        existingUser.setVerified(false);
-        existingUser.setRole(Role.REGISTERED_USER);
-        existingUser.setBirthdate(LocalDate.now().minusYears(30));
-        existingUser.setProvider("EMAIL");
-        existingUser.setSocialId(null);
+        when(userService.save(any(User.class))).thenReturn(savedUser);
+        when(jwtService.generateToken(id)).thenReturn("jwtToken");
 
-        when(userRepository.findByEmail("social@example.com")).thenReturn(existingUser);
-
-        Exception exception = assertThrows(UserAlreadyExistsException.class, () ->
-                authenticationService.socialLogin(request)
-        );
-        assertTrue(exception.getMessage().contains("An account with this email exists"));
-    }
-
-    @Test
-    void testSocialLogin_ExistingSocialUser() {
-        SocialLoginRequest request = new SocialLoginRequest();
-        request.setEmail("social@example.com");
-        request.setName("Social User");
-        request.setBirthdate(LocalDate.now().minusYears(25));
-        request.setProvider("GOOGLE");
-        request.setSocialId("social123");
-        request.setSocialToken("token");
-
-        User existingUser = new User();
-        existingUser.setEmail("social@example.com");
-        existingUser.setPassword(null);
-        existingUser.setName("Social User");
-        existingUser.setVerified(true);
-        existingUser.setRole(Role.REGISTERED_USER);
-        existingUser.setBirthdate(LocalDate.now().minusYears(25));
-        existingUser.setProvider("GOOGLE");
-        existingUser.setSocialId("social123");
-        UUID id = UUID.randomUUID();
-        existingUser.setId(id);
-
-        when(userRepository.findByEmail("social@example.com")).thenReturn(existingUser);
-        when(userRepository.findById(id)).thenReturn(Optional.of(existingUser));
-        when(userRepository.save(any(User.class))).thenReturn(existingUser);
-
-        String token = authenticationService.socialLogin(request);
-        assertNotNull(token);
-        UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
-
-        assertEquals("social@example.com", userResponse.getEmail());
-    }
-
-    @Test
-    void testSocialLogin_NewUser() {
-        SocialLoginRequest request = new SocialLoginRequest();
-        request.setEmail("social@example.com");
-        request.setName("Social User");
-        request.setBirthdate(LocalDate.now().minusYears(25));
-        request.setProvider("GOOGLE");
-        request.setSocialId("social123");
-        request.setSocialToken("token");
-
-        when(userRepository.findByEmail("social@example.com")).thenReturn(null);
-        User savedUser = new User();
-        savedUser.setEmail("social@example.com");
-        savedUser.setPassword(null);
-        savedUser.setName("Social User");
-        savedUser.setVerified(true);
-        savedUser.setRole(Role.REGISTERED_USER);
-        savedUser.setBirthdate(request.getBirthdate());
-        savedUser.setProvider("GOOGLE");
-        savedUser.setSocialId("social123");
-
-        UUID id = UUID.randomUUID();
-        savedUser.setId(id);
-        when(userRepository.save(any(User.class))).thenReturn(savedUser);
-        when(userRepository.findById(id)).thenReturn(Optional.of(savedUser));
+        String token = authenticationService.registerUser(request);
 
-        String token = authenticationService.socialLogin(request);
         assertNotNull(token);
-        UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
-        assertEquals("social@example.com", userResponse.getEmail());
+        assertEquals("jwtToken", token);
+        verify(otpService, times(1)).generateOTP("test@example.com");
+        verify(userService, times(1)).save(any(User.class));
     }
 
     // loginUser tests
 
     @Test
     void testLoginUser_EmailNotFound() {
-        when(userRepository.findByEmail("notfound@example.com")).thenReturn(null);
+        when(userService.findByEmail("notfound@example.com")).thenReturn(Optional.empty());
+
         Exception exception = assertThrows(InvalidCredentialsException.class, () ->
                 authenticationService.loginUser("notfound@example.com", "password")
         );
-        assertTrue(exception.getMessage().contains("Invalid email"));
-    }
 
-    @Test
-    void testLoginUser_InvalidPassword_NullPassword() {
-        User user = new User();
-        user.setEmail("test@example.com");
-        user.setPassword(null);
-        user.setName("Test User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(LocalDate.now().minusYears(20));
-        user.setProvider("EMAIL");
-        user.setSocialId(null);
-
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
-
-        Exception exception = assertThrows(InvalidCredentialsException.class, () ->
-                authenticationService.loginUser("test@example.com", "password")
-        );
-        assertTrue(exception.getMessage().contains("Invalid password"));
+        assertEquals("Invalid email", exception.getMessage());
     }
 
     @Test
-    void testLoginUser_InvalidPassword_WrongMatch() {
+    void testLoginUser_InvalidPassword() {
         User user = new User();
         user.setEmail("test@example.com");
         user.setPassword("encodedPassword");
@@ -267,15 +133,15 @@ class AuthenticationServiceTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(20));
         user.setProvider("EMAIL");
-        user.setSocialId(null);
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(user));
         when(passwordEncoder.matches("wrongPassword", "encodedPassword")).thenReturn(false);
 
         Exception exception = assertThrows(InvalidCredentialsException.class, () ->
                 authenticationService.loginUser("test@example.com", "wrongPassword")
         );
-        assertTrue(exception.getMessage().contains("Invalid password"));
+
+        assertEquals("Invalid password", exception.getMessage());
     }
 
     @Test
@@ -288,55 +154,18 @@ class AuthenticationServiceTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(20));
         user.setProvider("EMAIL");
-        user.setSocialId(null);
 
         UUID id = UUID.randomUUID();
-        user.setId(id
-        );
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
+        user.setId(id);
+
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(user));
         when(passwordEncoder.matches("password", "encodedPassword")).thenReturn(true);
-        when(userRepository.findById(id)).thenReturn(Optional.of(user));
+        when(jwtService.generateToken(id)).thenReturn("jwtToken");
 
         String token = authenticationService.loginUser("test@example.com", "password");
-        assertNotNull(token);
-        UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
-        assertEquals("test@example.com", userResponse.getEmail());
-    }
-
-    // loginSocial tests
-
-    @Test
-    void testLoginSocial_UserNotFound() {
-        when(userRepository.findByEmail("notfound@example.com")).thenReturn(null);
-        Exception exception = assertThrows(InvalidCredentialsException.class, () ->
-                authenticationService.loginSocial("notfound@example.com")
-        );
-        assertTrue(exception.getMessage().contains("Social login failed"));
-    }
 
-    @Test
-    void testLoginSocial_Success() {
-        User user = new User();
-        user.setEmail("social@example.com");
-        user.setPassword(null);
-        user.setName("Social User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(LocalDate.now().minusYears(25));
-        user.setProvider("GOOGLE");
-        user.setSocialId("social123");
-
-        UUID id = UUID.randomUUID();
-        user.setId(id);
-
-        when(userRepository.findByEmail("social@example.com")).thenReturn(user);
-        when(userRepository.findById(id)).thenReturn(Optional.of(user));
-
-        String token = authenticationService.loginSocial("social@example.com");
         assertNotNull(token);
-        UserResponse userResponse = authenticationService.getUserFromJwtToken(token);
-        assertEquals("social@example.com", userResponse.getEmail());
-
+        assertEquals("jwtToken", token);
     }
 
     // verifyOTP tests
@@ -345,6 +174,7 @@ class AuthenticationServiceTest {
     void testVerifyOTP_Success() {
         // OTPService returns true and user is found
         when(otpService.verifyOTP("test@example.com", "123456")).thenReturn(true);
+
         User user = new User();
         user.setEmail("test@example.com");
         user.setPassword("encodedPassword");
@@ -353,34 +183,37 @@ class AuthenticationServiceTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(20));
         user.setProvider("EMAIL");
-        user.setSocialId(null);
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
-        when(userRepository.save(any(User.class))).thenReturn(user);
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(user));
+        when(userService.save(any(User.class))).thenReturn(user);
 
         boolean result = authenticationService.verifyOTP("test@example.com", "123456");
+
         assertTrue(result);
         assertTrue(user.isVerified());
-        verify(userRepository, times(1)).save(user);
+        verify(userService, times(1)).save(user);
     }
 
     @Test
     void testVerifyOTP_Success_UserNotFound() {
         // OTPService returns true but user is not found
         when(otpService.verifyOTP("nonexistent@example.com", "123456")).thenReturn(true);
-        when(userRepository.findByEmail("nonexistent@example.com")).thenReturn(null);
+        when(userService.findByEmail("nonexistent@example.com")).thenReturn(Optional.empty());
 
         boolean result = authenticationService.verifyOTP("nonexistent@example.com", "123456");
+
         assertTrue(result);
-        verify(userRepository, never()).save(any(User.class));
+        verify(userService, never()).save(any(User.class));
     }
 
     @Test
     void testVerifyOTP_Failure() {
         when(otpService.verifyOTP("test@example.com", "000000")).thenReturn(false);
+
         boolean result = authenticationService.verifyOTP("test@example.com", "000000");
+
         assertFalse(result);
-        verify(userRepository, never()).save(any(User.class));
+        verify(userService, never()).save(any(User.class));
     }
 
     // forgotPassword tests
@@ -395,23 +228,25 @@ class AuthenticationServiceTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(20));
         user.setProvider("EMAIL");
-        user.setSocialId(null);
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(user));
 
         assertDoesNotThrow(() -> authenticationService.forgotPassword("test@example.com"));
     }
 
     @Test
-    void testForgotPassword_Invalid() {
-        // Case 1: user not found
-        when(userRepository.findByEmail("notfound@example.com")).thenReturn(null);
-        Exception exception1 = assertThrows(IllegalArgumentException.class, () ->
+    void testForgotPassword_UserNotFound() {
+        when(userService.findByEmail("notfound@example.com")).thenReturn(Optional.empty());
+
+        Exception exception = assertThrows(IllegalArgumentException.class, () ->
                 authenticationService.forgotPassword("notfound@example.com")
         );
-        assertTrue(exception1.getMessage().contains("Password reset is only available for email-registered users."));
 
-        // Case 2: user exists but provider is not EMAIL
+        assertTrue(exception.getMessage().contains("Password reset is only available for email-registered users"));
+    }
+
+    @Test
+    void testForgotPassword_NonEmailProvider() {
         User user = new User();
         user.setEmail("social@example.com");
         user.setPassword(null);
@@ -420,152 +255,15 @@ class AuthenticationServiceTest {
         user.setRole(Role.REGISTERED_USER);
         user.setBirthdate(LocalDate.now().minusYears(25));
         user.setProvider("GOOGLE");
-        user.setSocialId("social123");
-
-        when(userRepository.findByEmail("social@example.com")).thenReturn(user);
-        Exception exception2 = assertThrows(IllegalArgumentException.class, () ->
-                authenticationService.forgotPassword("social@example.com")
-        );
-        assertTrue(exception2.getMessage().contains("Password reset is only available for email-registered users."));
-    }
-
-    // postContent tests
-
-    @Test
-    void testPostContent_UserNotFound() {
-        when(userRepository.findByEmail("notfound@example.com")).thenReturn(null);
-        String response = authenticationService.postContent("notfound@example.com", "Content");
-        assertEquals("User not found. Please register.", response);
-    }
-
-    @Test
-    void testPostContent_UserNotVerified() {
-        User user = new User();
-        user.setEmail("test@example.com");
-        user.setPassword("encodedPassword");
-        user.setName("Test User");
-        user.setVerified(false);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(LocalDate.now().minusYears(20));
-        user.setProvider("EMAIL");
-        user.setSocialId(null);
-
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
-        String response = authenticationService.postContent("test@example.com", "Content");
-        assertTrue(response.contains("not verified"));
-    }
-
-    @Test
-    void testPostContent_UserVerified() {
-        User user = new User();
-        user.setEmail("test@example.com");
-        user.setPassword("encodedPassword");
-        user.setName("Test User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-        user.setBirthdate(LocalDate.now().minusYears(20));
-        user.setProvider("EMAIL");
-        user.setSocialId(null);
 
-        when(userRepository.findByEmail("test@example.com")).thenReturn(user);
-        String response = authenticationService.postContent("test@example.com", "Content");
-        assertEquals("Content posted successfully", response);
-    }
+        when(userService.findByEmail("social@example.com")).thenReturn(Optional.of(user));
 
-    @Test
-    void testJwtTokenExpirationTime() {
-        // Generate a token for a random UUID
-        UUID userId = UUID.randomUUID();
-        String token = authenticationService.generateJwtToken(userId);
-        assertNotNull(token);
-
-        // Parse the token to extract claims
-        Key key = Keys.hmacShaKeyFor("5047c55bfe120155fd4e884845682bb8b8815c0048a686cc664d1ea6c8e094da".getBytes());
-        Claims claims = Jwts.parserBuilder()
-                .setSigningKey(key)
-                .build()
-                .parseClaimsJws(token)
-                .getBody();
-
-        // Extract the issued at and expiration times
-        Date issuedAt = claims.getIssuedAt();
-        Date expiration = claims.getExpiration();
-        assertNotNull(issuedAt);
-        assertNotNull(expiration);
-
-        // Calculate difference and verify it equals 86400000L (24 hours)
-        long timeDifference = expiration.getTime() - issuedAt.getTime();
-        assertEquals(86400000L, timeDifference,
-                "JWT token should expire exactly 24 hours (86400000 milliseconds) after issuance");
-    }
-
-    // Tests for getUserFromJwtToken method
-
-    @Test
-    void testGetUserFromJwtToken_InvalidToken() {
-        // Test with malformed token
-        Exception exception = assertThrows(InvalidCredentialsException.class, () ->
-                authenticationService.getUserFromJwtToken("invalid.token.format")
-        );
-        assertEquals("Invalid token", exception.getMessage());
-    }
-
-    @Test
-    void testGetUserFromJwtToken_ExpiredToken() throws Exception {
-        // Create a JWT token with custom expiration (already expired)
-        UUID userId = UUID.randomUUID();
-        Key key = Keys.hmacShaKeyFor("5047c55bfe120155fd4e884845682bb8b8815c0048a686cc664d1ea6c8e094da".getBytes());
-
-        String expiredToken = Jwts.builder()
-                .setSubject(userId.toString())
-                .setIssuedAt(new Date(System.currentTimeMillis() - 200000)) // 200 seconds ago
-                .setExpiration(new Date(System.currentTimeMillis() - 100000)) // 100 seconds ago (expired)
-                .signWith(key, SignatureAlgorithm.HS256)
-                .compact();
-
-        Exception exception = assertThrows(InvalidCredentialsException.class, () ->
-                authenticationService.getUserFromJwtToken(expiredToken)
-        );
-        assertEquals("Invalid token", exception.getMessage());
-    }
-
-    @Test
-    void testGetUserFromJwtToken_UserNotFound() {
-        // Create valid token with random UUID that doesn't exist in DB
-        UUID nonExistentId = UUID.randomUUID();
-        String token = authenticationService.generateJwtToken(nonExistentId);
-
-        when(userRepository.findById(nonExistentId)).thenReturn(Optional.empty());
-
-        Exception exception = assertThrows(InvalidCredentialsException.class, () ->
-                authenticationService.getUserFromJwtToken(token)
+        Exception exception = assertThrows(IllegalArgumentException.class, () ->
+                authenticationService.forgotPassword("social@example.com")
         );
-        assertEquals("User not found", exception.getMessage());
-    }
-
-    @Test
-    void testGetUserFromJwtToken_Success() {
-        // Create user and token for explicit testing
-        UUID userId = UUID.randomUUID();
-        User user = new User();
-        user.setId(userId);
-        user.setEmail("test@example.com");
-        user.setName("Test User");
-        user.setVerified(true);
-        user.setRole(Role.REGISTERED_USER);
-
-        // Generate a valid token
-        String token = authenticationService.generateJwtToken(userId);
-
-        when(userRepository.findById(userId)).thenReturn(Optional.of(user));
-
-        // Test successful retrieval
-        UserResponse response = authenticationService.getUserFromJwtToken(token);
 
-        assertNotNull(response);
-        assertEquals("test@example.com", response.getEmail());
-        assertEquals("Test User", response.getName());
-        assertTrue(response.isVerified());
+        assertTrue(exception.getMessage().contains("Password reset is only available for email-registered users"));
     }
 
-}
+    // Add missing methods for other functionality if needed
+}
\ No newline at end of file
diff --git a/src/test/java/com/safetypin/authentication/service/GoogleAuthServiceTest.java b/src/test/java/com/safetypin/authentication/service/GoogleAuthServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a411399dd66ca0d35fcdc0818a7b16f5048dc95a
--- /dev/null
+++ b/src/test/java/com/safetypin/authentication/service/GoogleAuthServiceTest.java
@@ -0,0 +1,469 @@
+package com.safetypin.authentication.service;
+
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
+import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
+import com.safetypin.authentication.dto.GoogleAuthDTO;
+import com.safetypin.authentication.exception.ApiException;
+import com.safetypin.authentication.exception.InvalidCredentialsException;
+import com.safetypin.authentication.exception.UserAlreadyExistsException;
+import com.safetypin.authentication.model.User;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.*;
+import org.mockito.junit.jupiter.MockitoExtension;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.*;
+import java.time.LocalDate;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class GoogleAuthServiceTest {
+
+    @Mock
+    private UserService userService;
+
+    @Mock
+    private JwtService jwtService;
+
+    @Mock
+    private GoogleIdToken idToken;
+
+    @Mock
+    private GoogleIdToken.Payload payload;
+
+    @Mock
+    private GoogleIdTokenVerifier verifier;
+
+    @Mock
+    private GoogleAuthorizationCodeTokenRequest tokenRequest;
+
+    @Mock
+    private GoogleTokenResponse tokenResponse;
+
+    @Spy
+    @InjectMocks
+    private GoogleAuthService googleAuthService;
+
+    @Mock
+    private Appender<ILoggingEvent> mockAppender;
+
+    @Captor
+    private ArgumentCaptor<ILoggingEvent> loggingEventCaptor;
+
+    private GoogleAuthDTO googleAuthDTO;
+    private UUID testUserId;
+
+    private final String testAccessToken = "test-access-token";
+
+    private final String testGoogleClientId = "test-client-id";
+
+    private final String testIdToken = "test-id-token";
+
+    @BeforeEach
+    void setup() {
+        ReflectionTestUtils.setField(googleAuthService, "googleClientId", testGoogleClientId);
+        ReflectionTestUtils.setField(googleAuthService, "googleClientSecret", "test-client-secret");
+
+        googleAuthDTO = new GoogleAuthDTO();
+        googleAuthDTO.setIdToken(testIdToken);
+        googleAuthDTO.setServerAuthCode("test-auth-code");
+
+        testUserId = UUID.randomUUID();
+        // Get Logback Logger
+        Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+        root.setLevel(Level.INFO);
+
+        // Clear previous appenders to avoid duplicates
+        root.detachAndStopAllAppenders();
+
+        // Add mock appender
+        root.addAppender(mockAppender);
+    }
+
+    private void setPrivateField(Object instance, String fieldName, Object value) throws Exception {
+        java.lang.reflect.Field field = instance.getClass().getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(instance, value);
+    }
+
+    @Test
+    void authenticate_NewUser_Success() throws Exception {
+        // Mock verify ID token
+        doReturn(payload).when(googleAuthService).verifyIdToken(anyString());
+        when(payload.getEmail()).thenReturn("test@example.com");
+        when(payload.get("name")).thenReturn("Test User");
+
+        // Mock user service
+        when(userService.findByEmail(anyString())).thenReturn(Optional.empty());
+
+        // Mock getAccessToken
+        doReturn(testAccessToken).when(googleAuthService).getAccessToken(anyString());
+
+        // Mock getUserBirthdate to return a specific date
+        LocalDate birthdate = LocalDate.of(1990, 1, 1);
+        doReturn(birthdate).when(googleAuthService).getUserBirthdate(anyString());
+
+        // Mock user save
+        User savedUser = new User();
+        savedUser.setId(testUserId);
+        when(userService.save(any(User.class))).thenReturn(savedUser);
+
+        // Mock JWT generation
+        when(jwtService.generateToken(any(UUID.class))).thenReturn("test-jwt-token");
+
+        // Execute
+        String result = googleAuthService.authenticate(googleAuthDTO);
+
+        // Verify
+        assertEquals("test-jwt-token", result);
+        verify(userService).findByEmail("test@example.com");
+        verify(userService).save(any(User.class));
+        verify(jwtService).generateToken(testUserId);
+    }
+
+    @Test
+    void authenticate_ExistingGoogleUser_Success() throws Exception {
+        // Mock verify ID token
+        doReturn(payload).when(googleAuthService).verifyIdToken(anyString());
+        when(payload.getEmail()).thenReturn("test@example.com");
+
+        // Mock existing user
+        User existingUser = new User();
+        existingUser.setId(testUserId);
+        existingUser.setProvider("GOOGLE");
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(existingUser));
+
+        // Mock JWT generation
+        when(jwtService.generateToken(any(UUID.class))).thenReturn("test-jwt-token");
+
+        // Execute
+        String result = googleAuthService.authenticate(googleAuthDTO);
+
+        // Verify
+        assertEquals("test-jwt-token", result);
+        verify(userService).findByEmail("test@example.com");
+        verify(userService, never()).save(any(User.class));
+        verify(jwtService).generateToken(testUserId);
+    }
+
+    @Test
+    void authenticate_ExistingUserWithDifferentProvider_ThrowsException() throws Exception {
+        // Mock verify ID token
+        doReturn(payload).when(googleAuthService).verifyIdToken(anyString());
+        when(payload.getEmail()).thenReturn("test@example.com");
+
+        // Mock existing user with different provider
+        User existingUser = new User();
+        existingUser.setProvider("EMAIL");
+        when(userService.findByEmail("test@example.com")).thenReturn(Optional.of(existingUser));
+
+        // Execute and verify
+        UserAlreadyExistsException exception = assertThrows(
+                UserAlreadyExistsException.class,
+                () -> googleAuthService.authenticate(googleAuthDTO)
+        );
+
+        assertTrue(exception.getMessage().contains("Please sign in using EMAIL"));
+    }
+
+    @Test
+    void verifyIdToken_NullToken_ThrowsException() {
+        // Execute and verify
+        IllegalArgumentException exception = assertThrows(
+                IllegalArgumentException.class,
+                () -> googleAuthService.verifyIdToken(null)
+        );
+
+        assertEquals("ID Token cannot be null", exception.getMessage());
+    }
+
+    @Test
+    void verifyIdToken_ValidToken_ReturnsPayload() throws Exception {
+        // Mock the verifier creation
+        doReturn(verifier).when(googleAuthService).createIdTokenVerifier();
+
+        // Set up the verifier to return our mock ID token
+        when(verifier.verify(testIdToken)).thenReturn(idToken);
+        when(idToken.getPayload()).thenReturn(payload);
+
+        // Execute
+        GoogleIdToken.Payload result = googleAuthService.verifyIdToken(testIdToken);
+
+        // Verify
+        assertSame(payload, result);
+        verify(verifier).verify(testIdToken);
+    }
+
+    @Test
+    void verifyIdToken_InvalidToken_ThrowsException() throws Exception {
+        // Create a spy on the service to override the verifier creation
+
+        // Mock the verifier creation
+        doReturn(verifier).when(googleAuthService).createIdTokenVerifier();
+
+        // Set up the verifier to return null (invalid token)
+        when(verifier.verify(anyString())).thenReturn(null);
+
+        // Execute and verify
+        InvalidCredentialsException exception = assertThrows(
+                InvalidCredentialsException.class,
+                () -> googleAuthService.verifyIdToken(testIdToken)
+        );
+
+        assertEquals("Invalid ID Token", exception.getMessage());
+        verify(verifier).verify(testIdToken);
+    }
+
+    @Test
+    void getAccessToken_Success() throws Exception {
+
+        // Mock the token request creation
+        doReturn(tokenRequest).when(googleAuthService).createAuthorizationCodeTokenRequest("test-auth-code");
+
+        // Set up the token request to return our mock token response
+        when(tokenRequest.execute()).thenReturn((tokenResponse));
+        when(tokenResponse.getAccessToken()).thenReturn(testAccessToken);
+
+        // Execute
+        String result = googleAuthService.getAccessToken("test-auth-code");
+
+        // Verify
+        assertEquals(testAccessToken, result);
+        verify(tokenRequest).execute();
+    }
+
+    @Test
+    void extractBirthday_ValidResponse_ReturnsBirthdate() {
+        String jsonResponse = "{"
+                + "\"birthdays\": ["
+                + "  {"
+                + "    \"date\": {"
+                + "      \"year\": 1990,"
+                + "      \"month\": 1,"
+                + "      \"day\": 15"
+                + "    }"
+                + "  }"
+                + "]"
+                + "}";
+
+        LocalDate result = googleAuthService.extractBirthday(jsonResponse);
+
+        assertEquals(LocalDate.of(1990, 1, 15), result);
+    }
+
+    @Test
+    void extractBirthday_NoYearProvided_ReturnsCurrentYear() {
+        String jsonResponse = "{"
+                + "\"birthdays\": ["
+                + "  {"
+                + "    \"date\": {"
+                + "      \"month\": 1,"
+                + "      \"day\": 15"
+                + "    }"
+                + "  }"
+                + "]"
+                + "}";
+
+        LocalDate result = googleAuthService.extractBirthday(jsonResponse);
+
+        assertEquals(LocalDate.of(LocalDate.now().getYear(), 1, 15), result);
+    }
+
+    @Test
+    void extractBirthday_NoBirthdayField_ReturnsNull() {
+        String jsonResponse = "{}";
+
+        LocalDate result = googleAuthService.extractBirthday(jsonResponse);
+
+        assertNull(result);
+    }
+
+    @Test
+    void extractBirthday_EmptyBirthdaysArray_ReturnsNull() {
+        String jsonResponse = "{\"birthdays\": []}";
+
+        LocalDate result = googleAuthService.extractBirthday(jsonResponse);
+
+        assertNull(result);
+    }
+
+    @Test
+    void extractBirthday_NoDateField_ReturnsNull() {
+        String jsonResponse = "{"
+                + "\"birthdays\": ["
+                + "  {}"
+                + "]"
+                + "}";
+
+        LocalDate result = googleAuthService.extractBirthday(jsonResponse);
+
+        assertNull(result);
+    }
+
+    @Test
+    void getUserBirthdate_Success() {
+        // Setup private method mocking
+        doReturn("test-json-response").when(googleAuthService).fetchUserData(anyString());
+
+        // Mock extract birthday
+        LocalDate birthdate = LocalDate.of(1990, 1, 15);
+        doReturn(birthdate).when(googleAuthService).extractBirthday(anyString());
+
+        // Execute
+        LocalDate result = googleAuthService.getUserBirthdate(testAccessToken);
+
+        // Verify
+        assertEquals(birthdate, result);
+    }
+
+    @Test
+    void authenticate_Exception_ThrowsApiException() throws Exception {
+        // Mock verify ID token to throw exception
+        doThrow(new IOException("Test exception")).when(googleAuthService).verifyIdToken(anyString());
+
+        // Execute and verify
+        ApiException exception = assertThrows(
+                ApiException.class,
+                () -> googleAuthService.authenticate(googleAuthDTO)
+        );
+
+        assertEquals("Authentication failed", exception.getMessage());
+    }
+
+    @Test
+    void testCreateIdTokenVerifier_Configurations() throws Exception {
+        // Create a real instance of GoogleAuthService for this test
+        GoogleAuthService realService = new GoogleAuthService(userService, jwtService);
+
+        // Use reflection to set the client ID for testing
+        setPrivateField(realService, "googleClientId", testGoogleClientId);
+
+        // Call the createIdTokenVerifier method
+        GoogleIdTokenVerifier googleVerifier = realService.createIdTokenVerifier();
+
+        // Assertions to verify the verifier's configuration
+        assertNotNull(googleVerifier, "Verifier should not be null");
+    }
+
+    @Test
+    void testCreateTokenRequests_Configurations() throws Exception {
+        // Create a real instance of GoogleAuthService for this test
+        GoogleAuthService realService = new GoogleAuthService(userService, jwtService);
+
+        // Use reflection to set the client ID for testing
+        setPrivateField(realService, "googleClientId", testGoogleClientId);
+
+        assertNotNull(realService.createAuthorizationCodeTokenRequest("dumb-bunny"));
+    }
+
+    @Test
+    void testFetchUserData_Successful() {
+        // Create a test GoogleAuthService with a protected method for URL creation
+        GoogleAuthService spyService = spy(new GoogleAuthService(userService, jwtService) {
+            @Override
+            protected URL createURL(String urlString) throws IOException {
+                URL mockUrl = mock(URL.class);
+                HttpURLConnection mockConn = mock(HttpURLConnection.class);
+
+                // Prepare input stream
+                String testResponse = "test response data";
+                InputStream inputStream = new ByteArrayInputStream(testResponse.getBytes());
+
+                // Mock URL and connection behaviors
+                when(mockUrl.openConnection()).thenReturn(mockConn);
+                when(mockConn.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
+                when(mockConn.getInputStream()).thenReturn(inputStream);
+
+                return mockUrl;
+            }
+        });
+
+        // Execute and verify
+        String response = spyService.fetchUserData(testAccessToken);
+        assertEquals("test response data", response);
+    }
+
+    @Test
+    void testFetchUserData_ApiError() {
+        // Arrange & Act
+        String result = googleAuthService.fetchUserData(testAccessToken);
+
+        // Assert
+        assertNull(result);
+
+        // Verify logging occurred
+        verify(mockAppender).doAppend(loggingEventCaptor.capture());
+        ILoggingEvent loggingEvent = loggingEventCaptor.getValue();
+
+        assertEquals(Level.ERROR, loggingEvent.getLevel());
+        assertTrue(loggingEvent.getFormattedMessage().contains("Error fetching data from Google API"));
+    }
+
+    @Test
+    void testFetchUserData_InvalidAPIFormat() throws IOException {
+        // Arrange
+        doThrow(new MalformedURLException("Invalid URL format"))
+                .when(googleAuthService).createURL(anyString());
+
+        // Act
+        String result = googleAuthService.fetchUserData(testAccessToken);
+
+        // Assert
+        assertNull(result);
+
+        // Verify logging occurred
+        verify(mockAppender).doAppend(loggingEventCaptor.capture());
+        ILoggingEvent loggingEvent = loggingEventCaptor.getValue();
+
+        assertEquals(Level.ERROR, loggingEvent.getLevel());
+        assertTrue(loggingEvent.getFormattedMessage().contains("Invalid API URL"));
+    }
+
+    @Test
+    void testFetchUserData_IOException() {
+        // Create a test GoogleAuthService with a protected method for URL creation
+        GoogleAuthService spyService = spy(new GoogleAuthService(userService, jwtService) {
+            @Override
+            protected URL createURL(String urlString) throws IOException {
+                URL mockUrl = mock(URL.class);
+                HttpURLConnection mockConn = mock(HttpURLConnection.class);
+
+                // Mock URL and connection behaviors
+                when(mockUrl.openConnection()).thenReturn(mockConn);
+                when(mockConn.getResponseCode()).thenThrow(new IOException("Network error"));
+
+                return mockUrl;
+            }
+        });
+
+        // Execute and verify
+        String response = spyService.fetchUserData(testAccessToken);
+        assertNull(response);
+
+        // Verify logging occurred
+        verify(mockAppender).doAppend(loggingEventCaptor.capture());
+        ILoggingEvent loggingEvent = loggingEventCaptor.getValue();
+
+        assertEquals(Level.ERROR, loggingEvent.getLevel());
+        assertTrue(loggingEvent.getFormattedMessage().contains("IO error when fetching user data"));
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/safetypin/authentication/service/JwtServiceTest.java b/src/test/java/com/safetypin/authentication/service/JwtServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc11b7f2cc730642b0dfff0a48ec9660e4aecdaa
--- /dev/null
+++ b/src/test/java/com/safetypin/authentication/service/JwtServiceTest.java
@@ -0,0 +1,151 @@
+package com.safetypin.authentication.service;
+
+import com.safetypin.authentication.dto.UserResponse;
+import com.safetypin.authentication.exception.InvalidCredentialsException;
+import com.safetypin.authentication.model.User;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtException;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Date;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class JwtServiceTest {
+
+    @Mock
+    private UserService userService;
+
+    private JwtService jwtService;
+
+    private final String secretKey = "testSecretKeyWithAtLeast256BitsForHmacSha256Algorithm";
+    private final UUID userId = UUID.randomUUID();
+    private final User mockUser = mock(User.class);
+    private final UserResponse mockUserResponse = mock(UserResponse.class);
+
+    @BeforeEach
+    void setUp() {
+        // Create JwtService instance with the mocked UserService and test secret key
+        jwtService = new JwtService(secretKey, userService);
+    }
+
+    @Test
+    void constructor_shouldInitializeKeyAndUserService() {
+        // Verify constructor properly initializes the service
+        assertNotNull(jwtService);
+    }
+
+    @Test
+    void generateToken_shouldCreateValidJwt() {
+        // Generate a token
+        String token = jwtService.generateToken(userId);
+
+        // Verify token is not null or empty
+        assertNotNull(token);
+        assertFalse(token.isEmpty());
+
+        // Verify token can be parsed
+        Claims claims = jwtService.parseToken(token);
+        assertEquals(userId.toString(), claims.getSubject());
+        assertFalse(claims.getExpiration().before(new Date()));
+    }
+
+    @Test
+    void parseToken_shouldDecodeValidToken() {
+        // Generate a token
+        String token = jwtService.generateToken(userId);
+
+        // Parse the token
+        Claims claims = jwtService.parseToken(token);
+
+        // Verify claims
+        assertNotNull(claims);
+        assertEquals(userId.toString(), claims.getSubject());
+        assertNotNull(claims.getIssuedAt());
+        assertNotNull(claims.getExpiration());
+    }
+
+    @Test
+    void parseToken_shouldThrowExceptionForInvalidToken() {
+        // Invalid token
+        String invalidToken = "invalid.token.string";
+
+        // Verify exception is thrown
+        assertThrows(JwtException.class, () -> jwtService.parseToken(invalidToken));
+    }
+
+    @Test
+    void getUserFromJwtToken_shouldReturnUserForValidToken() throws InvalidCredentialsException {
+        // Set up mock responses
+        when(userService.findById(userId)).thenReturn(Optional.of(mockUser));
+        when(mockUser.generateUserResponse()).thenReturn(mockUserResponse);
+
+        // Generate a token
+        String token = jwtService.generateToken(userId);
+
+        // Get user from token
+        UserResponse response = jwtService.getUserFromJwtToken(token);
+
+        // Verify result
+        assertSame(mockUserResponse, response);
+        verify(userService).findById(userId);
+        verify(mockUser).generateUserResponse();
+    }
+
+    @Test
+    void getUserFromJwtToken_shouldThrowExceptionForExpiredToken() {
+        // Create a JwtService with a custom expiration time
+        JwtService shortExpirationJwtService = new JwtService(secretKey, userService);
+
+        // Create a new token with an expiration date in the past
+        Date pastDate = new Date(System.currentTimeMillis() - 1000); // 1 second in the past
+
+        // Use reflection to mock the parseToken method to return expired claims
+        JwtService spyService = spy(shortExpirationJwtService);
+        Claims expiredClaims = mock(Claims.class);
+        when(expiredClaims.getExpiration()).thenReturn(pastDate);
+        when(expiredClaims.getSubject()).thenReturn(userId.toString());
+        doReturn(expiredClaims).when(spyService).parseToken(anyString());
+
+        // Verify exception is thrown
+        InvalidCredentialsException exception = assertThrows(
+                InvalidCredentialsException.class,
+                () -> spyService.getUserFromJwtToken("expired-token")
+        );
+        assertEquals("Token expired", exception.getMessage());
+    }
+
+    @Test
+    void getUserFromJwtToken_shouldThrowExceptionWhenUserNotFound() {
+        // Set up mock to return empty optional
+        when(userService.findById(userId)).thenReturn(Optional.empty());
+
+        // Generate token
+        String token = jwtService.generateToken(userId);
+
+        // Verify exception is thrown
+        InvalidCredentialsException exception = assertThrows(
+                InvalidCredentialsException.class,
+                () -> jwtService.getUserFromJwtToken(token)
+        );
+        assertEquals("User not found", exception.getMessage());
+        verify(userService).findById(userId);
+    }
+
+    @Test
+    void getUserFromJwtToken_shouldHandleInvalidToken() {
+        // Invalid token
+        String invalidToken = "invalid.token.string";
+
+        // Verify exception is thrown
+        assertThrows(JwtException.class, () -> jwtService.getUserFromJwtToken(invalidToken));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/com/safetypin/authentication/service/TokenExpirationTest.java b/src/test/java/com/safetypin/authentication/service/TokenExpirationTest.java
index 6fcd5a1a471e93a0980b12f55cc7cb2f3abcc9d1..0db448055a6d2c6b778ba0dd51478c9d08a32363 100644
--- a/src/test/java/com/safetypin/authentication/service/TokenExpirationTest.java
+++ b/src/test/java/com/safetypin/authentication/service/TokenExpirationTest.java
@@ -7,21 +7,17 @@ import com.safetypin.authentication.repository.UserRepository;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.JwtException;
 import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.Keys;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.springframework.security.crypto.password.PasswordEncoder;
 
-import java.security.Key;
 import java.util.Date;
 import java.util.Optional;
 import java.util.UUID;
 
 import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
 
 public class TokenExpirationTest {
@@ -34,9 +30,16 @@ public class TokenExpirationTest {
     @Mock
     private PasswordEncoder passwordEncoder;
 
+    @Mock
+    private UserService userService;
+
     @Mock
     private OTPService otpService;
 
+    @Mock
+    private JwtService jwtService;
+
+
     @BeforeEach
     void setUp() {
         MockitoAnnotations.openMocks(this);
@@ -46,7 +49,7 @@ public class TokenExpirationTest {
     void testExpiredTokenThrowsCorrectException() {
         // Create a special test-only version of AuthenticationService
         TestAuthenticationService testService = new TestAuthenticationService(
-                userRepository, passwordEncoder, otpService);
+                userService, passwordEncoder, otpService, jwtService);
 
         // Create a UUID for our test
         UUID userId = UUID.randomUUID();
@@ -69,10 +72,11 @@ public class TokenExpirationTest {
 
     // This class extends AuthenticationService to allow us to test specific code paths
     private class TestAuthenticationService extends AuthenticationService {
-        public TestAuthenticationService(UserRepository userRepository, 
+        public TestAuthenticationService(UserService userService,
                                        PasswordEncoder passwordEncoder, 
-                                       OTPService otpService) {
-            super(userRepository, passwordEncoder, otpService);
+                                       OTPService otpService,
+                                         JwtService jwtService) {
+            super(userService, passwordEncoder, otpService, jwtService);
         }
 
         // This method simulates the token expiration check portion of getUserFromJwtToken
diff --git a/src/test/java/com/safetypin/authentication/service/UserServiceTest.java b/src/test/java/com/safetypin/authentication/service/UserServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..64dd562813fecb7c3eee0d4af5171c065b866798
--- /dev/null
+++ b/src/test/java/com/safetypin/authentication/service/UserServiceTest.java
@@ -0,0 +1,125 @@
+package com.safetypin.authentication.service;
+
+import com.safetypin.authentication.model.User;
+import com.safetypin.authentication.repository.UserRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class UserServiceTest {
+
+    @Mock
+    private UserRepository userRepository;
+
+    private UserService userService;
+
+    @BeforeEach
+    void setUp() {
+        userService = new UserService(userRepository);
+    }
+
+    @Test
+    void testFindById_WhenUserExists_ReturnUser() {
+        // Arrange
+        UUID userId = UUID.randomUUID();
+        User expectedUser = new User();
+        expectedUser.setId(userId);
+
+        when(userRepository.findById(userId)).thenReturn(Optional.of(expectedUser));
+
+        // Act
+        Optional<User> result = userService.findById(userId);
+
+        // Assert
+        assertTrue(result.isPresent());
+        assertEquals(expectedUser, result.get());
+        verify(userRepository).findById(userId);
+    }
+
+    @Test
+    void testFindById_WhenUserDoesNotExist_ReturnEmptyOptional() {
+        // Arrange
+        UUID userId = UUID.randomUUID();
+        when(userRepository.findById(userId)).thenReturn(Optional.empty());
+
+        // Act
+        Optional<User> result = userService.findById(userId);
+
+        // Assert
+        assertFalse(result.isPresent());
+        verify(userRepository).findById(userId);
+    }
+
+    @Test
+    void testFindByEmail_WhenUserExists_ReturnUser() {
+        // Arrange
+        String email = "test@example.com";
+        User expectedUser = new User();
+        expectedUser.setEmail(email);
+
+        when(userRepository.findByEmail(email)).thenReturn(expectedUser);
+
+        // Act
+        Optional<User> result = userService.findByEmail(email);
+
+        // Assert
+        assertTrue(result.isPresent());
+        assertEquals(expectedUser, result.get());
+        verify(userRepository).findByEmail(email);
+    }
+
+    @Test
+    void testFindByEmail_WhenUserDoesNotExist_ReturnEmptyOptional() {
+        // Arrange
+        String email = "nonexistent@example.com";
+        when(userRepository.findByEmail(email)).thenReturn(null);
+
+        // Act
+        Optional<User> result = userService.findByEmail(email);
+
+        // Assert
+        assertFalse(result.isPresent());
+        verify(userRepository).findByEmail(email);
+    }
+
+    @Test
+    void testSave_ShouldCallRepositorySaveAndReturnUser() {
+        // Arrange
+        User userToSave = new User();
+        userToSave.setEmail("test@example.com");
+
+        when(userRepository.save(any(User.class))).thenReturn(userToSave);
+
+        // Act
+        User savedUser = userService.save(userToSave);
+
+        // Assert
+        assertNotNull(savedUser);
+        assertEquals(userToSave, savedUser);
+        verify(userRepository).save(userToSave);
+    }
+
+    @Test
+    void testConstructor_InitializesRepositoryCorrectly() {
+        // Arrange & Act
+        UserService service = new UserService(userRepository);
+
+        // Assert
+        assertNotNull(service);
+
+        // Verify that the repository is correctly initialized by calling a method
+        UUID randomId = UUID.randomUUID();
+        service.findById(randomId);
+        verify(userRepository).findById(randomId);
+    }
+}
\ No newline at end of file