creditu-common-library 2.3.14 → 2.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Creditú CommonLibrary
2
2
 
3
3
  ## Descripción
4
- Esta librería, contiene los módulos y funciones matemáticas y financerias para el manejo de cálculos en el producto digital.
4
+ Esta librería contiene los módulos y funciones matemáticas y financieras para el manejo de cálculos en el producto digital.
5
5
 
6
6
  ## Instalar en tu repositorio
7
7
 
@@ -21,7 +21,7 @@ La librería tiene dos módulos:
21
21
 
22
22
  - `Finance`: expone varios servicios orientados a un dominio específico, y cuyas funciones resuelven diversas fórmulas financieras en su ámbito.
23
23
  Los services expuestos son:
24
- - `ConstantsService`: es un servicio auxiliar, que contiene funciones que calculan constantes que, a su vez, agrupan parametros conocidos para diversos propósitos en cálculos financieros.
24
+ - `ConstantsService`: es un servicio auxiliar, que contiene funciones que calculan constantes que, a su vez, agrupan parámetros conocidos para diversos propósitos en cálculos financieros.
25
25
  - `CreditInsuranceService`: este servicio tiene funciones de cálculo para el dominio `Seguros`.
26
26
  - `FinanceService`: este servicio auxiliar tiene funciones genéricas de funciones financieras, como interés anual, mensual, etc.
27
27
  - `PaymentService`: este servicio tiene funciones de cálculo para el dominio `Dividendo`.
@@ -6,7 +6,10 @@ interface RequestWithStartTime extends Request {
6
6
  export declare class AppLoggerMiddleware implements NestMiddleware {
7
7
  private logger;
8
8
  constructor(logger?: Logger);
9
+ private readonly defaultSanitizeOptions;
9
10
  private logObject;
11
+ private isBase64;
12
+ private truncateValue;
10
13
  private sanitizeObject;
11
14
  use(request: RequestWithStartTime, response: Response, next: NextFunction): void;
12
15
  }
@@ -33,35 +33,91 @@ var AppLoggerMiddleware = /** @class */ (function () {
33
33
  function AppLoggerMiddleware(logger) {
34
34
  if (logger === void 0) { logger = new common_1.Logger('HTTP'); }
35
35
  this.logger = logger;
36
+ this.defaultSanitizeOptions = {
37
+ maxStringLength: 1000,
38
+ maxArrayLength: 10,
39
+ maxDepth: 5,
40
+ truncateBase64: true,
41
+ base64Preview: 50
42
+ };
36
43
  this.logObject = function (obj) { return (0, util_1.inspect)(obj, { showHidden: false, depth: null, colors: true }); };
37
44
  }
38
- AppLoggerMiddleware.prototype.sanitizeObject = function (obj) {
45
+ AppLoggerMiddleware.prototype.isBase64 = function (str) {
46
+ try {
47
+ // Verifica si es una cadena base64 válida
48
+ return btoa(atob(str)) === str && str.length > 100; // Solo considera base64 si es largo
49
+ }
50
+ catch (err) {
51
+ return false;
52
+ }
53
+ };
54
+ AppLoggerMiddleware.prototype.truncateValue = function (value, options) {
55
+ if (typeof value === 'string') {
56
+ // Detectar y truncar base64
57
+ if (options.truncateBase64 && this.isBase64(value)) {
58
+ var preview = value.substring(0, options.base64Preview);
59
+ return "".concat(preview, "... [BASE64_TRUNCATED - Original length: ").concat(value.length, " chars]");
60
+ }
61
+ // Truncar strings largos
62
+ if (value.length > options.maxStringLength) {
63
+ return "".concat(value.substring(0, options.maxStringLength), "... [TRUNCATED - Original length: ").concat(value.length, " chars]");
64
+ }
65
+ }
66
+ return value;
67
+ };
68
+ AppLoggerMiddleware.prototype.sanitizeObject = function (obj, options, currentDepth) {
39
69
  var _this = this;
70
+ if (options === void 0) { options = this.defaultSanitizeOptions; }
71
+ if (currentDepth === void 0) { currentDepth = 0; }
40
72
  if (!obj)
41
73
  return obj;
42
- // Si es string, lo devolvemos directamente
43
- if (typeof obj === 'string')
44
- return obj;
74
+ // Limitar profundidad para evitar recursión infinita
75
+ if (currentDepth > options.maxDepth) {
76
+ return '[MAX_DEPTH_REACHED]';
77
+ }
78
+ // Si es string, verificar si necesita truncado
79
+ if (typeof obj === 'string') {
80
+ return this.truncateValue(obj, options);
81
+ }
45
82
  // Si no es un objeto (número, booleano, etc.), lo devolvemos directamente
46
83
  if (typeof obj !== 'object')
47
84
  return obj;
48
85
  // Si es un array, sanitizamos cada elemento
49
86
  if (Array.isArray(obj)) {
50
- return obj.map(function (item) { return _this.sanitizeObject(item); });
87
+ var truncatedArray = obj.slice(0, options.maxArrayLength);
88
+ var sanitizedArray = truncatedArray.map(function (item) { return _this.sanitizeObject(item, options, currentDepth + 1); });
89
+ // Si el array fue truncado, añadir información
90
+ if (obj.length > options.maxArrayLength) {
91
+ sanitizedArray.push("[ARRAY_TRUNCATED - Showing ".concat(options.maxArrayLength, " of ").concat(obj.length, " items]"));
92
+ }
93
+ return sanitizedArray;
51
94
  }
52
95
  // Si es un objeto, hacemos una copia para no modificar el original
53
96
  var sanitized = __assign({}, obj);
54
97
  // Lista de campos sensibles a ocultar
55
98
  var sensitiveFields = ['password', 'token', 'secret', 'apiKey', 'creditCard', 'Authorization'];
99
+ // Lista de campos que típicamente contienen datos grandes
100
+ var largeDataFields = ['file', 'image', 'document', 'attachment', 'data', 'content', 'buffer'];
56
101
  var _loop_1 = function (key) {
57
102
  // Si es un campo sensible, lo ocultamos
58
103
  if (sensitiveFields.some(function (field) { return key.toLowerCase().includes(field.toLowerCase()); })) {
59
104
  sanitized[key] = '[REDACTED]';
60
105
  // eslint-disable-next-line brace-style
61
106
  }
107
+ // Si es un campo que típicamente contiene datos grandes, usar opciones más restrictivas
108
+ else if (largeDataFields.some(function (field) { return key.toLowerCase().includes(field.toLowerCase()); })) {
109
+ var restrictiveOptions = __assign(__assign({}, options), { maxStringLength: 100, base64Preview: 30 });
110
+ sanitized[key] = this_1.sanitizeObject(sanitized[key], restrictiveOptions, currentDepth + 1);
111
+ // eslint-disable-next-line brace-style
112
+ }
62
113
  // Si es un objeto anidado, lo procesamos recursivamente
63
114
  else if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
64
- sanitized[key] = this_1.sanitizeObject(sanitized[key]);
115
+ sanitized[key] = this_1.sanitizeObject(sanitized[key], options, currentDepth + 1);
116
+ // eslint-disable-next-line brace-style
117
+ }
118
+ // Para valores primitivos, aplicar truncado si es necesario
119
+ else {
120
+ sanitized[key] = this_1.truncateValue(sanitized[key], options);
65
121
  }
66
122
  };
67
123
  var this_1 = this;
@@ -75,8 +131,24 @@ var AppLoggerMiddleware = /** @class */ (function () {
75
131
  AppLoggerMiddleware.prototype.use = function (request, response, next) {
76
132
  // Añadir marca de tiempo al inicio de la petición
77
133
  request.startTime = Date.now();
134
+ // Opciones específicas para request (más permisivo)
135
+ var requestSanitizeOptions = {
136
+ maxStringLength: 500,
137
+ maxArrayLength: 5,
138
+ maxDepth: 3,
139
+ truncateBase64: true,
140
+ base64Preview: 30
141
+ };
142
+ // Opciones específicas para response (más restrictivo)
143
+ var responseSanitizeOptions = {
144
+ maxStringLength: 300,
145
+ maxArrayLength: 3,
146
+ maxDepth: 3,
147
+ truncateBase64: true,
148
+ base64Preview: 20
149
+ };
78
150
  // Captura del cuerpo de la solicitud (sanitizado)
79
- var requestBody = this.sanitizeObject(request.body);
151
+ var requestBody = this.sanitizeObject(request.body, requestSanitizeOptions);
80
152
  // Interceptar el método write y end para capturar la respuesta
81
153
  var originalWrite = response.write;
82
154
  var originalEnd = response.end;
@@ -86,7 +158,7 @@ var AppLoggerMiddleware = /** @class */ (function () {
86
158
  // eslint-disable-next-line func-names
87
159
  response.send = function (body) {
88
160
  if (body && typeof body === 'object' && response.statusCode >= 400) {
89
- var sanitizedBody = this.sanitizeObject(body);
161
+ var sanitizedBody = this.sanitizeObject(body, responseSanitizeOptions);
90
162
  var responseTime = Date.now() - request.startTime;
91
163
  this.logger.error("Error Response (".concat(response.statusCode, "): ").concat(JSON.stringify({
92
164
  method: request.method,
@@ -107,7 +179,10 @@ var AppLoggerMiddleware = /** @class */ (function () {
107
179
  for (var _i = 1; _i < arguments.length; _i++) {
108
180
  args[_i - 1] = arguments[_i];
109
181
  }
110
- chunks.push(Buffer.from(chunk));
182
+ // Solo capturar chunks si no son demasiado grandes
183
+ if (chunks.length < 10 && chunk.length < 50000) {
184
+ chunks.push(Buffer.from(chunk));
185
+ }
111
186
  return originalWrite.apply(response, __spreadArray([chunk], args, true));
112
187
  };
113
188
  // Interceptar end
@@ -117,7 +192,7 @@ var AppLoggerMiddleware = /** @class */ (function () {
117
192
  for (var _i = 1; _i < arguments.length; _i++) {
118
193
  args[_i - 1] = arguments[_i];
119
194
  }
120
- if (chunk) {
195
+ if (chunk && chunks.length < 10 && chunk.length < 50000) {
121
196
  chunks.push(Buffer.from(chunk));
122
197
  }
123
198
  var method = request.method, originalUrl = request.originalUrl;
@@ -127,16 +202,29 @@ var AppLoggerMiddleware = /** @class */ (function () {
127
202
  var responseBody = '';
128
203
  var parsedBody;
129
204
  if (chunks.length > 0) {
130
- responseBody = Buffer.concat(chunks).toString('utf8');
131
- try {
132
- parsedBody = JSON.parse(responseBody);
205
+ var totalSize = chunks.reduce(function (acc, chunk) { return acc + chunk.length; }, 0);
206
+ // Si el response es muy grande, no lo parseamos completo
207
+ if (totalSize > 100000) {
208
+ parsedBody = "[RESPONSE_TOO_LARGE - Size: ".concat(totalSize, " bytes]");
133
209
  }
134
- catch (e) {
135
- parsedBody = responseBody;
210
+ else {
211
+ responseBody = Buffer.concat(chunks).toString('utf8');
212
+ try {
213
+ parsedBody = JSON.parse(responseBody);
214
+ }
215
+ catch (e) {
216
+ // Si no es JSON válido y es muy largo, truncarlo
217
+ if (responseBody.length > 1000) {
218
+ parsedBody = "".concat(responseBody.substring(0, 1000), "... [TRUNCATED]");
219
+ }
220
+ else {
221
+ parsedBody = responseBody;
222
+ }
223
+ }
136
224
  }
137
225
  }
138
226
  // Sanitizar la respuesta
139
- var sanitizedResponseBody = this.sanitizeObject(parsedBody);
227
+ var sanitizedResponseBody = this.sanitizeObject(parsedBody, responseSanitizeOptions);
140
228
  // Mensaje base con tiempo de respuesta
141
229
  var baseMessage = "".concat(method, " ").concat(originalUrl, " ").concat(statusCode, " ").concat(statusMessage !== null && statusMessage !== void 0 ? statusMessage : '', " - ").concat(responseTime, "ms");
142
230
  // Mensaje detallado con cuerpos de solicitud y respuesta
@@ -81,7 +81,7 @@ export declare class InstallmentService {
81
81
  baseBalance(numberOfGraceMonths: number, graceMonthsInterestMethod: GraceMonthsInterestMethod, monthlyInterestRate: number): number;
82
82
  /**
83
83
  * Calcula la cuota del crédito (Ccr)
84
- * Mas info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
84
+ * Más info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
85
85
  * @param monthlyPayment Dividendo (D). Se obtiene amplificando el dividendo unitario (baseMonthlyPayment) por el monto aprobado.
86
86
  * @param creditInsuranceFee Cuota del seguro de crédito (C_s^cr)
87
87
  * @param lifeInsuranceFee Cuota del seguro de desgravamen (C_s^d)
@@ -157,7 +157,7 @@ var InstallmentService = /** @class */ (function () {
157
157
  };
158
158
  /**
159
159
  * Calcula la cuota del crédito (Ccr)
160
- * Mas info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
160
+ * Más info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
161
161
  * @param monthlyPayment Dividendo (D). Se obtiene amplificando el dividendo unitario (baseMonthlyPayment) por el monto aprobado.
162
162
  * @param creditInsuranceFee Cuota del seguro de crédito (C_s^cr)
163
163
  * @param lifeInsuranceFee Cuota del seguro de desgravamen (C_s^d)
@@ -1,7 +1,7 @@
1
- import { CreditInsurancePercentageFinanced, OperationalExpensesFinancing, CreditAmount, CreditTaxRate, CreditTaxRatePercentage } from '../../shared/models';
2
1
  import { MathService } from '../../math';
3
- import { OfferInputs, OfferParams, OfferResponse } from '../models/dto';
2
+ import { CreditAmount, CreditInsurancePercentageFinanced, CreditTaxRate, CreditTaxRatePercentage, OperationalExpensesFinancing } from '../../shared/models';
4
3
  import { CreditInsuranceFeeTermDefinition } from '../../shared/models/enum/credit-insurance-fee-term-definition.enum';
4
+ import { OfferInputs, OfferParams, OfferResponse } from '../models/dto';
5
5
  /**
6
6
  * Servicio que ofrece las funciones necesarias para diversos cálculos financieros.
7
7
  */
@@ -73,7 +73,6 @@ export declare class OfferService {
73
73
  * Más info en: {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#carga-financiera}
74
74
  * @param totalInstallment Cuota Total (C_tot)
75
75
  * @param disposableIncome Ingresos Mensuales (Im)
76
- * @param maximumBackendRatio Máximo (CF)
77
76
  */
78
77
  getBackEndRatio(totalInstallment: number, disposableIncome: number): number;
79
78
  /**
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OfferService = void 0;
4
- var models_1 = require("../../shared/models");
5
- var finance_service_1 = require("./finance.service");
6
4
  var math_1 = require("../../math");
5
+ var models_1 = require("../../shared/models");
6
+ var credit_insurance_fee_term_definition_enum_1 = require("../../shared/models/enum/credit-insurance-fee-term-definition.enum");
7
+ var product_enum_1 = require("../models/product.enum");
8
+ var constants_service_1 = require("./constants.service");
7
9
  var credit_insurance_service_1 = require("./credit-insurance.service");
10
+ var finance_service_1 = require("./finance.service");
11
+ var installment_service_1 = require("./installment.service");
8
12
  var loan_to_value_service_1 = require("./loan-to-value.service");
9
13
  var maximum_local_service_1 = require("./maximum-local.service");
10
- var installment_service_1 = require("./installment.service");
11
- var constants_service_1 = require("./constants.service");
12
14
  var operational_expenses_1 = require("./operational-expenses");
13
- var credit_insurance_fee_term_definition_enum_1 = require("../../shared/models/enum/credit-insurance-fee-term-definition.enum");
14
- var product_enum_1 = require("../models/product.enum");
15
15
  /**
16
16
  * Servicio que ofrece las funciones necesarias para diversos cálculos financieros.
17
17
  */
@@ -158,7 +158,7 @@ var OfferService = /** @class */ (function () {
158
158
  var debtGuaranteeViv = this.maximumLocal.debtGuaranteeViv(propertyValue, maximumPropertyLTV, k1Fin, k2Fin);
159
159
  var approvedAmountLoanToValue = this.maximumLocal.debtGuarantee(debtGuaranteeViv, debtGuaranteeCr);
160
160
  var approvedAmount = this.getApprovedAmount(approvedAmountFinanceCharge, maximumLocalIncomeDividend, approvedAmountLoanToValue);
161
- var credituAmount = this.math.round(this.credituAmount(downPayment, subsidy, propertyValue, creditInsuranceFactor, creditInsurancePercentageFinanced, operationalExpensesWeightedSum, operationalExpensesFinancing, creditTaxRate, creditTaxRatePercentage, amountRequestedByClient), 2);
161
+ var credituAmount = Math.floor((this.credituAmount(downPayment, subsidy, propertyValue, creditInsuranceFactor, creditInsurancePercentageFinanced, operationalExpensesWeightedSum, operationalExpensesFinancing, creditTaxRate, creditTaxRatePercentage, amountRequestedByClient) * 100) / 100); // Redondear a dos decimales
162
162
  var creditAmount = this.getCreditAmountToOffer(approvedAmount, credituAmount, creditMinAmount, creditMaxAmount);
163
163
  var financingAmount = this.financingAmount(creditAmount, k1Fin, k2Fin);
164
164
  var installment = this.installment.getMonthlyPayment(baseMonthlyPayment, creditAmount);
@@ -169,7 +169,7 @@ var OfferService = /** @class */ (function () {
169
169
  : operationalExpensesFinanceable;
170
170
  var loanToValueCredit = this.ltv.credit(financingAmount, creditInsurancePremium, propertyValue, creditInsurancePercentageFinanced, operationalExpensesFinanced, operationalExpensesFinancing);
171
171
  var financingRatio = this.math.divide(financingAmount, amountRequestedByClient);
172
- var loanToValueHome = this.ltv.home(financingAmount, propertyValue);
172
+ var loanToValueHome = this.ltv.home(credituAmount, propertyValue);
173
173
  var creditInsuranceInstallment = this.insurance.creditInsurance(financingAmount, creditInsuranceFactor, creditInsurancePercentageFinanced.value(), creditInsuranceNumberOfMonths, isCreditInsuranceAccelerated, creditInsurancePremium, numberOfGraceMonths, installment);
174
174
  var lifeInsuranceFee = this.insurance.lifeInsurance(creditAmount, totalLifeInsuranceMonthlyRate);
175
175
  var propertyInsuranceFee = this.insurance.propertyInsurance(propertyValue, propertyTypeFactor, propertyInsuranceMonthlyRate);
@@ -281,7 +281,7 @@ var OfferService = /** @class */ (function () {
281
281
  var _a = this.math, subtract = _a.subtract, multiply = _a.multiply;
282
282
  var calculatedAmount = subtract(multiply(creditAmount, k1Fin), k2Fin);
283
283
  // Si el resultado es menor que creditAmount * 0.5, devolver al menos eso
284
- return calculatedAmount < (creditAmount * 0.5) ? creditAmount * 0.5 : calculatedAmount;
284
+ return calculatedAmount < (creditAmount * 0.25) ? creditAmount * 0.25 : calculatedAmount;
285
285
  };
286
286
  /**
287
287
  * Función que calcula la Cuota Total (C_tot)
@@ -311,8 +311,7 @@ var OfferService = /** @class */ (function () {
311
311
  creditInstallmentValue = this.math.subtract(creditInstallment, creditInsuranceInstallment);
312
312
  }
313
313
  var numerator = this.math.add(creditInstallmentValue, otherMortages);
314
- var frontEndRatioCalculated = this.math.divide(numerator, monthlyIncome);
315
- return frontEndRatioCalculated;
314
+ return this.math.divide(numerator, monthlyIncome);
316
315
  };
317
316
  /**
318
317
  * Función que calcula la Carga Financiera (CF), en la teoría financiera
@@ -320,11 +319,9 @@ var OfferService = /** @class */ (function () {
320
319
  * Más info en: {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#carga-financiera}
321
320
  * @param totalInstallment Cuota Total (C_tot)
322
321
  * @param disposableIncome Ingresos Mensuales (Im)
323
- * @param maximumBackendRatio Máximo (CF)
324
322
  */
325
323
  OfferService.prototype.getBackEndRatio = function (totalInstallment, disposableIncome) {
326
- var backEndRatioCalculated = this.math.divide(totalInstallment, disposableIncome);
327
- return backEndRatioCalculated;
324
+ return this.math.divide(totalInstallment, disposableIncome);
328
325
  };
329
326
  /**
330
327
  * Función que calcula el Monto aprobado es el mínimo entre Máximo local
@@ -366,12 +363,16 @@ var OfferService = /** @class */ (function () {
366
363
  */
367
364
  // eslint-disable-next-line class-methods-use-this
368
365
  OfferService.prototype.getCreditAmountToOffer = function (approvedAmount, credituAmount, creditMinAmount, creditMaxAmount) {
366
+ if (creditMinAmount.value() > creditMaxAmount.value()) {
367
+ throw new Error('Credit minimum amount cannot be greater than maximum amount');
368
+ }
369
369
  models_1.Guarder.defined(creditMinAmount, 'CreditMinAmount');
370
+ models_1.Guarder.defined(creditMaxAmount, 'CreditMaxAmount');
370
371
  var minApprovedAmount = Math.min(approvedAmount, credituAmount);
371
372
  if (minApprovedAmount > creditMaxAmount.value())
372
373
  return creditMaxAmount.value();
373
374
  if (minApprovedAmount < creditMinAmount.value())
374
- return creditMinAmount.value();
375
+ return 0;
375
376
  return minApprovedAmount;
376
377
  };
377
378
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creditu-common-library",
3
- "version": "2.3.14",
3
+ "version": "2.3.16",
4
4
  "description": "Common library for Creditu applications",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -9,6 +9,7 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "build": "tsc",
12
+ "build:watch": "tsc --watch",
12
13
  "lint": "tsc --noEmit && eslint \"src/**/*.ts\" --no-fix",
13
14
  "test:unit": "jest",
14
15
  "test:cov": "jest --coverage",
@@ -25,9 +26,9 @@
25
26
  },
26
27
  "homepage": "https://gitlab.com/creditu-team/creditu-common-library#readme",
27
28
  "devDependencies": {
28
- "@babel/preset-typescript": "^7.27.0",
29
- "@nestjs/testing": "^10.4.15",
30
- "@types/express": "^5.0.1",
29
+ "@babel/preset-typescript": "^7.27.1",
30
+ "@nestjs/testing": "^10.4.18",
31
+ "@types/express": "^5.0.2",
31
32
  "@types/jest": "^29.5.14",
32
33
  "@typescript-eslint/eslint-plugin": "^5.62.0",
33
34
  "@typescript-eslint/parser": "^5.62.0",
@@ -35,12 +36,12 @@
35
36
  "eslint-config-airbnb-base": "^15.0.0",
36
37
  "eslint-plugin-import": "^2.31.0",
37
38
  "jest": "^29.7.0",
38
- "ts-jest": "^29.3.1",
39
+ "ts-jest": "^29.3.4",
39
40
  "ts-node": "^10.9.2",
40
41
  "typescript": "^4.9.5"
41
42
  },
42
43
  "dependencies": {
43
- "@nestjs/common": "^10.4.15",
44
+ "@nestjs/common": "^10.4.18",
44
45
  "creditu-date-model": "^2.9.1",
45
46
  "dinero.js": "^1.9.1",
46
47
  "express": "^4.21.2",
@@ -226,7 +226,7 @@ describe('offerService CL', () => {
226
226
  const math = new MathService(true, 20);
227
227
  const offerService = new OfferService(math);
228
228
  const result = offerService.calculateCreditAmountToOffer(inputs, params);
229
- expect(result).toMatchObject(expectedResult);
229
+ expect(result).toMatchObject({ ...expectedResult, approvedAmount: 0 });
230
230
  });
231
231
 
232
232
  it('CHILE, SUBSIDY, SUBSIDY_1_2 A', () => {
@@ -7,28 +7,27 @@ describe('offer service functional tests common', () => {
7
7
  const math = new MathService(true, 20);
8
8
  const offerService = new OfferService(math);
9
9
  describe('getCreditAmountToOffer', () => {
10
- it('getCreditAmountToOffer should return 0 when minApprovedAmount < creditMinAmount', () => {
10
+ it('getCreditAmountToOffer should return 0 when minApprovedAmount < creditMinAmount', async () => {
11
11
  // ARRANGE
12
12
  const creditMinAmount = new CreditAmount(10);
13
13
  const creditMaxAmount = new CreditAmount(0);
14
14
  // ACT
15
- const result = offerService.getCreditAmountToOffer(
15
+ expect(() => offerService.getCreditAmountToOffer(
16
16
  0,
17
17
  9,
18
18
  creditMinAmount,
19
19
  creditMaxAmount
20
- );
20
+ ))
21
+ .toThrow('Credit minimum amount cannot be greater than maximum amount');
21
22
  // ASSERT
22
- expect(result).toBe(0);
23
23
  });
24
- it('getCreditAmountToOffer should return creditMaxAmount when minApprovedAmount > creditMaxAmount', () => {
25
- // ARRANGE
26
- const creditMinAmount = new CreditAmount(0);
27
- const creditMaxAmount = new CreditAmount(10);
28
- // ACT
29
- const result = offerService.getCreditAmountToOffer(100, 100, creditMinAmount, creditMaxAmount);
30
- // ASSERT
31
- expect(result).toBe(10);
24
+ it('should throw error when creditMinAmount > creditMaxAmount', () => {
25
+ const creditMinAmount = new CreditAmount(10);
26
+ const creditMaxAmount = new CreditAmount(0);
27
+
28
+ expect(() => {
29
+ offerService.getCreditAmountToOffer(0, 9, creditMinAmount, creditMaxAmount);
30
+ }).toThrow('Credit minimum amount cannot be greater than maximum amount');
32
31
  });
33
32
  it('getCreditAmountToOffer should return approvedAmount when ir more than credituAmount and is in range', () => {
34
33
  // ARRANGE