Skip to content

Commit

Permalink
Merge pull request #9966 from marmelab/fix-default-translation-key
Browse files Browse the repository at this point in the history
Fix `<SimpleShowLayout>` uses a wrong translation key for field labels
  • Loading branch information
slax57 authored Jul 1, 2024
2 parents 39ee8d0 + bda1bdb commit 7a79484
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 159 deletions.
12 changes: 9 additions & 3 deletions packages/ra-core/src/core/SourceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ export type SourceContextValue = {
* );
* };
*/
export const SourceContext = createContext<SourceContextValue>({
export const SourceContext = createContext<SourceContextValue | undefined>(
undefined
);

const defaultContextValue = {
getSource: (source: string) => source,
getLabel: (source: string) => source,
});

};
export const SourceContextProvider = SourceContext.Provider;

export const useSourceContext = () => {
const context = useContext(SourceContext);
if (!context) {
return defaultContextValue;
}
return context;
};

Expand Down
214 changes: 66 additions & 148 deletions packages/ra-core/src/i18n/useTranslateLabel.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,177 +1,95 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { useTranslateLabel } from './useTranslateLabel';
import { TestTranslationProvider } from './TestTranslationProvider';
import { SourceContextProvider } from '..';

import {
Basic,
I18nLabelAsKey,
I18nNoTranslation,
I18nTranslation,
InSourceContext,
InSourceContextI18nKey,
InSourceContextNoTranslation,
InSourceContextWithResource,
LabelElement,
LabelEmpty,
LabelFalse,
LabelText,
Resource,
Source,
} from './useTranslateLabel.stories';

describe('useTranslateLabel', () => {
const TranslateLabel = ({
source,
label,
resource,
}: {
source?: string;
label?: string | false | React.ReactElement;
resource?: string;
}) => {
const translateLabel = useTranslateLabel();
return (
<>
{translateLabel({
label,
source,
resource,
})}
</>
);
};
it('should compose a translation key from the resource and source', () => {
render(<Basic />);
screen.getByText('resources.posts.fields.title');
});

it('should use the resource in the translation key', () => {
render(<Resource />);
screen.getByText('resources.comments.fields.title');
});

it('should use the source in the translation key', () => {
render(<Source />);
screen.getByText('resources.posts.fields.date');
});

it('should return null when label is false', () => {
render(
<TestTranslationProvider>
<TranslateLabel label={false} source="title" resource="posts" />
</TestTranslationProvider>
);
render(<LabelFalse />);
expect(screen.queryByText(/title/)).toBeNull();
});

it('should return null when label is empty', () => {
render(
<TestTranslationProvider>
<TranslateLabel label="" source="title" resource="posts" />
</TestTranslationProvider>
);
render(<LabelEmpty />);
expect(screen.queryByText(/title/)).toBeNull();
});

it('should return the label element when provided', () => {
render(
<TestTranslationProvider>
<TranslateLabel
label={<span>My title</span>}
source="title"
resource="posts"
/>
</TestTranslationProvider>
);
render(<LabelElement />);
screen.getByText('My title');
});

it('should return the label text when provided', () => {
render(
<TestTranslationProvider messages={{}}>
<TranslateLabel
label="My title"
source="title"
resource="posts"
/>
</TestTranslationProvider>
);
render(<LabelText />);
screen.getByText('My title');
});

it('should return the translated label text when provided', () => {
render(
<TestTranslationProvider
messages={{
test: { title: 'My title' },
}}
>
<TranslateLabel
label="test.title"
source="title"
resource="posts"
/>
</TestTranslationProvider>
);
screen.getByText('My title');
});
describe('i18n', () => {
it('should use the source and resource to create a default translation key', () => {
render(<I18nTranslation />);
screen.getByText('My Title');
});

it('should return the inferred label from source and resource when no label is provided', () => {
render(
<TestTranslationProvider messages={{}}>
<TranslateLabel source="title" resource="posts" />
</TestTranslationProvider>
);
screen.getByText('Title');
});
it('should use the label as key when provided', () => {
render(<I18nLabelAsKey />);
screen.getByText('My title');
});

it('should return the translated inferred label from source and resource when no label is provided', () => {
render(
<TestTranslationProvider
messages={{
resources: {
posts: {
fields: {
title: 'My Title',
},
},
},
}}
>
<TranslateLabel source="title" resource="posts" />
</TestTranslationProvider>
);
screen.getByText('My Title');
it('should infer a human readable default label when no translation is provided', () => {
render(<I18nNoTranslation />);
screen.getByText('Title');
});
});

it('should return the inferred label from SourceContext when no label is provided but a SourceContext is present', () => {
render(
<TestTranslationProvider messages={{}}>
<SourceContextProvider
value={{
getSource: source => source,
getLabel: source => `test.${source}`,
}}
>
<TranslateLabel source="title" resource="posts" />
</SourceContextProvider>
</TestTranslationProvider>
);
screen.getByText('Title');
});
describe('SourceContext', () => {
it('should call getLabel for the default label', () => {
render(<InSourceContext />);
screen.getByText('Label for title');
});

it('should return the translated label from SourceContext when no label is provided but a SourceContext is present', () => {
render(
<TestTranslationProvider
messages={{
test: {
title: 'Label for title',
},
}}
>
<SourceContextProvider
value={{
getSource: source => source,
getLabel: source => `test.${source}`,
}}
>
<TranslateLabel source="title" />
</SourceContextProvider>
</TestTranslationProvider>
);
screen.getByText('Label for title');
});
it('should use the getLabel return as translation key', () => {
render(<InSourceContextI18nKey />);
screen.getByText('test.title');
});

it('should infer a human readable default label when no translation is provided', () => {
render(<InSourceContextNoTranslation />);
screen.getByText('Title');
});

it('should return the inferred label when a resource prop is provided even when a SourceContext is present', () => {
render(
<TestTranslationProvider
messages={{
test: {
title: 'Label for title',
},
}}
>
<SourceContextProvider
value={{
getSource: source => source,
getLabel: source => `test.${source}`,
}}
>
<TranslateLabel source="title" resource="posts" />
</SourceContextProvider>
</TestTranslationProvider>
);
screen.getByText('Title');
it('should infer a human readable default label when a resource is provided', () => {
render(<InSourceContextWithResource />);
screen.getByText('Title');
});
});
});
Loading

0 comments on commit 7a79484

Please sign in to comment.