Krishna0718 commited on
Commit
bb5169d
·
1 Parent(s): 36117aa

Adding file for new hugging face docker space

Browse files
Files changed (29) hide show
  1. Dockerfile +28 -0
  2. README.md +5 -4
  3. docker-compose.yml +38 -0
  4. pom.xml +93 -0
  5. src/main/java/com/krishna/FormApplication.java +13 -0
  6. src/main/java/com/krishna/config/WebConfig.java +28 -0
  7. src/main/java/com/krishna/controller/CommentController.java +46 -0
  8. src/main/java/com/krishna/controller/LikeController.java +40 -0
  9. src/main/java/com/krishna/controller/PostController.java +115 -0
  10. src/main/java/com/krishna/controller/UserController.java +131 -0
  11. src/main/java/com/krishna/dto/CommentDTO.java +23 -0
  12. src/main/java/com/krishna/dto/LoginResponseDTO.java +70 -0
  13. src/main/java/com/krishna/dto/PostRequestDTO.java +30 -0
  14. src/main/java/com/krishna/dto/PostUpdateDTO.java +29 -0
  15. src/main/java/com/krishna/model/CommentModel.java +46 -0
  16. src/main/java/com/krishna/model/LikeModel.java +56 -0
  17. src/main/java/com/krishna/model/PostModel.java +53 -0
  18. src/main/java/com/krishna/model/UserModel.java +96 -0
  19. src/main/java/com/krishna/repository/CommentRepository.java +11 -0
  20. src/main/java/com/krishna/repository/LikeRepository.java +23 -0
  21. src/main/java/com/krishna/repository/PostRepository.java +13 -0
  22. src/main/java/com/krishna/repository/UserRepository.java +13 -0
  23. src/main/java/com/krishna/service/CommentService.java +48 -0
  24. src/main/java/com/krishna/service/LikeService.java +66 -0
  25. src/main/resources/application.properties +16 -0
  26. src/test/java/com/krishna/controller/CommentControllerTest.java +80 -0
  27. src/test/java/com/krishna/controller/LikeControllerTest.java +92 -0
  28. src/test/java/com/krishna/controller/PostControllerTest.java +147 -0
  29. src/test/java/com/krishna/controller/UserControllerTest.java +118 -0
