Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions lib/services/immoscout/immoscout-web-translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,33 @@ const WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP = {
'wohnung-kaufen-mit-balkon': { equipment: ['balcony'] },
'wohnung-mit-garten-mieten': { equipment: ['garden'] },
'eigentumswohnung-mit-garten': { equipment: ['garden'] },
};

const BASE_SLUGS = {
// Category "Wohnungstyp"
'souterrainwohnung-mieten': { apartmenttypes: ['halfbasement'] },
'erdgeschosswohnung-mieten': { apartmenttypes: ['groundfloor'] },
'hochparterrewohnung-mieten': { apartmenttypes: ['raisedgroundfloor'] },
'etagenwohnung-mieten': { apartmenttypes: ['apartment'] },
'loft-mieten': { apartmenttypes: ['loft'] },
'maisonette-mieten': { apartmenttypes: ['maisonette'] },
'terrassenwohnung-mieten': { apartmenttypes: ['terracedflat'] },
'penthouse-mieten': { apartmenttypes: ['penthouse'] },
'dachgeschosswohnung-mieten': { apartmenttypes: ['roofstorey'] },
souterrainwohnung: { apartmenttypes: ['halfbasement'] },
erdgeschosswohnung: { apartmenttypes: ['groundfloor'] },
hochparterrewohnung: { apartmenttypes: ['raisedgroundfloor'] },
etagenwohnung: { apartmenttypes: ['apartment'] },
loft: { apartmenttypes: ['loft'] },
maisonette: { apartmenttypes: ['maisonette'] },
terrassenwohnung: { apartmenttypes: ['terracedflat'] },
penthouse: { apartmenttypes: ['penthouse'] },
dachgeschosswohnung: { apartmenttypes: ['roofstorey'] },
// Category "Ausstattung"
'wohnung-mit-garage-mieten': { equipment: ['parking'] },
'wohnung-mit-einbaukueche-mieten': { equipment: ['builtinkitchen'] },
'wohnung-mit-keller-mieten': { equipment: ['cellar'] },
'wohnung-mit-garage': { equipment: ['parking'] },
'wohnung-mit-einbaukueche': { equipment: ['builtinkitchen'] },
'wohnung-mit-keller': { equipment: ['cellar'] },
// Category "Merkmale"
'neubauwohnung-mieten': { newbuilding: true },
'barrierefreie-wohnung-mieten': { equipment: ['handicappedaccessible'] },
neubauwohnung: { newbuilding: true },
'barrierefreie-wohnung': { equipment: ['handicappedaccessible'] },
};

for (const [key, value] of Object.entries(BASE_SLUGS)) {
WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP[`${key}-mieten`] = value;
WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP[`${key}-kaufen`] = value;
}

// SEO-optimized rental paths used by the ImmoScout web UI when the user
// configures a maximum warmrent. Example: "wohnung-bis-800-euro-warm" means
// "apartment for rent up to 800 EUR warmrent". The web UI generates these
Expand Down Expand Up @@ -201,7 +209,9 @@ export function convertWebToMobile(webUrl) {
// Test for seo optimized apartment path (only used on the ImmoScout web app)
if (WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP[realTypeKey]) {
additionalParamsFromWebPath = WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP[realTypeKey];
realType = REAL_ESTATE_TYPE['wohnung-mieten'];
realType = realTypeKey.endsWith('-kaufen')
? REAL_ESTATE_TYPE['wohnung-kaufen']
: REAL_ESTATE_TYPE['wohnung-mieten'];
} else {
// Test for SEO max-warmrent path, e.g. "wohnung-bis-800-euro-warm"
const seoMaxWarmrent = parseSeoMaxWarmrentPath(realTypeKey);
Expand Down
59 changes: 59 additions & 0 deletions test/services/immoscout/immoscout-web-translator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,65 @@ describe('#immoscout-mobile URL conversion', () => {
expect(queryParams.get('pricetype')).toBe('calculatedtotalrent');
});

// Buy-side apartment sub-type SEO paths.
it.each([
['souterrainwohnung-kaufen', 'halfbasement'],
['erdgeschosswohnung-kaufen', 'groundfloor'],
['hochparterrewohnung-kaufen', 'raisedgroundfloor'],
['etagenwohnung-kaufen', 'apartment'],
['loft-kaufen', 'loft'],
['maisonette-kaufen', 'maisonette'],
['terrassenwohnung-kaufen', 'terracedflat'],
['penthouse-kaufen', 'penthouse'],
['dachgeschosswohnung-kaufen', 'roofstorey'],
])('should convert %s to apartmentbuy with apartmenttype %s', (slug, apartmentType) => {
const webUrl = `https://www.immobilienscout24.de/Suche/de/berlin/berlin/${slug}`;

const converted = convertWebToMobile(webUrl);
const queryParams = new URL(converted).searchParams;
expect(queryParams.get('realestatetype')).toBe('apartmentbuy');
expect(queryParams.get('apartmenttypes')).toBe(apartmentType);
});

// Buy-side equipment/feature SEO paths follow the same "-kaufen" suffix
// pattern as the apartment sub-types above (also verified live).
it.each([
['wohnung-mit-garage-kaufen', 'parking'],
['wohnung-mit-einbaukueche-kaufen', 'builtinkitchen'],
['wohnung-mit-keller-kaufen', 'cellar'],
['barrierefreie-wohnung-kaufen', 'handicappedaccessible'],
])('should convert %s to apartmentbuy with equipment %s', (slug, equipment) => {
const webUrl = `https://www.immobilienscout24.de/Suche/de/berlin/berlin/${slug}`;

const converted = convertWebToMobile(webUrl);
const queryParams = new URL(converted).searchParams;
expect(queryParams.get('realestatetype')).toBe('apartmentbuy');
expect(queryParams.get('equipment')).toBe(equipment);
});

it('should convert neubauwohnung-kaufen to apartmentbuy with newbuilding=true', () => {
const webUrl = 'https://www.immobilienscout24.de/Suche/de/berlin/berlin/neubauwohnung-kaufen';

const converted = convertWebToMobile(webUrl);
const queryParams = new URL(converted).searchParams;
expect(queryParams.get('realestatetype')).toBe('apartmentbuy');
expect(queryParams.get('newbuilding')).toBe('true');
});

// Sanity check: the corresponding "-mieten" slugs must remain untouched
// by the suffix-based realType resolution introduced above.
it.each([
['souterrainwohnung-mieten', 'halfbasement'],
['dachgeschosswohnung-mieten', 'roofstorey'],
])('should keep %s resolving to apartmentrent with apartmenttype %s', (slug, apartmentType) => {
const webUrl = `https://www.immobilienscout24.de/Suche/de/berlin/berlin/${slug}`;

const converted = convertWebToMobile(webUrl);
const queryParams = new URL(converted).searchParams;
expect(queryParams.get('realestatetype')).toBe('apartmentrent');
expect(queryParams.get('apartmenttypes')).toBe(apartmentType);
});

// Test URL conversion with unsupported query parameters
it('should remove unsupported query parameters', () => {
const webUrl = 'https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten?minimuminternetspeed=100000';
Expand Down
Loading