Explorar el Código

fix(core): Fix EntityHydrator when hydrating empty array relation

Fixes #1153
Michael Bromley hace 4 años
padre
commit
70e0314f97

+ 19 - 0
packages/core/e2e/entity-hydrator.e2e-spec.ts

@@ -118,6 +118,19 @@ describe('Entity hydration', () => {
         expect(getVariantWithName(hydrateProduct, 'Laptop 15 inch 16GB').price).toBe(229900);
         expect(getVariantWithName(hydrateProduct, 'Laptop 15 inch 16GB').priceWithTax).toBe(275880);
     });
+
+    // https://github.com/vendure-ecommerce/vendure/issues/1153
+    it('correctly handles empty array relations', async () => {
+        // Product T_5 has no asset defined
+        const { hydrateProductAsset } = await adminClient.query<HydrateProductAssetQuery>(
+            GET_HYDRATED_PRODUCT_ASSET,
+            {
+                id: 'T_5',
+            },
+        );
+
+        expect(hydrateProductAsset.assets).toEqual([]);
+    });
 });
 
 function getVariantWithName(product: Product, name: string) {
@@ -125,9 +138,15 @@ function getVariantWithName(product: Product, name: string) {
 }
 
 type HydrateProductQuery = { hydrateProduct: Product };
+type HydrateProductAssetQuery = { hydrateProductAsset: Product };
 
 const GET_HYDRATED_PRODUCT = gql`
     query GetHydratedProduct($id: ID!) {
         hydrateProduct(id: $id)
     }
 `;
+const GET_HYDRATED_PRODUCT_ASSET = gql`
+    query GetHydratedProductAsset($id: ID!) {
+        hydrateProductAsset(id: $id)
+    }
+`;

+ 12 - 0
packages/core/e2e/fixtures/test-plugins/hydration-test-plugin.ts

@@ -34,6 +34,17 @@ export class TestAdminPluginResolver {
         });
         return product;
     }
+
+    // Test case for https://github.com/vendure-ecommerce/vendure/issues/1153
+    @Query()
+    async hydrateProductAsset(@Ctx() ctx: RequestContext, @Args() args: { id: ID }) {
+        const product = await this.connection.getRepository(ctx, Product).findOne(args.id);
+        // tslint:disable-next-line:no-non-null-assertion
+        await this.entityHydrator.hydrate(ctx, product!, {
+            relations: ['assets'],
+        });
+        return product;
+    }
 }
 
 @VendurePlugin({
@@ -43,6 +54,7 @@ export class TestAdminPluginResolver {
         schema: gql`
             extend type Query {
                 hydrateProduct(id: ID!): JSON
+                hydrateProductAsset(id: ID!): JSON
             }
         `,
     },

+ 3 - 3
packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts

@@ -222,9 +222,9 @@ export class EntityHydrator {
         return currentMetadata.target as Type<VendureEntity>;
     }
 
-    private isTranslatable(input: any | any[]): input is Translatable {
+    private isTranslatable<T extends VendureEntity>(input: T | T[] | undefined): boolean {
         return Array.isArray(input)
-            ? input[0].hasOwnProperty('translations')
-            : input.hasOwnProperty('translations');
+            ? input[0]?.hasOwnProperty('translations') ?? false
+            : input?.hasOwnProperty('translations') ?? false;
     }
 }