Spaces:
Sleeping
Sleeping
Commit
·
bb5169d
1
Parent(s):
36117aa
Adding file for new hugging face docker space
Browse files- Dockerfile +28 -0
- README.md +5 -4
- docker-compose.yml +38 -0
- pom.xml +93 -0
- src/main/java/com/krishna/FormApplication.java +13 -0
- src/main/java/com/krishna/config/WebConfig.java +28 -0
- src/main/java/com/krishna/controller/CommentController.java +46 -0
- src/main/java/com/krishna/controller/LikeController.java +40 -0
- src/main/java/com/krishna/controller/PostController.java +115 -0
- src/main/java/com/krishna/controller/UserController.java +131 -0
- src/main/java/com/krishna/dto/CommentDTO.java +23 -0
- src/main/java/com/krishna/dto/LoginResponseDTO.java +70 -0
- src/main/java/com/krishna/dto/PostRequestDTO.java +30 -0
- src/main/java/com/krishna/dto/PostUpdateDTO.java +29 -0
- src/main/java/com/krishna/model/CommentModel.java +46 -0
- src/main/java/com/krishna/model/LikeModel.java +56 -0
- src/main/java/com/krishna/model/PostModel.java +53 -0
- src/main/java/com/krishna/model/UserModel.java +96 -0
- src/main/java/com/krishna/repository/CommentRepository.java +11 -0
- src/main/java/com/krishna/repository/LikeRepository.java +23 -0
- src/main/java/com/krishna/repository/PostRepository.java +13 -0
- src/main/java/com/krishna/repository/UserRepository.java +13 -0
- src/main/java/com/krishna/service/CommentService.java +48 -0
- src/main/java/com/krishna/service/LikeService.java +66 -0
- src/main/resources/application.properties +16 -0
- src/test/java/com/krishna/controller/CommentControllerTest.java +80 -0
- src/test/java/com/krishna/controller/LikeControllerTest.java +92 -0
- src/test/java/com/krishna/controller/PostControllerTest.java +147 -0
- 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:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 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 |
+
}
|