Add tests for browser selection of language and refactor

This commit is contained in:
Blade Barringer
2015-11-13 18:05:45 -06:00
parent f672ac8c59
commit 4cd4c588a8
2 changed files with 136 additions and 25 deletions

View File

@@ -128,4 +128,114 @@ describe('getUserLanguage', () => {
}); });
}); });
}); });
context('browser fallback', () => {
it('uses browser specificed language', (done) => {
req.headers['accept-language'] = 'pt';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('pt');
done();
});
});
it('uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
done();
});
});
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', (done) => {
req.headers['accept-language'] = 'blah, he, pt, it';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('he');
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
done();
});
});
it('uses normal version of language if specialized locale is passed in', (done) => {
req.headers['accept-language'] = 'fr-CA';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('fr');
done();
});
});
it('uses es if es is passed in', (done) => {
req.headers['accept-language'] = 'es';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es');
done();
});
});
it('uses es_419 if applicable es-languages are passed in', (done) => {
req.headers['accept-language'] = 'es-mx';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
done();
});
});
it('uses es_419 if multiple es languages are passed in', (done) => {
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('es_419');
done();
});
});
it('zh', (done) => {
req.headers['accept-language'] = 'zh-TW';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('zh_TW');
done();
});
});
it('uses english if browser specified language is not compatible', (done) => {
req.headers['accept-language'] = 'blah';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
done();
});
});
it('uses english if browser does not specify', (done) => {
req.headers['accept-language'] = '';
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
done();
});
});
it('uses english if browser does not supply an accept-language header', (done) => {
delete req.headers['accept-language'];
getUserLanguage(req, res, () => {
expect(req.language).to.equal('en');
done();
});
});
});
}); });

View File

@@ -7,42 +7,43 @@ import {
multipleVersionsLanguages, multipleVersionsLanguages,
} from '../../libs/api-v3/i18n'; } from '../../libs/api-v3/i18n';
function _getFromBrowser (req) { function _getUniqueListOfLanguages (languages) {
let acceptedLanguages = accepts(req).languages(); let acceptableLanguages = _(languages).map((lang) => {
let acceptable = _(acceptedLanguages).map((lang) => {
return lang.slice(0, 2); return lang.slice(0, 2);
}).uniq().value(); }).uniq().value();
let matches = _.intersection(acceptable, defaultLangCodes); let uniqueListOfLanguages = _.intersection(acceptableLanguages, defaultLangCodes);
let iAcceptedCompleteLang = matches.length > 0 ? multipleVersionsLanguages.indexOf(matches[0].toLowerCase()) : -1; return uniqueListOfLanguages;
}
if (iAcceptedCompleteLang !== -1) { function _checkForApplicableLanguageVariant (originalLanguageOptions) {
let acceptedCompleteLang = _.find(acceptedLanguages, (accepted) => { let languageVariant = _.find(originalLanguageOptions, (accepted) => {
return accepted.slice(0, 2) === multipleVersionsLanguages[iAcceptedCompleteLang]; let trimmedAccepted = accepted.slice(0, 2);
return multipleVersionsLanguages[trimmedAccepted];
}); });
if (acceptedCompleteLang) { return languageVariant;
acceptedCompleteLang = acceptedCompleteLang.toLowerCase(); }
function _getFromBrowser (req) {
let originalLanguageOptions = accepts(req).languages();
let uniqueListOfLanguages = _getUniqueListOfLanguages(originalLanguageOptions);
let baseLanguage = (uniqueListOfLanguages[0] || '').toLowerCase();
let languageMapping = multipleVersionsLanguages[baseLanguage];
if (languageMapping) {
let languageVariant = _checkForApplicableLanguageVariant(originalLanguageOptions);
if (languageVariant) {
languageVariant = languageVariant.toLowerCase();
} else { } else {
return 'en'; return 'en';
} }
if (matches[0] === 'es') { return languageMapping[languageVariant] || baseLanguage;
// In case of a Latin American version of Spanish use 'es_419'
return multipleVersionsLanguages.es.indexOf(acceptedCompleteLang !== -1) ? 'es_419' : 'es';
} else if (matches[0] === 'zh') {
let iChinese = multipleVersionsLanguages.zh.indexOf(acceptedCompleteLang.toLowerCase());
return iChinese !== -1 ? multipleVersionsLanguages.zh[iChinese] : 'zh';
} else { } else {
return 'en'; return baseLanguage || 'en';
}
} else if (matches.length > 0) {
return matches[0].toLowerCase();
} else {
return 'en';
} }
} }