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

statuscompliance / status-backend / 14592205578

22 Apr 2025 10:08AM UTC coverage: 45.53% (+9.6%) from 35.962%
14592205578

Pull #90

github

web-flow
Merge ac2816879 into ef0c8590e
Pull Request #90: test(utils): added dates

315 of 808 branches covered (38.99%)

Branch coverage included in aggregate %.

96 of 115 new or added lines in 1 file covered. (83.48%)

130 existing lines in 3 files now uncovered.

831 of 1709 relevant lines covered (48.62%)

5.31 hits per line

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

5.22
/src/controllers/catalog.controller.js
1
import { models } from '../models/models.js';
2
import { storeGuaranteePoints } from '../utils/storeGuaranteePoints.js';
3
import registry from '../config/registry.js';
4
import { agreementBuilder } from '../utils/agreementBuilder.js';
5
import { v4 as uuidv4 } from 'uuid';
6
import _ from 'lodash';
7
import { finalizeControlsByCatalogId } from './control.controller.js';
8

9
export const getCatalogs = async (req, res) => {
17✔
10
  try {
×
11
    const { status } = req.query;
×
12
    
UNCOV
13
    let where = {};
×
14
    if (status === 'finalized' || status === 'draft') {
×
UNCOV
15
      where = { status };
×
16
    }
17
    
UNCOV
18
    const catalogs = await models.Catalog.findAll({ where });
×
19
    res.status(200).json(catalogs);
×
20
  } catch (error) {
UNCOV
21
    res.status(500).json({ message: `Failed to retrieve catalogs, error: ${error.message}` });
×
22
  }
23
};
24

25
export const getCatalog = async (req, res) => {
17✔
26
  try {
×
UNCOV
27
    const row = await models.Catalog.findByPk(req.params.id);
×
28

UNCOV
29
    if (!row) {
×
UNCOV
30
      return res.status(404).json({ message: 'Catalog not found' });
×
31
    }
32

33
    res.status(200).json(row);
×
34
  } catch (error) {
35
    res.status(500).json({ message: `Failed to retrieve catalog, error: ${error.message}` });
×
36
  }
37
};
38

39
export const createCatalog = async (req, res) => {
17✔
UNCOV
40
  try {
×
UNCOV
41
    const { name, description, startDate, endDate, dashboard_id, status } = req.body;
×
UNCOV
42
    if (!name || !startDate || !endDate) {
×
UNCOV
43
      return res.status(400).json({ message: 'Missing required fields: name, startDate, and/or endDate' });
×
44
    }
UNCOV
45
    const tpaId = status === 'draft' ? null : `tpa-${uuidv4()}`;
×
UNCOV
46
    const rows = await models.Catalog.create({
×
47
      name,
48
      description,
49
      startDate,
50
      endDate,
51
      dashboard_id,
52
      tpaId,
53
      status: status || 'finalized',
×
54
    });
55
    res.status(201).json(rows);
×
56
  } catch (error) {
57
    res.status(500).json({ message: `Failed to create catalog, error: ${error.message}` });
×
58
  }
59
};
60

61
export const updateCatalog = async (req, res) => {
17✔
UNCOV
62
  try {
×
UNCOV
63
    const { id } = req.params;
×
UNCOV
64
    const { name, description, startDate, endDate, dashboard_id, tpaId, status } = req.body;
×
65

66
    const currentCatalog = await models.Catalog.findByPk(id);
×
UNCOV
67
    if (!currentCatalog) {
×
UNCOV
68
      return res.status(404).json({ message: 'Catalog not found' });
×
69
    }
70

71
    // Prevent changing status from finalized to draft
UNCOV
72
    if (currentCatalog.status === 'finalized' && status === 'draft') {
×
UNCOV
73
      return res.status(400).json({ message: 'Cannot change status from finalized to draft' });
×
74
    }
75

UNCOV
76
    const updatedCatalog = await models.Catalog.update(
×
77
      {
78
        name,
79
        description,
80
        startDate,
81
        endDate,
82
        dashboard_id,
83
        tpaId,
84
        status,
85
      },
86
      {
87
        where: {
88
          id,
89
        },
90
        returning: true,
91
        plain: true,
92
      }
93
    );
94
    res.status(200).json(updatedCatalog[1]); // The first element is the number of affectedRows
×
95
  } catch (error) {
UNCOV
96
    res.status(500).json({ message: `Failed to update catalog, error: ${error.message}` });
×
97
  }
98
};
99

100
export const deleteCatalog = async (req, res) => {
17✔
101
  const result = await models.Catalog.destroy({
×
102
    where: {
103
      id: req.params.id,
104
    },
105
  });
106

UNCOV
107
  if (result <= 0)
×
UNCOV
108
    return res.status(404).json({
×
109
      message: 'Catalog not found',
110
    });
111

UNCOV
112
  res.sendStatus(204);
×
113
};
114

