diff --git a/models/state/LICENSE b/models/state/LICENSE new file mode 100644 index 000000000..e113013cb --- /dev/null +++ b/models/state/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) commercetools GmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/models/state/README.md b/models/state/README.md new file mode 100644 index 000000000..a9bf2504d --- /dev/null +++ b/models/state/README.md @@ -0,0 +1,25 @@ +# @commercetools-test-data/state + +This package provides data models for the commercetools platform `State` representations. + +https://docs.commercetools.com/api/projects/states#representations + +# Install + +```bash +$ pnpm add -D @commercetools-test-data/state +``` + +# Usage + +```ts +import { + State, + StateDraft, + type TState, + type TStateDraft, +} from '@commercetools-test-data/state'; + +const state = State.random().build(); +const StateDraft = StateDraft.random().build(); +``` diff --git a/models/state/package.json b/models/state/package.json new file mode 100644 index 000000000..44389f857 --- /dev/null +++ b/models/state/package.json @@ -0,0 +1,37 @@ +{ + "name": "@commercetools-test-data/state", + "version": "6.4.1", + "description": "Data model for commercetools API State", + "bugs": "https://github.com/commercetools/test-data/issues", + "repository": { + "type": "git", + "url": "https://github.com/commercetools/test-data.git", + "directory": "models/state" + }, + "keywords": [ + "javascript", + "typescript", + "test-data" + ], + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "main": "dist/commercetools-test-data-state.cjs.js", + "module": "dist/commercetools-test-data-state.esm.js", + "files": [ + "dist", + "package.json", + "LICENSE", + "README.md" + ], + "dependencies": { + "@babel/runtime": "^7.17.9", + "@babel/runtime-corejs3": "^7.17.9", + "@commercetools-test-data/commons": "6.4.1", + "@commercetools-test-data/core": "6.4.1", + "@commercetools-test-data/utils": "6.4.1", + "@commercetools/platform-sdk": "^6.0.0", + "@faker-js/faker": "^8.0.0" + } +} diff --git a/models/state/src/builder.spec.ts b/models/state/src/builder.spec.ts new file mode 100644 index 000000000..45329529e --- /dev/null +++ b/models/state/src/builder.spec.ts @@ -0,0 +1,121 @@ +/* eslint-disable jest/no-disabled-tests */ +/* eslint-disable jest/valid-title */ + +import { createBuilderSpec } from '@commercetools-test-data/core/test-utils'; +import type { TState, TStateGraphql } from './types'; +import * as State from './index'; +import { roles } from './constants'; + +describe('builder', () => { + it( + ...createBuilderSpec( + 'default', + State.random(), + expect.objectContaining({ + id: expect.any(String), + version: expect.any(Number), + key: expect.any(String), + type: expect.any(String), + name: expect.objectContaining({ + de: expect.any(String), + en: expect.any(String), + fr: expect.any(String), + }), + description: expect.objectContaining({ + en: expect.any(String), + }), + initial: expect.any(Boolean), + builtIn: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + createdAt: expect.any(String), + createdBy: expect.objectContaining({ + customer: expect.objectContaining({ typeId: 'customer' }), + }), + lastModifiedAt: expect.any(String), + lastModifiedBy: expect.objectContaining({ + customer: expect.objectContaining({ typeId: 'customer' }), + }), + }) + ) + ); + it( + ...createBuilderSpec( + 'rest', + State.random(), + expect.objectContaining({ + id: expect.any(String), + version: expect.any(Number), + key: expect.any(String), + type: expect.any(String), + name: expect.objectContaining({ + de: expect.any(String), + en: expect.any(String), + fr: expect.any(String), + }), + description: expect.objectContaining({ + en: expect.any(String), + }), + initial: expect.any(Boolean), + builtIn: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + createdAt: expect.any(String), + createdBy: expect.objectContaining({ + customer: expect.objectContaining({ typeId: 'customer' }), + }), + lastModifiedAt: expect.any(String), + lastModifiedBy: expect.objectContaining({ + customer: expect.objectContaining({ typeId: 'customer' }), + }), + }) + ) + ); + // Note that the State graphql is provided as scaffolding only and may not be complete at this time. + it( + ...createBuilderSpec( + 'graphql', + State.random(), + expect.objectContaining({ + id: expect.any(String), + version: expect.any(Number), + key: expect.any(String), + type: expect.any(String), + name: expect.arrayContaining([ + expect.objectContaining({ + locale: 'en', + value: expect.any(String), + }), + expect.objectContaining({ + locale: 'de', + value: expect.any(String), + }), + expect.objectContaining({ + locale: 'fr', + value: expect.any(String), + }), + ]), + description: expect.arrayContaining([ + expect.objectContaining({ + locale: 'en', + value: expect.any(String), + }), + ]), + initial: expect.any(Boolean), + builtIn: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + createdAt: expect.any(String), + createdBy: expect.objectContaining({ + customerRef: expect.objectContaining({ typeId: 'customer' }), + userRef: expect.objectContaining({ typeId: 'user' }), + }), + lastModifiedAt: expect.any(String), + lastModifiedBy: expect.objectContaining({ + customerRef: expect.objectContaining({ typeId: 'customer' }), + userRef: expect.objectContaining({ typeId: 'user' }), + }), + }) + ) + ); +}); diff --git a/models/state/src/builder.ts b/models/state/src/builder.ts new file mode 100644 index 000000000..a590781ac --- /dev/null +++ b/models/state/src/builder.ts @@ -0,0 +1,12 @@ +import { Builder } from '@commercetools-test-data/core'; +import generator from './generator'; +import transformers from './transformers'; +import type { TCreateStateBuilder, TState } from './types'; + +const Model: TCreateStateBuilder = () => + Builder({ + generator, + transformers, + }); + +export default Model; diff --git a/models/state/src/constants.ts b/models/state/src/constants.ts new file mode 100644 index 000000000..fe735c99c --- /dev/null +++ b/models/state/src/constants.ts @@ -0,0 +1,17 @@ +const roles = { + ReviewIncludedInStatistics: 'ReviewIncludedInStatistics', + Return: 'Return', +} as const; + +const type = { + OrderState: 'OrderState', + LineItemState: 'LineItemState', + ProductState: 'ProductState', + ReviewState: 'ReviewState', + PaymentState: 'PaymentState', + QuoteRequestState: 'QuoteRequestState', + StagedQuoteState: 'StagedQuoteState', + QuoteState: 'QuoteState', +} as const; + +export { roles, type }; diff --git a/models/state/src/generator.ts b/models/state/src/generator.ts new file mode 100644 index 000000000..25dd332c8 --- /dev/null +++ b/models/state/src/generator.ts @@ -0,0 +1,38 @@ +import { + ClientLogging, + LocalizedString, +} from '@commercetools-test-data/commons'; +import { + sequence, + fake, + Generator, + oneOf, +} from '@commercetools-test-data/core'; +import { createRelatedDates } from '@commercetools-test-data/utils'; +import { roles, type } from './constants'; +import { TState } from './types'; + +const [getOlderDate, getNewerDate] = createRelatedDates(); + +// https://docs.commercetools.com/api/projects/States#States + +const generator = Generator({ + fields: { + id: fake((f) => f.string.uuid()), + version: sequence(), + key: fake((f) => f.lorem.slug(2)), + type: oneOf(...Object.values(type)), + name: fake(() => LocalizedString.random()), + description: fake(() => LocalizedString.random()), + initial: fake((f) => f.datatype.boolean()), + builtIn: fake((f) => f.datatype.boolean()), + roles: [oneOf(...Object.values(roles))], + transitions: null, + createdAt: fake(getOlderDate), + createdBy: fake(() => ClientLogging.random()), + lastModifiedAt: fake(getNewerDate), + lastModifiedBy: fake(() => ClientLogging.random()), + }, +}); + +export default generator; diff --git a/models/state/src/index.ts b/models/state/src/index.ts new file mode 100644 index 000000000..f88b31ee1 --- /dev/null +++ b/models/state/src/index.ts @@ -0,0 +1,7 @@ +export * as StateDraft from './state-draft'; +export * as State from '.'; + +export { default as random } from './builder'; +export { default as presets } from './presets'; +export * from './types'; +export * as constants from './constants'; diff --git a/models/state/src/presets/index.ts b/models/state/src/presets/index.ts new file mode 100644 index 000000000..763e57fe0 --- /dev/null +++ b/models/state/src/presets/index.ts @@ -0,0 +1,3 @@ +const presets = {}; + +export default presets; diff --git a/models/state/src/state-draft/builder.spec.ts b/models/state/src/state-draft/builder.spec.ts new file mode 100644 index 000000000..91c90b486 --- /dev/null +++ b/models/state/src/state-draft/builder.spec.ts @@ -0,0 +1,98 @@ +/* eslint-disable jest/no-disabled-tests */ +/* eslint-disable jest/valid-title */ + +import { createBuilderSpec } from '@commercetools-test-data/core/test-utils'; +import type { TStateDraft, TStateDraftGraphql } from '../types'; +import * as StateDraft from './index'; +import { roles } from '../constants'; + +describe('builder', () => { + it( + ...createBuilderSpec( + 'default', + StateDraft.random(), + expect.objectContaining({ + key: expect.any(String), + type: expect.any(String), + name: expect.objectContaining({ + de: expect.any(String), + en: expect.any(String), + fr: expect.any(String), + }), + description: expect.objectContaining({ + en: expect.any(String), + }), + initial: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + }) + ) + ); + + it( + ...createBuilderSpec( + 'rest', + StateDraft.random(), + expect.objectContaining({ + key: expect.any(String), + type: expect.any(String), + name: expect.objectContaining({ + de: expect.any(String), + en: expect.any(String), + fr: expect.any(String), + }), + description: expect.objectContaining({ + en: expect.any(String), + }), + initial: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + }) + ) + ); + // Note that the StateDraft graphql is provided as scaffolding only and may not be complete at this time. + it( + ...createBuilderSpec( + 'graphql', + StateDraft.random(), + expect.objectContaining({ + key: expect.any(String), + type: expect.any(String), + name: expect.arrayContaining([ + expect.objectContaining({ + locale: 'en', + value: expect.any(String), + }), + expect.objectContaining({ + locale: 'de', + value: expect.any(String), + }), + expect.objectContaining({ + locale: 'fr', + value: expect.any(String), + }), + ]), + description: expect.arrayContaining([ + expect.objectContaining({ + locale: 'en', + value: expect.any(String), + __typename: 'LocalizedString', + }), + expect.objectContaining({ + locale: 'de', + value: expect.any(String), + __typename: 'LocalizedString', + }), + expect.objectContaining({ + locale: 'fr', + value: expect.any(String), + __typename: 'LocalizedString', + }), + ]), + initial: expect.any(Boolean), + roles: expect.any(Array), + transitions: null, + }) + ) + ); +}); diff --git a/models/state/src/state-draft/builder.ts b/models/state/src/state-draft/builder.ts new file mode 100644 index 000000000..13bac3ee9 --- /dev/null +++ b/models/state/src/state-draft/builder.ts @@ -0,0 +1,12 @@ +import { Builder } from '@commercetools-test-data/core'; +import type { TCreateStateDraftBuilder, TStateDraft } from '../types'; +import generator from './generator'; +import transformers from './transformers'; + +const Model: TCreateStateDraftBuilder = () => + Builder({ + generator, + transformers, + }); + +export default Model; diff --git a/models/state/src/state-draft/generator.ts b/models/state/src/state-draft/generator.ts new file mode 100644 index 000000000..0ff2009ca --- /dev/null +++ b/models/state/src/state-draft/generator.ts @@ -0,0 +1,20 @@ +import { LocalizedString } from '@commercetools-test-data/commons'; +import { fake, Generator, oneOf } from '@commercetools-test-data/core'; +import { roles, type } from '../constants'; +import { TStateDraft } from '../types'; + +// https://docs.commercetools.com/api/projects/states#statedraft + +const generator = Generator({ + fields: { + key: fake((f) => f.lorem.slug(2)), + type: oneOf(...Object.values(type)), + name: fake(() => LocalizedString.random()), + description: fake(() => LocalizedString.random()), + initial: fake((f) => f.datatype.boolean()), + roles: [oneOf(...Object.values(roles))], + transitions: null, + }, +}); + +export default generator; diff --git a/models/state/src/state-draft/index.ts b/models/state/src/state-draft/index.ts new file mode 100644 index 000000000..4cfba5b7f --- /dev/null +++ b/models/state/src/state-draft/index.ts @@ -0,0 +1,2 @@ +export { default as random } from './builder'; +export { default as presets } from './presets/change-history-data'; diff --git a/models/state/src/state-draft/presets/change-history-data/index.ts b/models/state/src/state-draft/presets/change-history-data/index.ts new file mode 100644 index 000000000..7dcf53ab5 --- /dev/null +++ b/models/state/src/state-draft/presets/change-history-data/index.ts @@ -0,0 +1,7 @@ +import withTypeLineItemState from './with-type-line-item-state'; + +const presets = { + withTypeLineItemState, +}; + +export default presets; diff --git a/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.spec.ts b/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.spec.ts new file mode 100644 index 000000000..da46c14ce --- /dev/null +++ b/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.spec.ts @@ -0,0 +1,15 @@ +import type { TState } from '../../../types'; +import withTypeLineItemState from './with-type-line-item-state'; + +describe('State with type of LineItemState and role of Return', () => { + it('should return a State containing a type of LineItemState and role of Return', () => { + const typeLineItemState = withTypeLineItemState().build(); + + expect(typeLineItemState).toEqual( + expect.objectContaining({ + type: 'LineItemState', + roles: ['Return'], + }) + ); + }); +}); diff --git a/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.ts b/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.ts new file mode 100644 index 000000000..c0b4f3155 --- /dev/null +++ b/models/state/src/state-draft/presets/change-history-data/with-type-line-item-state.ts @@ -0,0 +1,7 @@ +import State from '../../builder'; + +//`LineItemState` requires a role of `Return` +const withTypeLineItemState = () => + State().type('LineItemState').roles(['Return']); + +export default withTypeLineItemState; diff --git a/models/state/src/state-draft/presets/index.ts b/models/state/src/state-draft/presets/index.ts new file mode 100644 index 000000000..5346f1f1b --- /dev/null +++ b/models/state/src/state-draft/presets/index.ts @@ -0,0 +1,5 @@ +import changeHistoryData from './change-history-data'; + +const presets = { changeHistoryData }; + +export default presets; diff --git a/models/state/src/state-draft/transformers.ts b/models/state/src/state-draft/transformers.ts new file mode 100644 index 000000000..b08fcfb5a --- /dev/null +++ b/models/state/src/state-draft/transformers.ts @@ -0,0 +1,16 @@ +import { Transformer } from '@commercetools-test-data/core'; +import type { TStateDraft, TStateDraftGraphql } from '../types'; +const transformers = { + default: Transformer('default', { + buildFields: ['name', 'description', 'transitions'], + }), + rest: Transformer('rest', { + buildFields: ['name', 'description', 'transitions'], + }), + // Note that the StateDraft graphql is provided as scaffolding only and may not be complete at this time. + graphql: Transformer('graphql', { + buildFields: ['name', 'description', 'transitions'], + }), +}; + +export default transformers; diff --git a/models/state/src/transformers.ts b/models/state/src/transformers.ts new file mode 100644 index 000000000..030c869fc --- /dev/null +++ b/models/state/src/transformers.ts @@ -0,0 +1,48 @@ +import { LocalizedString } from '@commercetools-test-data/commons'; +import { Transformer } from '@commercetools-test-data/core'; +import type { TState, TStateGraphql } from './types'; + +const transformers = { + default: Transformer('default', { + buildFields: [ + 'name', + 'description', + 'createdBy', + 'lastModifiedBy', + 'transitions', + ], + }), + rest: Transformer('rest', { + buildFields: [ + 'name', + 'description', + 'createdBy', + 'lastModifiedBy', + 'transitions', + ], + }), + // Note that the State graphql is provided as scaffolding only and may not be complete at this time. + graphql: Transformer('graphql', { + buildFields: [ + 'name', + 'description', + 'createdBy', + 'lastModifiedBy', + 'transitions', + ], + addFields: ({ fields }) => { + const nameAllLocales = LocalizedString.toLocalizedField(fields.name); + const descriptionAllLocales = LocalizedString.toLocalizedField( + fields.description + ); + + return { + __typename: 'State', + nameAllLocales, + descriptionAllLocales, + }; + }, + }), +}; + +export default transformers; diff --git a/models/state/src/types.ts b/models/state/src/types.ts new file mode 100644 index 000000000..58fdc40d6 --- /dev/null +++ b/models/state/src/types.ts @@ -0,0 +1,15 @@ +import type { State, StateDraft } from '@commercetools/platform-sdk'; +import type { TBuilder } from '@commercetools-test-data/core'; + +export type TState = State; +export type TStateDraft = StateDraft; + +export type TStateGraphql = TState & { + __typename: 'State'; +}; +export type TStateDraftGraphql = TStateDraft; + +export type TStateBuilder = TBuilder; +export type TStateDraftBuilder = TBuilder; +export type TCreateStateBuilder = () => TStateBuilder; +export type TCreateStateDraftBuilder = () => TStateDraftBuilder; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9936c6655..c89094fcc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + settings: autoInstallPeers: true excludeLinksFromLockfile: false @@ -887,6 +891,30 @@ importers: specifier: ^8.0.0 version: 8.0.0 + models/state: + dependencies: + '@babel/runtime': + specifier: ^7.17.9 + version: 7.23.4 + '@babel/runtime-corejs3': + specifier: ^7.17.9 + version: 7.23.4 + '@commercetools-test-data/commons': + specifier: 6.4.1 + version: 6.4.1 + '@commercetools-test-data/core': + specifier: 6.4.1 + version: 6.4.1 + '@commercetools-test-data/utils': + specifier: 6.4.1 + version: 6.4.1 + '@commercetools/platform-sdk': + specifier: ^6.0.0 + version: 6.0.0 + '@faker-js/faker': + specifier: ^8.0.0 + version: 8.3.1 + models/store: dependencies: '@babel/runtime': @@ -3097,6 +3125,21 @@ packages: - encoding dev: false + /@commercetools-test-data/commons@6.4.1: + resolution: {integrity: sha512-77+dDMcLKOUPyrFOoM9SrpptdV6D+fiqKUT4k0gZZ5lwFlOYcvZnbu6P7p1WyT7C0JxuEdq3d5PWy5wSfgIdRg==} + dependencies: + '@babel/runtime': 7.23.4 + '@babel/runtime-corejs3': 7.23.4 + '@commercetools-test-data/core': 6.4.1 + '@commercetools-test-data/utils': 6.4.1 + '@commercetools/platform-sdk': 6.0.0 + '@faker-js/faker': 8.3.1 + '@types/lodash': 4.14.202 + lodash: 4.17.21 + transitivePeerDependencies: + - encoding + dev: false + /@commercetools-test-data/core@5.11.2: resolution: {integrity: sha512-iz++zEBengERwg3REm51RsEFmiUeNPQz1K9K2kZjH1sAkFxOf1ydmpM0Tt4Awmi/OHQ+G2tGKKdJewm8AQyHNg==} dependencies: @@ -3107,6 +3150,16 @@ packages: lodash: 4.17.21 dev: false + /@commercetools-test-data/core@6.4.1: + resolution: {integrity: sha512-rQO3SYMOiVSzFxFQP/BZCG/d/VnnaDikCzqT3RCZJ7VSAGVykiiJgUUbVxDzdsNYWNl/RQGeSxs2MDRwPTK4kg==} + dependencies: + '@babel/runtime': 7.23.4 + '@babel/runtime-corejs3': 7.23.4 + '@faker-js/faker': 8.3.1 + '@types/lodash': 4.14.202 + lodash: 4.17.21 + dev: false + /@commercetools-test-data/product-variant@5.11.2: resolution: {integrity: sha512-7VT0Iez2bi8fhpqJOzVx/WfmLV+mAXlc5SOxZoTeP1JyUyY07GiujI0ctKAh8Q3/0qzVyJ08RFV1BLtYxLWeKA==} dependencies: @@ -3130,6 +3183,14 @@ packages: '@faker-js/faker': 8.3.1 dev: false + /@commercetools-test-data/utils@6.4.1: + resolution: {integrity: sha512-fkYsW3YQgA2ciqsuAObgK0yuB4H6SL5hlMqMBT6MmYpxfV+MYAaBi7JQLqXGQ/leXqd4fpAxHdZ6JRfyeolz5g==} + dependencies: + '@babel/runtime': 7.23.4 + '@babel/runtime-corejs3': 7.23.4 + '@faker-js/faker': 8.3.1 + dev: false + /@commercetools/platform-sdk@4.11.0: resolution: {integrity: sha512-ftcq6mCxzpIG9wmGpTED6KQCApk4nyURh81J3PRP3d48oCLOrkZSyzDDfvflGoVZQeIcox+YdtyqZoryFrRtmQ==} engines: {node: '>=14'}