Skip to content

Commit

Permalink
Update management of locale-based props for GraphQL transformers (#629)
Browse files Browse the repository at this point in the history
* refactor: updated some properties management in graphql transformers

* chore: push refreshed lock file

* chore: changesets added
  • Loading branch information
CarlosCortizasCT authored Aug 13, 2024
1 parent 29ab14e commit a4e8796
Show file tree
Hide file tree
Showing 13 changed files with 354 additions and 28 deletions.
24 changes: 24 additions & 0 deletions .changeset/clever-taxis-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@commercetools-test-data/category': patch
---

Fixed the return type for some properties in the GraphQL representation:

- name
- description
- slug
- metaTitle
- metaKeywords
- metaDescription

They all were returning a value with type `TLocalizedStringGraphql` where they should be returning a `string`.

From the consumer point of view, mocking those values won't change so they can still use the `LocalizedString` common model to set it up:

```js
Category.random()
.name(LocalizedString.random().en('Shoes').de('Schuhe'))
.buildGraphql();
```

The actual `string` returned will be the one with the default locale (`en`) or the first one if that one does not exist.
24 changes: 24 additions & 0 deletions .changeset/curvy-cycles-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@commercetools-test-data/product': patch
---

Fixed the return type for some properties in the GraphQL representation:

- name
- description
- slug
- metaTitle
- metaKeywords
- metaDescription

They all were returning a value with type `TLocalizedStringGraphql` where they should be returning a `string`.

From the consumer point of view, mocking those values won't change so they can still use the `LocalizedString` common model to set it up:

```js
Product.random()
.name(LocalizedString.random().en('Shoes').de('Schuhe'))
.buildGraphql();
```

The actual `string` returned will be the one with the default locale (`en`) or the first one if that one does not exist.
9 changes: 9 additions & 0 deletions .changeset/yellow-rats-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@commercetools-test-data/commons': minor
---

Added a new helper in the `LocalizedString` model which allows to get the default locale value out of all configured ones.

The default value has been configured to be `en`.

In case the model does not have that one configured, the helper will return the first one configured.
1 change: 1 addition & 0 deletions models/category/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@babel/runtime-corejs3": "^7.17.9",
"@commercetools-test-data/commons": "9.0.7",
"@commercetools-test-data/core": "9.0.7",
"@commercetools-test-data/type": "9.0.7",
"@commercetools-test-data/utils": "9.0.7",
"@commercetools/platform-sdk": "^7.0.0",
"@faker-js/faker": "^8.0.0"
Expand Down
96 changes: 79 additions & 17 deletions models/category/src/builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* eslint-disable jest/valid-title */
import { LocalizedString } from '@commercetools-test-data/commons';
import { createBuilderSpec } from '@commercetools-test-data/core/test-utils';
import { CustomFieldBooleanType } from '@commercetools-test-data/type';
import type { TCategory, TCategoryGraphql } from './types';
import * as Category from './index';

Expand Down Expand Up @@ -66,23 +67,7 @@ describe('builder', () => {
Category.random().name(LocalizedString.random().en('Pants').de('Hosen')),
expect.objectContaining({
__typename: 'Category',
name: expect.arrayContaining([
expect.objectContaining({
__typename: 'LocalizedString',
locale: 'de',
value: 'Hosen',
}),
expect.objectContaining({
__typename: 'LocalizedString',
locale: 'en',
value: 'Pants',
}),
expect.objectContaining({
__typename: 'LocalizedString',
locale: 'fr',
value: expect.any(String),
}),
]),
name: expect.any(String),
nameAllLocales: expect.arrayContaining([
expect.objectContaining({
__typename: 'LocalizedString',
Expand All @@ -101,6 +86,7 @@ describe('builder', () => {
}),
]),
orderHint: expect.any(String),
description: undefined,
descriptionAllLocales: null,
createdBy: expect.objectContaining({
customerRef: expect.objectContaining({ typeId: 'customer' }),
Expand All @@ -113,4 +99,80 @@ describe('builder', () => {
})
)
);

it('should allow customization', () => {
const category = Category.random()
.ancestors([Category.random().key('category-ancestor-id-1')])
.custom(CustomFieldBooleanType.random())
.description(LocalizedString.random().en('Trendy pants'))
.externalId('external-id-123')
.id('category-123')
.key('key-pants')
.metaDescription(LocalizedString.random().en('Trendy pants (meta)'))
.metaKeywords(LocalizedString.random().en('pants (meta)'))
.metaTitle(LocalizedString.random().en('Pants (meta)'))
.name(LocalizedString.random().en('Pants'))
.orderHint('0.5')
.parent(Category.random().key('category-parent-id-1'))
.slug(LocalizedString.random().en('product-slug-1'))
.version(200)
.buildGraphql();

expect(category).toEqual(
expect.objectContaining({
ancestors: expect.arrayContaining([
expect.objectContaining({
key: 'category-ancestor-id-1',
}),
]),
custom: expect.objectContaining({
name: 'Boolean',
}),
description: 'Trendy pants',
descriptionAllLocales: expect.arrayContaining([
expect.objectContaining({
locale: 'en',
value: 'Trendy pants',
}),
]),
externalId: 'external-id-123',
id: 'category-123',
key: 'key-pants',
metaTitle: 'Pants (meta)',
metaTitleAllLocales: expect.arrayContaining([
expect.objectContaining({
locale: 'en',
value: 'Pants (meta)',
}),
]),
metaKeywords: 'pants (meta)',
metaKeywordsAllLocales: expect.arrayContaining([
expect.objectContaining({
locale: 'en',
value: 'pants (meta)',
}),
]),
metaDescription: 'Trendy pants (meta)',
metaDescriptionAllLocales: expect.arrayContaining([
expect.objectContaining({
locale: 'en',
value: 'Trendy pants (meta)',
}),
]),
name: 'Pants',
nameAllLocales: expect.arrayContaining([
expect.objectContaining({
locale: 'en',
value: 'Pants',
}),
]),
orderHint: '0.5',
parent: expect.objectContaining({
key: 'category-parent-id-1',
}),
slug: 'product-slug-1',
version: 200,
})
);
});
});
39 changes: 37 additions & 2 deletions models/category/src/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,52 @@ const transformers = {
buildFields,
}),
graphql: Transformer<TCategory, TCategoryGraphql>('graphql', {
buildFields,
addFields: ({ fields }) => {
buildFields: [
'createdBy',
'lastModifiedBy',
'ancestors',
'parent',
'custom',
'assets',
],
replaceFields: ({ fields }) => {
const nameAllLocales = LocalizedString.toLocalizedField(fields.name);
const descriptionAllLocales = LocalizedString.toLocalizedField(
fields.description
);
const slugAllLocales = LocalizedString.toLocalizedField(fields.slug);
const metaTitleAllLocales = LocalizedString.toLocalizedField(
fields.metaTitle
);
const metaKeywordsAllLocales = LocalizedString.toLocalizedField(
fields.metaKeywords
);
const metaDescriptionAllLocales = LocalizedString.toLocalizedField(
fields.metaDescription
);

return {
...(fields as unknown as TCategoryGraphql),
__typename: 'Category',
name: LocalizedString.resolveGraphqlDefaultLocaleValue(nameAllLocales)!,
nameAllLocales,
description: LocalizedString.resolveGraphqlDefaultLocaleValue(
descriptionAllLocales
),
descriptionAllLocales,
slug: LocalizedString.resolveGraphqlDefaultLocaleValue(slugAllLocales)!,
slugAllLocales,
metaTitle:
LocalizedString.resolveGraphqlDefaultLocaleValue(metaTitleAllLocales),
metaTitleAllLocales,
metaKeywords: LocalizedString.resolveGraphqlDefaultLocaleValue(
metaKeywordsAllLocales
),
metaKeywordsAllLocales,
metaDescription: LocalizedString.resolveGraphqlDefaultLocaleValue(
metaDescriptionAllLocales
),
metaDescriptionAllLocales,
};
},
}),
Expand Down
19 changes: 15 additions & 4 deletions models/category/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,29 @@ export type TCategoryBuilder = TBuilder<TCategory>;
export type TCreateCategoryBuilder = () => TCategoryBuilder;
export type TCategoryGraphql = Omit<
TCategory,
// In GraphQL, we prefer to use `nameAllLocales` instead of `name`.
// The shape of these props is different in GraphQL
| 'name'
// In GraphQL, we prefer to use `descriptionAllLocales` instead of `description`.
| 'description'
// In GraphQL, the object shape is different.
| 'slug'
| 'createdBy'
// In GraphQL, the object shape is different.
| 'lastModifiedBy'
| 'metaTitle'
| 'metaKeywords'
| 'metaDescription'
> & {
__typename: 'Category';
createdBy: TClientLoggingGraphql;
lastModifiedBy: TClientLoggingGraphql;
name: string;
nameAllLocales?: TLocalizedStringGraphql | null;
description?: string;
descriptionAllLocales?: TLocalizedStringGraphql | null;
slug: string;
slugAllLocales?: TLocalizedStringGraphql | null;
metaTitle?: string;
metaTitleAllLocales?: TLocalizedStringGraphql | null;
metaKeywords?: string;
metaKeywordsAllLocales?: TLocalizedStringGraphql | null;
metaDescription?: string;
metaDescriptionAllLocales?: TLocalizedStringGraphql | null;
};
16 changes: 15 additions & 1 deletion models/commons/src/localized-string/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,18 @@ const toLocalizedField = <Model>(value?: Model) => {
return localizedField;
};

export { toLocalizedField };
const DEFAULT_LOCALE = 'en';

const resolveGraphqlDefaultLocaleValue = (
allLocales: TLocalizedStringGraphql | null
) => {
if (!allLocales) {
return undefined;
}
const defaultLocaleName = allLocales.find(
(name) => name.locale === DEFAULT_LOCALE
);
return defaultLocaleName ? defaultLocaleName.value : allLocales[0].value;
};

export { resolveGraphqlDefaultLocaleValue, toLocalizedField };
2 changes: 1 addition & 1 deletion models/commons/src/localized-string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export * as LocalizedStringDraft from './localized-string-draft';

export { default as random } from './builder';
export { default as presets } from './presets';
export { toLocalizedField } from './helpers';
export { resolveGraphqlDefaultLocaleValue, toLocalizedField } from './helpers';
Loading

0 comments on commit a4e8796

Please sign in to comment.