mock-data.service.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import * as faker from 'faker/locale/en_GB';
  2. import * as fs from 'fs-extra';
  3. import gql from 'graphql-tag';
  4. import * as path from 'path';
  5. import {
  6. AddOptionGroupToProduct,
  7. AddOptionGroupToProductVariables,
  8. Asset,
  9. CreateFacet,
  10. CreateFacetValueWithFacetInput,
  11. CreateFacetVariables,
  12. CreateProduct,
  13. CreateProductOptionGroup,
  14. CreateProductOptionGroupVariables,
  15. CreateProductVariables,
  16. GenerateProductVariants,
  17. GenerateProductVariantsVariables,
  18. LanguageCode,
  19. ProductTranslationInput,
  20. UpdateProductVariants,
  21. UpdateProductVariantsVariables,
  22. } from 'shared/generated-types';
  23. import { CREATE_FACET } from '../../admin-ui/src/app/data/definitions/facet-definitions';
  24. import {
  25. ADD_OPTION_GROUP_TO_PRODUCT,
  26. CREATE_PRODUCT,
  27. CREATE_PRODUCT_OPTION_GROUP,
  28. GENERATE_PRODUCT_VARIANTS,
  29. UPDATE_PRODUCT_VARIANTS,
  30. } from '../../admin-ui/src/app/data/definitions/product-definitions';
  31. import { CreateAddressDto } from '../src/entity/address/address.dto';
  32. import { Channel } from '../src/entity/channel/channel.entity';
  33. import { CreateCustomerDto } from '../src/entity/customer/customer.dto';
  34. import { Customer } from '../src/entity/customer/customer.entity';
  35. import { SimpleGraphQLClient } from './simple-graphql-client';
  36. // tslint:disable:no-console
  37. /**
  38. * A service for creating mock data via the GraphQL API.
  39. */
  40. export class MockDataService {
  41. apiUrl: string;
  42. constructor(private client: SimpleGraphQLClient, private logging = true) {
  43. // make the generated results deterministic
  44. faker.seed(1);
  45. }
  46. async populateChannels(channelCodes: string[]): Promise<Channel[]> {
  47. const channels: Channel[] = [];
  48. for (const code of channelCodes) {
  49. const channel = await this.client.query<any>(gql`
  50. mutation {
  51. createChannel(code: "${code}") {
  52. id
  53. code
  54. token
  55. }
  56. }
  57. `);
  58. channels.push(channel.createChannel);
  59. this.log(`Created Channel: ${channel.createChannel.code}`);
  60. }
  61. return channels;
  62. }
  63. async populateOptions(): Promise<string> {
  64. return this.client
  65. .query<CreateProductOptionGroup, CreateProductOptionGroupVariables>(CREATE_PRODUCT_OPTION_GROUP, {
  66. input: {
  67. code: 'size',
  68. translations: [
  69. { languageCode: LanguageCode.en, name: 'Size' },
  70. { languageCode: LanguageCode.de, name: 'Größe' },
  71. ],
  72. options: [
  73. {
  74. code: 'small',
  75. translations: [
  76. { languageCode: LanguageCode.en, name: 'Small' },
  77. { languageCode: LanguageCode.de, name: 'Klein' },
  78. ],
  79. },
  80. {
  81. code: 'large',
  82. translations: [
  83. { languageCode: LanguageCode.en, name: 'Large' },
  84. { languageCode: LanguageCode.de, name: 'Groß' },
  85. ],
  86. },
  87. ],
  88. },
  89. })
  90. .then(data => {
  91. this.log('Created option group:', data.createProductOptionGroup.name);
  92. return data.createProductOptionGroup.id;
  93. });
  94. }
  95. async populateCustomers(count: number = 5): Promise<any> {
  96. for (let i = 0; i < count; i++) {
  97. const firstName = faker.name.firstName();
  98. const lastName = faker.name.lastName();
  99. const query1 = gql`
  100. mutation CreateCustomer($input: CreateCustomerInput!, $password: String) {
  101. createCustomer(input: $input, password: $password) {
  102. id
  103. emailAddress
  104. }
  105. }
  106. `;
  107. const variables1 = {
  108. input: {
  109. firstName,
  110. lastName,
  111. emailAddress: faker.internet.email(firstName, lastName),
  112. phoneNumber: faker.phone.phoneNumber(),
  113. } as CreateCustomerDto,
  114. password: 'test',
  115. };
  116. const customer: Customer | void = await this.client
  117. .query(query1, variables1)
  118. .then((data: any) => data.createCustomer as Customer, err => this.log(err));
  119. if (customer) {
  120. const query2 = gql`
  121. mutation($customerId: ID!, $input: CreateAddressInput) {
  122. createCustomerAddress(customerId: $customerId, input: $input) {
  123. id
  124. streetLine1
  125. }
  126. }
  127. `;
  128. const variables2 = {
  129. input: {
  130. fullName: `${firstName} ${lastName}`,
  131. streetLine1: faker.address.streetAddress(),
  132. city: faker.address.city(),
  133. province: faker.address.county(),
  134. postalCode: faker.address.zipCode(),
  135. country: faker.address.country(),
  136. } as CreateAddressDto,
  137. customerId: customer.id,
  138. };
  139. await this.client.query(query2, variables2).then(
  140. data => {
  141. this.log(`Created Customer ${i + 1}:`, data);
  142. return data as Customer;
  143. },
  144. err => this.log(err),
  145. );
  146. }
  147. }
  148. }
  149. async populateAssets(): Promise<Asset[]> {
  150. const fileNames = await fs.readdir(path.join(__dirname, 'assets'));
  151. const filePaths = fileNames.map(fileName => path.join(__dirname, 'assets', fileName));
  152. return this.client.uploadAssets(filePaths).then(response => {
  153. console.log(`Created ${response.createAssets.length} Assets`);
  154. return response.createAssets;
  155. });
  156. }
  157. async populateProducts(count: number = 5, optionGroupId: string): Promise<any> {
  158. for (let i = 0; i < count; i++) {
  159. const query = CREATE_PRODUCT;
  160. const name = faker.commerce.productName();
  161. const slug = name.toLowerCase().replace(/\s+/g, '-');
  162. const description = faker.lorem.sentence();
  163. const languageCodes = [LanguageCode.en, LanguageCode.de];
  164. const variables: CreateProductVariables = {
  165. input: {
  166. translations: languageCodes.map(code =>
  167. this.makeProductTranslation(code, name, slug, description),
  168. ),
  169. },
  170. };
  171. const product = await this.client
  172. .query<CreateProduct, CreateProductVariables>(query, variables)
  173. .then(
  174. data => {
  175. this.log(`Created Product ${i + 1}:`, data.createProduct.name);
  176. return data;
  177. },
  178. err => this.log(err),
  179. );
  180. if (product) {
  181. await this.client.query<AddOptionGroupToProduct, AddOptionGroupToProductVariables>(
  182. ADD_OPTION_GROUP_TO_PRODUCT,
  183. {
  184. productId: product.createProduct.id,
  185. optionGroupId,
  186. },
  187. );
  188. const prodWithVariants = await this.makeProductVariant(product.createProduct.id);
  189. const variants = prodWithVariants.generateVariantsForProduct.variants;
  190. for (const variant of variants) {
  191. const variantEN = variant.translations[0];
  192. const variantDE = { ...variantEN };
  193. variantDE.languageCode = LanguageCode.de;
  194. variantDE.name = variantDE.name.replace(LanguageCode.en, LanguageCode.de);
  195. delete variantDE.id;
  196. variant.translations.push(variantDE);
  197. }
  198. await this.client.query<UpdateProductVariants, UpdateProductVariantsVariables>(
  199. UPDATE_PRODUCT_VARIANTS,
  200. {
  201. input: variants.map(({ id, translations, sku, price }) => ({
  202. id,
  203. translations,
  204. sku,
  205. price,
  206. })),
  207. },
  208. );
  209. }
  210. }
  211. }
  212. async populateFacets() {
  213. await this.client.query<CreateFacet, CreateFacetVariables>(CREATE_FACET, {
  214. input: {
  215. code: 'brand',
  216. translations: [
  217. {
  218. languageCode: LanguageCode.en,
  219. name: 'Brand',
  220. },
  221. {
  222. languageCode: LanguageCode.en,
  223. name: 'Marke',
  224. },
  225. ],
  226. values: this.makeFacetValues(10),
  227. },
  228. });
  229. this.log('Created "brand" Facet');
  230. }
  231. private makeFacetValues(count: number): CreateFacetValueWithFacetInput[] {
  232. return Array.from({ length: count }).map(() => {
  233. const brand = faker.company.companyName();
  234. return {
  235. code: brand.replace(/\s/g, '_'),
  236. translations: [
  237. {
  238. languageCode: LanguageCode.en,
  239. name: brand,
  240. },
  241. {
  242. languageCode: LanguageCode.de,
  243. name: brand,
  244. },
  245. ],
  246. };
  247. });
  248. }
  249. private makeProductTranslation(
  250. languageCode: LanguageCode,
  251. name: string,
  252. slug: string,
  253. description: string,
  254. ): ProductTranslationInput {
  255. return {
  256. languageCode,
  257. name: `${languageCode} ${name}`,
  258. slug: `${languageCode} ${slug}`,
  259. description: `${languageCode} ${description}`,
  260. };
  261. }
  262. private async makeProductVariant(productId: string): Promise<GenerateProductVariants> {
  263. const query = GENERATE_PRODUCT_VARIANTS;
  264. return this.client.query<GenerateProductVariants, GenerateProductVariantsVariables>(query, {
  265. productId,
  266. defaultSku: faker.random.alphaNumeric(5),
  267. defaultPrice: faker.random.number({
  268. min: 100,
  269. max: 1000,
  270. }),
  271. });
  272. }
  273. private log(...args: any[]) {
  274. if (this.logging) {
  275. console.log(...args);
  276. }
  277. }
  278. }