getProductRepositoryStub = ({
        ghostProductStripePriceId = stripeCustomerSubscriptionItem.price.id,
        resolveGhostProductPrice = true,
        resolveStripeProduct = true
    } = {}) => {
        // Ghost product price
        const priceStub = {
            get: sinon.stub().returns(null)
        };

        priceStub.get.withArgs('stripe_price_id').returns(ghostProductStripePriceId);

        // Ghost product
        const productStub = {
            related: sinon.stub().returns(null),
            get: key => ghostProduct[key]
        };

        productStub.related.withArgs('stripeProducts').returns({
            first: sinon.stub().returns(resolveStripeProduct ? productStub : null)
        });

        productStub.related.withArgs('stripePrices').returns({
            find: sinon.stub().returns(resolveGhostProductPrice ? priceStub : null)
        });

        // Product repository
        const productRepositoryStub = {
            get: sinon.stub().resolves(null),
            update: sinon.stub().resolves(productStub)
        };

        productRepositoryStub.get.withArgs(
            {id: PRODUCT_ID},
            {...OPTIONS, withRelated: ['stripePrices', 'stripeProducts']}
        ).resolves(productStub);

        return productRepositoryStub;
    }
Returns a stubbed product repository

@param {Object} options
@param {String} [options.ghostProductStripePriceId] - The Stripe price ID of the Ghost product, defaults to the Stripe price ID of the Stripe customer's existing subscription
@param {Boolean} [options.resolveGhostProductPrice] - Whether the product repository should resolve the Ghost product price, defaults to true
@param {Boolean} [options.resolveStripeProduct] - Whether the product repository should resolve the Stripe product, defaults to true
@returns {Object}