@bytebrand/export-cars 1.26.42 → 1.26.44

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.
Files changed (29) hide show
  1. package/dist/configs/autouncle.config.js +0 -22
  2. package/dist/configs/autouncle.config.js.map +1 -1
  3. package/dist/exporters/autouncle.exporter.js +0 -10
  4. package/dist/exporters/autouncle.exporter.js.map +1 -1
  5. package/dist/interfaces/export-item.interface.d.ts +2 -2
  6. package/dist/services/autouncle-feed-run.d.ts +0 -6
  7. package/dist/services/autouncle-feed-run.js +1 -11
  8. package/dist/services/autouncle-feed-run.js.map +1 -1
  9. package/dist/transformers/autouncle.transformer.d.ts +0 -3
  10. package/dist/transformers/autouncle.transformer.js +4 -7
  11. package/dist/transformers/autouncle.transformer.js.map +1 -1
  12. package/dist/transformers/meinstadt.transformer.d.ts +2 -0
  13. package/dist/transformers/meinstadt.transformer.js +13 -5
  14. package/dist/transformers/meinstadt.transformer.js.map +1 -1
  15. package/dist/tsconfig.build.tsbuildinfo +1 -1
  16. package/docs/autouncle/AUDIT.md +103 -103
  17. package/docs/autouncle/RUNBOOK.md +0 -2
  18. package/docs/meinestadt/AUDIT.md +20 -4
  19. package/docs/meinestadt/PARTNER-QUESTIONS.md +1 -1
  20. package/package.json +1 -1
  21. package/src/configs/autouncle.config.ts +1 -26
  22. package/src/exporters/autouncle.exporter.ts +0 -12
  23. package/src/interfaces/export-item.interface.ts +3 -2
  24. package/src/services/autouncle-feed-run.ts +2 -19
  25. package/src/transformers/autouncle.transformer.ts +6 -13
  26. package/src/transformers/meinstadt.transformer.ts +21 -4
  27. package/test/autouncle-feed-run.test.ts +2 -25
  28. package/test/autouncle-mapping.test.ts +2 -21
  29. package/test/meinstadt-mapping.test.ts +35 -1
@@ -143,15 +143,10 @@ const tests: Array<[string, () => void | Promise<void>]> = [
143
143
  assert.deepEqual([none.fuel_economy, none.co2_emission], ['', '']);
144
144
  }],
145
145
 
