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

GrottoCenter / grottocenter-api / 25442209472

06 May 2026 02:34PM UTC coverage: 86.286% (-0.09%) from 86.372%
25442209472

push

github

dawoldo
test(1451): added missing test for sending messages to an unauthorized user

3041 of 3674 branches covered (82.77%)

Branch coverage included in aggregate %.

6365 of 7227 relevant lines covered (88.07%)

50.67 hits per line

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

80.25
/api/controllers/v1/message/create.js
1
const MessageService = require('../../../services/MessageService');
1✔
2
const ControllerService = require('../../../services/ControllerService');
1✔
3
const CommonService = require('../../../services/CommonService');
1✔
4
const NotificationService = require('../../../services/NotificationService');
1✔
5

6
/**
7
 * MessageController.create
8
 *
9
 * @description :: Send a private message.
10
 * @help        :: See https://sailsjs.com/documentation/concepts/controllers
11
 */
12

13
module.exports = async (req, res) => {
1✔
14
  const senderId = req.token.id;
14✔
15
  const recipientId = req.param('recipientId');
14✔
16
  const conversationId = req.param('conversationId');
14✔
17
  const body = req.param('body');
14✔
18

19
  // Validation
20
  if (!body || body.trim().length === 0) {
14✔
21
    return res.badRequest(
2✔
22
      sails.helpers.formatMessagingError(
23
        req,
24
        'Message body cannot be empty.',
25
        'E_VALIDATION'
26
      )
27
    );
28
  }
29
  if (body.length > 5000) {
12✔
30
    return res.badRequest(
1✔
31
      sails.helpers.formatMessagingError(
32
        req,
33
        'Message body cannot exceed 5000 characters.',
34
        'E_VALIDATION'
35
      )
36
    );
37
  }
38

39
  let finalConversationId;
40

41
  // 1. Resolve Conversation or Recipient Eligibility
42
  if (conversationId) {
11✔
43
    try {
3✔
44
      const queryResult = await CommonService.query(
3✔
45
        'SELECT 1 FROM j_participant WHERE id_conversation = $1 AND id_caver = $2',
46
        [conversationId, senderId]
47
      );
48

49
      if (queryResult.rows.length === 0) {
3✔
50
        return res.forbidden(
1✔
51
          sails.helpers.formatMessagingError(
52
            req,
53
            'You are not a participant in this conversation.',
54
            'E_AUTHORIZATION'
55
          )
56
        );
57
      }
58

59
      // Check if the other participant is still eligible
60
      const otherParticipantId = await MessageService.getOtherParticipantId(
2✔
61
        conversationId,
62
        senderId
63
      );
64
      if (otherParticipantId) {
2!
65
        try {
2✔
66
          await MessageService.getEligibleRecipient(otherParticipantId);
2✔
67
        } catch (err) {
68
          if (err.code === 'E_NOT_FOUND') {
1!
69
            return res.notFound(
×
70
              sails.helpers.formatMessagingError(
71
                req,
72
                err.message,
73
                'E_NOT_FOUND'
74
              )
75
            );
76
          }
77
          if (err.code === 'E_FORBIDDEN') {
1!
78
            return res.forbidden(
1✔
79
              sails.helpers.formatMessagingError(
80
                req,
81
                err.message,
82
                'E_AUTHORIZATION'
83
              )
84
            );
85
          }
86
          throw err;
×
87
        }
88
      }
89

90
      finalConversationId = conversationId;
1✔
91
    } catch (err) {
92
      sails.log.error(err);
×
93
      return res.serverError(
×
94
        sails.helpers.formatMessagingError(
95
          req,
96
          'An error occurred while verifying conversation membership.',
97
          'E_SERVER_ERROR'
98
        )
99
      );
100
    }
101
  } else if (recipientId) {
8!
102
    if (Number(recipientId) === Number(senderId)) {
8✔
103
      return res.badRequest(
1✔
104
        sails.helpers.formatMessagingError(
105
          req,
106
          'You cannot send a message to yourself.',
107
          'E_VALIDATION'
108
        )
109
      );
110
    }
111

112
    try {
7✔
113
      await MessageService.getEligibleRecipient(recipientId);
7✔
114
    } catch (err) {
115
      if (err.code === 'E_NOT_FOUND') {
3✔
116
        return res.notFound(
1✔
117
          sails.helpers.formatMessagingError(req, err.message, 'E_NOT_FOUND')
118
        );
119
      }
120
      if (err.code === 'E_FORBIDDEN') {
2!
121
        return res.forbidden(
2✔
122
          sails.helpers.formatMessagingError(
123
            req,
124
            err.message,
125
            'E_AUTHORIZATION'
126
          )
127
        );
128
      }
129
      sails.log.error(err);
×
130
      return res.serverError(
×
131
        sails.helpers.formatMessagingError(
132
          req,
133
          'An error occurred while verifying the recipient.',
134
          'E_SERVER_ERROR'
135
        )
136
      );
137
    }
138

139
    // 2. Resolve/Create Conversation for the Recipient
140
    try {
4✔
141
      finalConversationId = await MessageService.findExistingConversation(
4✔
142
        senderId,
143
        recipientId
144
      );
145
      if (!finalConversationId) {
4✔
146
        const newConvo = await MessageService.createConversation(
2✔
147
          senderId,
148
          recipientId
149
        );
150
        finalConversationId = newConvo.id;
2✔
151
      }
152
    } catch (err) {
153
      sails.log.error(err);
×
154
      return res.serverError(
×
155
        sails.helpers.formatMessagingError(
156
          req,
157
          'An error occurred while establishing the conversation.',
158
          'E_SERVER_ERROR'
159
        )
160
      );
161
    }
162
  } else {
163
    return res.badRequest(
×
164
      sails.helpers.formatMessagingError(
165
        req,
166
        'You must provide either a recipientId or a conversationId.',
167
        'E_VALIDATION'
168
      )
169
    );
170
  }
171

172
  // 3. Create the message
173
  try {
5✔
174
    const newMessage = await TMessage.create({
5✔
175
      conversation: finalConversationId,
176
      caverSender: senderId,
177
      body: body.trim(),
178
      dateSent: new Date(),
179
    }).fetch();
180

181
    // Notify recipient
182
    // Errors are handled inside the service to avoid affecting message creation
183
    await NotificationService.notifyMessageRecipient(
5✔
184
      req,
185
      senderId,
186
      finalConversationId
187
    );
188

189
    return ControllerService.treat(
5✔
190
      req,
191
      null,
192
      MessageService.formatMessage(newMessage),
193
      { controllerMethod: 'MessageController.create' },
194
      res
195
    );
196
  } catch (err) {
197
    sails.log.error(err);
×
198
    return res.serverError(
×
199
      sails.helpers.formatMessagingError(
200
        req,
201
        'An error occurred while sending the message.',
202
        'E_SERVER_ERROR'
203
      )
204
    );
205
  }
206
};
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