fixing tests

This commit is contained in:
Christian Kellner
2025-05-26 10:43:13 +02:00
6 changed files with 69 additions and 17 deletions

View File

@@ -22,7 +22,7 @@ If you want to try out _Fredy_, you can access the demo version [here](https://f
## Usage ## Usage
- Make sure to use Node.js 22 or above - Make sure to use Node.js 20 or above
- Run the following commands: - Run the following commands:
```ssh ```ssh
yarn (or npm install) yarn (or npm install)
@@ -112,6 +112,10 @@ Put your config.json into a path of your choice, such as `/path/to/your/conf/`.
Example: `docker create --name fredy -v /path/to/your/conf/:/conf -p 9998:9998 fredy/fredy` Example: `docker create --name fredy -v /path/to/your/conf/:/conf -p 9998:9998 fredy/fredy`
## Logs
You can browse the logs with `docker logs fredy -f`.
### 👐 Contributing ### 👐 Contributing
Thanks to all the people who already contributed! Thanks to all the people who already contributed!
@@ -121,6 +125,7 @@ Thanks to all the people who already contributed!
See [Contributing](https://github.com/orangecoding/fredy/blob/master/CONTRIBUTING.md) See [Contributing](https://github.com/orangecoding/fredy/blob/master/CONTRIBUTING.md)
## Logs
You can browse the logs with `docker logs fredy -f`. ## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=orangecoding/fredy&type=Date)](https://www.star-history.com/#orangecoding/fredy&Date)

View File

@@ -23,7 +23,7 @@ const config = {
id: 'a@href', id: 'a@href',
price: 'div[data-testid="cardmfe-price-testid"] | removeNewline | trim', price: 'div[data-testid="cardmfe-price-testid"] | removeNewline | trim',
size: 'div[data-testid="cardmfe-keyfacts-testid"] | removeNewline | trim', size: 'div[data-testid="cardmfe-keyfacts-testid"] | removeNewline | trim',
title: '.css-jv3zx6', title: 'div[data-testid="cardmfe-description-box-text-test-id"] > div:nth-of-type(2)',
link: 'a@href', link: 'a@href',
address: 'div[data-testid="cardmfe-description-box-address"] | removeNewline | trim', address: 'div[data-testid="cardmfe-description-box-address"] | removeNewline | trim',
}, },

View File

@@ -79,6 +79,7 @@ const PARAM_NAME_MAP = {
geocoordinates: 'geocoordinates', geocoordinates: 'geocoordinates',
shape: 'shape', shape: 'shape',
sorting: 'sorting', sorting: 'sorting',
newbuilding: 'newbuilding',
}; };
const EQUIPMENT_MAP = { const EQUIPMENT_MAP = {
@@ -89,6 +90,7 @@ const EQUIPMENT_MAP = {
garden: 'garden', garden: 'garden',
guesttoilet: 'guestToilet', guesttoilet: 'guestToilet',
balcony: 'balcony', balcony: 'balcony',
handicappedaccessible: 'handicappedAccessible',
}; };
const REAL_ESTATE_TYPE = { const REAL_ESTATE_TYPE = {
@@ -98,6 +100,29 @@ const REAL_ESTATE_TYPE = {
'haus-kaufen': 'housebuy', 'haus-kaufen': 'housebuy',
}; };
const WEB_PATH_TO_APARTMENT_EQUIPMENT_MAP = {
// Category "Balkon/Terrasse"
'wohnung-mit-balkon-mieten': { equipment: ['balcony'] },
'wohnung-mit-garten-mieten': { equipment: ['garden'] },
// 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'] },
// Category "Ausstattung"
'wohnung-mit-garage-mieten': { equipment: ['parking'] },
'wohnung-mit-einbaukueche-mieten': { equipment: ['builtinkitchen'] },
'wohnung-mit-keller-mieten': { equipment: ['cellar'] },
// Category "Merkmale"
'neubauwohnung-mieten': { newbuilding: true },
'barrierefreie-wohnung-mieten': { equipment: ['handicappedaccessible'] },
};
export function convertWebToMobile(webUrl) { export function convertWebToMobile(webUrl) {
let url; let url;
try { try {
@@ -112,9 +137,17 @@ export function convertWebToMobile(webUrl) {
} }
const realTypeKey = segments.at(-1); const realTypeKey = segments.at(-1);
const realType = REAL_ESTATE_TYPE[realTypeKey]; let realType = REAL_ESTATE_TYPE[realTypeKey];
let additionalParamsFromWebPath;
if (!realType) { if (!realType) {
throw new Error(`Real estate type not found: ${realTypeKey}`); // 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'];
} else {
throw new Error(`Real estate type not found: ${realTypeKey}`);
}
} }
if (segments.includes('shape')) { if (segments.includes('shape')) {
@@ -132,6 +165,7 @@ export function convertWebToMobile(webUrl) {
searchType: isRadius ? 'radius' : 'region', searchType: isRadius ? 'radius' : 'region',
realestatetype: realType, realestatetype: realType,
...(isRadius ? {} : { geocodes }), ...(isRadius ? {} : { geocodes }),
...additionalParamsFromWebPath,
}; };
if (webParams.geocoordinates) { if (webParams.geocoordinates) {
@@ -141,7 +175,11 @@ export function convertWebToMobile(webUrl) {
for (const [key, val] of Object.entries(webParams)) { for (const [key, val] of Object.entries(webParams)) {
if (key === 'equipment') { if (key === 'equipment') {
const items = [].concat(val).flatMap((v) => `${v}`.split(',')); const items = [].concat(val).flatMap((v) => `${v}`.split(','));
mobileParams[PARAM_NAME_MAP[key]] = items.map((item) => EQUIPMENT_MAP[item.toLowerCase()]).filter(Boolean); const currentEquipmentParams = mobileParams[PARAM_NAME_MAP[key]];
mobileParams[PARAM_NAME_MAP[key]] = [
...(currentEquipmentParams ?? []),
...items.map((item) => EQUIPMENT_MAP[item.toLowerCase()]).filter(Boolean),
];
} else { } else {
mobileParams[PARAM_NAME_MAP[key]] = val; mobileParams[PARAM_NAME_MAP[key]] = val;
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "fredy", "name": "fredy",
"version": "12.0.0", "version": "11.2.1",
"description": "[F]ind [R]eal [E]states [d]amn eas[y].", "description": "[F]ind [R]eal [E]states [d]amn eas[y].",
"scripts": { "scripts": {
"start": "node prod.js", "start": "node prod.js",

View File

@@ -37,7 +37,7 @@
"enabled": true "enabled": true
}, },
"wgGesucht": { "wgGesucht": {
"url": "https://www.wg-gesucht.de/wg-zimmer-in-Duesseldorf.30.0.1.0.html?offer_filter=1&noDeact=1&city_id=30&category=0&rent_type=0&rMax=5000", "url": "https://www.wg-gesucht.de/wg-zimmer-in-Duesseldorf.30.0.1.0.html",
"enabled": true "enabled": true
} }
} }

View File

@@ -16,6 +16,15 @@ describe('#immoscout-mobile URL conversion', () => {
expect(actualMobileUrl).to.equal(expectedMobileUrl); expect(actualMobileUrl).to.equal(expectedMobileUrl);
}); });
// Test URL conversion of web-only SEO path
it('should convert a SEO web path to the correct query params', () => {
const webUrl = 'https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mit-balkon-mieten?equipment=garden';
const converted = convertWebToMobile(webUrl);
const queryParams = new URL(converted).searchParams;
expect(queryParams.get('equipment').split(',')).to.include.members(['garden', 'balcony']);
});
// Test URL conversion with unsupported query parameters // Test URL conversion with unsupported query parameters
it('should remove unsupported query parameters', () => { it('should remove unsupported query parameters', () => {
const webUrl = 'https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten?minimuminternetspeed=100000'; const webUrl = 'https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten?minimuminternetspeed=100000';