Browse Source

feat(core): Normalize product slug values

Relates to #103
Michael Bromley 6 years ago
parent
commit
e2235cba9b

+ 21 - 1
packages/core/e2e/product.e2e-spec.ts

@@ -179,7 +179,7 @@ describe('Product resolver', () => {
                             {
                                 languageCode: LanguageCode.en,
                                 name: 'en Baked Potato',
-                                slug: 'en-baked-potato',
+                                slug: 'en Baked Potato',
                                 description: 'A baked potato',
                             },
                             {
@@ -250,6 +250,26 @@ describe('Product resolver', () => {
             expect(result.updateProduct).toMatchSnapshot();
         });
 
+        it('slug is normalized to be url-safe', async () => {
+            const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
+                UPDATE_PRODUCT,
+                {
+                    input: {
+                        id: newProduct.id,
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'en Mashed Potato',
+                                slug: 'A (very) nice potato!!1',
+                                description: 'A blob of mashed potato',
+                            },
+                        ],
+                    },
+                },
+            );
+            expect(result.updateProduct.slug).toBe('a-very-nice-potato1');
+        });
+
         it('updateProduct accepts partial input', async () => {
             const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
                 UPDATE_PRODUCT,

+ 14 - 0
packages/core/src/service/services/product.service.ts

@@ -6,6 +6,7 @@ import {
     DeletionResult,
     UpdateProductInput,
 } from '@vendure/common/lib/generated-types';
+import { normalizeString } from '@vendure/common/lib/normalize-string';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { Connection } from 'typeorm';
 
@@ -99,6 +100,7 @@ export class ProductService {
     }
 
     async create(ctx: RequestContext, input: CreateProductInput): Promise<Translated<Product>> {
+        this.normalizeSlugs(input);
         const product = await this.translatableSaver.create({
             input,
             entityType: Product,
@@ -117,6 +119,7 @@ export class ProductService {
 
     async update(ctx: RequestContext, input: UpdateProductInput): Promise<Translated<Product>> {
         await getEntityOrThrow(this.connection, Product, input.id);
+        this.normalizeSlugs(input);
         const product = await this.translatableSaver.update({
             input,
             entityType: Product,
@@ -183,4 +186,15 @@ export class ProductService {
         }
         return product;
     }
+
+    private normalizeSlugs<T extends CreateProductInput | UpdateProductInput>(input: T): T {
+        if (input.translations) {
+            input.translations.forEach(t => {
+                if (t.slug) {
+                    t.slug = normalizeString(t.slug, '-');
+                }
+            });
+        }
+        return input;
+    }
 }