All files / src/controllers posts_controller.ts

51.85% Statements 42/81
62.96% Branches 17/27
44.44% Functions 4/9
52.5% Lines 42/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174                    7x 12x 12x           12x   12x           7x 8x 8x 8x 8x     8x 2x 6x 1x   5x     8x 2x     6x 6x   6x                       7x 3x 3x 3x 1x   2x               7x 3x 3x 3x 3x           3x   2x   1x 1x     1x     1x     1x             7x                                           7x                                   7x                       7x                                
import { Request, Response } from 'express';
import * as postsService from '../services/posts_service';
import { handleError } from '../utils/handle_error';
import {CustomRequest} from "types/customRequest";
import {PostData} from "types/post_types";
import {getLikedPostsByUser, getPostLikesCount, postExists, updatePostLike} from "../services/posts_service";
import LikeModel from '../models/like_model';
import mongoose from 'mongoose';
 
 
export const addPost = async (req: CustomRequest, res: Response): Promise<void> => {
    try {
        const postData: PostData = {
            title: req.body.title,
            content: req.body.content,
            owner: req.user.id
        };
 
        const savedPost: PostData = await postsService.addPost(postData);
 
        res.status(201).json(savedPost);
    } catch (err) {
        handleError(err, res);
    }
};
 
export const getPosts = async (req: Request, res: Response): Promise<void> => {
    try {
        const page = parseInt(req.query.page as string) || 1; // Default to page 1
        const limit = parseInt(req.query.limit as string) || 5; // Default to 5 posts per page
        const skip = (page - 1) * limit;
 
        let posts;
        if (req.query.owner) {
            posts = await postsService.getPosts(req.query.owner as string, skip, limit);
        } else if (req.query.username) {
            posts = await postsService.getPostsByUsername(req.query.username as string);
        } else {
            posts = await postsService.getPosts(undefined, skip, limit);
        }
 
        if (posts.length === 0) {
            res.status(200).json([]);
        }
        else {
            const totalPosts = await postsService.getTotalPosts(req.query.owner as string, req.query.username as string);
            const totalPages = Math.ceil(totalPosts / limit);
 
            res.status(200).json({
                posts,
                totalPosts,
                totalPages,
                currentPage: page,
            });
        }
    } catch (err) {
        handleError(err, res);
    }
};
 
export const getPostById = async (req: Request, res: Response): Promise<void> => {
    try {
        const post = await postsService.getPostById(req.params.postId);
        if (!post) {
            res.status(404).json({ message: 'Post not found' });
        } else {
            res.json(post);
        }
    } catch (err) {
        handleError(err, res);
    }
};
 
// TODO - create a difference between PUT and PATCH
export const updatePost = async (req: CustomRequest, res: Response): Promise<void> => {
    try {
        const owner = req.user.id;
        const postId = req.params.postId;
        const postData: PostData = {
            title: req.body.title,
            content: req.body.content,
            owner
        };
 
        if (await postsService.postExists(postId)) {
 
            if (await postsService.isPostOwnedByUser(postId, owner)) {
 
                const updatedPost = await postsService.updatePost(postId, postData);
                Iif (!updatedPost) {
                    res.status(404).json({message: 'Post not found'});
                } else {
                    res.status(200).json(updatedPost);
                }
            } else { // If someone not the owner
                res.status(403).json({message: 'Forbidden'});
            }
        } else { // If someone  try to update post that doesn't exist
            res.status(404).json({ message: 'Post not found' });
        }
    } catch (err) {
        handleError(err, res);
    }
};
 
export const updateLikeByPostId = async (req: CustomRequest, res: Response): Promise<void> => {
    const userId = req.user.id;
    const id = req.params.postId;
    const booleanValue: any = req.body.value;
    try {
        if (booleanValue instanceof String && booleanValue != "false" && booleanValue != "true") {
            res.status(400).send("Bad Request. Body accepts `true` or `false` values only");
        }
 
        const oldPost = await postExists(id);
        if (oldPost == null) {
            res.status(404).send('Post not found');
        }
 
        await updatePostLike(id, booleanValue, userId)
 
        res.status(200).send("Success");
    } catch(err) {
        handleError(err, res);
    }
}
 
export const getLikesByPostId = async (req: Request, res: Response): Promise<void> => {
    const postId = req.params.postId;
 
    try {
        // Fetch the count of likes and the list of users who liked the post
        const likes = await LikeModel.find({ postId: new mongoose.Types.ObjectId(postId) }).select('userId').exec();
        const likesCount = likes.length;
        const likedBy = likes.map((like) => like.userId.toString()); // Extract user IDs
 
        res.status(200).json({ count: likesCount, likedBy });
    } catch (error) {
        console.error(`Error fetching likes for post ${postId}:`, error);
        handleError(error, res);
    }
};
 
 
 
export const getLikedPosts =  async (req: CustomRequest, res: Response): Promise<void> => {
    try {
        const userId = req.user.id;
        const likedPostsByUserId = await  getLikedPostsByUser(userId)
 
        res.status(200).send(likedPostsByUserId);
    } catch(err){
        handleError(err, res);
    }
}
 
 
export const deletePostById = async (req: Request, res: Response): Promise<void> => {
    try {
        const postId = req.params.postId;
        const post = await postsService.getPostById(postId);
        if (!post) {
            res.status(404).json({ message: 'Post not found' });
        } else {
            await postsService.deletePostById(postId);
            res.json({ message: 'Post and associated comments deleted successfully' });
        }
    } catch (err) {
        handleError(err, res);
    }
};