瀏覽代碼

Start populating mock data via the gql api

Michael Bromley 7 年之前
父節點
當前提交
8b8e20fa4c

+ 0 - 0
modules/core/common/common-types.ts


+ 67 - 0
modules/mock-data/mock-data-client.service.ts

@@ -0,0 +1,67 @@
+import * as faker from 'faker/locale/en_GB';
+import { request } from 'graphql-request';
+import { CreateProductVariantDto } from '../core/entity/product-variant/create-product-variant.dto';
+import { CreateProductDto } from '../core/entity/product/create-product.dto';
+import { Product } from '../core/entity/product/product.interface';
+import { LanguageCode } from '../core/locale/language-code';
+import { LocalizedInput } from '../core/locale/locale-types';
+
+// tslint:disable:no-console
+/**
+ * A service for creating mock data via the GraphQL API.
+ */
+export class MockDataClientService {
+    async populateProducts(): Promise<any> {
+        for (let i = 0; i < 5; i++) {
+            const query = `mutation CreateProduct($input: CreateProductInput) {
+                            createProduct(input: $input) { id, name }
+                           }`;
+
+            const name = faker.commerce.productName();
+            const slug = name.toLowerCase().replace(/\s+/g, '-');
+            const description = faker.lorem.sentence();
+            const languageCodes = [LanguageCode.EN, LanguageCode.DE, LanguageCode.ES];
+
+            const variables = {
+                input: {
+                    image: faker.image.imageUrl(),
+                    translations: languageCodes.map(code => this.makeProductTranslation(code, name, slug, description)),
+                    variants: [
+                        this.makeProductVariant(`${name} Variant 1`, languageCodes),
+                        this.makeProductVariant(`${name} Variant 2`, languageCodes),
+                    ],
+                } as CreateProductDto,
+            };
+
+            await request('http://localhost:3000/graphql', query, variables).then(
+                data => console.log('Created Product:', data),
+                err => console.log(err),
+            );
+        }
+    }
+
+    private makeProductTranslation(
+        languageCode: LanguageCode,
+        name: string,
+        slug: string,
+        description: string,
+    ): LocalizedInput<Product> {
+        return {
+            languageCode,
+            name: `${languageCode} ${name}`,
+            slug: `${languageCode} ${slug}`,
+            description: `${languageCode} ${description}`,
+        };
+    }
+
+    private makeProductVariant(variantName: string, languageCodes: LanguageCode[]): CreateProductVariantDto {
+        return {
+            price: faker.random.number({ min: 100, max: 5000 }),
+            sku: faker.random.alphaNumeric(8).toUpperCase(),
+            translations: languageCodes.map(code => ({
+                languageCode: code,
+                name: `${variantName} ${code}`,
+            })),
+        };
+    }
+}

+ 17 - 14
modules/testing/mock-data.service.ts → modules/mock-data/mock-data.service.ts

