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

GrottoCenter / grottocenter-api / 26978265319

04 Jun 2026 08:40PM UTC coverage: 86.893% (-0.02%) from 86.914%
26978265319

push

github

ClemRz
fix(document): map titleAndDescriptionLanguage for description creation

- Read titleAndDescriptionLanguage.id instead of mainLanguage for TDescription.language
- Read documentMainLanguage.id instead of mainLanguage for TDocument.languages
- Add 400 validation when titleAndDescriptionLanguage is missing
- Keep backward-compat fallback to mainLanguage for both fields
- Add service and route tests for new mapping and validation

Closes #1617

3546 of 4245 branches covered (83.53%)

Branch coverage included in aggregate %.

9 of 9 new or added lines in 3 files covered. (100.0%)

2 existing lines in 2 files now uncovered.

7088 of 7993 relevant lines covered (88.68%)

56.06 hits per line

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

87.18
/api/controllers/v1/document/create.js
1
const ControllerService = require('../../../services/ControllerService');
1✔
2
const DocumentService = require('../../../services/DocumentService');
1✔
3
const { toDocument } = require('../../../services/mapping/converters');
1✔
4
const FileService = require('../../../services/FileService');
1✔
5
const {
6
  TYPES_ALLOWING_ISSUE,
7
} = require('../../../../config/constants/document');
1✔
8

9
module.exports = async (req, res) => {
1✔
10
  // Validate required language fields
11
  const hasDescriptionLanguage = Boolean(
7✔
12
    req.body.titleAndDescriptionLanguage?.id ?? req.body.mainLanguage
10✔
13
  );
14
  if (!hasDescriptionLanguage) {
7✔
15
    return res.badRequest(
2✔
16
      'Missing required field: titleAndDescriptionLanguage.'
17
    );
18
  }
19

20
  const documentData = await DocumentService.getConvertedDataFromClient(
5✔
21
    req.body
22
  );
23
  const descriptionData = DocumentService.getDescriptionDataFromClient(
5✔
24
    req.body,
25
    req.token.id
26
  );
27

28
  // Validate that the issue field is only set for types that support it
29
  if (
5!
30
    documentData.issue != null &&
5!
31
    !TYPES_ALLOWING_ISSUE.includes(documentData.type)
32
  ) {
UNCOV
33
    return res.badRequest(
×
34
      'The "issue" field is only allowed for documents of type Book or Issue. ' +
35
        'Articles should be linked to a parent document of type Issue instead.'
36
    );
37
  }
38

39
  const cleanedData = {
5✔
40
    ...documentData,
41
    author: req.token.id,
42
    dateInscription: new Date(),
43
  };
44

45
  const createdDocument = await DocumentService.createDocument(
5✔
46
    req,
47
    cleanedData,
48
    descriptionData
49
  );
50
  const errorFiles = [];
5✔
51
  if (req.files && req.files.files) {
5✔
52
    const { files } = req.files;
1✔
53
    try {
1✔
54
      await Promise.all(
1✔
55
        files.map(async (file) => {
56
          await FileService.document.create(file, createdDocument.id);
1✔
57
        })
58
      );
59
    } catch (err) {
60
      errorFiles.push({
×
61
        fileName: err.fileName,
62
        error: err.message,
63
      });
64
    }
65
  }
66

67
  const newDoc = await DocumentService.getPopulatedDocument(createdDocument.id);
5✔
68

69
  const out = {
5✔
70
    document: toDocument(newDoc),
71
    status:
72
      errorFiles.length > 0
5!
73
        ? {
74
            errorCode: 'FileNotImported',
75
            errorString: 'Some files were not imported.',
76
            content: errorFiles,
77
          }
78
        : undefined,
79
  };
80

81
  return ControllerService.treat(
5✔
82
    req,
83
    null,
84
    out,
85
    { controllerMethod: 'DocumentController.create' },
86
    res
87
  );
88
};
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