115
export async function calculatePoints(req, res) {
116
  try {
×
UNCOV
117
    const agreementId = req.params.tpaId;
×
118
    const { from, to } = req.query;
×
119

UNCOV
120
    const catalog = await models.Catalog.findOne({ where: {tpaId: agreementId}});
×
UNCOV
121
    const controls = await models.Control.findAll({where: {catalogId: catalog.id}});
×
122

123
    await updateOrCreateAgreement(catalog, controls, agreementId);
×
124
    
125
    const guaranteesStates = await registry.get(`api/v6/states/${agreementId}/guarantees`, {
×
126
      params: { from, to, newPeriodsFromGuarantees: false },
127
      headers: { 'x-access-token': req.cookies.accessToken }
128
    });
UNCOV
129
    const { storedPoints, error } = await storeGuaranteePoints(guaranteesStates.data, agreementId);
×
UNCOV
130
    if (error.length > 0) {
×
131
      const points = await models.Point.findAll({where: {agreementId}});
×
UNCOV
132
      if (points.length > 0) {
×
UNCOV
133
        res.status(200).json(points);
×
134
      } else {
UNCOV
135
        res.status(400).json(error);
×
136
      }
137
    } else {
UNCOV
138
      res.status(200).json(storedPoints);
×
139
    }
140
  } catch (error) {
141
    res.status(500).json({
×
142
      message: `Failed to get points, error: ${error.message}`,
143
    });
144
  }
145
}
146

147
async function updateOrCreateAgreement(catalog, controls, agreementId) {
148
  const agreement = await agreementBuilder(catalog, controls, { id: agreementId });
×
UNCOV
149
  try {
×
UNCOV
150
    const response = await registry.get(`api/v6/agreements/${agreementId}`);
×
151
    const oldAgreement = response.data;
×
152

153
    if (!_.isEqual(agreement, oldAgreement)) {
×
UNCOV
154
      console.log(`Updating agreement ${agreementId}`);
×
155
      await registry.put(`api/v6/agreements/${agreementId}`, agreement);
×
156
    }
157
  } catch (error) {
UNCOV
158
    if (error.response?.status === 404) {
×
UNCOV
159
      console.log(`Creating agreement ${agreementId}`);
×
UNCOV
160
      await registry.post('api/v6/agreements', agreement);
×
161
    } else {
UNCOV
162
      throw error; // Rethrow other errors
×
163
    }
164
  }
165
}
166

167
// Draft Catalogs
168

169
export const createDraftCatalog = async (req, res) => {
17✔
UNCOV
170
  try {
×
171
    const { name, description, startDate, endDate, dashboard_id } = req.body;
×
UNCOV
172
    if (!name || !startDate) {
×
UNCOV
173
      return res.status(400).json({ message: 'Missing required fields: name and/or startDate' });
×
174
    }
175
    
176
    const rows = await models.Catalog.create({
×
177
      name,
178
      description,
179
      startDate: startDate,
180
      endDate,
181
      dashboard_id,
182
      tpaId: null,
183
      status: 'draft',
184
    });
UNCOV
185
    res.status(201).json(rows);
×
186
  } catch (error) {
UNCOV
187
    res.status(500).json({ message: `Failed to create draft catalog, error: ${error.message}` });
×
188
  }
189
};
190

191
export const finalizeCatalog = async (req, res) => {
17✔
UNCOV
192
  try {
×
193
    const { id } = req.params;
×
194
    
UNCOV
195
    const currentCatalog = await models.Catalog.findByPk(id);
×
UNCOV
196
    if (!currentCatalog) {
×
UNCOV
197
      return res.status(404).json({ message: 'Catalog not found' });
×
198
    }
199
    
UNCOV
200
    if (currentCatalog.status !== 'draft') {
×
201
      return res.status(400).json({ message: 'Only draft catalogs can be finalized' });
×
202
    }
203
    
UNCOV
204
    if (!currentCatalog.startDate || !currentCatalog.endDate) {
×
UNCOV
205
      return res.status(400).json({ message: 'Catalog must have startDate and endDate to be finalized' });
×
206
    }
207
    
UNCOV
208
    const tpaId = `tpa-${uuidv4()}`;
×
209
    
210
    // First we update the catalog status and TPA ID
211
    const updatedCatalog = await models.Catalog.update(
×
212
      {
213
        status: 'finalized',
214
        tpaId,
215
      },
216
      {
217
        where: {
218
          id,
219
        },
220
        returning: true,
221
        plain: true,
222
      }
223
    );
224
    
225
    // Then we finalize the controls
UNCOV
226
    const controlsResult = await finalizeControlsByCatalogId(id);
×
227
    
228
    // Return the updated catalog and the number of finalized controls
UNCOV
229
    res.status(200).json({
×
230
      catalog: updatedCatalog[1],
231
      controls: {
232
        finalized: controlsResult.updated.length,
233
      }
234
    });
235
  } catch (error) {
UNCOV
236
    res.status(500).json({ message: `Failed to finalize catalog, error: ${error.message}` });
×
237
  }
238
};
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