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

GrottoCenter / grottocenter-api / 11210769896

07 Oct 2024 07:32AM UTC coverage: 46.184% (+0.08%) from 46.105%
11210769896

push

github

vmarseguerra
fix(entities): small issues
- document description body is not saved when importing a csv
- cannot get statistics for country and massif
- broken sql dev setup
- missing 'names' key in massif converter
- stop validating the mimeType when uploading a file

740 of 2199 branches covered (33.65%)

Branch coverage included in aggregate %.

0 of 3 new or added lines in 3 files covered. (0.0%)

251 existing lines in 21 files now uncovered.

2485 of 4784 relevant lines covered (51.94%)

4.46 hits per line

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

8.6
/api/controllers/v1/document/delete.js
1
const ControllerService = require('../../../services/ControllerService');
1✔
2
const NotificationService = require('../../../services/NotificationService');
1✔
3
const DocumentService = require('../../../services/DocumentService');
1✔
4
const RightService = require('../../../services/RightService');
1✔
5
const { toDocument } = require('../../../services/mapping/converters');
1✔
6
const FileService = require('../../../services/FileService');
1✔
7
const RecentChangeService = require('../../../services/RecentChangeService');
1✔
8

9
module.exports = async (req, res) => {
1✔
UNCOV
10
  const hasRight = RightService.hasGroup(
×
11
    req.token.groups,
12
    RightService.G.MODERATOR
13
  );
14
  if (!hasRight) {
×
UNCOV
15
    return res.forbidden('You are not authorized to delete a document.');
×
16
  }
17

18
  // Check if document exists and if it's not already deleted
19
  const documentId = req.param('id');
×
20
  const document = await DocumentService.getPopulatedDocument(documentId);
×
21
  if (!document) {
×
UNCOV
22
    return res.notFound({ message: `Document of id ${documentId} not found.` });
×
23
  }
24

25
  if (!document.isDeleted) {
×
26
    const redirectTo = parseInt(req.param('entityId'), 10);
×
27
    if (!Number.isNaN(redirectTo)) {
×
28
      document.redirectTo = redirectTo;
×
UNCOV
29
      await TDocument.updateOne(documentId)
×
30
        .set({ redirectTo })
31
        .catch(() => {});
32
    }
33

34
    await TDocument.destroyOne({ id: documentId }); // Soft delete
×
35
    document.isDeleted = true;
×
36

UNCOV
37
    await DocumentService.deleteESDocument(document).catch(() => {});
×
38
    await RecentChangeService.setDeleteRestoreAuthor(
×
39
      'delete',
40
      'document',
41
      documentId,
42
      req.token.id
43
    );
44
  }
45

46
  const deletePermanently = !!req.param('isPermanent');
×
UNCOV
47
  const mergeIntoId = parseInt(req.param('entityId'), 10);
×
UNCOV
48
  let shouldMergeInto = !Number.isNaN(mergeIntoId);
×
49
  let mergeIntoEntity;
50
  if (shouldMergeInto) {
×
UNCOV
51
    mergeIntoEntity = await DocumentService.appendPopulateForFullDocument(
×
52
      TDocument.findOne(mergeIntoId)
53
    );
UNCOV
54
    shouldMergeInto = !!mergeIntoEntity;
×
55
  }
56

UNCOV
57
  if (deletePermanently) {
×
UNCOV
58
    await TDocument.update({ redirectTo: documentId }).set({
×
59
      redirectTo: shouldMergeInto ? mergeIntoId : null,
×
60
    });
UNCOV
61
    await TDocument.update({ parent: documentId }).set({
×
62
      parent: shouldMergeInto ? mergeIntoId : null,
×
63
    });
UNCOV
64
    await HDocument.update({ parent: documentId }).set({
×
65
      parent: shouldMergeInto ? mergeIntoId : null,
×
66
    });
67
    await TDocument.update({ authorizationDocument: null }).set({
×
68
      authorizationDocument: null,
69
    });
70

71
    await TNotification.destroy({ document: documentId });
×
72

73
    // eslint-disable-next-line no-inner-declarations
74
    async function linkedEntitiesDeleteOrMerge(key) {
75
      if (document[key].length === 0) return;
×
UNCOV
76
      if (shouldMergeInto) {
×
UNCOV
77
        const existingEntities = mergeIntoEntity[key].map((e) => e.id);
×
78
        const entitiesToAdd = document[key]
×
79
          .map((e) => e.id)
×
80
          .filter((e) => !existingEntities.includes(e));
×
UNCOV
81
        await TDocument.addToCollection(mergeIntoId, key, entitiesToAdd);
×
82
      }
83
      await TDocument.updateOne(documentId).set({ [key]: [] });
×
84
    }
85

UNCOV
86
    if (document.files.length > 0) {
×
UNCOV
87
      if (shouldMergeInto) {
×
88
        TFile.update({ document: documentId }).set({ document: mergeIntoId });
×
89
      } else {
90
        await Promise.all(
×
91
          document.files.map((e) => FileService.document.delete(e))
×
92
        );
93
      }
94
    }
95

96
    await linkedEntitiesDeleteOrMerge('countries');
×
UNCOV
97
    await linkedEntitiesDeleteOrMerge('isoRegions');
×
98
    await linkedEntitiesDeleteOrMerge('languages');
×
UNCOV
99
    await linkedEntitiesDeleteOrMerge('massifs');
×
UNCOV
100
    await linkedEntitiesDeleteOrMerge('subjects');
×
101
    await linkedEntitiesDeleteOrMerge('authorsGrotto');
×
102
    await linkedEntitiesDeleteOrMerge('authors');
×
103

UNCOV
104
    await TDocument.updateOne(documentId).set({ regions: [] });
×
105

106
    await TDocumentDuplicate.destroy({ id: documentId });
×
107

108
    // Documents have no TName but a TDescription instead
109
    await TDescription.destroy({ document: documentId }); // TDescription first soft delete
×
UNCOV
110
    await HDescription.destroy({ document: documentId });
×
UNCOV
111
    await TDescription.destroy({ document: documentId });
×
112

UNCOV
113
    await HDocument.destroy({ t_id: documentId });
×
UNCOV
114
    await TDocument.destroyOne({ id: documentId }); // Hard delete
×
115
  }
116

UNCOV
117
  await NotificationService.notifySubscribers(
×
118
    req,
119
    document,
120
    req.token.id,
121
    deletePermanently
×
122
      ? NotificationService.NOTIFICATION_TYPES.PERMANENT_DELETE
123
      : NotificationService.NOTIFICATION_TYPES.DELETE,
124
    NotificationService.NOTIFICATION_ENTITIES.DOCUMENT
125
  );
126

UNCOV
127
  return ControllerService.treatAndConvert(
×
128
    req,
129
    null,
130
    document,
131
    { controllerMethod: 'DocumentController.delete' },
132
    res,
133
    toDocument
134
  );
135
};
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