• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Seniru / defendxstore / 14822442930

04 May 2025 03:02PM UTC coverage: 38.666% (-0.8%) from 39.419%
14822442930

push

github

web-flow
feat: forum and support updates (#87)

* feat: forum thread improvements + post replies

* update: forum index page

- display proper message count
- display category
- link to the actual thread
- search function

* update: update create thread interface

* update: improve ticket row

* update: minor changes for create ticket page

* update: change ticket page with more details

* feat: ticket index ui update and filtering

* feat: create support dashboard

* fix: returning tickets of other users

* feat: delete tickets

* feat: implement ticket page interactions

- resolve ticket
- edit ticket
- delete ticket

* update: prettify

* feat: delete thread (frontend integration)

* feat: edit forum thread

* fix: typo

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: VenuGH <venurilewsandi09@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

100 of 501 branches covered (19.96%)

Branch coverage included in aggregate %.

7 of 44 new or added lines in 4 files covered. (15.91%)

4 existing lines in 2 files now uncovered.

613 of 1343 relevant lines covered (45.64%)

8.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

18.18
/backend/src/controllers/forums.js
1
const { StatusCodes } = require("http-status-codes")
3✔
2
const createResponse = require("../utils/createResponse")
3✔
3
const ForumThread = require("../models/ForumThread")
3✔
4
const ForumThreadReply = require("../models/ForumThreadReply")
3✔
5
const User = require("../models/User")
3✔
6

7
const createThread = async (req, res, next) => {
3✔
8
    try {
×
9
        const { title, content, category } = req.body
×
NEW
10
        const user = await User.findOne({ username: req.user.username }).exec()
×
11
        const thread = new ForumThread({
×
12
            title,
13
            content,
14
            createdDate: Date.now(),
15
            edittedDate: null,
16
            category,
17
            createdUser: user._id,
18
        })
19
        await thread.save()
×
20
        return createResponse(res, StatusCodes.CREATED, thread)
×
21
    } catch (error) {
22
        next(error)
×
23
    }
24
}
25

26
const getAllThreads = async (req, res, next) => {
3✔
27
    try {
×
NEW
28
        const { q, category } = req.query
×
29

NEW
30
        const query = { title: { $regex: q || "", $options: "i" } }
×
NEW
31
        if (category) query.category = category
×
32

NEW
33
        const forums = await ForumThread.find(query)
×
34
            .populate({ path: "createdUser", select: "username" })
35
            .exec()
UNCOV
36
        return createResponse(res, StatusCodes.OK, forums)
×
37
    } catch (error) {
38
        next(error)
×
39
    }
40
}
41

42
const getThread = async (req, res, next) => {
3✔
43
    try {
×
44
        const { threadId } = req.params
×
NEW
45
        const thread = await ForumThread.findOne({ _id: threadId })
×
46
            .populate({ path: "createdUser", select: "username" })
47
            .populate({
48
                path: "replies",
49
                populate: { path: "createdUser", select: "username" },
50
            })
51
            .exec()
52
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
×
53
        return createResponse(res, StatusCodes.OK, thread)
×
54
    } catch (error) {
55
        next(error)
×
56
    }
57
}
58

59
const editThread = async (req, res, next) => {
3✔
60
    try {
×
61
        const { threadId } = req.params
×
62
        const { title, content, category } = req.body
×
63
        const thread = await ForumThread.findOneAndUpdate(
×
64
            { _id: threadId },
65
            { title, content, category, editedDate: Date.now() },
66
        ).exec()
67
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
×
68
        return createResponse(res, StatusCodes.OK, "Thread updated")
×
69
    } catch (error) {
70
        next(error)
×
71
    }
72
}
73

74
const deleteThread = async (req, res, next) => {
3✔
75
    try {
×
76
        const { threadId } = req.params
×
77
        const forumThread = await ForumThread.findOneAndDelete({ _id: threadId }).exec()
×
78
        if (!forumThread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
×
79
        return createResponse(res, StatusCodes.OK, "Thread deleted")
×
80
    } catch (error) {
81
        next(error)
×
82
    }
83
}
84

85
const createReply = async (req, res, next) => {
3✔
NEW
86
    try {
×
NEW
87
        const { threadId } = req.params
×
NEW
88
        const { content } = req.body
×
NEW
89
        if (!content) return createResponse(res, StatusCodes.BAD_REQUEST, "Missing content")
×
90

NEW
91
        const user = await User.findOne({ username: req.user.username }).exec()
×
NEW
92
        const reply = await ForumThreadReply.create({
×
93
            threadId,
94
            content,
95
            createdDate: Date.now(),
96
            createdUser: user._id,
97
        })
98

NEW
99
        await ForumThread.findByIdAndUpdate(threadId, {
×
100
            $push: { replies: reply._id },
101
        }).exec()
102

NEW
103
        return createResponse(res, StatusCodes.CREATED, reply)
×
104
    } catch (error) {
NEW
105
        next(error)
×
106
    }
107
}
108

109
module.exports = {
3✔
110
    createThread,
111
    getAllThreads,
112
    getThread,
113
    editThread,
114
    deleteThread,
115
    createReply,
116
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc