@open3cl/engine 1.7.0 → 1.7.1
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/10_besoin_fr.spec.js +1 -0
- package/10_clim.spec.js +1 -0
- package/11_besoin_ecs.spec.js +1 -0
- package/11_ecs.spec.js +1 -0
- package/12.4_pac.spec.js +1 -0
- package/13.2_generateur_combustion.spec.js +3 -3
- package/13.2_generateur_combustion_ch.spec.js +3 -3
- package/14_generateur_ecs.spec.js +1 -0
- package/15_conso_aux.spec.js +3 -3
- package/2021_04_13_confort_ete.spec.js +1 -0
- package/3.1_b.spec.js +1 -0
- package/3.2.1_mur.spec.js +1 -0
- package/3.2.2_plancher_bas.spec.js +1 -0
- package/3.2.3_plancher_haut.spec.js +1 -0
- package/3.3.1.4_porte.spec.js +1 -0
- package/3.3_baie_vitree.spec.js +1 -0
- package/3.4_pont_thermique.spec.js +1 -0
- package/4_ventilation.spec.js +1 -0
- package/5_conso_ventilation.spec.js +1 -0
- package/6.2_surface_sud_equivalente.spec.js +1 -0
- package/9_besoin_ch.spec.js +1 -0
- package/9_chauffage.spec.js +3 -3
- package/9_conso_ch.spec.js +1 -0
- package/9_emetteur_ch.spec.js +1 -0
- package/9_generateur_ch.spec.js +1 -0
- package/README.md +412 -291
- package/conso.spec.js +1 -0
- package/engine.js +3 -1
- package/engine.spec.js +1 -0
- package/package.json +15 -14
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +0 -222
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +0 -345
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +0 -87
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +0 -260
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +0 -272
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +0 -231
- package/features/engine/domain/ch/generateur-ch.service.spec.js +0 -849
- package/features/engine/domain/conso/froid/conso-froid.service.spec.js +0 -233
- package/features/engine/domain/ecs/installation-ecs.service.spec.js +0 -337
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +0 -607
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +0 -550
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +0 -82
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +0 -542
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +0 -430
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +0 -411
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +0 -653
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +0 -117
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +0 -508
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import corpus from '../../../../../../test/corpus-sano.json';
|
|
2
|
-
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
3
|
-
import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
|
|
4
|
-
import { ContexteBuilder } from '../../contexte.builder.js';
|
|
5
|
-
import { getAdemeFileJson } from '../../../../../../test/test-helpers.js';
|
|
6
|
-
import { BesoinEcsService } from './besoin-ecs.service.js';
|
|
7
|
-
import { EcsTvStore } from '../../../../dpe/infrastructure/ecs/ecsTv.store.js';
|
|
8
|
-
import { describeIntegration } from '../../../../../../test/helpers/integration-test.js';
|
|
9
|
-
|
|
10
|
-
/** @type {BesoinEcsService} **/
|
|
11
|
-
let service;
|
|
12
|
-
|
|
13
|
-
/** @type {DpeNormalizerService} **/
|
|
14
|
-
let normalizerService;
|
|
15
|
-
|
|
16
|
-
/** @type {ContexteBuilder} **/
|
|
17
|
-
let contexteBuilder;
|
|
18
|
-
|
|
19
|
-
/** @type {EcsTvStore} **/
|
|
20
|
-
let tvStore;
|
|
21
|
-
|
|
22
|
-
describe('Calcul du besoin en eau chaude sanitaire', () => {
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
tvStore = new EcsTvStore();
|
|
25
|
-
service = new BesoinEcsService(tvStore);
|
|
26
|
-
normalizerService = new DpeNormalizerService();
|
|
27
|
-
contexteBuilder = new ContexteBuilder();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('Determination du besoin en eau chaude sanitaire pour un mois donné', () => {
|
|
31
|
-
vi.spyOn(tvStore, 'getTefs').mockReturnValue(0.5);
|
|
32
|
-
|
|
33
|
-
/** @type {Contexte} */
|
|
34
|
-
const ctx = {
|
|
35
|
-
altitude: {
|
|
36
|
-
value: '400-800m'
|
|
37
|
-
},
|
|
38
|
-
zoneClimatique: {
|
|
39
|
-
value: 'h1a'
|
|
40
|
-
},
|
|
41
|
-
nadeq: 2
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
expect(service.besoinEcsMois(ctx, 'Janvier', false)).toBeCloseTo(159.5, 2);
|
|
45
|
-
expect(service.besoinEcsMois(ctx, 'Janvier', true)).toBeCloseTo(225.01, 2);
|
|
46
|
-
expect(tvStore.getTefs).toHaveBeenCalledWith('400-800m', 'h1a', 'Janvier');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("Sommation du besoin ECS sur les douze mois de l'année", () => {
|
|
50
|
-
// On isole execute de la formule mensuelle : besoinEcsMois est doublé pour ne mesurer
|
|
51
|
-
// que la logique d'agrégation (une valeur conventionnelle, une valeur dépensière par mois).
|
|
52
|
-
vi.spyOn(service, 'besoinEcsMois').mockImplementation((ctx, mois, depensier) =>
|
|
53
|
-
depensier ? 10 : 1
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
/** @type {Contexte} */
|
|
57
|
-
const ctx = { altitude: { value: '400-800m' }, zoneClimatique: { value: 'h1a' }, nadeq: 2 };
|
|
58
|
-
|
|
59
|
-
const res = service.execute(ctx);
|
|
60
|
-
|
|
61
|
-
// 12 mois : conventionnel = 12 * 1, dépensier = 12 * 10
|
|
62
|
-
expect(res).toStrictEqual({ besoin_ecs: 12, besoin_ecs_depensier: 120 });
|
|
63
|
-
expect(service.besoinEcsMois).toHaveBeenCalledTimes(24);
|
|
64
|
-
expect(service.besoinEcsMois).toHaveBeenCalledWith(ctx, 'Janvier', false);
|
|
65
|
-
expect(service.besoinEcsMois).toHaveBeenCalledWith(ctx, 'Janvier', true);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describeIntegration("Test d'intégration pour le besoin en eau chaude sanitaire", () => {
|
|
69
|
-
test.each(corpus)('vérification des sorties besoin_ecs pour dpe %s', (ademeId) => {
|
|
70
|
-
/**
|
|
71
|
-
* @type {Dpe}
|
|
72
|
-
*/
|
|
73
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
74
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
75
|
-
|
|
76
|
-
/** @type {Contexte} */
|
|
77
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
78
|
-
|
|
79
|
-
const ecs = service.execute(ctx);
|
|
80
|
-
expect(ecs.besoin_ecs).toBeCloseTo(dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs, 2);
|
|
81
|
-
expect(ecs.besoin_ecs_depensier).toBeCloseTo(
|
|
82
|
-
dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs_depensier,
|
|
83
|
-
2
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
});
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import corpus from '../../../../../../test/corpus-sano.json';
|
|
3
|
-
import { expect_or, getAdemeFileJson } from '../../../../../../test/test-helpers.js';
|
|
4
|
-
import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
|
|
5
|
-
import { ContexteBuilder } from '../../contexte.builder.js';
|
|
6
|
-
import { PerteEcsRecupService } from './perte-ecs-recup.service.js';
|
|
7
|
-
import { FrTvStore } from '../../../../dpe/infrastructure/froid/frTv.store.js';
|
|
8
|
-
import { mois_liste } from '../../../../../utils.js';
|
|
9
|
-
import { EcsTvStore } from '../../../../dpe/infrastructure/ecs/ecsTv.store.js';
|
|
10
|
-
import { GenerateurEcsService } from '../../ecs/generateur-ecs.service.js';
|
|
11
|
-
import { InstallationEcsService } from '../../ecs/installation-ecs.service.js';
|
|
12
|
-
import { describeIntegration } from '../../../../../../test/helpers/integration-test.js';
|
|
13
|
-
|
|
14
|
-
/** @type {PerteEcsRecupService} **/
|
|
15
|
-
let service;
|
|
16
|
-
|
|
17
|
-
/** @type {FrTvStore} **/
|
|
18
|
-
let tvStore;
|
|
19
|
-
|
|
20
|
-
/** @type {InstallationEcsService} **/
|
|
21
|
-
let installationEcsService;
|
|
22
|
-
|
|
23
|
-
/** @type {DpeNormalizerService} **/
|
|
24
|
-
let normalizerService;
|
|
25
|
-
|
|
26
|
-
/** @type {ContexteBuilder} **/
|
|
27
|
-
let contexteBuilder;
|
|
28
|
-
|
|
29
|
-
describe('Calcul des pertes de distribution et stockage récupérées', () => {
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
tvStore = new FrTvStore();
|
|
32
|
-
service = new PerteEcsRecupService(tvStore);
|
|
33
|
-
installationEcsService = new InstallationEcsService(new GenerateurEcsService(new EcsTvStore()));
|
|
34
|
-
normalizerService = new DpeNormalizerService();
|
|
35
|
-
contexteBuilder = new ContexteBuilder();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test.each([
|
|
39
|
-
{
|
|
40
|
-
label: 'Installation ECS en mode conventionnel',
|
|
41
|
-
depensier: false,
|
|
42
|
-
expected: 0.192
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
label: 'Installation ECS en mode dépensier',
|
|
46
|
-
depensier: true,
|
|
47
|
-
expected: 0.725
|
|
48
|
-
}
|
|
49
|
-
])('Calcul des pertes de distribution récupérées pour $label', ({ depensier, expected }) => {
|
|
50
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(depensier ? 1.5 : 0.8);
|
|
51
|
-
|
|
52
|
-
/** @type {Contexte} */
|
|
53
|
-
const ctx = {
|
|
54
|
-
altitude: { value: '400-800m' },
|
|
55
|
-
zoneClimatique: { value: 'h1a' },
|
|
56
|
-
inertie: { ilpa: 1 }
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/** @type {Logement} */
|
|
60
|
-
const logement = {
|
|
61
|
-
installation_ecs_collection: {
|
|
62
|
-
installation_ecs: [
|
|
63
|
-
{
|
|
64
|
-
donnee_utilisateur: {
|
|
65
|
-
QdwIndVc: { conventionnel: 100, depensier: 200 },
|
|
66
|
-
QdwColVc: { conventionnel: 50, depensier: 120 }
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
donnee_utilisateur: {
|
|
71
|
-
QdwIndVc: { conventionnel: 150, depensier: 280 },
|
|
72
|
-
QdwColVc: { conventionnel: 65, depensier: 135 }
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
expect(service.pertesDistributionEcsRecup(ctx, logement, depensier)).toBeCloseTo(expected, 3);
|
|
80
|
-
for (const mois of mois_liste) {
|
|
81
|
-
expect(tvStore.getData).toHaveBeenCalledWith(
|
|
82
|
-
depensier ? 'nref21' : 'nref19',
|
|
83
|
-
'400-800m',
|
|
84
|
-
'h1a',
|
|
85
|
-
mois,
|
|
86
|
-
1
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test.each([
|
|
92
|
-
{
|
|
93
|
-
label: 'Installation ECS en mode conventionnel',
|
|
94
|
-
depensier: false,
|
|
95
|
-
expected: 63.209
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
label: 'Installation ECS en mode dépensier',
|
|
99
|
-
depensier: true,
|
|
100
|
-
expected: 118.516
|
|
101
|
-
}
|
|
102
|
-
])('Calcul des pertes de stockage récupérées pour $label', ({ depensier, expected }) => {
|
|
103
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(depensier ? 1.5 : 0.8);
|
|
104
|
-
|
|
105
|
-
/** @type {Contexte} */
|
|
106
|
-
const ctx = {
|
|
107
|
-
altitude: { value: '400-800m' },
|
|
108
|
-
zoneClimatique: { value: 'h1a' },
|
|
109
|
-
inertie: { ilpa: 1 }
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/** @type {Logement} */
|
|
113
|
-
const logement = {
|
|
114
|
-
installation_ecs_collection: {
|
|
115
|
-
installation_ecs: [
|
|
116
|
-
{ donnee_utilisateur: { QgwRecuperable: 120012 } },
|
|
117
|
-
{ donnee_utilisateur: { QgwRecuperable: 150 } }
|
|
118
|
-
]
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
expect(service.pertesStockageEcsRecup(ctx, logement, depensier)).toBeCloseTo(expected, 3);
|
|
123
|
-
for (const mois of mois_liste) {
|
|
124
|
-
expect(tvStore.getData).toHaveBeenCalledWith(
|
|
125
|
-
depensier ? 'nref21' : 'nref19',
|
|
126
|
-
'400-800m',
|
|
127
|
-
'h1a',
|
|
128
|
-
mois,
|
|
129
|
-
1
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test('Agrégation et conversion en kWh des pertes ECS récupérées (execute)', () => {
|
|
135
|
-
// On isole execute des formules mensuelles : les deux méthodes de calcul sont doublées
|
|
136
|
-
// pour ne vérifier que la conversion Wh -> kWh (division par 1000) et le mapping des 4 champs.
|
|
137
|
-
vi.spyOn(service, 'pertesDistributionEcsRecup').mockImplementation(
|
|
138
|
-
(ctx, logement, depensier) => (depensier ? 2000 : 1000)
|
|
139
|
-
);
|
|
140
|
-
vi.spyOn(service, 'pertesStockageEcsRecup').mockImplementation((ctx, logement, depensier) =>
|
|
141
|
-
depensier ? 4000 : 3000
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
const res = service.execute({}, {});
|
|
145
|
-
|
|
146
|
-
expect(res).toStrictEqual({
|
|
147
|
-
pertes_distribution_ecs_recup: 1,
|
|
148
|
-
pertes_distribution_ecs_recup_depensier: 2,
|
|
149
|
-
pertes_stockage_ecs_recup: 3,
|
|
150
|
-
pertes_stockage_ecs_recup_depensier: 4
|
|
151
|
-
});
|
|
152
|
-
expect(service.pertesDistributionEcsRecup).toHaveBeenCalledWith({}, {}, false);
|
|
153
|
-
expect(service.pertesDistributionEcsRecup).toHaveBeenCalledWith({}, {}, true);
|
|
154
|
-
expect(service.pertesStockageEcsRecup).toHaveBeenCalledWith({}, {}, false);
|
|
155
|
-
expect(service.pertesStockageEcsRecup).toHaveBeenCalledWith({}, {}, true);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test("Pertes nulles en l'absence d'installation ECS", () => {
|
|
159
|
-
// Valeur de repli [] quand installation_ecs_collection est absente : aucune installation à sommer.
|
|
160
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(1);
|
|
161
|
-
|
|
162
|
-
/** @type {Contexte} */
|
|
163
|
-
const ctx = {
|
|
164
|
-
altitude: { value: '400-800m' },
|
|
165
|
-
zoneClimatique: { value: 'h1a' },
|
|
166
|
-
inertie: { ilpa: 0 }
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
expect(service.pertesDistributionEcsRecup(ctx, {}, false)).toBe(0);
|
|
170
|
-
expect(service.pertesStockageEcsRecup(ctx, {}, false)).toBe(0);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describeIntegration("Test d'intégration des installations ECS", () => {
|
|
174
|
-
test.each(corpus)(
|
|
175
|
-
'vérification des pertes de distribution ecs recup des installations ECS pour dpe %s',
|
|
176
|
-
(ademeId) => {
|
|
177
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
178
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
179
|
-
|
|
180
|
-
/** @type {Contexte} */
|
|
181
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
182
|
-
|
|
183
|
-
installationEcsService.execute(ctx, dpeRequest.logement, {
|
|
184
|
-
besoin_ecs: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs,
|
|
185
|
-
besoin_ecs_depensier: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs_depensier
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
const pertesStockage = service.execute(ctx, dpeRequest.logement);
|
|
189
|
-
|
|
190
|
-
expect_or(
|
|
191
|
-
() =>
|
|
192
|
-
expect(pertesStockage.pertes_distribution_ecs_recup).toBeCloseTo(
|
|
193
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_distribution_ecs_recup
|
|
194
|
-
),
|
|
195
|
-
() =>
|
|
196
|
-
expect(pertesStockage.pertes_distribution_ecs_recup * 1000).toBeCloseTo(
|
|
197
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_distribution_ecs_recup
|
|
198
|
-
)
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
test.each(corpus)(
|
|
204
|
-
'vérification des pertes de distribution ecs recup depensier des installations ECS pour dpe %s',
|
|
205
|
-
(ademeId) => {
|
|
206
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
207
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
208
|
-
|
|
209
|
-
/** @type {Contexte} */
|
|
210
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
211
|
-
|
|
212
|
-
installationEcsService.execute(ctx, dpeRequest.logement, {
|
|
213
|
-
besoin_ecs: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs,
|
|
214
|
-
besoin_ecs_depensier: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs_depensier
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
const pertesStockage = service.execute(ctx, dpeRequest.logement);
|
|
218
|
-
|
|
219
|
-
expect_or(
|
|
220
|
-
() =>
|
|
221
|
-
expect(pertesStockage.pertes_distribution_ecs_recup_depensier).toBeCloseTo(
|
|
222
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_distribution_ecs_recup_depensier
|
|
223
|
-
),
|
|
224
|
-
() =>
|
|
225
|
-
expect(pertesStockage.pertes_distribution_ecs_recup_depensier * 1000).toBeCloseTo(
|
|
226
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_distribution_ecs_recup_depensier
|
|
227
|
-
)
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
test.each(corpus)(
|
|
233
|
-
'vérification des pertes de stockage ecs recup des installations ECS pour dpe %s',
|
|
234
|
-
(ademeId) => {
|
|
235
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
236
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
237
|
-
|
|
238
|
-
/** @type {Contexte} */
|
|
239
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
240
|
-
|
|
241
|
-
installationEcsService.execute(ctx, dpeRequest.logement, {
|
|
242
|
-
besoin_ecs: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs,
|
|
243
|
-
besoin_ecs_depensier: dpeRequest.logement.sortie.apport_et_besoin.besoin_ecs_depensier
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
const pertesStockage = service.execute(ctx, dpeRequest.logement);
|
|
247
|
-
expect_or(
|
|
248
|
-
() =>
|
|
249
|
-
expect(pertesStockage.pertes_stockage_ecs_recup).toBeCloseTo(
|
|
250
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_stockage_ecs_recup
|
|
251
|
-
),
|
|
252
|
-
() =>
|
|
253
|
-
expect(pertesStockage.pertes_stockage_ecs_recup * 1000).toBeCloseTo(
|
|
254
|
-
dpeRequest.logement.sortie.apport_et_besoin.pertes_stockage_ecs_recup
|
|
255
|
-
)
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
|
|
3
|
-
import { ContexteBuilder } from '../../contexte.builder.js';
|
|
4
|
-
import corpus from '../../../../../../test/corpus-sano.json';
|
|
5
|
-
import { getAdemeFileJson } from '../../../../../../test/test-helpers.js';
|
|
6
|
-
import { FrTvStore } from '../../../../dpe/infrastructure/froid/frTv.store.js';
|
|
7
|
-
import { ApportGratuitService } from '../apport_gratuit/apport-gratuit.service.js';
|
|
8
|
-
import { BesoinFroidService } from './besoin-froid.service.js';
|
|
9
|
-
import { describeIntegration } from '../../../../../../test/helpers/integration-test.js';
|
|
10
|
-
|
|
11
|
-
/** @type {ApportGratuitService} **/
|
|
12
|
-
let apportGratuitService;
|
|
13
|
-
|
|
14
|
-
/** @type {BesoinFroidService} **/
|
|
15
|
-
let service;
|
|
16
|
-
|
|
17
|
-
/** @type {DpeNormalizerService} **/
|
|
18
|
-
let normalizerService;
|
|
19
|
-
|
|
20
|
-
/** @type {ContexteBuilder} **/
|
|
21
|
-
let contexteBuilder;
|
|
22
|
-
|
|
23
|
-
/** @type {FrTvStore} **/
|
|
24
|
-
let tvStore;
|
|
25
|
-
|
|
26
|
-
describe('Calcul des besoins en froid du logement', () => {
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
tvStore = new FrTvStore();
|
|
29
|
-
apportGratuitService = new ApportGratuitService();
|
|
30
|
-
service = new BesoinFroidService(tvStore, apportGratuitService);
|
|
31
|
-
normalizerService = new DpeNormalizerService();
|
|
32
|
-
contexteBuilder = new ContexteBuilder();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('Besoins en froid à 0 si aucune climatisation dans le logement', () => {
|
|
36
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(10);
|
|
37
|
-
|
|
38
|
-
/** @type {Contexte} */
|
|
39
|
-
const ctx = { zoneClimatique: { id: 1 } };
|
|
40
|
-
expect(service.execute(ctx, {})).toStrictEqual({ besoin_fr: 0, besoin_fr_depensier: 0 });
|
|
41
|
-
expect(service.execute(ctx, { enveloppe: {} })).toStrictEqual({
|
|
42
|
-
besoin_fr: 0,
|
|
43
|
-
besoin_fr_depensier: 0
|
|
44
|
-
});
|
|
45
|
-
expect(service.execute(ctx, { climatisation_collection: {} })).toStrictEqual({
|
|
46
|
-
besoin_fr: 0,
|
|
47
|
-
besoin_fr_depensier: 0
|
|
48
|
-
});
|
|
49
|
-
expect(service.execute(ctx, { climatisation_collection: { climatisation: [] } })).toStrictEqual(
|
|
50
|
-
{ besoin_fr: 0, besoin_fr_depensier: 0 }
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
expect(tvStore.getData).not.toHaveBeenCalled();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe('Determination du besoin en froid pour un mois donné', () => {
|
|
57
|
-
test.each([
|
|
58
|
-
{
|
|
59
|
-
data: 0,
|
|
60
|
-
aijFr: 1,
|
|
61
|
-
asjFr: 0.2,
|
|
62
|
-
inertie: 4,
|
|
63
|
-
depensier: false,
|
|
64
|
-
expected: 0
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
data: 0,
|
|
68
|
-
aijFr: 1,
|
|
69
|
-
asjFr: 0.2,
|
|
70
|
-
inertie: 4,
|
|
71
|
-
depensier: true,
|
|
72
|
-
expected: 0
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
data: 58,
|
|
76
|
-
aijFr: 1,
|
|
77
|
-
asjFr: 0.2,
|
|
78
|
-
inertie: 4,
|
|
79
|
-
depensier: false,
|
|
80
|
-
expected: 0
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
data: 58,
|
|
84
|
-
aijFr: 1,
|
|
85
|
-
asjFr: 0.2,
|
|
86
|
-
inertie: 4,
|
|
87
|
-
depensier: true,
|
|
88
|
-
expected: 0
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
data: 30,
|
|
92
|
-
aijFr: 1000,
|
|
93
|
-
asjFr: 2580,
|
|
94
|
-
inertie: 4,
|
|
95
|
-
depensier: false,
|
|
96
|
-
expected: 6.25
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
data: 30,
|
|
100
|
-
aijFr: 1000,
|
|
101
|
-
asjFr: 2580,
|
|
102
|
-
inertie: 4,
|
|
103
|
-
depensier: true,
|
|
104
|
-
expected: 0
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
data: 30,
|
|
108
|
-
aijFr: 1500,
|
|
109
|
-
asjFr: 5580,
|
|
110
|
-
inertie: 4,
|
|
111
|
-
depensier: true,
|
|
112
|
-
expected: 12.38
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
data: 30,
|
|
116
|
-
aijFr: 10000,
|
|
117
|
-
asjFr: 2000,
|
|
118
|
-
inertie: 4,
|
|
119
|
-
depensier: false,
|
|
120
|
-
expected: 16.72
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
data: 30,
|
|
124
|
-
aijFr: 10000,
|
|
125
|
-
asjFr: 2000,
|
|
126
|
-
inertie: 1,
|
|
127
|
-
depensier: true,
|
|
128
|
-
expected: 20.25
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
data: 30,
|
|
132
|
-
aijFr: 10000,
|
|
133
|
-
asjFr: 2000,
|
|
134
|
-
inertie: 2,
|
|
135
|
-
depensier: true,
|
|
136
|
-
expected: 20.25
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
data: 30,
|
|
140
|
-
aijFr: 10000,
|
|
141
|
-
asjFr: 2000,
|
|
142
|
-
inertie: 3,
|
|
143
|
-
depensier: true,
|
|
144
|
-
expected: 19.66
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
data: 30,
|
|
148
|
-
aijFr: 10000,
|
|
149
|
-
asjFr: 2000,
|
|
150
|
-
inertie: 4,
|
|
151
|
-
depensier: true,
|
|
152
|
-
expected: 19.22
|
|
153
|
-
}
|
|
154
|
-
])(
|
|
155
|
-
'nref: $data, eFr: $data, tempExtMoyClim: $data, aijFr: $aijFr, asjFr: $asjFr,' +
|
|
156
|
-
'inertie: $inertie, depensier: $depensier',
|
|
157
|
-
({ data, aijFr, asjFr, inertie, depensier, expected }) => {
|
|
158
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(data);
|
|
159
|
-
vi.spyOn(apportGratuitService, 'apportInterneMois').mockReturnValue(aijFr);
|
|
160
|
-
vi.spyOn(apportGratuitService, 'apportSolaireMois').mockReturnValue(asjFr);
|
|
161
|
-
|
|
162
|
-
/** @type {Logement} **/
|
|
163
|
-
const logement = {
|
|
164
|
-
enveloppe: {},
|
|
165
|
-
sortie: { deperdition: { deperdition_enveloppe: 100 } }
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
/** @type {Contexte} */
|
|
169
|
-
const ctx = {
|
|
170
|
-
altitude: { value: '400-800m' },
|
|
171
|
-
zoneClimatique: { value: 'h1a' },
|
|
172
|
-
inertie: { id: inertie },
|
|
173
|
-
surfaceHabitable: 25
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const ssd = service.besoinFrMois(ctx, logement, 'Janvier', depensier);
|
|
177
|
-
|
|
178
|
-
expect(tvStore.getData).toHaveBeenCalledWith(
|
|
179
|
-
depensier ? 'nref26' : 'nref28',
|
|
180
|
-
'400-800m',
|
|
181
|
-
'h1a',
|
|
182
|
-
'Janvier'
|
|
183
|
-
);
|
|
184
|
-
if (data > 0) {
|
|
185
|
-
expect(tvStore.getData).toHaveBeenCalledWith(
|
|
186
|
-
depensier ? 'e_fr_26' : 'e_fr_28',
|
|
187
|
-
'400-800m',
|
|
188
|
-
'h1a',
|
|
189
|
-
'Janvier'
|
|
190
|
-
);
|
|
191
|
-
expect(tvStore.getData).toHaveBeenCalledWith(
|
|
192
|
-
depensier ? 'textmoy_clim_26' : 'textmoy_clim_28',
|
|
193
|
-
'400-800m',
|
|
194
|
-
'h1a',
|
|
195
|
-
'Janvier'
|
|
196
|
-
);
|
|
197
|
-
expect(apportGratuitService.apportInterneMois).toHaveBeenCalledWith(ctx, data);
|
|
198
|
-
expect(apportGratuitService.apportSolaireMois).toHaveBeenCalledWith(
|
|
199
|
-
ctx,
|
|
200
|
-
{},
|
|
201
|
-
'Janvier',
|
|
202
|
-
data
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
expect(ssd).toBeCloseTo(expected, 2);
|
|
207
|
-
}
|
|
208
|
-
);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
test('Sommation du besoin en froid sur les douze mois en présence de climatisation', () => {
|
|
212
|
-
// Climatisation présente : execute doit agréger besoinFrMois sur les 12 mois.
|
|
213
|
-
// besoinFrMois est doublé pour n'évaluer que la logique d'agrégation.
|
|
214
|
-
vi.spyOn(service, 'besoinFrMois').mockImplementation((ctx, logement, mois, depensier) =>
|
|
215
|
-
depensier ? 5 : 2
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
/** @type {Contexte} */
|
|
219
|
-
const ctx = { zoneClimatique: { id: 1 } };
|
|
220
|
-
|
|
221
|
-
/** @type {Logement} */
|
|
222
|
-
const logement = { climatisation_collection: { climatisation: [{}] } };
|
|
223
|
-
|
|
224
|
-
const res = service.execute(ctx, logement);
|
|
225
|
-
|
|
226
|
-
expect(res).toStrictEqual({ besoin_fr: 24, besoin_fr_depensier: 60 });
|
|
227
|
-
expect(service.besoinFrMois).toHaveBeenCalledTimes(24);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test('Facteur d’utilisation lorsque le ratio de bilan thermique Rbth vaut exactement 1', () => {
|
|
231
|
-
// Branche fut = a / (a + 1) : atteinte uniquement quand Rbth === 1.
|
|
232
|
-
// Rbth = (aijFr + asjFr) / (GV * (tempExtMoyClim - 28) * nref)
|
|
233
|
-
// = 6000 / (100 * (30 - 28) * 30) = 1
|
|
234
|
-
vi.spyOn(tvStore, 'getData').mockReturnValue(30);
|
|
235
|
-
vi.spyOn(apportGratuitService, 'apportInterneMois').mockReturnValue(6000);
|
|
236
|
-
vi.spyOn(apportGratuitService, 'apportSolaireMois').mockReturnValue(0);
|
|
237
|
-
|
|
238
|
-
/** @type {Logement} **/
|
|
239
|
-
const logement = { enveloppe: {}, sortie: { deperdition: { deperdition_enveloppe: 100 } } };
|
|
240
|
-
|
|
241
|
-
/** @type {Contexte} */
|
|
242
|
-
const ctx = {
|
|
243
|
-
altitude: { value: '400-800m' },
|
|
244
|
-
zoneClimatique: { value: 'h1a' },
|
|
245
|
-
inertie: { id: 4 },
|
|
246
|
-
surfaceHabitable: 25
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
// Valeur de référence de régression (module réel exécuté avec ces entrées)
|
|
250
|
-
expect(service.besoinFrMois(ctx, logement, 'Janvier', false)).toBeCloseTo(9.608856088560886, 9);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
describeIntegration("Test d'intégration pour le besoin en froid", () => {
|
|
254
|
-
test.each(corpus)('vérification des sorties besoin_fr pour dpe %s', (ademeId) => {
|
|
255
|
-
/**
|
|
256
|
-
* @type {Dpe}
|
|
257
|
-
*/
|
|
258
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
259
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
260
|
-
|
|
261
|
-
/** @type {Contexte} */
|
|
262
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
263
|
-
|
|
264
|
-
const ecs = service.execute(ctx, dpeRequest.logement);
|
|
265
|
-
expect(ecs.besoin_fr).toBeCloseTo(dpeRequest.logement.sortie.apport_et_besoin.besoin_fr, 2);
|
|
266
|
-
expect(ecs.besoin_fr_depensier).toBeCloseTo(
|
|
267
|
-
dpeRequest.logement.sortie.apport_et_besoin.besoin_fr_depensier,
|
|
268
|
-
2
|
|
269
|
-
);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|