openvibers/openvibe.host Commits
Host: a plan page links its provider (Visit provider) (#77)
Changes
@@@ -146,7 +146,7 @@ function createCatalog({ store, community = null, log = console }) {return { plans: rows.slice(0, 50).map(planOut), next_cursor: rows.length > 50 ? String(offset + 50) : null };}async function plan(id) {-- const p = await db.prepare("SELECT p.*, v.slug AS provider_slug, v.name AS provider_name, v.affiliate_url, v.affiliate_note FROM catalog_plans p JOIN catalog_providers v ON v.id = p.provider_id WHERE p.id = ? AND p.status = 'active' AND v.status = 'active'").get(id);++ const p = await db.prepare("SELECT p.*, v.slug AS provider_slug, v.name AS provider_name, v.homepage_url, v.affiliate_url, v.affiliate_note FROM catalog_plans p JOIN catalog_providers v ON v.id = p.provider_id WHERE p.id = ? AND p.status = 'active' AND v.status = 'active'").get(id);if (!p) missing();return { ...planOut(p), price_history: (await db.prepare('SELECT * FROM catalog_price_changes WHERE plan_id = ? ORDER BY observed_at DESC').all(id)).map((h) => ({ ...h, checked_at: new Date(Number(h.observed_at)).toISOString(), source_url: p.source_url })) };}@@@ -51,6 +51,7 @@ const { boot, check, done } = require('./stageb/boot');assert.ok(types(plans.text).includes('ItemList'));const planPage = await t.api('GET', `/catalog/plans/${cheap.id}`);const product = ld(planPage.text).find((x) => x['@type'] === 'Product');++ assert.match(planPage.text, /class="hc-visit"/, 'a plan page offers a way to the provider');assert.ok(product && product.offers.price === '4.00' && product.offers.priceCurrency === 'USD' && product.offers.priceSpecification.unitText === 'MONTH');assert.ok(!types((await t.api('GET', '/catalog?min_vcpu=2')).text).includes('ItemList'), 'a filtered view carries no JSON-LD');const promos = await t.api('GET', '/api/v1/catalog/promos'); assert.strictEqual(promos.json().promos.length, 1);
@@ -146,7 +146,7 @@ function createCatalog({ store, community = null, log = console }) {
@@ -146,7 +146,7 @@ function createCatalog({ store, community = null, log = console }) {
return { plans: rows.slice(0, 50).map(planOut), next_cursor: rows.length > 50 ? String(offset + 50) : null };
return { plans: rows.slice(0, 50).map(planOut), next_cursor: rows.length > 50 ? String(offset + 50) : null };
}
}
async function plan(id) {
async function plan(id) {
- const p = await db.prepare("SELECT p.*, v.slug AS provider_slug, v.name AS provider_name, v.affiliate_url, v.affiliate_note FROM catalog_plans p JOIN catalog_providers v ON v.id = p.provider_id WHERE p.id = ? AND p.status = 'active' AND v.status = 'active'").get(id);
+ const p = await db.prepare("SELECT p.*, v.slug AS provider_slug, v.name AS provider_name, v.homepage_url, v.affiliate_url, v.affiliate_note FROM catalog_plans p JOIN catalog_providers v ON v.id = p.provider_id WHERE p.id = ? AND p.status = 'active' AND v.status = 'active'").get(id);
if (!p) missing();
if (!p) missing();
return { ...planOut(p), price_history: (await db.prepare('SELECT * FROM catalog_price_changes WHERE plan_id = ? ORDER BY observed_at DESC').all(id)).map((h) => ({ ...h, checked_at: new Date(Number(h.observed_at)).toISOString(), source_url: p.source_url })) };
return { ...planOut(p), price_history: (await db.prepare('SELECT * FROM catalog_price_changes WHERE plan_id = ? ORDER BY observed_at DESC').all(id)).map((h) => ({ ...h, checked_at: new Date(Number(h.observed_at)).toISOString(), source_url: p.source_url })) };
}
}
@@ -51,6 +51,7 @@ const { boot, check, done } = require('./stageb/boot');
@@ -51,6 +51,7 @@ const { boot, check, done } = require('./stageb/boot');
assert.ok(types(plans.text).includes('ItemList'));
assert.ok(types(plans.text).includes('ItemList'));
const planPage = await t.api('GET', `/catalog/plans/${cheap.id}`);
const planPage = await t.api('GET', `/catalog/plans/${cheap.id}`);
const product = ld(planPage.text).find((x) => x['@type'] === 'Product');
const product = ld(planPage.text).find((x) => x['@type'] === 'Product');
+ assert.match(planPage.text, /class="hc-visit"/, 'a plan page offers a way to the provider');
assert.ok(product && product.offers.price === '4.00' && product.offers.priceCurrency === 'USD' && product.offers.priceSpecification.unitText === 'MONTH');
assert.ok(product && product.offers.price === '4.00' && product.offers.priceCurrency === 'USD' && product.offers.priceSpecification.unitText === 'MONTH');
assert.ok(!types((await t.api('GET', '/catalog?min_vcpu=2')).text).includes('ItemList'), 'a filtered view carries no JSON-LD');
assert.ok(!types((await t.api('GET', '/catalog?min_vcpu=2')).text).includes('ItemList'), 'a filtered view carries no JSON-LD');
const promos = await t.api('GET', '/api/v1/catalog/promos'); assert.strictEqual(promos.json().promos.length, 1);
const promos = await t.api('GET', '/api/v1/catalog/promos'); assert.strictEqual(promos.json().promos.length, 1);