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

GrottoCenter / grottocenter-api / 10996310862

23 Sep 2024 02:22PM UTC coverage: 46.158% (-2.8%) from 48.952%
10996310862

push

github

vmarseguerra
feat(entities): adds delete / restore for document

740 of 2203 branches covered (33.59%)

Branch coverage included in aggregate %.

24 of 153 new or added lines in 17 files covered. (15.69%)

484 existing lines in 49 files now uncovered.

2462 of 4734 relevant lines covered (52.01%)

4.5 hits per line

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

52.0
/api/services/CommentService.js
1
const moment = require('moment');
2✔
2
const momentDurationFormatSetup = require('moment-duration-format');
2✔
3

4
const CommonService = require('./CommonService');
2✔
5

6
momentDurationFormatSetup(moment);
2✔
7

8
function average(arr) {
9
  if (arr.length === 0) return 0;
24✔
10
  return arr.reduce((a, b) => a + b, 0) / arr.length;
30✔
11
}
12

13
module.exports = {
2✔
14
  /**
15
   * @param {integer} entranceId - id of the entrance for which stats are needed
16
   *
17
   * @returns {Promise} which resolves to the succesfully getStats
18
   */
19
  getStatsFromComments: (comments) => {
20
    const filterFn = (e) => e && e > 0;
54✔
21
    return {
8✔
22
      aestheticism: average(
23
        comments.map((c) => c.aestheticism).filter(filterFn)
18✔
24
      ),
25
      caving: average(comments.map((c) => c.caving).filter(filterFn)),
18✔
26
      approach: average(comments.map((c) => c.approach).filter(filterFn)),
18✔
27
    };
28
  },
29

30
  getStatsFromId: async (entranceId) => {
31
    const [aestheticism, caving, approach] = await Promise.all([
1✔
32
      TComment.avg('aestheticism').where({
33
        entrance: entranceId,
34
        aestheticism: { '>': 0 },
35
      }),
36
      TComment.avg('caving').where({
37
        entrance: entranceId,
38
        caving: { '>': 0 },
39
      }),
40
      TComment.avg('approach').where({
41
        entrance: entranceId,
42
        approach: { '>': 0 },
43
      }),
44
    ]);
45

46
    return { aestheticism, caving, approach };
1✔
47
  },
48

49
  /**
50
   * @param {integer} entranceId - id of the entrance for which time infos are needed
51
   *
52
   * @returns {Promise} which resolves to the succesfully getTimeInfos
53
   */
54
  getTimeInfos: async (entranceId) => {
55
    // query to get time infos average
UNCOV
56
    const TIME_INFO_QUERY = `
×
57
    SELECT avg(e_t_trail) AS avg_t_trail, avg(e_t_underground) AS avg_t_underground
58
    FROM t_comment WHERE id_entrance=$1`;
59

UNCOV
60
    const timeInfosQueryResult = await CommonService.query(TIME_INFO_QUERY, [
×
61
      entranceId,
62
    ]);
UNCOV
63
    const timeInfos = timeInfosQueryResult.rows[0];
×
64

65
    let avgTTrailFormatted = null;
×
UNCOV
66
    let avgTUndergroundFormatted = null;
×
67
    if (timeInfos.avg_t_trail !== null) {
×
68
      avgTTrailFormatted = module.exports.postgreIntervalObjectToDbString(
×
69
        timeInfos.avg_t_trail
70
      );
71
    }
UNCOV
72
    if (timeInfos.avg_t_underground !== null) {
×
UNCOV
73
      avgTUndergroundFormatted = module.exports.postgreIntervalObjectToDbString(
×
74
        timeInfos.avg_t_underground
75
      );
76
    }
77

UNCOV
78
    return {
×
79
      eTTrail: avgTTrailFormatted,
80
      eTUnderground: avgTUndergroundFormatted,
81
    };
82
  },
83

84
  /**
85
   *
86
   * @param pgInterval PostgresInterval Object {hours: ${number}, minutes: ${number}, seconds: ${number}}
87
   * @returns string with format hh:mm:ss
88
   */
89
  postgreIntervalObjectToDbString: (pgInterval) => {
90
    if (!pgInterval) return null;
47!
91
    const emptyDuration = {
47✔
92
      days: 0,
93
      hours: 0,
94
      minutes: 0,
95
      seconds: 0,
96
    };
97
    return moment
47✔
98
      .duration(Object.assign(emptyDuration, pgInterval))
99
      .format('hh:mm:ss', {
100
        trim: false,
101
      });
102
  },
103

104
  getEntranceComments: async (entranceId, where = {}) => {
×
105
    if (!entranceId) return [];
8!
106
    return TComment.find({ ...where, entrance: entranceId })
8✔
107
      .populate('author')
108
      .populate('reviewer');
109
  },
110

111
  getEntranceHComments: async (entranceId, where = {}) => {
×
UNCOV
112
    if (!entranceId) return [];
×
UNCOV
113
    const commentIds = await TComment.find({
×
114
      where: { ...where, entrance: entranceId },
115
      select: ['id'],
116
    });
UNCOV
117
    return module.exports.getHComments(commentIds.map((e) => e.id));
×
118
  },
119

120
  getComment: async (commentId) =>
121
    TComment.findOne({ id: commentId }).populate('author').populate('reviewer'),
3✔
122

123
  getHComments: async (commentId) =>
UNCOV
124
    HComment.find({ t_id: commentId }).populate('reviewer').populate('author'),
×
125
};
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