openvibers/openvibe.host Commits

Provider pages link to reviews: Review <name> opens OpenVibe.Reviews' form for it (found or added there), and Other review sites opens Reviews' search of the others; a registrar is reviewed as a service (#134)

OP OpenVibers committed 25 days ago · 9f451e788e · 3 files, +16 −0

Changes

ddiff --git a/server/render/catalog.js b/server/render/catalog.js
iindex 738a6bf..a6f0b48 100644
---- a/server/render/catalog.js
++++ b/server/render/catalog.js
@@@ -25,6 +25,7 @@ const SORTS = [['price', 'Lowest price'], ['price_per_vcpu', 'Price per vCPU'],
const RAM = [['', 'Any RAM'], ['1024', '1 GB+'], ['2048', '2 GB+'], ['4096', '4 GB+'], ['8192', '8 GB+'], ['16384', '16 GB+'], ['32768', '32 GB+'], ['65536', '64 GB+']];
const UNKNOWN = '<span class="hc-unknown" title="The source does not state it">Unknown</span>';
++const REVIEWS_URL = 'https://openvibe.reviews';
const num = (v) => (v == null || v === '' ? null : Number(v));
function money(v, currency, digits = 2) {
const n = num(v);
@@@ -182,6 +183,17 @@ ${d.comments.length ? `<ol class="hc-comments">${d.comments.map(one).join('')}</
<p>${d.thread.visibility === 'locked' ? 'This thread is locked.' : out(threadUrl, 'Join the discussion on OpenVibe.Community', { cls: 'button hc-button-quiet' })}</p></section>`;
}
++// Members' reviews live on OpenVibe.Reviews: its /review page finds the provider there (or adds it) and opens the form;
++// /everywhere opens other review sites' own searches for the name. Host fetches nothing from either.
++function reviewsSection(p) {
++ const registrar = !p.plans.length && p.domains;
++ const write = `${REVIEWS_URL}/review?kind=${registrar ? 'service' : 'hosting'}&name=${encodeURIComponent(p.name)}`;
++ const elsewhere = `${REVIEWS_URL}/everywhere?q=${encodeURIComponent(p.name)}&kind=${registrar ? 'company' : 'hosting'}`;
++ return `<section class="hc-reviews" aria-labelledby="hc-reviews-h"><h2 id="hc-reviews-h">Reviews</h2>
++<p>Used ${esc(p.name)}? Review it on OpenVibe.Reviews, where reviews come from signed-in members, or see what other review sites say about it.</p>
++<p class="hc-more">${out(write, `Review ${esc(p.name)}`, { cls: 'button' })} ${out(elsewhere, 'Other review sites →')}</p></section>`;
++}
++
function provider(p, discussion = null, extra = '') {
const cheapest = p.plans.length ? p.plans.reduce((m, x) => (Number(x.price_monthly) < Number(m.price_monthly) ? x : m), p.plans[0]) : null;
return `<nav class="hc-crumbs" aria-label="Breadcrumb">${link('/catalog', 'Catalog')} / ${link('/catalog/providers', 'Providers')}</nav>
@@@ -192,6 +204,7 @@ ${visit(p)}
</header>
${p.plans.length ? planTable(p.plans, { caption: `${p.name}'s plans, lowest price first`, showProvider: false }) : p.domains ? `<p class="hc-more">${link(`/catalog/domains?registrar=${encodeURIComponent(p.slug)}&sort=tld`, `See ${esc(p.name)}'s domain prices →`, 'button')}</p>` : '<div class="hc-empty"><p>No plan of this provider is listed right now.</p></div>'}
${extra}
++${reviewsSection(p)}
${discussionSection(discussion)}
<h2>Promotions</h2>
${promoCards(p.promos, { showProvider: false })}
ddiff --git a/test/catalog-domains.test.js b/test/catalog-domains.test.js
iindex fb71373..6aaf3c6 100644
---- a/test/catalog-domains.test.js
++++ b/test/catalog-domains.test.js
@@@ -140,6 +140,7 @@ function fakeRegistry() {
const pb = await t.api('GET', '/catalog/providers/porkbun');
assert.match(pb.text, /6 domain endings priced/);
assert.doesNotMatch(pb.text, /No plan of this provider/);
++ assert.match(pb.text, /href="https:\/\/openvibe\.reviews\/review\?kind=service&amp;name=Porkbun"/, 'a registrar is reviewed as a service');
const front = await t.api('GET', '/');
assert.match(front.text, /Domain names, compared too/);
assert.match(front.text, /href="\/catalog\/domains"/);
ddiff --git a/test/catalog-public.test.js b/test/catalog-public.test.js
iindex 06c008a..2f2d934 100644
---- a/test/catalog-public.test.js
++++ b/test/catalog-public.test.js
@@@ -35,6 +35,8 @@ const { boot, check, done } = require('./helpers/boot');
});
await check('affiliate disclosure and rel render; promos end by time', async () => {
const page = await t.api('GET', `/catalog/providers/${p.slug}`); assert.strictEqual(page.status, 200); assert.match(page.text, /rel="sponsored nofollow noopener"/); assert.match(page.text, /OpenVibe may earn a commission/);
++ assert.ok(page.text.includes(`href="https://openvibe.reviews/review?kind=hosting&amp;name=${encodeURIComponent(p.name)}"`), 'a link to review the provider');
++ assert.match(page.text, /href="https:\/\/openvibe\.reviews\/everywhere\?q=[^"]+&amp;kind=hosting"/);
const plans = await t.api('GET', '/catalog'); assert.match(plans.text, /<form class="hc-filters" method="get" action="\/catalog"/); assert.match(plans.text, /<table class="hc-table">/);
assert.match(plans.text, /How the comparison works/); assert.doesNotMatch(plans.text, /<script[^>]*src="[^"]*catalog/, 'the catalog needs no script of its own');
const front = await t.api('GET', '/'); assert.strictEqual(front.status, 200);