Repository: mirumee/saleor-dashboard
Pull request #165 (2019-09-11 08:45:53)

Fix en locale matching
I want to merge this change because this PR fixes bug causing users to see `en` locale only if no other `navigator.languages` matched. It caused `navigator.languages = ['en', 'fr', 'es']` to match `fr`, even though there is a `en` locale.

### Pull Request Checklist

<!-- Please keep this section. It will make maintainer's life easier. -->

1. [x] All visible strings are translated with proper context.
1. [x] All data-formatting is locale-aware (dates, numbers, and so on).
1. [x] Translated strings are extracted to `.pot` file.
1. [x] Number of API calls is optimized.
1. [x] The changes are tested.
1. [x] Type definitions are up to date.
1. [x] Changes are mentioned in the changelog.


codecov[bot]: # [Codecov](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=h1) Report
> Merging [#165](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=desc) into [master](https://codecov.io/gh/mirumee/saleor-dashboard/commit/2287411d5ac5a28070f0a13a7a044298efc4223c?src=pr&el=desc) will **increase** coverage by `0.09%`.
> The diff coverage is `33.33%`.

[![Impacted file tree graph](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165/graphs/tree.svg?width=650&token=GuvRMxAgM1&height=150&src=pr)](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #165      +/-   ##
==========================================
+ Coverage   73.64%   73.74%   +0.09%     
==========================================
  Files         528      528              
  Lines        5327     5328       +1     
  Branches      911      911              
==========================================
+ Hits         3923     3929       +6     
+ Misses       1259     1254       -5     
  Partials      145      145
```


| [Impacted Files](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/components/Locale/Locale.tsx](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165/diff?src=pr&el=tree#diff-c3JjL2NvbXBvbmVudHMvTG9jYWxlL0xvY2FsZS50c3g=) | `68.75% <33.33%> (+35.41%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=footer). Last update [2287411...2c8249c](https://codecov.io/gh/mirumee/saleor-dashboard/pull/165?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4cecca6c..fdf7c97bd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,3 +18,4 @@ All notable, unreleased changes to this project will be documented in this file.
 - Replace checkbox with switch component in "product type has variants" - #152 by @dominik-zeglen
 - Add password reset flow - #147 by @dominik-zeglen
 - Add support for multiple values in filters - #160 by @dominik-zeglen
+- Fix en locale matching - #165 by @dominik-zeglen
diff --git a/src/components/Locale/Locale.tsx b/src/components/Locale/Locale.tsx
index 0a83cc640..a5d23b8e8 100644
--- a/src/components/Locale/Locale.tsx
+++ b/src/components/Locale/Locale.tsx
@@ -52,7 +52,7 @@ export const LocaleContext = React.createContext<LocaleContextType>(
 
 const { Consumer: LocaleConsumer, Provider: RawLocaleProvider } = LocaleContext;
 
-enum Locale {
+export enum Locale {
   AR = "ar",
   AZ = "az",
   BG = "bg",
@@ -62,6 +62,7 @@ enum Locale {
   DA = "da",
   DE = "de",
   EL = "el",
+  EN = "en",
   ES = "es",
   ES_CO = "es-co",
   ET = "et",
@@ -107,6 +108,8 @@ const localeData: Record<Locale, LocaleMessages> = {
   [Locale.DA]: locale_DA,
   [Locale.DE]: locale_DE,
   [Locale.EL]: locale_EL,
+  // Default language
+  [Locale.EN]: undefined,
   [Locale.ES]: locale_ES,
   [Locale.ES_CO]: locale_ES_CO,
   [Locale.ET]: locale_ET,
@@ -141,10 +144,10 @@ const localeData: Record<Locale, LocaleMessages> = {
   [Locale.ZH_HANT]: locale_ZH_HANT
 };
 
-function getMatchingLocale(): Locale {
+export function getMatchingLocale(languages: readonly string[]): Locale {
   const localeEntries = Object.entries(Locale);
 
-  for (const preferredLocale of navigator.languages) {
+  for (const preferredLocale of languages) {
     for (const localeEntry of localeEntries) {
       if (localeEntry[1].toLowerCase() === preferredLocale.toLowerCase()) {
         return Locale[localeEntry[0]];
@@ -156,7 +159,9 @@ function getMatchingLocale(): Locale {
 }
 
 const LocaleProvider: React.FC = ({ children }) => {
-  const [locale] = React.useState(getMatchingLocale() || defaultLocale);
+  const [locale] = React.useState(
+    getMatchingLocale(navigator.languages) || defaultLocale
+  );
 
   return (
     <IntlProvider


Test patch:
diff --git a/src/components/Locale/Locale.test.ts b/src/components/Locale/Locale.test.ts
new file mode 100644
index 000000000..082a9a1e3
--- /dev/null
+++ b/src/components/Locale/Locale.test.ts
@@ -0,0 +1,25 @@
+import { getMatchingLocale, Locale } from "./Locale";
+
+describe("Matches locale to browser settings", () => {
+  it("if first language is an exact match", () => {
+    const locales = ["fr", "es", "en"];
+
+    expect(getMatchingLocale(locales)).toBe(Locale.FR);
+  });
+
+  it("if there is an exact match, but it's not first preference", () => {
+    const locales = ["does-not-exist", "tr", "de", "fr"];
+
+    expect(getMatchingLocale(locales)).toBe(Locale.TR);
+  });
+
+  it("or returns undefined if there is no match", () => {
+    const locales = [
+      "does-not-exist-1",
+      "does-not-exist-2",
+      "does-not-exist-3"
+    ];
+
+    expect(getMatchingLocale(locales)).toBe(undefined);
+  });
+});