146
- ['EnVKV: estimated values withheld by the publication gate; the CO2-derived class goes with CO2', () => {
146
+ ['EnVKV: the stored values are sent as in the Google / Meta feeds (no filter); WLTP class as before', () => {
147
147
  const c = car('w1', { 'consumption.wltpCombined': 5.8, 'environmentEmissions.wltpCo2': 132, 'environmentEmissions.wltpEnergyEfficiencyClass': 'D' });
148
148
  const sent = item(c);
149
149
  assert.deepEqual([sent.fuel_economy, sent.co2_emission, sent.co2_effiency_class], ['5.8', '132', 'D']);
150
- const noFuel = item(c, { withheldEnvkv: ['fuel_consumption'] });
151
- assert.deepEqual([noFuel.fuel_economy, noFuel.co2_emission, noFuel.co2_effiency_class], ['', '132', 'D']);
152
- const noCo2 = item(c, { withheldEnvkv: ['co2_emissions'] });
153
- assert.deepEqual([noCo2.fuel_economy, noCo2.co2_emission, noCo2.co2_effiency_class], ['5.8', '', '']);
154
- assert.deepEqual(Object.keys(noCo2), HISTORIC_KEYS);
155
150
  }],
156
151
 
157
152
  ['seller address: the dealer\'s own address, region from the postal code table', () => {
@@ -226,26 +221,12 @@ const tests: Array<[string, () => void | Promise<void>]> = [
226
221
  assert.equal(dry.maxImages, 0);
227
222
  assert.equal(dry.feedGuard.minPublishedItems, 1);
228
223
  assert.equal(new AutouncleConfig({ ...base, autouncleDryRun: 'no' } as any).dryRun, true);
229
- const gateTable = { publicationGateBqProject: 'p', publicationGateBqDataset: 'd', publicationGateBqTable: 't' };
230
- const live = new AutouncleConfig({ ...base, ...gateTable, publicationGate: 'enforce', autouncleDryRun: 'false', autouncleMaxImages: '12', feedGuardMinPublishedItems: '50' } as any);
224
+ const live = new AutouncleConfig({ ...base, autouncleDryRun: 'false', autouncleMaxImages: '12', feedGuardMinPublishedItems: '50' } as any);
231
225
  assert.equal(live.dryRun, false);
232
226
  assert.equal(live.outputFiles[0], 'resources/autouncle-export/api_export_cars_autouncle.json');
233
227
  assert.equal(live.stateDir, 'resources/autouncle-state/export');
234
228
  assert.equal(live.maxImages, 12);
235
229
  assert.equal(live.feedGuard.minPublishedItems, 50);
236
- assert.deepEqual(live.publicationGate, { mode: 'enforce', project: 'p', dataset: 'd', table: 't' });
237
- }],
238
-
239
- ['config: publication gate off by default for a dry-run; a live run needs enforce; audit / enforce need the table', () => {
240
- const base = { environment: Environment.DEVELOP, exportType: ExportType.AUTOUNCLE };
241
- const gateTable = { publicationGateBqProject: 'p', publicationGateBqDataset: 'd', publicationGateBqTable: 't' };
242
- assert.equal(new AutouncleConfig({ ...base } as any).publicationGate, undefined);
243
- assert.equal(new AutouncleConfig({ ...base, publicationGate: 'off' } as any).publicationGate, undefined);
244
- assert.equal(new AutouncleConfig({ ...base, ...gateTable, publicationGate: 'Audit' } as any).publicationGate.mode, 'audit');
245
- assert.throws(() => new AutouncleConfig({ ...base, autouncleDryRun: 'false' } as any), /needs publicationGate=enforce/);
246
- assert.throws(() => new AutouncleConfig({ ...base, ...gateTable, publicationGate: 'audit', autouncleDryRun: 'false' } as any), /needs publicationGate=enforce/);
247
- assert.throws(() => new AutouncleConfig({ ...base, publicationGate: 'enforce' } as any), /needs publicationGateBqProject/);
248
- assert.throws(() => new AutouncleConfig({ ...base, publicationGate: 'strict' } as any), /must be off, audit or enforce/);
249
230
  }],
250
231
  ];
251
232
 
@@ -6,6 +6,8 @@ import { de } from '@bytebrand/i18n-dictionaries';
6
6
  import { MeinstadtConfig, parseMeinstadtCpc } from '../src/configs/meinstadt.config';
7
7
  import { Environment, ExportType, ImageType } from '../src/enums';
8
8
  import {
9
+ MEINSTADT_LINK_PARAMS,
10
+ getMeinstadtTitle,
9
11
  mapMeinstadtItem,
10
12
  toAccidentFree,
11
13
  toMeinstadtImages,
@@ -119,6 +121,38 @@ const tests: Array<[string, () => void | Promise<void>]> = [
119
121
  assert.equal(mapMeinstadtItem(car('l2', { 'mainData.condition': 'selector_unknown', 'mainData.mileage': 5 }), ctx()).usageState, 'Neu');
120
122
  }],
121
123
 
124
+ ['listingUrl (ADV-327): partner in source, identical legacy + utm pairs, no paid medium, stable per car', () => {
125
+ assert.equal(MEINSTADT_LINK_PARAMS, 'source=meinestadt&medium=listing&campaign=listing&utm_source=meinestadt&utm_medium=listing&utm_campaign=listing');
126
+ const a = mapMeinstadtItem(car('car-a'), ctx()).listingUrl;
127
+ assert.equal(a, `https://www.auto.de/search/vehicle/car-a?${MEINSTADT_LINK_PARAMS}`);
128
+ assert.equal(mapMeinstadtItem(car('car-a'), ctx()).listingUrl, a);
129
+ assert.notEqual(mapMeinstadtItem(car('car-b'), ctx()).listingUrl, a);
130
+ assert.ok(!/medium=cpc|source=classifieds/.test(a));
131
+ }],
132
+
133
+ ['EnVKV: WLTP picks of the Google feed, legacy only as fallback; BEV no fuel, CO2 0; 0 / missing -> null', () => {
134
+ const wltp = mapMeinstadtItem(car('e1', { 'consumption.wltpCombined': 5.8, 'environmentEmissions.wltpCo2': 132 }), ctx());
135
+ assert.deepEqual([wltp.fuelConsumptionCombined, wltp.co2Emissions], [5.8, 132]);
136
+ // fixture has only the legacy fields (6.1 l, 137 g) -> sent as before
137
+ const legacy = mapMeinstadtItem(car('e2'), ctx());
138
+ assert.deepEqual([legacy.fuelConsumptionCombined, legacy.co2Emissions], [6.1, 137]);
139
+ // CBD mirrors kWh into consumptionCombined for BEVs: never sent as fuel consumption
140
+ const bev = mapMeinstadtItem(car('e3', { 'consumption.fuel': 'selector_fuel_electrical', 'consumption.consumptionCombined': 16.5, 'environmentEmissions.co2': null }), ctx());
141
+ assert.deepEqual([bev.fuelConsumptionCombined, bev.co2Emissions], [null, 0]);
142
+ const none = mapMeinstadtItem(car('e4', { 'consumption.consumptionCombined': 0, 'environmentEmissions.co2': null }), ctx());
143
+ assert.deepEqual([none.fuelConsumptionCombined, none.co2Emissions], [null, null]);
144
+ }],
145
+
146
+ ['title: make model subModel, missing parts left out (never "undefined" / "null")', () => {
147
+ assert.equal(getMeinstadtTitle(car('t1')), 'Opel Astra 1.2 Turbo Edition');
148
+ assert.equal(getMeinstadtTitle(car('t2', { 'mainData.subModel': null })), 'Opel Astra');
149
+ assert.equal(getMeinstadtTitle(car('t3', { 'mainData.subModel': ' ' })), 'Opel Astra');
150
+ const noSub = car('t4');
151
+ delete noSub.mainData.subModel;
152
+ assert.equal(mapMeinstadtItem(noSub, ctx()).title, 'Opel Astra');
153
+ assert.equal(getMeinstadtTitle(car('t5', { 'mainData.subModel': ' 1.5 TSI ' })), 'Opel Astra 1.5 TSI');
154
+ }],
155
+
122
156
  ['item: historical keys and order, slash keys kept literally, no city/zip/lat/long', () => {
123
157
  const item = mapMeinstadtItem(car('k1'), ctx({ images: ['https://x/1.jpeg', 'https://x/2.jpeg'] }));
124
158
  assert.deepEqual(Object.keys(item), [
@@ -133,7 +167,7 @@ const tests: Array<[string, () => void | Promise<void>]> = [
133
167
  make: 'Opel',
134
168
  model: 'Astra',
135
169
  cpc: '0.99',
136
- listingUrl: 'https://www.auto.de/search/vehicle/k1?source=classifieds&medium=listing&campaign=meinestadt',
170
+ listingUrl: 'https://www.auto.de/search/vehicle/k1?source=meinestadt&medium=listing&campaign=listing&utm_source=meinestadt&utm_medium=listing&utm_campaign=listing',
137
171
  title: 'Opel Astra 1.2 Turbo Edition',
138
172
  accidentFree: true,
139
173
  mileage: 13000,