You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

697 lines
14 KiB

const proxyquire = require('proxyquire').noCallThru();
const libpostal = require('../../../controller/libpostal');
const _ = require('lodash');
const mock_logger = require('pelias-mock-logger');
module.exports.tests = {};
module.exports.tests.interface = (test, common) => {
test('valid interface', (t) => {
t.equal(typeof libpostal, 'function', 'libpostal is a function');
t.equal(typeof libpostal(), 'function', 'libpostal returns a controller');
t.end();
});
};
module.exports.tests.early_exit_conditions = (test, common) => {
test('should_execute returning false should not call service', t => {
const service = () => {
t.fail('service should not have been called');
};
const should_execute = (req) => {
// req and res should be passed to should_execute
t.deepEquals(req, {
clean: {
text: 'original query'
}
});
return false;
};
const controller = libpostal(service, should_execute);
const req = {
clean: {
text: 'original query'
}
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query'
}
}, 'req should not have been modified');
t.end();
});
});
};
module.exports.tests.error_conditions = (test, common) => {
test('service returning error should append and not modify req.clean', t => {
const service = (req, callback) => {
callback('libpostal service error', []);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query'
},
errors: ['libpostal service error']
}, 'req should not have been modified');
t.end();
});
});
};
module.exports.tests.failure_conditions = (test, common) => {
test('service returning 2 or more of a label should return undefined and log message', t => {
const logger = mock_logger();
const service = (req, callback) => {
const response = [
{
label: 'road',
value: 'road value 1'
},
{
label: 'city',
value: 'city value'
},
{
label: 'road',
value: 'road value 2'
}
];
callback(null, response);
};
const controller = proxyquire('../../../controller/libpostal', {
'pelias-logger': logger
})(service, () => true);
const req = {
clean: {
text: 'query value'
},
errors: []
};
controller(req, undefined, () => {
t.ok(logger.isWarnMessage('discarding libpostal parse of \'query value\' due to duplicate field assignments'));
t.deepEquals(req, {
clean: {
text: 'query value'
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('service returning empty array should not set parsed_text or parser', t => {
const logger = mock_logger();
const service = (req, callback) => {
callback(null, []);
};
const controller = proxyquire('../../../controller/libpostal', {
'pelias-logger': logger
})(service, () => true);
const req = {
clean: {
text: 'query value'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'query value'
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
};
module.exports.tests.success_conditions = (test, common) => {
test('service returning valid response should convert and append', t => {
const service = (req, callback) => {
const response = [
{
label: 'island',
value: 'island value'
},
{
label: 'category',
value: 'category value'
},
{
label: 'house',
value: 'house value'
},
{
label: 'house_number',
value: 'house_number value'
},
{
label: 'road',
value: 'road value'
},
{
label: 'suburb',
value: 'suburb value'
},
{
label: 'city_district',
value: 'city_district value'
},
{
label: 'city',
value: 'city value'
},
{
label: 'state_district',
value: 'state_district value'
},
{
label: 'state',
value: 'state value'
},
{
label: 'postcode',
value: 'postcode value'
},
{
label: 'country',
value: 'country value'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
island: 'island value',
category: 'category value',
query: 'house value',
number: 'house_number value',
street: 'road value',
neighbourhood: 'suburb value',
borough: 'city_district value',
city: 'city value',
county: 'state_district value',
state: 'state value',
postalcode: 'postcode value',
country: 'country value'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('ISO-2 country should be converted to ISO-3', t => {
const service = (req, callback) => {
const response = [
{
label: 'country',
value: 'ca'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
country: 'CAN'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
};
module.exports.tests.bug_fixes = (test, common) => {
test('bug fix: incorrect parsing of diagonal directionals', t => {
const service = (req, callback) => {
const response =[
{
'label': 'house_number',
'value': '4004'
},
{
'label': 'road',
'value': 'nw'
},
{
'label': 'suburb',
'value': 'beaverton-hillsdale'
},
{
'label': 'city',
'value': 'portland'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
number: '4004',
street: 'nw beaverton-hillsdale',
city: 'portland'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: incorrect parsing of diagonal directionals - no subsequent element', t => {
const service = (req, callback) => {
const response = [
{
'label': 'test',
'value': 'test'
},
{
'label': 'road',
'value': 'nw'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
street: 'nw'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: recast label for "zoo" from borough/city_district to house', t => {
const service = (req, callback) => {
const response = [
{
'label': 'city_district',
'value': 'zoo'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
query: 'zoo'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: correctly parse australian-style unit numbers', t => {
const service = (req, callback) => {
const response = [
{
'label': 'house_number',
'value': '11/1015'
},
{
'label': 'road',
'value': 'nudgee road'
},
{
'label': 'suburb',
'value': 'banyo'
},
{
'label': 'postcode',
'value': '4014'
},
{
'label': 'state',
'value': 'qld'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
unit: '11',
number: '1015',
street: 'nudgee road',
neighbourhood: 'banyo',
postalcode: '4014',
state: 'qld'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: correctly parse australian-style unit numbers - with plus', t => {
const service = (req, callback) => {
const response = [
{
'label': 'house_number',
'value': '2+3/32'
},
{
'label': 'road',
'value': 'dixon street'
},
{
'label': 'suburb',
'value': 'strathpine'
},
{
'label': 'postcode',
'value': '4500'
},
{
'label': 'state',
'value': 'qld'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
unit: '2+3',
number: '32',
street: 'dixon street',
neighbourhood: 'strathpine',
postalcode: '4500',
state: 'qld'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: correctly parse australian-style unit numbers - with unit spelled out', t => {
const service = (req, callback) => {
const response = [
{
'label': 'house_number',
'value': 'unit 3 /30'
},
{
'label': 'road',
'value': 'dan rees street'
},
{
'label': 'suburb',
'value': 'wallsend'
},
{
'label': 'postcode',
'value': '2287'
},
{
'label': 'state',
'value': 'nsw'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
unit: 'unit 3',
number: '30',
street: 'dan rees street',
neighbourhood: 'wallsend',
postalcode: '2287',
state: 'nsw'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
test('bug fix: correctly parse australian-style unit numbers - no-op if "unit" already assigned', t => {
const service = (req, callback) => {
const response = [
{
'label': 'unit',
'value': '99'
},
{
'label': 'house_number',
'value': '11/1015'
},
{
'label': 'road',
'value': 'nudgee road'
},
{
'label': 'suburb',
'value': 'banyo'
},
{
'label': 'postcode',
'value': '4014'
},
{
'label': 'state',
'value': 'qld'
}
];
callback(null, response);
};
const controller = libpostal(service, () => true);
const req = {
clean: {
text: 'original query'
},
errors: []
};
controller(req, undefined, () => {
t.deepEquals(req, {
clean: {
text: 'original query',
parser: 'libpostal',
parsed_text: {
unit: '99',
number: '11/1015',
street: 'nudgee road',
neighbourhood: 'banyo',
postalcode: '4014',
state: 'qld'
}
},
errors: []
}, 'req should not have been modified');
t.end();
});
});
};
module.exports.all = (tape, common) => {
function test(name, testFunction) {
return tape(`GET /libpostal ${name}`, testFunction);
}
for( const testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};