Dockerfile ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -------- Stage 1: Build the Spring Boot application --------
2
+ FROM maven:3.9.6-eclipse-temurin-21 AS build
3
+
4
+ # Create a working directory
5
+ WORKDIR /app
6
+
7
+ # Copy the Maven project files
8
+ COPY pom.xml .
9
+ COPY src ./src
10
+
11
+ # Build the project (skip tests to speed up)
12
+ RUN mvn clean package -DskipTests
13
+
14
+
15
+ # -------- Stage 2: Create a lightweight runtime image --------
16
+ FROM openjdk:21-jdk
17
+
18
+ # Set working directory in runtime container
19
+ WORKDIR /app
20
+
21
+ # Copy the built jar file from the build stage
22
+ COPY --from=build /app/target/*.jar app.jar
23
+
24
+ # Expose the Spring Boot default port
25
+ EXPOSE 8080
26
+
27
+ # Run the app
28
+ ENTRYPOINT ["java", "-jar", "app.jar"]
README.md CHANGED
@@ -1,10 +1,11 @@
1
  ---
2
- title: Mymedia Java Backend
3
- emoji: 📉
4
- colorFrom: pink
5
- colorTo: blue
6
  sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: My Media
3
+ emoji: 🏢
4
+ colorFrom: green
5
+ colorTo: pink
6
  sdk: docker
7
  pinned: false
8
+ license: mit
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
docker-compose.yml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.7'
2
+ services:
3
+ app:
4
+ build:
5
+ context: .
6
+ dockerfile: Dockerfile
7
+ ports:
8
+ - 8081:8080
9
+ depends_on:
10
+ mysqldb:
11
+ condition: service_healthy
12
+ environment:
13
+ - SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb:3306/mystara
14
+ - SPRING_DATASOURCE_USERNAME=root
15
+ - SPRING_DATASOURCE_PASSWORD=root
16
+ networks:
17
+ - springboot-mysql-network
18
+ mysqldb:
19
+ image: mysql:8.0
20
+ ports:
21
+ - 3307:3306
22
+ environment:
23
+ - MYSQL_DATABASE=mystara
24
+ - MYSQL_ROOT_PASSWORD=root
25
+ volumes:
26
+ - mysql-data:/var/lib/mysql
27
+ networks:
28
+ - springboot-mysql-network
29
+ healthcheck:
30
+ test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-proot"]
31
+ retries: 10
32
+ interval: 3s
33
+ timeout: 30s
34
+ volumes:
35
+ mysql-data:
36
+ networks:
37
+ springboot-mysql-network:
38
+ name: springboot-mysql-network
pom.xml ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5
+ <modelVersion>4.0.0</modelVersion>
6
+ <parent>
7
+ <groupId>org.springframework.boot</groupId>
8
+ <artifactId>spring-boot-starter-parent</artifactId>
9
+ <version>3.1.5</version>
10
+ <relativePath />
11
+ </parent>
12
+ <groupId>com.bezkoder</groupId>
13
+ <artifactId>My_media</artifactId>
14
+ <version>0.0.1-SNAPSHOT</version>
15
+ <name>spring-boot-data-jpa</name>
16
+ <description>Demo project for Spring Boot Apis CRUD using Spring Data JPA</description>
17
+
18
+ <properties>
19
+ <java.version>21</java.version>
20
+ </properties>
21
+
22
+ <dependencies>
23
+ <!-- Web -->
24
+ <dependency>
25
+ <groupId>org.springframework.boot</groupId>
26
+ <artifactId>spring-boot-starter-web</artifactId>
27
+ </dependency>
28
+
29
+ <!-- Spring Data JPA -->
30
+ <dependency>
31
+ <groupId>org.springframework.boot</groupId>
32
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
33
+ </dependency>
34
+
35
+ <!-- MySQL Driver -->
36
+ <dependency>
37
+ <groupId>com.mysql</groupId>
38
+ <artifactId>mysql-connector-j</artifactId>
39
+ <scope>runtime</scope>
40
+ </dependency>
41
+
42
+ <!-- Validation (optional but useful for input checks) -->
43
+ <dependency>
44
+ <groupId>jakarta.validation</groupId>
45
+ <artifactId>jakarta.validation-api</artifactId>
46
+ </dependency>
47
+
48
+ <!-- Lombok (optional, for cleaner model code) -->
49
+ <dependency>
50
+ <groupId>org.projectlombok</groupId>
51
+ <artifactId>lombok</artifactId>
52
+ <optional>true</optional>
53
+ </dependency>
54
+
55
+ <!-- Testing -->
56
+ <dependency>
57
+ <groupId>org.springframework.boot</groupId>
58
+ <artifactId>spring-boot-starter-test</artifactId>
59
+ <scope>test</scope>
60
+ </dependency>
61
+
62
+ <!--Swagger-->
63
+ <dependency>
64
+ <groupId>org.springdoc</groupId>
65
+ <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
66
+ <version>2.2.0</version>
67
+ </dependency>
68
+ <!-- JWT -->
69
+ <dependency>
70
+ <groupId>com.auth0</groupId>
71
+ <artifactId>java-jwt</artifactId>
72
+ <version>4.4.0</version>
73
+ </dependency>
74
+
75
+
76
+ <dependency>
77
+ <groupId>commons-codec</groupId>
78
+ <artifactId>commons-codec</artifactId>
79
+ <version>1.15</version>
80
+ </dependency>
81
+ </dependencies>
82
+
83
+
84
+ <build>
85
+ <plugins>
86
+ <plugin>
87
+ <groupId>org.springframework.boot</groupId>
88
+ <artifactId>spring-boot-maven-plugin</artifactId>
89
+ </plugin>
90
+ </plugins>
91
+ </build>
92
+
93
+ </project>
src/main/java/com/krishna/FormApplication.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna;
2
+
3
+ import org.springframework.boot.SpringApplication;
4
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
5
+
6
+ @SpringBootApplication
7
+ public class FormApplication {
8
+
9
+ public static void main(String[] args) {
10
+ SpringApplication.run(FormApplication.class, args);
11
+ }
12
+
13
+ }
src/main/java/com/krishna/config/WebConfig.java ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.config;
2
+
3
+ import org.springframework.context.annotation.Bean;
4
+ import org.springframework.context.annotation.Configuration;
5
+ import org.springframework.web.servlet.config.annotation.CorsRegistry;
6
+ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7
+
8
+ @Configuration
9
+ public class WebConfig {
10
+
11
+ @Bean
12
+ public WebMvcConfigurer corsConfigurer() {
13
+ return new WebMvcConfigurer() {
14
+ @Override
15
+ public void addCorsMappings(CorsRegistry registry) {
16
+ registry.addMapping("/**")
17
+ .allowedOrigins(
18
+ "http://127.0.0.1:5500",
19
+ "http://localhost:5173",
20
+ "https://my-media-718.netlify.app"
21
+ )
22
+ .allowedMethods("*")
23
+ .allowedHeaders("*")
24
+ .allowCredentials(true);
25
+ }
26
+ };
27
+ }
28
+ }
src/main/java/com/krishna/controller/CommentController.java ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.krishna.dto.CommentDTO;
4
+ import com.krishna.model.CommentModel;
5
+ import com.krishna.service.CommentService;
6
+ import org.springframework.beans.factory.annotation.Autowired;
7
+ import org.springframework.http.HttpStatus;
8
+ import org.springframework.http.ResponseEntity;
9
+ import org.springframework.web.bind.annotation.*;
10
+
11
+ import java.util.List;
12
+
13
+ @CrossOrigin(origins = {"http://localhost:8080", "http://localhost:8081", "http://127.0.0.1:5500", "http://localhost:5173/", "https://my-media-718.netlify.app/"})
14
+ @RestController
15
+ @RequestMapping("/comments")
16
+ public class CommentController {
17
+
18
+ @Autowired
19
+ private CommentService commentService;
20
+
21
+ @PostMapping("/add")
22
+ public ResponseEntity<?> addComment(@RequestBody CommentDTO dto) {
23
+ try {
24
+ CommentModel comment = commentService.addComment(dto);
25
+ return ResponseEntity.ok(comment);
26
+ } catch (Exception e) {
27
+ return ResponseEntity.badRequest().body("Error: " + e.getMessage());
28
+ }
29
+ }
30
+
31
+ @GetMapping("/post/{postId}")
32
+ public ResponseEntity<List<CommentModel>> getComments(@PathVariable Long postId) {
33
+ return ResponseEntity.ok(commentService.getCommentsByPost(postId));
34
+ }
35
+
36
+ // ✅ Corrected delete mapping for deleting a COMMENT
37
+ @DeleteMapping("/{commentId}")
38
+ public ResponseEntity<String> deleteComment(@PathVariable Long commentId) {
39
+ try {
40
+ commentService.deleteComment(commentId);
41
+ return ResponseEntity.ok("Comment deleted successfully.");
42
+ } catch (Exception e) {
43
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Error: " + e.getMessage());
44
+ }
45
+ }
46
+ }
src/main/java/com/krishna/controller/LikeController.java ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.krishna.service.LikeService;
4
+ import org.springframework.beans.factory.annotation.Autowired;
5
+ import org.springframework.http.ResponseEntity;
6
+ import org.springframework.web.bind.annotation.*;
7
+
8
+ import java.util.UUID;
9
+
10
+ @CrossOrigin(origins = {"http://localhost:8080", "http://localhost:8081", "http://127.0.0.1:5500", "http://localhost:5173/", "https://my-media-718.netlify.app"})
11
+ @RestController
12
+ @RequestMapping("/likes")
13
+ public class LikeController {
14
+
15
+ @Autowired
16
+ private LikeService likeService;
17
+
18
+ @PostMapping("/toggle")
19
+ public ResponseEntity<String> toggleLike(
20
+ @RequestParam UUID userId,
21
+ @RequestParam Long postId
22
+ ) {
23
+ boolean liked = likeService.toggleLike(userId, postId);
24
+ return ResponseEntity.ok(liked ? "Post liked successfully" : "Post unliked");
25
+ }
26
+
27
+ @GetMapping("/count/{postId}")
28
+ public Long getLikeCount(@PathVariable Long postId) {
29
+ return likeService.getLikeCount(postId);
30
+ }
31
+
32
+ @GetMapping("/status")
33
+ public ResponseEntity<Boolean> checkIfUserLikedPost(
34
+ @RequestParam UUID userId,
35
+ @RequestParam Long postId
36
+ ) {
37
+ boolean liked = likeService.hasUserLikedPost(userId, postId);
38
+ return ResponseEntity.ok(liked);
39
+ }
40
+ }
src/main/java/com/krishna/controller/PostController.java ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.krishna.dto.PostRequestDTO;
4
+ import com.krishna.dto.PostUpdateDTO;
5
+ import com.krishna.model.PostModel;
6
+ import com.krishna.model.UserModel;
7
+ import com.krishna.repository.LikeRepository;
8
+ import com.krishna.repository.PostRepository;
9
+ import com.krishna.repository.UserRepository;
10
+ import org.springframework.beans.factory.annotation.Autowired;
11
+ import org.springframework.http.HttpStatus;
12
+ import org.springframework.http.ResponseEntity;
13
+ import org.springframework.web.bind.annotation.*;
14
+
15
+ import java.util.List;
16
+ import java.util.Optional;
17
+ import java.util.UUID;
18
+
19
+ @RestController
20
+ @RequestMapping("/posts")
21
+ @CrossOrigin(origins = {"http://localhost:8080", "http://localhost:8081", "http://127.0.0.1:5500", "http://localhost:5173/", "https://my-media-718.netlify.app/"})
22
+ public class PostController {
23
+
24
+ @Autowired
25
+ private PostRepository postRepository;
26
+
27
+ @Autowired
28
+ private UserRepository userRepository;
29
+
30
+ @Autowired
31
+ private LikeRepository likeRepository;
32
+
33
+ @PostMapping("/add")
34
+ public ResponseEntity<PostModel> createPost(@RequestBody PostRequestDTO postRequestDTO) {
35
+ try {
36
+ UUID userId = postRequestDTO.getUserId();
37
+ if (userId == null) {
38
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
39
+ }
40
+
41
+ UserModel user = userRepository.findById(userId).orElse(null);
42
+ if (user == null) {
43
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
44
+ }
45
+
46
+ PostModel postModel = new PostModel();
47
+ postModel.setUserModel(user);
48
+ postModel.setContent(postRequestDTO.getContent());
49
+ postModel.setImageUrl(postRequestDTO.getImageUrl());
50
+
51
+ PostModel savedPost = postRepository.save(postModel);
52
+ return ResponseEntity.status(HttpStatus.CREATED).body(savedPost);
53
+
54
+ } catch (Exception e) {
55
+ e.printStackTrace();
56
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
57
+ }
58
+ }
59
+
60
+ // READ: All Posts
61
+ @GetMapping
62
+ public ResponseEntity<List<PostModel>> getAllPosts() {
63
+ try {
64
+ List<PostModel> posts = postRepository.findAll();
65
+ return ResponseEntity.ok(posts);
66
+ } catch (Exception e) {
67
+ e.printStackTrace();
68
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
69
+ }
70
+ }
71
+
72
+ // UPDATE
73
+ @PutMapping("/{id}")
74
+ public ResponseEntity<PostModel> updatePost(@PathVariable Long id, @RequestBody PostUpdateDTO postUpdateDTO) {
75
+ try {
76
+ Optional<PostModel> optionalPost = postRepository.findById(id);
77
+ if (optionalPost.isEmpty()) {
78
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
79
+ }
80
+
81
+ PostModel post = optionalPost.get();
82
+ post.setContent(postUpdateDTO.getContent());
83
+ post.setImageUrl(postUpdateDTO.getImageUrl());
84
+
85
+ PostModel updatedPost = postRepository.save(post);
86
+ return ResponseEntity.ok(updatedPost);
87
+
88
+ } catch (Exception e) {
89
+ e.printStackTrace();
90
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
91
+ }
92
+ }
93
+
94
+ // DELETE
95
+ @DeleteMapping("/{id}")
96
+ public ResponseEntity<String> deletePost(@PathVariable Long id) {
97
+ try {
98
+ Optional<PostModel> optionalPost = postRepository.findById(id);
99
+ if (optionalPost.isEmpty()) {
100
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Post not found");
101
+ }
102
+
103
+ // Delete associated likes first
104
+ likeRepository.deleteByPostId(id);
105
+
106
+
107
+ postRepository.deleteById(id);
108
+ return ResponseEntity.ok("Post deleted successfully");
109
+
110
+ } catch (Exception e) {
111
+ e.printStackTrace();
112
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Something went wrong");
113
+ }
114
+ }
115
+ }
src/main/java/com/krishna/controller/UserController.java ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.auth0.jwt.JWT;
4
+ import com.auth0.jwt.algorithms.Algorithm;
5
+ import com.krishna.dto.LoginResponseDTO;
6
+ import com.krishna.model.UserModel;
7
+ import com.krishna.repository.UserRepository;
8
+ import org.springframework.beans.factory.annotation.Autowired;
9
+ import org.springframework.http.HttpStatus;
10
+ import org.springframework.http.ResponseEntity;
11
+ import org.springframework.web.bind.annotation.*;
12
+
13
+ import java.security.MessageDigest;
14
+ import java.util.Date;
15
+ import java.util.List;
16
+ import java.util.Optional;
17
+
18
+ @CrossOrigin(origins = {"http://localhost:8080", "http://localhost:8081", "http://127.0.0.1:5500", "http://localhost:5173/", "https://my-media-718.netlify.app/"})
19
+ @RestController
20
+ @RequestMapping("/user")
21
+ public class UserController {
22
+
23
+ @Autowired
24
+ private UserRepository userRepository;
25
+
26
+ private final String JWT_SECRET = "your_secret_key"; // Replace with a secure secret in production
27
+
28
+ // 🔐 Utility method to hash password with SHA-1
29
+ private String hashPasswordSHA1(String password) throws Exception {
30
+ MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
31
+ byte[] hashBytes = sha1.digest(password.getBytes("UTF-8"));
32
+ StringBuilder sb = new StringBuilder();
33
+ for (byte b : hashBytes) {
34
+ sb.append(String.format("%02x", b));
35
+ }
36
+ return sb.toString();
37
+ }
38
+
39
+ // 📝 Register a new user
40
+ @PostMapping("/register")
41
+ public ResponseEntity<?> registerUser(@RequestBody UserModel user) {
42
+ try {
43
+ if (user.getEmail() == null || user.getPassword() == null) {
44
+ return ResponseEntity.badRequest().body("Email, password and username are required.");
45
+ }
46
+
47
+ Optional<UserModel> existingUser = userRepository.findByEmail(user.getEmail());
48
+ if (existingUser.isPresent()) {
49
+ return ResponseEntity.badRequest().body("Email already registered.");
50
+ }
51
+
52
+ // 🔐 Hash password before storing
53
+ String hashedPassword = hashPasswordSHA1(user.getPassword());
54
+ user.setPassword(hashedPassword);
55
+
56
+ // ✅ Set default profile image if not provided
57
+ if (user.getProfileUrl() == null || user.getProfileUrl().isEmpty()) {
58
+ user.setProfileUrl("../assets/images/profile-pic.jpg");
59
+ }
60
+
61
+ UserModel savedUser = userRepository.save(user);
62
+ return ResponseEntity.ok(savedUser);
63
+
64
+ } catch (Exception e) {
65
+ e.printStackTrace();
66
+ return ResponseEntity.status(500).body("Error: " + e.getMessage());
67
+ }
68
+ }
69
+
70
+
71
+ // 🔐 Login a user
72
+ @PostMapping("/login")
73
+ public ResponseEntity<?> loginUser(@RequestBody UserModel loginRequest) {
74
+ try {
75
+ if (loginRequest.getEmail() == null || loginRequest.getPassword() == null) {
76
+ return ResponseEntity.badRequest().body("Email and password are required.");
77
+ }
78
+
79
+ Optional<UserModel> userOpt = userRepository.findByEmail(loginRequest.getEmail());
80
+ if (userOpt.isPresent()) {
81
+ UserModel user = userOpt.get();
82
+
83
+ // 🔐 Hash incoming password
84
+ String hashedInputPassword = hashPasswordSHA1(loginRequest.getPassword());
85
+
86
+ // ✅ Match hashed password
87
+ if (user.getPassword().equals(hashedInputPassword)) {
88
+ String token = generateToken(user);
89
+
90
+ LoginResponseDTO response = new LoginResponseDTO(
91
+ user.getId(),
92
+ user.getEmail(),
93
+ token,
94
+ user.getUsername(),
95
+ user.getFullName(),
96
+ user.getProfileUrl()
97
+ );
98
+
99
+ return ResponseEntity.ok(response);
100
+ } else {
101
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid password.");
102
+ }
103
+ } else {
104
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found.");
105
+ }
106
+
107
+ } catch (Exception e) {
108
+ e.printStackTrace();
109
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Login error: " + e.getMessage());
110
+ }
111
+ }
112
+
113
+ // 🔐 JWT Token generation
114
+ private String generateToken(UserModel user) {
115
+ Algorithm algorithm = Algorithm.HMAC256(JWT_SECRET);
116
+ return JWT.create()
117
+ .withSubject(user.getEmail())
118
+ .withClaim("fullName", user.getFullName())
119
+ .withIssuedAt(new Date())
120
+ .withExpiresAt(new Date(System.currentTimeMillis() + 3600 * 1000))
121
+ .sign(algorithm);
122
+ }
123
+
124
+ // 🔍 Search users by username or fullName
125
+ @GetMapping("/search")
126
+ public ResponseEntity<List<UserModel>> searchUsers(@RequestParam("query") String query) {
127
+ List<UserModel> users = userRepository.findByUsernameContainingIgnoreCaseOrFullNameContainingIgnoreCase(query, query);
128
+ return ResponseEntity.ok(users);
129
+ }
130
+
131
+ }
src/main/java/com/krishna/dto/CommentDTO.java ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.dto;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonProperty;
4
+
5
+ import java.util.UUID;
6
+
7
+ public class CommentDTO {
8
+ @JsonProperty("userId")
9
+ private UUID userId;
10
+ @JsonProperty("postId")
11
+ private Long postId;
12
+
13
+ private String content;
14
+
15
+ public UUID getUserId() { return userId; }
16
+ public void setUserId(UUID userId) { this.userId = userId; }
17
+
18
+ public Long getPostId() { return postId; }
19
+ public void setPostId(Long postId) { this.postId = postId; }
20
+
21
+ public String getContent() { return content; }
22
+ public void setContent(String content) { this.content = content; }
23
+ }
src/main/java/com/krishna/dto/LoginResponseDTO.java ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.dto;
2
+
3
+ import java.util.UUID;
4
+
5
+ public class LoginResponseDTO {
6
+ private UUID userId;
7
+ private String email;
8
+ private String token;
9
+ private String username;
10
+ private String fullName;
11
+ private String profileUrl;
12
+
13
+ public LoginResponseDTO(UUID userId, String email, String token, String username, String fullName, String profileUrl) {
14
+ this.userId = userId;
15
+ this.email = email;
16
+ this.username = username;
17
+ this.token = token;
18
+ this.fullName = fullName;
19
+ this.profileUrl = profileUrl;
20
+ }
21
+
22
+ // Getters and Setters
23
+ public UUID getUserId() {
24
+ return userId;
25
+ }
26
+
27
+ public void setUserId(UUID userId) {
28
+ this.userId = userId;
29
+ }
30
+
31
+ public String getEmail() {
32
+ return email;
33
+ }
34
+
35
+ public void setEmail(String email) {
36
+ this.email = email;
37
+ }
38
+
39
+ public String getToken() {
40
+ return token;
41
+ }
42
+
43
+ public void setToken(String token) {
44
+ this.token = token;
45
+ }
46
+
47
+ public String getUsername() {
48
+ return username;
49
+ }
50
+
51
+ public void setUsername(String username) {
52
+ this.username = username;
53
+ }
54
+
55
+ public String getFullName() {
56
+ return fullName;
57
+ }
58
+
59
+ public void setFullName(String fullName) {
60
+ this.fullName = fullName;
61
+ }
62
+
63
+ public String getProfileUrl() {
64
+ return profileUrl;
65
+ }
66
+
67
+ public void setProfileUrl(String profileUrl) {
68
+ this.profileUrl = profileUrl;
69
+ }
70
+ }
src/main/java/com/krishna/dto/PostRequestDTO.java ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.dto;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonProperty;
4
+
5
+ import java.util.UUID;
6
+
7
+ public class PostRequestDTO {
8
+ private String content;
9
+
10
+ @JsonProperty("imageUrl")
11
+ private String imageUrl;
12
+
13
+ @JsonProperty("userId")
14
+ private UUID userId;
15
+
16
+ public PostRequestDTO(UUID userId, String content, String imageUrl) {
17
+ this.userId = userId;
18
+ this.content = content;
19
+ this.imageUrl = imageUrl;
20
+ }
21
+
22
+ public String getContent() { return content; }
23
+ public void setContent(String content) { this.content = content; }
24
+
25
+ public String getImageUrl() { return imageUrl; }
26
+ public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
27
+
28
+ public UUID getUserId() { return userId; }
29
+ public void setUserId(UUID userId) { this.userId = userId; }
30
+ }
src/main/java/com/krishna/dto/PostUpdateDTO.java ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.dto;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonProperty;
4
+
5
+ import java.util.UUID;
6
+
7
+ public class PostUpdateDTO {
8
+ private String content;
9
+
10
+ @JsonProperty("image_url")
11
+ private String imageUrl;
12
+
13
+ @JsonProperty("userId")
14
+ private UUID userId;
15
+
16
+ public PostUpdateDTO( String content, String imageUrl) {
17
+ this.content = content;
18
+ this.imageUrl = imageUrl;
19
+ }
20
+
21
+ public String getContent() { return content; }
22
+ public void setContent(String content) { this.content = content; }
23
+
24
+ public String getImageUrl() { return imageUrl; }
25
+ public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
26
+
27
+ public UUID getUserId() { return userId; }
28
+ public void setUserId(UUID userId) { this.userId = userId; }
29
+ }
src/main/java/com/krishna/model/CommentModel.java ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.model;
2
+
3
+ import jakarta.persistence.*;
4
+ import java.util.UUID;
5
+
6
+ @Entity
7
+ @Table(name = "comments")
8
+ public class CommentModel {
9
+
10
+ @Id
11
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
12
+ private Long id;
13
+
14
+ @Column(nullable = false)
15
+ private String content;
16
+
17
+ @ManyToOne
18
+ @JoinColumn(name = "user_id", nullable = false)
19
+ private UserModel user;
20
+
21
+ @ManyToOne
22
+ @JoinColumn(name = "post_id", nullable = false)
23
+ private PostModel post;
24
+
25
+ // Constructors
26
+ public CommentModel() {}
27
+
28
+ public CommentModel(String content, UserModel user, PostModel post) {
29
+ this.content = content;
30
+ this.user = user;
31
+ this.post = post;
32
+ }
33
+
34
+ // Getters and Setters
35
+ public Long getId() { return id; }
36
+ public void setId(Long id) { this.id = id; }
37
+
38
+ public String getContent() { return content; }
39
+ public void setContent(String content) { this.content = content; }
40
+
41
+ public UserModel getUser() { return user; }
42
+ public void setUser(UserModel user) { this.user = user; }
43
+
44
+ public PostModel getPost() { return post; }
45
+ public void setPost(PostModel post) { this.post = post; }
46
+ }
src/main/java/com/krishna/model/LikeModel.java ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.model;
2
+
3
+ import jakarta.persistence.*;
4
+ import java.util.*;
5
+
6
+ @Entity
7
+ @Table(name = "likes", uniqueConstraints = {
8
+ @UniqueConstraint(columnNames = {"user_id", "post_id"})
9
+ })
10
+ public class LikeModel {
11
+
12
+ @Id
13
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
14
+ private Long id;
15
+
16
+ @ManyToOne
17
+ private UserModel user;
18
+
19
+ @ManyToOne
20
+ private PostModel post;
21
+
22
+
23
+
24
+ public LikeModel() {}
25
+
26
+ public LikeModel(UserModel user, PostModel post) {
27
+ this.user = user;
28
+ this.post = post;
29
+ }
30
+
31
+ // Getters and setters
32
+
33
+ public Long getId() {
34
+ return id;
35
+ }
36
+
37
+ public void setId(Long id) {
38
+ this.id = id;
39
+ }
40
+
41
+ public PostModel getPost() {
42
+ return post;
43
+ }
44
+
45
+ public void setPost(PostModel post) {
46
+ this.post = post;
47
+ }
48
+
49
+ public UserModel getUser() {
50
+ return user;
51
+ }
52
+
53
+ public void setUser(UserModel user) {
54
+ this.user = user;
55
+ }
56
+ }
src/main/java/com/krishna/model/PostModel.java ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.model;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4
+ import jakarta.persistence.*;
5
+ import org.hibernate.annotations.CreationTimestamp;
6
+ import org.hibernate.annotations.UpdateTimestamp;
7
+
8
+ import java.time.LocalDateTime;
9
+
10
+ @Entity
11
+ @Table(name = "posts")
12
+ public class PostModel {
13
+
14
+ @Id
15
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
16
+ private Long id;
17
+
18
+ @ManyToOne(fetch = FetchType.EAGER)
19
+ @JoinColumn(name = "user_id", nullable = false)
20
+ @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
21
+ private UserModel userModel;
22
+
23
+ @Column(nullable = false, columnDefinition = "TEXT")
24
+ private String content;
25
+
26
+ @Column(name = "image_url", columnDefinition = "TEXT")
27
+ private String imageUrl;
28
+
29
+ @CreationTimestamp
30
+ private LocalDateTime createdAt;
31
+
32
+ @UpdateTimestamp
33
+ private LocalDateTime updatedAt;
34
+
35
+ // Getters and setters
36
+ public Long getId() { return id; }
37
+ public void setId(Long id) { this.id = id; }
38
+
39
+ public UserModel getUserModel() { return userModel; }
40
+ public void setUserModel(UserModel userModel) { this.userModel = userModel; }
41
+
42
+ public String getContent() { return content; }
43
+ public void setContent(String content) { this.content = content; }
44
+
45
+ public String getImageUrl() { return imageUrl; }
46
+ public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
47
+
48
+ public LocalDateTime getCreatedAt() { return createdAt; }
49
+ public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
50
+
51
+ public LocalDateTime getUpdatedAt() { return updatedAt; }
52
+ public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
53
+ }
src/main/java/com/krishna/model/UserModel.java ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.model;
2
+
3
+ import com.fasterxml.jackson.annotation.JsonProperty;
4
+ import jakarta.persistence.*;
5
+ import org.hibernate.annotations.GenericGenerator;
6
+
7
+ import java.util.UUID;
8
+
9
+ @Entity
10
+ @Table(name = "Users")
11
+
12
+ public class UserModel {
13
+
14
+ @Id
15
+ @GeneratedValue(generator = "UUID")
16
+ @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
17
+ @Column(name = "id", updatable = false, nullable = false)
18
+ private UUID id;
19
+
20
+ @Column(name = "fullName")
21
+ @JsonProperty("full_name")
22
+ private String fullName;
23
+
24
+ @Column(name = "userName")
25
+ @JsonProperty("user_name")
26
+ private String username;
27
+
28
+ @Column(name = "email")
29
+ private String email;
30
+
31
+ @Column(name = "password")
32
+ private String password;
33
+
34
+ @Column(name = "profile_url", columnDefinition = "TEXT")
35
+ @JsonProperty("profile_url")
36
+ private String profileUrl;
37
+
38
+ public UserModel() {
39
+ }
40
+
41
+ public UserModel(String fullName, String username, String email, String password, String profileUrl) {
42
+ this.fullName = fullName;
43
+ this.username = username;
44
+ this.email = email;
45
+ this.password = password;
46
+ this.profileUrl = profileUrl;
47
+ }
48
+
49
+ public UUID getId() {
50
+ return id;
51
+ }
52
+
53
+ public void setId(UUID id) {
54
+ this.id = id;
55
+ }
56
+
57
+ public String getFullName() {
58
+ return fullName;
59
+ }
60
+
61
+ public void setFullName(String fullName) {
62
+ this.fullName = fullName;
63
+ }
64
+
65
+ public String getUsername() {
66
+ return username;
67
+ }
68
+
69
+ public void setUsername(String username) {
70
+ this.username = username;
71
+ }
72
+
73
+ public String getEmail() {
74
+ return email;
75
+ }
76
+
77
+ public void setEmail(String email) {
78
+ this.email = email;
79
+ }
80
+
81
+ public String getPassword() {
82
+ return password;
83
+ }
84
+
85
+ public void setPassword(String password) {
86
+ this.password = password;
87
+ }
88
+
89
+ public String getProfileUrl() {
90
+ return profileUrl;
91
+ }
92
+
93
+ public void setProfileUrl(String profileUrl) {
94
+ this.profileUrl = profileUrl;
95
+ }
96
+ }
src/main/java/com/krishna/repository/CommentRepository.java ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.repository;
2
+
3
+ import com.krishna.model.CommentModel;
4
+ import org.springframework.data.jpa.repository.JpaRepository;
5
+
6
+ import java.util.List;
7
+ import java.util.UUID;
8
+
9
+ public interface CommentRepository extends JpaRepository<CommentModel, Long> {
10
+ List<CommentModel> findByPostId(Long postId);
11
+ }
src/main/java/com/krishna/repository/LikeRepository.java ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.repository;
2
+
3
+ import com.krishna.model.LikeModel;
4
+ import com.krishna.model.PostModel;
5
+ import com.krishna.model.UserModel;
6
+ import org.springframework.data.jpa.repository.JpaRepository;
7
+ import org.springframework.data.jpa.repository.Modifying;
8
+ import org.springframework.data.jpa.repository.Query;
9
+ import org.springframework.transaction.annotation.Transactional;
10
+
11
+ import java.util.Optional;
12
+
13
+ public interface LikeRepository extends JpaRepository<LikeModel, Long> {
14
+
15
+ Optional<LikeModel> findByUserAndPost(UserModel user, PostModel post);
16
+
17
+ Long countByPost(PostModel post);
18
+
19
+ @Transactional
20
+ @Modifying
21
+ @Query("DELETE FROM LikeModel l WHERE l.post.id = :postId")
22
+ void deleteByPostId(Long postId);
23
+ }
src/main/java/com/krishna/repository/PostRepository.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.repository;
2
+
3
+ import com.krishna.model.PostModel;
4
+ import org.springframework.data.jpa.repository.JpaRepository;
5
+ import org.springframework.stereotype.Repository;
6
+
7
+ import java.util.List;
8
+ import java.util.UUID;
9
+
10
+ @Repository
11
+ public interface PostRepository extends JpaRepository<PostModel, Long> {
12
+ List<PostModel> findByUserModelId(UUID id);
13
+ }
src/main/java/com/krishna/repository/UserRepository.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.repository;
2
+
3
+ import java.util.List;
4
+ import java.util.Optional;
5
+ import java.util.UUID;
6
+ import org.springframework.data.jpa.repository.JpaRepository;
7
+ import com.krishna.model.UserModel;
8
+
9
+ public interface UserRepository extends JpaRepository<UserModel, UUID> {
10
+ Optional<UserModel> findByEmail(String email);
11
+
12
+ List<UserModel> findByUsernameContainingIgnoreCaseOrFullNameContainingIgnoreCase(String username, String fullName);
13
+ }
src/main/java/com/krishna/service/CommentService.java ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.service;
2
+
3
+ import com.krishna.dto.CommentDTO;
4
+ import com.krishna.model.CommentModel;
5
+ import com.krishna.model.PostModel;
6
+ import com.krishna.model.UserModel;
7
+ import com.krishna.repository.CommentRepository;
8
+ import com.krishna.repository.PostRepository;
9
+ import com.krishna.repository.UserRepository;
10
+ import org.springframework.beans.factory.annotation.Autowired;
11
+ import org.springframework.stereotype.Service;
12
+
13
+ import java.util.List;
14
+ import java.util.UUID;
15
+
16
+ @Service
17
+ public class CommentService {
18
+
19
+ @Autowired
20
+ private CommentRepository commentRepository;
21
+
22
+ @Autowired
23
+ private UserRepository userRepository;
24
+
25
+ @Autowired
26
+ private PostRepository postRepository;
27
+
28
+ public CommentModel addComment(CommentDTO dto) throws Exception {
29
+ System.out.println("Received DTO: " + dto.getPostId() + ", " + dto.getUserId());
30
+
31
+ UserModel user = userRepository.findById(dto.getUserId())
32
+ .orElseThrow(() -> new Exception("User not found"));
33
+
34
+ PostModel post = postRepository.findById(dto.getPostId())
35
+ .orElseThrow(() -> new Exception("Post not found"));
36
+
37
+ CommentModel comment = new CommentModel(dto.getContent(), user, post);
38
+ return commentRepository.save(comment);
39
+ }
40
+
41
+ public List<CommentModel> getCommentsByPost(Long postId) {
42
+ return commentRepository.findByPostId(postId);
43
+ }
44
+
45
+ public void deleteComment(Long commentId) {
46
+ commentRepository.deleteById(commentId); // Or custom logic if needed
47
+ }
48
+ }
src/main/java/com/krishna/service/LikeService.java ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.service;
2
+
3
+ import com.krishna.model.LikeModel;
4
+ import com.krishna.model.PostModel;
5
+ import com.krishna.model.UserModel;
6
+ import com.krishna.repository.LikeRepository;
7
+ import com.krishna.repository.PostRepository;
8
+ import com.krishna.repository.UserRepository;
9
+ import org.springframework.beans.factory.annotation.Autowired;
10
+ import org.springframework.stereotype.Service;
11
+
12
+ import java.util.Optional;
13
+ import java.util.UUID;
14
+
15
+ @Service
16
+ public class LikeService {
17
+
18
+ @Autowired
19
+ private LikeRepository likeRepository;
20
+
21
+ @Autowired
22
+ private UserRepository userRepository;
23
+
24
+ @Autowired
25
+ private PostRepository postRepository;
26
+
27
+
28
+ public boolean toggleLike(UUID userId, Long postId) {
29
+ Optional<UserModel> userOpt = userRepository.findById(userId);
30
+ Optional<PostModel> postOpt = postRepository.findById(postId);
31
+
32
+ if (userOpt.isEmpty() || postOpt.isEmpty()) {
33
+ return false;
34
+ }
35
+
36
+ UserModel user = userOpt.get();
37
+ PostModel post = postOpt.get();
38
+
39
+ Optional<LikeModel> likeOpt = likeRepository.findByUserAndPost(user, post);
40
+
41
+ if (likeOpt.isPresent()) {
42
+ likeRepository.delete(likeOpt.get());
43
+ return false;
44
+ } else {
45
+ LikeModel newLike = new LikeModel(user, post);
46
+ likeRepository.save(newLike);
47
+ return true;
48
+ }
49
+ }
50
+
51
+ public Long getLikeCount(Long postId) {
52
+ Optional<PostModel> postOpt = postRepository.findById(postId);
53
+ return postOpt.map(likeRepository::countByPost).orElse(0L);
54
+ }
55
+
56
+ public boolean hasUserLikedPost(UUID userId, Long postId) {
57
+ Optional<UserModel> userOpt = userRepository.findById(userId);
58
+ Optional<PostModel> postOpt = postRepository.findById(postId);
59
+
60
+ if (userOpt.isEmpty() || postOpt.isEmpty()) {
61
+ return false;
62
+ }
63
+
64
+ return likeRepository.findByUserAndPost(userOpt.get(), postOpt.get()).isPresent();
65
+ }
66
+ }
src/main/resources/application.properties ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #MySQL configuration
2
+ spring.datasource.url=jdbc:mysql://localhost:3306/mystara
3
+ spring.datasource.username = root
4
+ spring.datasource.password = root
5
+ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
6
+
7
+ spring.jpa.hibernate.ddl-auto=update
8
+ spring.jpa.show-sql=true
9
+ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
10
+
11
+ spring.jackson.property-naming-strategy=SNAKE_CASE
12
+
13
+ spring.cache.type=simple
14
+
15
+ server.port=8080
16
+ logging.level.org.springframework=DEBUG
src/test/java/com/krishna/controller/CommentControllerTest.java ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.fasterxml.jackson.databind.ObjectMapper;
4
+ import com.krishna.dto.CommentDTO;
5
+ import com.krishna.model.CommentModel;
6
+ import com.krishna.service.CommentService;
7
+ import org.junit.jupiter.api.BeforeEach;
8
+ import org.junit.jupiter.api.Test;
9
+ import org.mockito.Mockito;
10
+
11
+ import org.springframework.beans.factory.annotation.Autowired;
12
+ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
13
+ import org.springframework.boot.test.mock.mockito.MockBean;
14
+
15
+ import org.springframework.http.MediaType;
16
+ import org.springframework.test.web.servlet.MockMvc;
17
+
18
+ import java.util.List;
19
+ import java.util.UUID;
20
+
21
+ import static org.mockito.ArgumentMatchers.any;
22
+ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
23
+ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
24
+
25
+ @WebMvcTest(CommentController.class)
26
+ public class CommentControllerTest {
27
+
28
+ @Autowired
29
+ private MockMvc mockMvc;
30
+
31
+ @MockBean
32
+ private CommentService commentService;
33
+
34
+ @Autowired
35
+ private ObjectMapper objectMapper;
36
+
37
+ private CommentModel mockComment;
38
+
39
+ @BeforeEach
40
+ void setup() {
41
+ mockComment = new CommentModel();
42
+ mockComment.setId(1L);
43
+ mockComment.setContent("Test comment");
44
+ // Optional: You can mock user/post if needed in your model
45
+ }
46
+
47
+ @Test
48
+ void testAddComment() throws Exception {
49
+ CommentDTO dto = new CommentDTO();
50
+ dto.setContent("Test comment");
51
+ dto.setPostId(100L);
52
+ dto.setUserId(UUID.randomUUID());
53
+
54
+ Mockito.when(commentService.addComment(any(CommentDTO.class))).thenReturn(mockComment);
55
+
56
+ mockMvc.perform(post("/comments/add")
57
+ .contentType(MediaType.APPLICATION_JSON)
58
+ .content(objectMapper.writeValueAsString(dto)))
59
+ .andExpect(status().isOk())
60
+ .andExpect(jsonPath("$.content").value("Test comment"));
61
+ }
62
+
63
+ @Test
64
+ void testGetCommentsByPost() throws Exception {
65
+ Mockito.when(commentService.getCommentsByPost(100L)).thenReturn(List.of(mockComment));
66
+
67
+ mockMvc.perform(get("/comments/post/100"))
68
+ .andExpect(status().isOk())
69
+ .andExpect(jsonPath("$[0].content").value("Test comment"));
70
+ }
71
+
72
+ @Test
73
+ void testDeletePost() throws Exception {
74
+ Mockito.doNothing().when(commentService).deleteComment(100L);
75
+
76
+ mockMvc.perform(delete("/comments/100"))
77
+ .andExpect(status().isOk())
78
+ .andExpect(content().string("Comment deleted successfully."));
79
+ }
80
+ }
src/test/java/com/krishna/controller/LikeControllerTest.java ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.krishna.service.LikeService;
4
+ import org.junit.jupiter.api.Test;
5
+ import org.mockito.Mockito;
6
+ import org.springframework.beans.factory.annotation.Autowired;
7
+ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
8
+ import org.springframework.boot.test.mock.mockito.MockBean;
9
+ import org.springframework.http.MediaType;
10
+ import org.springframework.test.web.servlet.MockMvc;
11
+
12
+ import java.util.UUID;
13
+
14
+ import static org.mockito.Mockito.when;
15
+ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
16
+ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
17
+
18
+ @WebMvcTest(LikeController.class)
19
+ class LikeControllerTest {
20
+
21
+ @Autowired
22
+ private MockMvc mockMvc;
23
+
24
+ @MockBean
25
+ private LikeService likeService;
26
+
27
+ @Test
28
+ void toggleLike_ShouldReturnLikedMessage() throws Exception {
29
+ UUID userId = UUID.randomUUID();
30
+ Long postId = 1L;
31
+
32
+ when(likeService.toggleLike(userId, postId)).thenReturn(true);
33
+
34
+ mockMvc.perform(post("/likes/toggle")
35
+ .param("userId", userId.toString())
36
+ .param("postId", postId.toString()))
37
+ .andExpect(status().isOk())
38
+ .andExpect(content().string("Post liked successfully"));
39
+ }
40
+
41
+ @Test
42
+ void toggleLike_ShouldReturnUnlikedMessage() throws Exception {
43
+ UUID userId = UUID.randomUUID();
44
+ Long postId = 2L;
45
+
46
+ when(likeService.toggleLike(userId, postId)).thenReturn(false);
47
+
48
+ mockMvc.perform(post("/likes/toggle")
49
+ .param("userId", userId.toString())
50
+ .param("postId", postId.toString()))
51
+ .andExpect(status().isOk())
52
+ .andExpect(content().string("Post unliked"));
53
+ }
54
+
55
+ @Test
56
+ void getLikeCount_ShouldReturnCount() throws Exception {
57
+ Long postId = 3L;
58
+ when(likeService.getLikeCount(postId)).thenReturn(42L);
59
+
60
+ mockMvc.perform(get("/likes/count/{postId}", postId))
61
+ .andExpect(status().isOk())
62
+ .andExpect(content().string("42"));
63
+ }
64
+
65
+ @Test
66
+ void checkIfUserLikedPost_ShouldReturnTrue() throws Exception {
67
+ UUID userId = UUID.randomUUID();
68
+ Long postId = 4L;
69
+
70
+ when(likeService.hasUserLikedPost(userId, postId)).thenReturn(true);
71
+
72
+ mockMvc.perform(get("/likes/status")
73
+ .param("userId", userId.toString())
74
+ .param("postId", postId.toString()))
75
+ .andExpect(status().isOk())
76
+ .andExpect(content().string("true"));
77
+ }
78
+
79
+ @Test
80
+ void checkIfUserLikedPost_ShouldReturnFalse() throws Exception {
81
+ UUID userId = UUID.randomUUID();
82
+ Long postId = 5L;
83
+
84
+ when(likeService.hasUserLikedPost(userId, postId)).thenReturn(false);
85
+
86
+ mockMvc.perform(get("/likes/status")
87
+ .param("userId", userId.toString())
88
+ .param("postId", postId.toString()))
89
+ .andExpect(status().isOk())
90
+ .andExpect(content().string("false"));
91
+ }
92
+ }
src/test/java/com/krishna/controller/PostControllerTest.java ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.fasterxml.jackson.databind.ObjectMapper;
4
+ import com.krishna.dto.PostRequestDTO;
5
+ import com.krishna.dto.PostUpdateDTO;
6
+ import com.krishna.model.PostModel;
7
+ import com.krishna.model.UserModel;
8
+ import com.krishna.repository.LikeRepository;
9
+ import com.krishna.repository.PostRepository;
10
+ import com.krishna.repository.UserRepository;
11
+ import org.junit.jupiter.api.BeforeEach;
12
+ import org.junit.jupiter.api.Test;
13
+ import org.springframework.beans.factory.annotation.Autowired;
14
+ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
15
+ import org.springframework.boot.test.mock.mockito.MockBean;
16
+ import org.springframework.http.MediaType;
17
+ import org.springframework.test.web.servlet.MockMvc;
18
+
19
+ import java.util.*;
20
+
21
+ import static org.mockito.Mockito.*;
22
+ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
23
+ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
24
+
25
+ @WebMvcTest(PostController.class)
26
+ class PostControllerTest {
27
+
28
+ @Autowired
29
+ private MockMvc mockMvc;
30
+
31
+ @MockBean
32
+ private PostRepository postRepository;
33
+
34
+ @MockBean
35
+ private UserRepository userRepository;
36
+
37
+ @MockBean
38
+ private LikeRepository likeRepository;
39
+
40
+ @Autowired
41
+ private ObjectMapper objectMapper;
42
+
43
+ private UUID userId;
44
+ private UserModel user;
45
+ private PostModel post;
46
+
47
+ @BeforeEach
48
+ void setUp() {
49
+ userId = UUID.randomUUID();
50
+ user = new UserModel();
51
+ user.setId(userId);
52
+ user.setFullName("Krishna");
53
+ user.setUsername("krish");
54
+ user.setEmail("krish@example.com");
55
+
56
+ post = new PostModel();
57
+ post.setId(1L);
58
+ post.setContent("Hello world");
59
+ post.setImageUrl("image.jpg");
60
+ post.setUserModel(user);
61
+ }
62
+
63
+ @Test
64
+ void createPost_ShouldReturnCreated() throws Exception {
65
+ PostRequestDTO request = new PostRequestDTO(userId, "New post", "img.jpg");
66
+
67
+ when(userRepository.findById(userId)).thenReturn(Optional.of(user));
68
+ when(postRepository.save(any(PostModel.class))).thenReturn(post);
69
+
70
+ mockMvc.perform(post("/posts/add")
71
+ .contentType(MediaType.APPLICATION_JSON)
72
+ .content(objectMapper.writeValueAsString(request)))
73
+ .andExpect(status().isCreated());
74
+ }
75
+
76
+ @Test
77
+ void createPost_ShouldReturnNotFound_WhenUserNotFound() throws Exception {
78
+ PostRequestDTO request = new PostRequestDTO(userId, "Post", "img.jpg");
79
+
80
+ when(userRepository.findById(userId)).thenReturn(Optional.empty());
81
+
82
+ mockMvc.perform(post("/posts/add")
83
+ .contentType(MediaType.APPLICATION_JSON)
84
+ .content(objectMapper.writeValueAsString(request)))
85
+ .andExpect(status().isNotFound());
86
+ }
87
+
88
+ @Test
89
+ void getAllPosts_ShouldReturnListOfPosts() throws Exception {
90
+ List<PostModel> posts = List.of(post);
91
+ when(postRepository.findAll()).thenReturn(posts);
92
+
93
+ mockMvc.perform(get("/posts"))
94
+ .andExpect(status().isOk())
95
+ .andExpect(jsonPath("$[0].content").value("Hello world"));
96
+ }
97
+
98
+ @Test
99
+ void updatePost_ShouldReturnUpdatedPost() throws Exception {
100
+ PostUpdateDTO updateDTO = new PostUpdateDTO("Updated content", "updated.jpg");
101
+
102
+ // Simulate that the post has been updated
103
+ post.setContent(updateDTO.getContent());
104
+ post.setImageUrl(updateDTO.getImageUrl());
105
+
106
+ when(postRepository.findById(1L)).thenReturn(Optional.of(post));
107
+ when(postRepository.save(any(PostModel.class))).thenReturn(post);
108
+
109
+ mockMvc.perform(put("/posts/1")
110
+ .contentType(MediaType.APPLICATION_JSON)
111
+ .content(objectMapper.writeValueAsString(updateDTO)))
112
+ .andExpect(status().isOk())
113
+ .andExpect(jsonPath("$.content").value("Updated content"));
114
+ }
115
+
116
+ @Test
117
+ void updatePost_ShouldReturnNotFound() throws Exception {
118
+ PostUpdateDTO updateDTO = new PostUpdateDTO("No post", "no.jpg");
119
+
120
+ when(postRepository.findById(2L)).thenReturn(Optional.empty());
121
+
122
+ mockMvc.perform(put("/posts/2")
123
+ .contentType(MediaType.APPLICATION_JSON)
124
+ .content(objectMapper.writeValueAsString(updateDTO)))
125
+ .andExpect(status().isNotFound());
126
+ }
127
+
128
+ @Test
129
+ void deletePost_ShouldReturnSuccess() throws Exception {
130
+ when(postRepository.findById(1L)).thenReturn(Optional.of(post));
131
+ doNothing().when(likeRepository).deleteByPostId(1L);
132
+ doNothing().when(postRepository).deleteById(1L);
133
+
134
+ mockMvc.perform(delete("/posts/1"))
135
+ .andExpect(status().isOk())
136
+ .andExpect(content().string("Post deleted successfully"));
137
+ }
138
+
139
+ @Test
140
+ void deletePost_ShouldReturnNotFound() throws Exception {
141
+ when(postRepository.findById(99L)).thenReturn(Optional.empty());
142
+
143
+ mockMvc.perform(delete("/posts/99"))
144
+ .andExpect(status().isNotFound())
145
+ .andExpect(content().string("Post not found"));
146
+ }
147
+ }
src/test/java/com/krishna/controller/UserControllerTest.java ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.krishna.controller;
2
+
3
+ import com.krishna.model.UserModel;
4
+ import com.krishna.repository.UserRepository;
5
+ import org.apache.commons.codec.digest.DigestUtils;
6
+ import org.junit.jupiter.api.BeforeEach;
7
+ import org.junit.jupiter.api.Test;
8
+ import org.mockito.Mockito;
9
+
10
+ import org.springframework.beans.factory.annotation.Autowired;
11
+ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
12
+ import org.springframework.boot.test.mock.mockito.MockBean;
13
+
14
+ import org.springframework.http.MediaType;
15
+ import org.springframework.test.web.servlet.MockMvc;
16
+
17
+ import java.util.HashMap;
18
+ import java.util.Map;
19
+ import java.util.Optional;
20
+ import java.util.UUID;
21
+
22
+ import static org.mockito.ArgumentMatchers.any;
23
+ import static org.mockito.Mockito.when;
24
+
25
+ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
26
+ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
27
+
28
+ import com.fasterxml.jackson.databind.ObjectMapper;
29
+
30
+ @WebMvcTest(UserController.class)
31
+ class UserControllerTest {
32
+
33
+ @Autowired
34
+ private MockMvc mockMvc;
35
+
36
+ @MockBean
37
+ private UserRepository userRepository;
38
+
39
+ private ObjectMapper objectMapper;
40
+ private UserModel user;
41
+
42
+ @BeforeEach
43
+ void setUp() {
44
+ objectMapper = new ObjectMapper();
45
+
46
+ String rawPassword = "Password@123";
47
+ String hashedPassword = DigestUtils.sha1Hex(rawPassword); // from Apache Commons Codec
48
+
49
+ user = new UserModel("Krishna Dev", "krish123", "krishna@example.com", hashedPassword, rawPassword);
50
+ user.setId(UUID.randomUUID());
51
+ }
52
+
53
+ @Test
54
+ void registerUser_Success() throws Exception {
55
+ when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.empty());
56
+ when(userRepository.save(any(UserModel.class))).thenReturn(user);
57
+
58
+ mockMvc.perform(post("/user/register")
59
+ .contentType(MediaType.APPLICATION_JSON)
60
+ .content(objectMapper.writeValueAsString(user)))
61
+ .andExpect(status().isOk())
62
+ .andExpect(jsonPath("$.email").value(user.getEmail()));
63
+ }
64
+
65
+ @Test
66
+ void registerUser_EmailAlreadyExists() throws Exception {
67
+ when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user));
68
+
69
+ mockMvc.perform(post("/user/register")
70
+ .contentType(MediaType.APPLICATION_JSON)
71
+ .content(objectMapper.writeValueAsString(user)))
72
+ .andExpect(status().isBadRequest())
73
+ .andExpect(content().string("Email already registered."));
74
+ }
75
+
76
+ @Test
77
+ void loginUser_Success() throws Exception {
78
+ when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user));
79
+
80
+ Map<String, String> loginRequest = new HashMap<>();
81
+ loginRequest.put("email", user.getEmail());
82
+ loginRequest.put("password", "Password@123");
83
+
84
+ mockMvc.perform(post("/user/login")
85
+ .contentType(MediaType.APPLICATION_JSON)
86
+ .content(objectMapper.writeValueAsString(loginRequest)))
87
+ .andExpect(status().isOk())
88
+ .andExpect(jsonPath("$.email").value("krishna@example.com"))
89
+ .andExpect(jsonPath("$.username").value("krish123"))
90
+ .andExpect(jsonPath("$.token").exists());
91
+ }
92
+
93
+ @Test
94
+ void loginUser_InvalidPassword() throws Exception {
95
+ when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user));
96
+
97
+ Map<String, String> loginRequest = new HashMap<>();
98
+ loginRequest.put("email", user.getEmail());
99
+ loginRequest.put("password", "WrongPassword123");
100
+
101
+ mockMvc.perform(post("/user/login")
102
+ .contentType(MediaType.APPLICATION_JSON)
103
+ .content(objectMapper.writeValueAsString(loginRequest)))
104
+ .andExpect(status().isUnauthorized())
105
+ .andExpect(content().string("Invalid password."));
106
+ }
107
+
108
+ @Test
109
+ void loginUser_UserNotFound() throws Exception {
110
+ when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.empty());
111
+
112
+ mockMvc.perform(post("/user/login")
113
+ .contentType(MediaType.APPLICATION_JSON)
114
+ .content(objectMapper.writeValueAsString(user)))
115
+ .andExpect(status().isNotFound())
116
+ .andExpect(content().string("User not found."));
117
+ }
118
+ }