@bytebrand/export-cars 1.26.41 → 1.26.43
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/dist/configs/autouncle.config.js +0 -22
- package/dist/configs/autouncle.config.js.map +1 -1
- package/dist/exporters/autouncle.exporter.js +0 -10
- package/dist/exporters/autouncle.exporter.js.map +1 -1
- package/dist/services/autouncle-feed-run.d.ts +0 -6
- package/dist/services/autouncle-feed-run.js +1 -10
- package/dist/services/autouncle-feed-run.js.map +1 -1
- package/dist/transformers/autouncle.transformer.d.ts +0 -2
- package/dist/transformers/autouncle.transformer.js +3 -5
- package/dist/transformers/autouncle.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/autouncle/AUDIT.md +6 -4
- package/docs/autouncle/RUNBOOK.md +0 -2
- package/package.json +1 -1
- package/src/configs/autouncle.config.ts +1 -26
- package/src/exporters/autouncle.exporter.ts +0 -12
- package/src/services/autouncle-feed-run.ts +1 -15
- package/src/transformers/autouncle.transformer.ts +6 -10
- package/test/autouncle-feed-run.test.ts +2 -25
- package/test/autouncle-mapping.test.ts +2 -21
package/docs/autouncle/AUDIT.md
CHANGED
|
@@ -58,8 +58,8 @@ Dry-run is the default and writes `resources/autouncle-dryrun/`, which no Cronic
|
|
|
58
58
|
| seller_region / city / street_address / postcode | UPA businessAddress, else mainAddress; region from the postal code table | if the table did not know the place, street/city/zip were **blanked** (664/1044 DEV cars) | dealer's own values kept, region `Deutschland` | |
|
|
59
59
|
| description | offer.offerDescription | raw | same; 192/1002 empty on DEV, some contain literal `\\` line breaks (dealer data) | → Q10 |
|
|
60
60
|
| images | Imbo images | default profile: `/large` (format negotiated, can be WebP), padded with **3 noimage placeholders** below 17 photos (2820 placeholder URLs on DEV) | `[{url}]`, ADV-336 clean profile, explicit `large-cached.jpeg`, every URL checked (200 + image/jpeg|png); no valid 3/4 hero → car not sent | limits → ADV-323 gate |
|
|
61
|
-
| fuel_economy / co2_emission | consumption.consumptionCombined / environmentEmissions.co2 | raw legacy fields; a BEV sent its kWh (CBD mirrors it into consumptionCombined) as fuel economy | since 1.26.41: the Google feed's EnVKV picks as plain numbers (WLTP first, legacy only as fallback; confirmed plug-in weighted); BEV: fuel `""`, CO₂ `0`;
|
|
62
|
-
| co2_effiency_class | environmentEmissions.wltpEnergyEfficiencyClass (ADV-187) | raw | same
|
|
61
|
+
| fuel_economy / co2_emission | consumption.consumptionCombined / environmentEmissions.co2 | raw legacy fields; a BEV sent its kWh (CBD mirrors it into consumptionCombined) as fuel economy | since 1.26.41: the Google feed's EnVKV picks as plain numbers (WLTP first, legacy only as fallback; confirmed plug-in weighted); BEV: fuel `""`, CO₂ `0`; no filter, the stored values as in the Google / Meta feeds | units → Q6 |
|
|
62
|
+
| co2_effiency_class | environmentEmissions.wltpEnergyEfficiencyClass (ADV-187) | raw | same | → Q6 |
|
|
63
63
|
| euro_emission_class / enviromental_sticker | environmentEmissions.* | raw selector keys | same (no schema to translate to) | → Q6 |
|
|
64
64
|
|
|
65
65
|
Car-level exclusions (new, counted in the report): `duplicate_id`, `filtered`, `no_id`, `no_dealer`,
|
|
@@ -77,8 +77,10 @@ Car-level exclusions (new, counted in the report): `duplicate_id`, `filtered`, `
|
|
|
77
77
|
8. Fail-closed: no `emptyDir`; empty / partial / stale snapshot, empty result or a drop > 20 % against the
|
|
78
78
|
last good run → run blocked (exit 1, `3.1` copy does not run), last good file stays. Lock per state dir.
|
|
79
79
|
9. Dry-run default; live only with `autouncleDryRun=false`.
|
|
80
|
-
10. (1.26.41, 10.11) EnVKV:
|
|
81
|
-
|
|
80
|
+
10. (1.26.41, 10.11) EnVKV: the Google feed's picks (WLTP first). DEV dry-run 10.11: 1731 ads, 128 BEV with fuel ""
|
|
81
|
+
and CO₂ 0, the WLTP picks changed 338 fuel / 403 CO₂ values against the legacy fields.
|
|
82
|
+
(1.26.43, 11.11) The EnVKV C8 publication gate of 1.26.41/42 was removed (user decision): like the Google and Meta
|
|
83
|
+
jobs, the feed sends the stored values without parameters. No `publicationGate*` params on this job.
|
|
82
84
|
11. (1.26.41, 10.11) `back_link` parameters per ADV-324 (partner in `source`, identical utm pair).
|
|
83
85
|
|
|
84
86
|
## 5. Evidence
|
|
@@ -15,8 +15,6 @@ Not activated. Nothing below has been done on any Cronicle host.
|
|
|
15
15
|
| `feedGuardMaxSourceAgeHours` | 26 | newest base export chunk must be younger |
|
|
16
16
|
| `feedGuardMaxStaleHours` | 48 | last good file reported STALE after this |
|
|
17
17
|
| `feedGuardAcceptDrop` | off | `true` for ONE run after a real stock drop |
|
|
18
|
-
| `publicationGate` | off | `audit` counts estimated EnVKV values, `enforce` sends them empty. **A live run needs `enforce`** (config error otherwise). enforce fails the run if the enrichment log cannot be read |
|
|
19
|
-
| `publicationGateBqProject` / `…Dataset` / `…Table` | — | CBD enrichment log table, same values as the Google job; required for audit / enforce |
|
|
20
18
|
|
|
21
19
|
`String` / `Number` rules stay as they are (PROD: dealer allow-list + `metaData.imagesCount:2`).
|
|
22
20
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toNumber } from 'lodash';
|
|
2
2
|
|
|
3
3
|
import { ExportType, FileType, ImageType } from '../enums';
|
|
4
|
-
import { Params
|
|
4
|
+
import { Params } from '../interfaces/params.interface';
|
|
5
5
|
import { FeedGuardOptions } from '../services/feed-guard';
|
|
6
6
|
import { Config } from './config';
|
|
7
7
|
|
|
@@ -55,33 +55,8 @@ export class AutouncleConfig extends Config {
|
|
|
55
55
|
maxStaleHours: positiveNumber(params.feedGuardMaxStaleHours, AUTOUNCLE_DEFAULTS.maxStaleHours),
|
|
56
56
|
acceptDrop: text(params.feedGuardAcceptDrop).toLowerCase() === 'true',
|
|
57
57
|
};
|
|
58
|
-
this.publicationGate = parsePublicationGate(params);
|
|
59
|
-
// ADV-322 "do not guess emissions": a live file never goes out with unchecked EnVKV estimates.
|
|
60
|
-
if (!this.dryRun && this.publicationGate?.mode !== 'enforce') {
|
|
61
|
-
throw new Error('a live AutoUncle run (autouncleDryRun=false) needs publicationGate=enforce');
|
|
62
|
-
}
|
|
63
58
|
this.outputFiles = [
|
|
64
59
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTOUNCLE}.${FileType.JSON}`,
|
|
65
60
|
];
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
|
-
|
|
69
|
-
// Same params and rules as the Google job (GoogleConfig): off by default; audit / enforce need the
|
|
70
|
-
// enrichment log table (publicationGateBqProject / Dataset / Table).
|
|
71
|
-
function parsePublicationGate(params: Params): PublicationGateConfig | undefined {
|
|
72
|
-
const mode = text(params.publicationGate).toLowerCase();
|
|
73
|
-
if (!mode || mode === 'off') return undefined;
|
|
74
|
-
if (mode !== 'audit' && mode !== 'enforce') {
|
|
75
|
-
throw new Error(`publicationGate must be off, audit or enforce, got "${mode}"`);
|
|
76
|
-
}
|
|
77
|
-
const gate = {
|
|
78
|
-
mode: mode as PublicationGateConfig['mode'],
|
|
79
|
-
project: text(params.publicationGateBqProject),
|
|
80
|
-
dataset: text(params.publicationGateBqDataset),
|
|
81
|
-
table: text(params.publicationGateBqTable),
|
|
82
|
-
};
|
|
83
|
-
if (!gate.project || !gate.dataset || !gate.table) {
|
|
84
|
-
throw new Error(`publicationGate=${mode} needs publicationGateBqProject, publicationGateBqDataset and publicationGateBqTable`);
|
|
85
|
-
}
|
|
86
|
-
return gate;
|
|
87
|
-
}
|
|
@@ -9,7 +9,6 @@ import { resolveOpenAiImageFields } from '../transformers/openai-image-fields';
|
|
|
9
9
|
import { CarService, RulesService, LoaderService, ConfigService, ImagesService } from '../services';
|
|
10
10
|
import { ImageUrlValidator } from '../services/image-url-validator.service';
|
|
11
11
|
import { FeedGuard } from '../services/feed-guard';
|
|
12
|
-
import { PublicationGate, loadPublicationGate } from '../services/publication-gate';
|
|
13
12
|
import { AutouncleFeedRun, AutouncleSourceCar } from '../services/autouncle-feed-run';
|
|
14
13
|
import { AutouncleConfig } from '../configs/autouncle.config';
|
|
15
14
|
import { Exporter } from '../interfaces/exporter.interface';
|
|
@@ -37,16 +36,6 @@ export class AutouncleExporter implements Exporter {
|
|
|
37
36
|
const transformer = await this.moduleRef.create(AutouncleTransformer);
|
|
38
37
|
const addresses = new Map<string, Promise<AutouncleAddress | null>>();
|
|
39
38
|
|
|
40
|
-
// EnVKV C8 (ADV-322): estimated values are withheld (enforce) or only counted (audit). enforce fails
|
|
41
|
-
// the job when the enrichment log cannot be read, so the last published file stays.
|
|
42
|
-
let gate: PublicationGate;
|
|
43
|
-
try {
|
|
44
|
-
gate = await loadPublicationGate(config.publicationGate);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
LoggerService.exitError(`autouncle feed not published: ${error?.message ?? error}`);
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
39
|
const run = new AutouncleFeedRun(
|
|
51
40
|
{
|
|
52
41
|
forEachChunk: fn => this.loaderService.process((chunk: FsChunkInterface) => fn(chunk.data as AutouncleSourceCar[])),
|
|
@@ -66,7 +55,6 @@ export class AutouncleExporter implements Exporter {
|
|
|
66
55
|
imageStats: () => validator.stats,
|
|
67
56
|
translate: key => transformer.translate(key),
|
|
68
57
|
guard: new FeedGuard(config.feedGuard),
|
|
69
|
-
gate,
|
|
70
58
|
},
|
|
71
59
|
{
|
|
72
60
|
runId: config.runId,
|
|
@@ -6,7 +6,6 @@ import { DataSchemes } from '@bytebrand/car-schema';
|
|
|
6
6
|
import { AutouncleJsonBuilder } from '../formats/autouncle-json.builder';
|
|
7
7
|
import { AutouncleAddress, AutouncleExclusion, getAutouncleExclusion, mapAutouncleItem } from '../transformers/autouncle.transformer';
|
|
8
8
|
import { FeedGuard, FeedGuardError, LastGood, inspectSourceSnapshot } from './feed-guard';
|
|
9
|
-
import { PublicationGate } from './publication-gate';
|
|
10
9
|
|
|
11
10
|
export interface AutouncleSourceCar {
|
|
12
11
|
car: DataSchemes.Car;
|
|
@@ -27,8 +26,6 @@ export interface AutouncleRunDeps {
|
|
|
27
26
|
imageStats: () => Record<string, number>;
|
|
28
27
|
translate: (key: string) => string;
|
|
29
28
|
guard: FeedGuard;
|
|
30
|
-
// EnVKV C8 publication gate (CBD enrichment log); absent = off
|
|
31
|
-
gate?: Pick<PublicationGate, 'mode' | 'estimatedAttributes'>;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
31
|
export interface AutouncleRunOptions {
|
|
@@ -57,8 +54,6 @@ export interface AutouncleRunReport {
|
|
|
57
54
|
excluded: Record<string, number>;
|
|
58
55
|
imagesPerItem: { min: number | null; max: number | null; total: number };
|
|
59
56
|
images: Record<string, number>;
|
|
60
|
-
// published items with an estimated EnVKV value per attribute; with gate enforce those were sent empty
|
|
61
|
-
envkv: { gate: 'off' | 'audit' | 'enforce'; estimated: Record<string, number> };
|
|
62
57
|
lastGood: LastGood | null;
|
|
63
58
|
lastGoodAgeHours: number | null;
|
|
64
59
|
stale: boolean;
|
|
@@ -98,7 +93,6 @@ export class AutouncleFeedRun {
|
|
|
98
93
|
excluded: {},
|
|
99
94
|
imagesPerItem: { min: null, max: null, total: 0 },
|
|
100
95
|
images: {},
|
|
101
|
-
envkv: { gate: this.deps.gate?.mode ?? 'off', estimated: {} },
|
|
102
96
|
lastGood,
|
|
103
97
|
lastGoodAgeHours: guard.staleHours(lastGood, startedAt),
|
|
104
98
|
stale: guard.isStale(lastGood, startedAt),
|
|
@@ -147,19 +141,11 @@ export class AutouncleFeedRun {
|
|
|
147
141
|
continue;
|
|
148
142
|
}
|
|
149
143
|
const images = await this.deps.resolveImages(source);
|
|
150
|
-
const
|
|
151
|
-
const mapped = mapAutouncleItem(source.car, {
|
|
152
|
-
domain: this.options.domain,
|
|
153
|
-
address,
|
|
154
|
-
images,
|
|
155
|
-
translate: this.deps.translate,
|
|
156
|
-
withheldEnvkv: this.deps.gate?.mode === 'enforce' ? estimated : [],
|
|
157
|
-
});
|
|
144
|
+
const mapped = mapAutouncleItem(source.car, { domain: this.options.domain, address, images, translate: this.deps.translate });
|
|
158
145
|
if (mapped.ok === false) {
|
|
159
146
|
increment(report.excluded, mapped.reason);
|
|
160
147
|
continue;
|
|
161
148
|
}
|
|
162
|
-
estimated.forEach(attribute => increment(report.envkv.estimated, attribute));
|
|
163
149
|
await builder.addItem(mapped.item, first);
|
|
164
150
|
first = false;
|
|
165
151
|
dealers.add(ownerId);
|
|
@@ -11,7 +11,7 @@ import { DEFAULT_REGION, MIN_MILEAGES } from '../constants/autouncle.contants';
|
|
|
11
11
|
import { AutouncleJsonItem } from '../interfaces';
|
|
12
12
|
import { OpenAiImageSelection } from './openai-image-fields';
|
|
13
13
|
import { toUnixSeconds } from './meinstadt.transformer';
|
|
14
|
-
import {
|
|
14
|
+
import { envkvCo2Value, envkvFuelConsumptionValue } from './google-feed-envkv';
|
|
15
15
|
|
|
16
16
|
// back_link parameters (ADV-324): the partner in `source`, so the reporting views, the CRM source and
|
|
17
17
|
// GA4 (utm_*) all see "autouncle". Legacy and utm pairs carry identical values (no parameterConflict).
|
|
@@ -46,8 +46,6 @@ export interface AutouncleMappingContext {
|
|
|
46
46
|
images: string[];
|
|
47
47
|
// German label of a selector (TranslatorExtended.translateVal)
|
|
48
48
|
translate: (key: string) => string;
|
|
49
|
-
// EnVKV attributes whose value is a CBD estimate and must not be published (publication gate, enforce)
|
|
50
|
-
withheldEnvkv?: GoogleEnvkvAttribute[];
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
export type AutouncleMapResult = { ok: true; item: AutouncleJsonItem } | { ok: false; reason: AutouncleExclusion };
|
|
@@ -188,10 +186,6 @@ export const mapAutouncleItem = (car: DataSchemes.Car, ctx: AutouncleMappingCont
|
|
|
188
186
|
const sellerId = toString(get(car, 'metaData.ownerId', '')).trim();
|
|
189
187
|
const price = getAutounclePrice(get(car, 'price.currentSalesPrice', null));
|
|
190
188
|
const firstRegistration = get(car, 'mainData.firstRegistration', null);
|
|
191
|
-
// EnVKV (ADV-322): the WLTP picks of the Google feed (legacy fields only as their fallback), never an
|
|
192
|
-
// estimated value. The energy class is derived from CO2, so it goes with a withheld CO2 value.
|
|
193
|
-
const withheld = ctx.withheldEnvkv ?? [];
|
|
194
|
-
const co2Withheld = withheld.includes('co2_emissions');
|
|
195
189
|
|
|
196
190
|
return {
|
|
197
191
|
ok: true,
|
|
@@ -223,10 +217,12 @@ export const mapAutouncleItem = (car: DataSchemes.Car, ctx: AutouncleMappingCont
|
|
|
223
217
|
seller_id: sellerId,
|
|
224
218
|
description: toString(get(car, 'offer.offerDescription', '')),
|
|
225
219
|
images: ctx.images.map(url => ({ url })),
|
|
226
|
-
|
|
227
|
-
|
|
220
|
+
// EnVKV (ADV-322): the same values as the Google feed (WLTP first, legacy only as fallback; BEV: no
|
|
221
|
+
// fuel, CO2 0), as plain numbers.
|
|
222
|
+
fuel_economy: toString(envkvFuelConsumptionValue(car) ?? ''),
|
|
223
|
+
co2_emission: toString(envkvCo2Value(car) ?? ''),
|
|
228
224
|
// ADV-187: canonical CO2-derived WLTP class, not the unvalidated legacy NEFZ class.
|
|
229
|
-
co2_effiency_class:
|
|
225
|
+
co2_effiency_class: toString(get(car, 'environmentEmissions.wltpEnergyEfficiencyClass', '')),
|
|
230
226
|
euro_emission_class: toString(get(car, 'environmentEmissions.emissionClass', '')),
|
|
231
227
|
enviromental_sticker: toString(get(car, 'environmentEmissions.emissionSticker', '')),
|
|
232
228
|
},
|
|
@@ -7,7 +7,7 @@ import { tmpdir } from 'os';
|
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
|
|
9
9
|
import { FeedGuard, FeedGuardError, FeedGuardOptions } from '../src/services/feed-guard';
|
|
10
|
-
import { AutouncleFeedRun,
|
|
10
|
+
import { AutouncleFeedRun, AutouncleSourceCar } from '../src/services/autouncle-feed-run';
|
|
11
11
|
import { toAutouncleImages } from '../src/transformers/autouncle.transformer';
|
|
12
12
|
import { selectOpenAiImageFields } from '../src/transformers/openai-image-fields';
|
|
13
13
|
import { buildImagesService } from './fixtures/images-service.harness';
|
|
@@ -63,9 +63,7 @@ const guardOptions = (world: World, extra: Partial<FeedGuardOptions> = {}): Feed
|
|
|
63
63
|
...extra,
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const run = async (world: World, { at = NOW, guard = {}, gate }: { at?: Date; guard?: Partial<FeedGuardOptions>; gate?: Gate } = {}) => {
|
|
66
|
+
const run = async (world: World, { at = NOW, guard = {} }: { at?: Date; guard?: Partial<FeedGuardOptions> } = {}) => {
|
|
69
67
|
const forEachChunk = async (fn: (cars: AutouncleSourceCar[]) => Promise<void>) => {
|
|
70
68
|
const names = (await fs.readdir(world.source)).sort((a, b) => Number(a.split('.')[1]) - Number(b.split('.')[1]));
|
|
71
69
|
for (const name of names) {
|
|
@@ -87,7 +85,6 @@ const run = async (world: World, { at = NOW, guard = {}, gate }: { at?: Date; gu
|
|
|
87
85
|
imageStats: () => ({ ok: 1 }),
|
|
88
86
|
translate: key => key,
|
|
89
87
|
guard: new FeedGuard(guardOptions(world, guard)),
|
|
90
|
-
gate,
|
|
91
88
|
},
|
|
92
89
|
{
|
|
93
90
|
runId: 'test',
|
|
@@ -234,26 +231,6 @@ const tests: Array<[string, () => Promise<void>]> = [
|
|
|
234
231
|
assert.equal(await exists(world.json), false);
|
|
235
232
|
}],
|
|
236
233
|
|
|
237
|
-
['EnVKV gate: enforce sends estimated values empty, audit only counts them; off without a gate', async () => {
|
|
238
|
-
const world = await newWorld();
|
|
239
|
-
await writeSource(world, [source('v1'), source('v2')]);
|
|
240
|
-
// v1: the CO2 value it would send is a CBD estimate
|
|
241
|
-
const estimatedAttributes = (c: any): any[] => (c._id === 'v1' ? ['co2_emissions'] : []);
|
|
242
|
-
|
|
243
|
-
const off = await run(world);
|
|
244
|
-
assert.deepEqual(off.envkv, { gate: 'off', estimated: {} });
|
|
245
|
-
|
|
246
|
-
const audit = await run(world, { at: new Date(NOW.getTime() + HOUR), gate: { mode: 'audit', estimatedAttributes } });
|
|
247
|
-
assert.deepEqual(audit.envkv, { gate: 'audit', estimated: { co2_emissions: 1 } });
|
|
248
|
-
assert.deepEqual((await readAds(world)).map((a: any) => a.co2_emission), ['137', '137']);
|
|
249
|
-
|
|
250
|
-
const enforce = await run(world, { at: new Date(NOW.getTime() + 2 * HOUR), gate: { mode: 'enforce', estimatedAttributes } });
|
|
251
|
-
assert.deepEqual(enforce.envkv, { gate: 'enforce', estimated: { co2_emissions: 1 } });
|
|
252
|
-
const ads = await readAds(world);
|
|
253
|
-
assert.deepEqual(ads.map((a: any) => [a.co2_emission, a.fuel_economy]), [['', '6.1'], ['137', '6.1']]);
|
|
254
|
-
assert.equal(ads.length, 2, 'a withheld value never drops the car');
|
|
255
|
-
}],
|
|
256
|
-
|
|
257
234
|
['second run with the same snapshot: byte-identical file (stable ids, order, links)', async () => {
|
|
258
235
|
const world = await newWorld();
|
|
259
236
|
await writeSource(world, [source('i1'), source('i2'), source('i3')]);
|
|
@@ -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:
|
|
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
|
|
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
|
|