mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
Add tests for browser selection of language and refactor
This commit is contained in:
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user