🐛 Fixed data importer allowing invalid free product to be imported (#20572)

refs
[ENG-1355](https://linear.app/tryghost/issue/ENG-1355/site-boot-cycling-due-to-free-tier-having-a-currency)

Fixed data importer allowing invalid free product to be imported which
could cause Ghost to not start due to the error:

`ValidationError: Free Tiers cannot have a currency`

It should not be possible to import a free product with pricing data (as
that means its not free 😄)
This commit is contained in:
Michael Barrett 2024-07-10 10:49:56 +01:00 committed by GitHub
parent 13bad88baf
commit 6bfba13937
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 0 deletions

View File

@ -122,8 +122,26 @@ class ProductsImporter extends BaseImporter {
this.dataToImport = this.dataToImport.filter(item => !duplicateProducts.includes(item.id));
}
preventInvalidFree() {
let invalidFreeProducts = [];
_.each(this.dataToImport, (product) => {
// A free product must not have any pricing data (otherwise it wouldn't be free, duh!)
if (product.type === 'free' && product.currency && product.monthly_price && product.yearly_price) {
this.problems.push({
message: 'Entry was not imported and ignored. Detected invalid entry.',
help: this.modelName,
context: JSON.stringify({product})
});
invalidFreeProducts.push(product.id);
}
});
// ignore invalid free products
this.dataToImport = this.dataToImport.filter(item => !invalidFreeProducts.includes(item.id));
}
beforeImport() {
this.populatePriceData();
this.preventInvalidFree();
return super.beforeImport();
}

View File

@ -109,5 +109,32 @@ describe('ProductsImporter', function () {
importer.beforeImport();
assert(importer.dataToImport.length === 1);
});
it('Does not import a free product that has pricing', function () {
const invalidFreeProduct = {
id: 'free123',
name: 'Free 123',
slug: 'free-123',
active: 1,
welcome_page_url: null,
visibility: 'public',
trial_days: 0,
description: null,
type: 'free',
currency: 'usd',
monthly_price: 100,
yearly_price: 1000,
created_at: '2024-07-10T00:00:00.000Z',
updated_at: '2024-07-10T00:00:00.000Z',
monthly_price_id: 'price_1',
yearly_price_id: 'price_2'
};
const importer = new ProductsImporter({products: [invalidFreeProduct], stripe_prices: fakePrices});
importer.beforeImport();
assert(importer.dataToImport.length === 0);
});
});
});