@@ -17,13 +17,23 @@ import { UserEntity } from '../core/entity/user/user.entity';
 
 // tslint:disable:no-console
 /**
- * A Class used for generating mock data.
+ * A Class used for generating mock data directly into the database via TypeORM.
  */
 export class MockDataService {
     connection: Connection;
 
-    populate(): Promise<any> {
-        return createConnection({
+    async populate(): Promise<any> {
+        this.connection = await this.connect();
+        await this.clearAllTables();
+        await this.populateCustomersAndAddresses();
+        await this.populateAdministrators();
+
+        const sizeOptionGroup = await this.populateOptions();
+        await this.populateProducts(sizeOptionGroup);
+    }
+
+    async connect(): Promise<Connection> {
+        this.connection = await createConnection({
             type: 'mysql',
             entities: ['./**/entity/**/*.entity.ts'],
             synchronize: true,
@@ -33,16 +43,9 @@ export class MockDataService {
             username: 'root',
             password: '',
             database: 'test',
-        }).then(async connection => {
-            this.connection = connection;
-
-            await this.clearAllTables();
-            await this.populateCustomersAndAddresses();
-            await this.populateAdministrators();
-
-            const sizeOptionGroup = await this.populateOptions();
-            await this.populateProducts(sizeOptionGroup);
         });
+
+        return this.connection;
     }
 
     async clearAllTables() {
@@ -129,12 +132,12 @@ export class MockDataService {
 
             // 1 - 4 variants
             const variantCount = Math.floor(Math.random() * 4) + 1;
-            const variants = [];
+            const variants: ProductVariantEntity[] = [];
             for (let j = 0; j < variantCount; j++) {
                 const variant = new ProductVariantEntity();
                 const variantName = `${name} variant ${j + 1}`;
                 variant.image = faker.image.imageUrl();
-                variant.price = faker.commerce.price(100, 12000, 0);
+                variant.price = faker.random.number({ min: 100, max: 12000 });
 
                 const variantTranslation1 = this.makeProductVariantTranslation('en', variantName);
                 const variantTranslation2 = this.makeProductVariantTranslation('de', variantName);

+ 16 - 0
modules/mock-data/populate.ts

@@ -0,0 +1,16 @@
+import { MockDataClientService } from './mock-data-client.service';
+import { MockDataService } from './mock-data.service';
+
+async function populate() {
+    const mockDataService = new MockDataService();
+    const mockDataClientService = new MockDataClientService();
+
+    await mockDataService.connect();
+    await mockDataService.clearAllTables();
+    await mockDataService.populateCustomersAndAddresses();
+    await mockDataService.populateAdministrators();
+    await mockDataService.populateOptions();
+    await mockDataClientService.populateProducts();
+}
+
+populate().then(() => process.exit(0));

+ 0 - 3
modules/testing/populate.ts

@@ -1,3 +0,0 @@
-import { MockDataService } from './mock-data.service';
-
-new MockDataService().populate().then(() => process.exit(0));

+ 1 - 1
nodemon-debug.json

@@ -1,6 +1,6 @@
 {
   "watch": ["modules"],
   "ext": "ts",
-  "ignore": ["src/**/*.spec.ts"],
+  "ignore": ["modules/**/*.spec.ts", "modules/mock-data/**/*"],
   "exec": "node --inspect=5858 -r ts-node/register modules/core/main.ts"
 }

+ 1 - 1
nodemon.json

@@ -1,6 +1,6 @@
 {
   "watch": ["modules"],
   "ext": "ts",
-  "ignore": ["src/**/*.spec.ts"],
+  "ignore": ["modules/**/*.spec.ts"],
   "exec": "ts-node -r tsconfig-paths/register modules/core/main.ts"
 }

+ 2 - 1
package.json

@@ -5,7 +5,7 @@
   "license": "MIT",
   "scripts": {
     "format": "prettier --write \"modules/**/*.ts\"",
-    "populate": "ts-node -r tsconfig-paths/register modules/testing/populate.ts",
+    "populate": "ts-node -r tsconfig-paths/register modules/mock-data/populate.ts",
     "start": "ts-node -r tsconfig-paths/register src/main.ts",
     "start:dev": "nodemon",
     "start:debug": "nodemon --config nodemon-debug.json",
@@ -59,6 +59,7 @@
     "@types/node": "^9.3.0",
     "@types/supertest": "^2.0.4",
     "faker": "^4.1.0",
+    "graphql-request": "^1.6.0",
     "husky": "^0.14.3",
     "jest": "^21.2.1",
     "lint-staged": "^7.1.3",

+ 21 - 0
yarn.lock

@@ -2011,6 +2011,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
+cross-fetch@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.0.0.tgz#a17475449561e0f325146cea636a8619efb9b382"
+  dependencies:
+    node-fetch "2.0.0"
+    whatwg-fetch "2.0.3"
+
 cross-spawn@^5.0.1:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -3124,6 +3131,12 @@ graphql-extensions@^0.0.x, graphql-extensions@~0.0.9:
     core-js "^2.5.3"
     source-map-support "^0.5.1"
 
+graphql-request@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.6.0.tgz#afe87cf2a336acabb0cc2a875900202eda89f412"
+  dependencies:
+    cross-fetch "2.0.0"
+
 graphql-tools@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.0.2.tgz#fb79821c23b0f5d11d842c4d0c15000d856c6c8c"
@@ -4934,6 +4947,10 @@ node-dir@0.1.8:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
 
+node-fetch@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.0.0.tgz#982bba43ecd4f2922a29cc186a6bbb0bb73fcba6"
+
 node-int64@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -7319,6 +7336,10 @@ whatwg-encoding@^1.0.1:
   dependencies:
     iconv-lite "0.4.19"
 
+whatwg-fetch@2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+
 whatwg-url@^4.3.0:
   version "4.8.0"
   resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0"