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

Seniru / defendxstore / 15041864302

15 May 2025 09:46AM UTC coverage: 87.526% (+49.6%) from 37.96%
15041864302

push

github

web-flow
test: improve test coverage (#98)

* test: fix failing tests due to invalid passwords

* test: add test cases for /api/tickets

* fix: unhandle conditions for tickets

* test: add test cases for /api/promo

* fix: unhandled conditions in promocodes

* test: add test cases for /api/forums

* fix: unhandled cases in forums

* test: add test cases for /api/sales/expenses

* test: add test cases for /api/notifications

* test: add test cases for /api/items

* fix: unhandled cases for items

* test: add test cases for /api/users/:username/cart

* test: add test cases for /api/orders

* fix: add missing cases for orders

* fix: unrecognizable test suite

* test: add test cases for /api/deliveries

* chore: create separate test runners for windows and linux

- these separate runners are to facilitate other services
- also adds more test coverage for routes in /api/items (recommended and trending)

* chore: fix linux test runner

* ci: run test using linux test runner

* fix: environment variables in ci environment

* misc: trying to fix

* ci: add coveralls actions

stupid ai removed it

* test: add test cases for /api/sales

* test: add integration tests for perks API

* test: add test cases for /api/reports

* test): ensure email is required for verification process and add tests for verification endpoints

* test: add excel attachment tests for downloadSheet functionality across multiple endpoints

557 of 705 branches covered (79.01%)

Branch coverage included in aggregate %.

88 of 96 new or added lines in 11 files covered. (91.67%)

76 existing lines in 9 files now uncovered.

1541 of 1692 relevant lines covered (91.08%)

87.8 hits per line

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

91.82
/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 {
30✔
9
        const { title, content, category } = req.body
30✔
10

11
        if (!title || !content || !category)
30✔
12
            return createResponse(
9✔
13
                res,
14
                StatusCodes.BAD_REQUEST,
15
                "Missing title, content or category",
16
            )
17

18
        const user = await User.findOne({ username: req.user.username }).exec()
21✔
19
        const thread = new ForumThread({
21✔
20
            title,
21
            content,
22
            createdDate: Date.now(),
23
            edittedDate: null,
24
            category,
25
            createdUser: user._id,
26
        })
27
        await thread.save()
21✔
28

29
        await user.incrementProgress("forumNewbie")
9✔
30
        await user.incrementProgress("threadMaster")
9✔
31

32
        return createResponse(res, StatusCodes.CREATED, thread)
9✔
33
    } catch (error) {
34
        if (error.name === "ValidationError")
12!
35
            return createResponse(res, StatusCodes.BAD_REQUEST, error.message)
12✔
36
        next(error)
×
37
    }
38
}
39

40
const getAllThreads = async (req, res, next) => {
3✔
41
    try {
15✔
42
        const { q, category } = req.query
15✔
43

44
        const query = { title: { $regex: q || "", $options: "i" } }
15✔
45
        if (category) query.category = category
15✔
46

47
        const forums = await ForumThread.find(query)
15✔
48
            .populate({ path: "createdUser", select: "username" })
49
            .exec()
50
        return createResponse(res, StatusCodes.OK, forums)
15✔
51
    } catch (error) {
UNCOV
52
        next(error)
×
53
    }
54
}
55

56
const getThread = async (req, res, next) => {
3✔
57
    try {
6✔
58
        const { threadId } = req.params
6✔
59
        const thread = await ForumThread.findOne({ _id: threadId })
6✔
60
            .populate({ path: "createdUser", select: "username" })
61
            .populate({
62
                path: "replies",
63
                populate: { path: "createdUser", select: "username" },
64
            })
65
            .exec()
66
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
6✔
67
        return createResponse(res, StatusCodes.OK, thread)
3✔
68
    } catch (error) {
UNCOV
69
        next(error)
×
70
    }
71
}
72

73
const editThread = async (req, res, next) => {
3✔
74
    try {
30✔
75
        const { threadId } = req.params
30✔
76
        const { title, content, category } = req.body
30✔
77
        if (!title || !content || !category)
30✔
78
            return createResponse(
9✔
79
                res,
80
                StatusCodes.BAD_REQUEST,
81
                "Missing title, content or category",
82
            )
83

84
        const user = await User.findOne({ username: req.user.username }).exec()
21✔
85
        const thread = await ForumThread.findById(threadId).exec()
21✔
86
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
21✔
87
        if (thread.createdUser.toString() != user._id.toString())
18✔
88
            return createResponse(
3✔
89
                res,
90
                StatusCodes.FORBIDDEN,
91
                "You are not allowed to edit this thread",
92
            )
93

94
        await ForumThread.findOneAndUpdate(
15✔
95
            { _id: threadId },
96
            { title, content, category, editedDate: Date.now() },
97
            { new: true, runValidators: true },
98
        ).exec()
99

100
        return createResponse(res, StatusCodes.OK, "Thread updated")
3✔
101
    } catch (error) {
102
        if (error.name === "ValidationError")
12!
103
            return createResponse(res, StatusCodes.BAD_REQUEST, error.message)
12✔
104
        next(error)
×
105
    }
106
}
107

108
const deleteThread = async (req, res, next) => {
3✔
109
    try {
9✔
110
        const { threadId } = req.params
9✔
111
        const user = await User.findOne({ username: req.user.username }).exec()
9✔
112
        const thread = await ForumThread.findById(threadId).exec()
9✔
113
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
9✔
114
        if (thread.createdUser.toString() != user._id.toString())
6✔
115
            return createResponse(
3✔
116
                res,
117
                StatusCodes.FORBIDDEN,
118
                "You are not allowed to delete this thread",
119
            )
120

121
        await ForumThread.findOneAndDelete({ _id: threadId }).exec()
3✔
122
        return createResponse(res, StatusCodes.OK, "Thread deleted")
3✔
123
    } catch (error) {
UNCOV
124
        next(error)
×
125
    }
126
}
127

128
const createReply = async (req, res, next) => {
3✔
129
    try {
18✔
130
        const { threadId } = req.params
18✔
131
        const { content } = req.body
18✔
132
        if (!content) return createResponse(res, StatusCodes.BAD_REQUEST, "Missing content")
18✔
133

134
        const user = await User.findOne({ username: req.user.username }).exec()
12✔
135
        const reply = await ForumThreadReply.create({
12✔
136
            threadId,
137
            content,
138
            createdDate: Date.now(),
139
            createdUser: user._id,
140
        })
141

142
        const thread = await ForumThread.findByIdAndUpdate(
6✔
143
            threadId,
144
            {
145
                $push: { replies: reply._id },
146
            },
147
            { runValidators: true },
148
        ).exec()
149

150
        if (!thread) return createResponse(res, StatusCodes.NOT_FOUND, "Thread not found")
6✔
151

152
        await user.incrementProgress("communityHelper")
3✔
153

154
        return createResponse(res, StatusCodes.CREATED, reply)
3✔
155
    } catch (error) {
156
        if (error.name === "ValidationError")
6!
157
            return createResponse(res, StatusCodes.BAD_REQUEST, error.message)
6✔
UNCOV
158
        next(error)
×
159
    }
160
}
161

162
module.exports = {
3✔
163
    createThread,
164
    getAllThreads,
165
    getThread,
166
    editThread,
167
    deleteThread,
168
    createReply,
169
}
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