Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix <SimpleShowLayout> uses a wrong translation key for field labels #9966

Merged
merged 5 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = ({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The components to test have moved to the stories file

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
Loading