Skip to content

Commit

Permalink
fix: allow products with no price (#54)
Browse files Browse the repository at this point in the history
* fix: allow products with no price

* fix: tests

* fix: test name
  • Loading branch information
dylandepass authored Nov 22, 2024
1 parent e94c004 commit 2fb5915
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 19 deletions.
6 changes: 1 addition & 5 deletions src/content/queries/cs-product.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import { errorWithResponse, forceImagesHTTPS } from '../../utils/http.js';
import { forceImagesHTTPS } from '../../utils/http.js';
import { gql, parseRating, parseSpecialToDate } from '../../utils/product.js';

/**
Expand Down Expand Up @@ -91,10 +91,6 @@ export const adapter = (config, productData) => {
} : null,
};

if (!minPrice && !maxPrice) {
throw errorWithResponse(400, 'no product price range found');
}

if (config.attributeOverrides?.product) {
Object.entries(config.attributeOverrides.product).forEach(([key, value]) => {
product.attributeMap[key] = product.attributeMap[value] ?? product[key];
Expand Down
6 changes: 1 addition & 5 deletions src/content/queries/cs-variants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import { errorWithResponse, forceImagesHTTPS } from '../../utils/http.js';
import { forceImagesHTTPS } from '../../utils/http.js';
import { gql, parseRating, parseSpecialToDate } from '../../utils/product.js';

/**
Expand Down Expand Up @@ -53,10 +53,6 @@ export const adapter = (config, variants) => variants.map(({ selections, product
selections: (selections ?? []).sort(),
};

if (!minPrice && !maxPrice) {
throw errorWithResponse(400, 'no variant price range found');
}

if (config.attributeOverrides?.variant) {
Object.entries(config.attributeOverrides.variant).forEach(([key, value]) => {
variant.attributeMap[key] = variant.attributeMap[value] ?? variant[key];
Expand Down
12 changes: 6 additions & 6 deletions src/templates/html/HTMLTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ ${HTMLTemplate.metaName('twitter:title', product.name)}
${HTMLTemplate.metaName('twitter:image', image?.url)}
${HTMLTemplate.metaName('twitter:description', product.metaDescription)}
${HTMLTemplate.metaName('twitter:label1', 'Price')}
${HTMLTemplate.metaName('twitter:data1', product.prices.final.amount)}
${HTMLTemplate.metaName('twitter:data1', product.prices?.final?.amount)}
${HTMLTemplate.metaName('twitter:label2', 'Availability')}
${HTMLTemplate.metaName('twitter:data2', product.inStock ? 'In stock' : 'Out of stock')}`;
}
Expand All @@ -129,8 +129,8 @@ ${HTMLTemplate.metaName('externalId', product.externalId)}
${HTMLTemplate.metaName('addToCartAllowed', product.addToCartAllowed)}
${HTMLTemplate.metaName('inStock', product.inStock ? 'true' : 'false')}
${HTMLTemplate.metaProperty('product:availability', product.inStock ? 'In stock' : 'Out of stock')}
${HTMLTemplate.metaProperty('product:price.amount', product.prices.final.amount)}
${HTMLTemplate.metaProperty('product:price.currency', product.prices.final.currency)}`;
${HTMLTemplate.metaProperty('product:price.amount', product.prices?.final?.amount)}
${HTMLTemplate.metaProperty('product:price.currency', product.prices?.final?.currency)}`;
}

/**
Expand Down Expand Up @@ -271,8 +271,8 @@ ${HTMLTemplate.indent(this.renderProductItems(opt.items), 2)}`).join('\n')}
*/
renderVariantPrices(prices) {
return /* html */ `\
<div>Regular: ${prices.regular.amount} ${prices.regular.currency}${HTMLTemplate.priceRange(prices.regular.minimumAmount, prices.regular.maximumAmount)}</div>
<div>Final: ${prices.final.amount} ${prices.final.currency}${HTMLTemplate.priceRange(prices.final.minimumAmount, prices.final.maximumAmount)}</div>`;
<div>Regular: ${prices.regular?.amount} ${prices.regular?.currency}${HTMLTemplate.priceRange(prices.regular?.minimumAmount, prices.regular?.maximumAmount)}</div>
<div>Final: ${prices.final?.amount} ${prices.final?.currency}${HTMLTemplate.priceRange(prices.final?.minimumAmount, prices.final?.maximumAmount)}</div>`;
}

/**
Expand All @@ -292,7 +292,7 @@ ${this.variants.map((v) => /* html */`\
<div>${v.name}</div>
<div>${v.description}</div>
<div>${v.inStock ? 'inStock' : ''}</div>
${HTMLTemplate.indent(this.renderVariantPrices(v.prices), 4)}
${v.prices ? HTMLTemplate.indent(this.renderVariantPrices(v.prices), 4) : ''}
<div>
${HTMLTemplate.indent(this.renderVariantImages(v.images), 6)}
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/templates/json/JSONTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,16 @@ export class JSONTemplate {
image: v.images?.[0]?.url ?? image,
availability: v.inStock ? 'InStock' : 'OutOfStock',
price: finalPrice,
priceCurrency: variantPrices.final?.currency,
priceCurrency: variantPrices?.final?.currency,
gtin: v.attributeMap.gtin,
priceValidUntil: v.specialToDate,
aggregateRating: this.renderRating(v),
};

if (finalPrice < regularPrice) {
offer.priceSpecification = this.renderOffersPriceSpecification(v);
if (variantPrices) {
if (finalPrice < regularPrice) {
offer.priceSpecification = this.renderOffersPriceSpecification(v);
}
}

return pruneUndefined(offer);
Expand Down
30 changes: 30 additions & 0 deletions test/templates/html/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,36 @@ describe('Render Product HTML', () => {
});
});

it('template should allow for missing prices', () => {
config.confMap = {
'/us/p/{{urlkey}}/{{sku}}': {},
};

product.prices = undefined;
variations.forEach((variant) => {
variant.prices = undefined;
});

const html = htmlTemplateFromContext(DEFAULT_CONTEXT({ config }), product, variations).render();
dom = new JSDOM(html);
document = dom.window.document;

const metaPriceAmount = document.querySelector('meta[property="product:price.amount"]');
assert.strictEqual(metaPriceAmount.getAttribute('content'), 'undefined', 'meta[property="product:price:amount"] should be undefined');

const metaPriceCurrency = document.querySelector('meta[property="product:price.currency"]');
assert.strictEqual(metaPriceCurrency.getAttribute('content'), 'undefined', 'meta[property="product:price.currency"] should be undefined');

const jsonLdScript = document.querySelector('script[type="application/ld+json"]');
const jsonLd = JSON.parse(jsonLdScript.textContent);

jsonLd.offers.forEach((offer) => {
assert.strictEqual(offer.price, undefined, 'price should be undefined');
assert.strictEqual(offer.priceCurrency, undefined, 'priceCurrency should be undefined');
assert.strictEqual(offer.priceSpecification, undefined, 'priceSpecification should be undefined');
});
});

it('should display the correct product name in <h1>', () => {
const h1 = document.querySelector('h1');
assert.strictEqual(h1.textContent, product.name, '<h1> content does not match product name');
Expand Down

0 comments on commit 2fb5915

Please sign in to comment.