openvibers/openvibe.coupons Commits
Coupons: the shop success chart shows on Product deals too (#152)
Changes
@@@ -266,7 +266,8 @@ function createPublicRoutes(ctx) {const ended = tab === 'codes' ? await Promise.all((await coupons.recentlyEnded(m.id)).map(async (c) => await coupons.view(c, { merchant: m }))) : [];const decision = publication.merchantDecision(m, active.length);const flashMsg = FLASH[req.query.done] || null;-- const success = tab === 'codes' ? await coupons.merchantWeeks(m.id) : null;++ // The success chart summarises every code, so it sits on the Codes and Product deals tabs (not About).++ const success = tab === 'about' ? null : await coupons.merchantWeeks(m.id);send(req, res, 200, {title: `${m.name} coupon codes`,description: active.length ? `${active.length} active code${active.length === 1 ? '' : 's'} for ${m.name}, with restrictions, expiry and people's reports.` : `No active codes for ${m.name} right now.`,@@@ -284,13 +284,13 @@ ${hints.length ? h`<ul class="hints ovk-note">${hints.map((x) => h`<li>How to ap${deals.length ? deals.map(card) : h`<p class="empty">No product deals for ${m.name} right now.</p>`}`;} else {body = h`${best ? h`<a class="cpn-best" href="#${best.id}"><span>Best code now</span><strong>${headline(best)}</strong><code>${best.code}</code><span class="meta">${`Confidence ${Math.round(best.confidence * 100)}%`}</span></a>` : ''}--${merchantTrend(success, m.name)}${codes.length ? codes.map(card) : active.length ? h`<p class="empty">No code for the whole shop right now; ${String(deals.length)} product deal${deals.length === 1 ? '' : 's'} <a href="${base}?tab=deals">in Product deals</a>.</p>` : h`<p class="empty">No active codes for ${m.name} right now.</p>`}<p>${k(kit.button({ href: `/submit?merchant=${encodeURIComponent(m.slug)}`, label: `Submit a code for ${m.name}`, icon: 'plus', kind: 'quiet', small: true }))}</p>${ended.length ? k(kit.fold({ title: 'Recently ended (not in active results)', meta: String(ended.length), body: String(h`<ul class="ended">${ended.map((v) => h`<li><code>${v.code}</code> — ${v.title} · ${v.status === 'expired' ? 'expired' : 'past its expiry'} ${v.expired_at ? v.expired_at.slice(0, 10) : v.expiry.expires_at ? v.expiry.expires_at.slice(0, 10) : ''}</li>`)}</ul>`) })) : ''}`;}return h`${k(head)}${flash(flashMsg)}++${tab === 'about' ? '' : merchantTrend(success, m.name)}${body}`;}@@@ -63,6 +63,9 @@ const forbidden = /reporter|install|channel|^day$|reporter_key|install_id/i;assert.match(page.text, /class="ovk-chart ovk-chart--line"/);assert.match(page.text, /\/shared\/kit-data\.css\?v=/);assert.match(page.text, /\/shared\/kit-data-web\.js\?v=/);++ const deals = await t.get(`/m/${shop.slug}?tab=deals`);++ assert.match(deals.text, /shop-trend-h/, 'the shop-wide chart is on the Product deals tab too');++ assert.doesNotMatch((await t.get(`/m/${shop.slug}?tab=about`)).text, /shop-trend-h/, 'About stays About');const j = (await t.get(`/api/v1/stores/${shop.slug}/success`)).json();assert.strictEqual(j.weeks.length, 12);assert.deepStrictEqual(j.weeks.filter(Boolean).map((w) => [w.worked, w.failed]), [[0, 3], [2, 1]]);
@@ -266,7 +266,8 @@ function createPublicRoutes(ctx) {
@@ -266,7 +266,8 @@ function createPublicRoutes(ctx) {
const ended = tab === 'codes' ? await Promise.all((await coupons.recentlyEnded(m.id)).map(async (c) => await coupons.view(c, { merchant: m }))) : [];
const ended = tab === 'codes' ? await Promise.all((await coupons.recentlyEnded(m.id)).map(async (c) => await coupons.view(c, { merchant: m }))) : [];
const decision = publication.merchantDecision(m, active.length);
const decision = publication.merchantDecision(m, active.length);
const flashMsg = FLASH[req.query.done] || null;
const flashMsg = FLASH[req.query.done] || null;
- const success = tab === 'codes' ? await coupons.merchantWeeks(m.id) : null;
+ // The success chart summarises every code, so it sits on the Codes and Product deals tabs (not About).
+ const success = tab === 'about' ? null : await coupons.merchantWeeks(m.id);
send(req, res, 200, {
send(req, res, 200, {
title: `${m.name} coupon codes`,
title: `${m.name} coupon codes`,
description: active.length ? `${active.length} active code${active.length === 1 ? '' : 's'} for ${m.name}, with restrictions, expiry and people's reports.` : `No active codes for ${m.name} right now.`,
description: active.length ? `${active.length} active code${active.length === 1 ? '' : 's'} for ${m.name}, with restrictions, expiry and people's reports.` : `No active codes for ${m.name} right now.`,
@@ -284,13 +284,13 @@ ${hints.length ? h`<ul class="hints ovk-note">${hints.map((x) => h`<li>How to ap
@@ -284,13 +284,13 @@ ${hints.length ? h`<ul class="hints ovk-note">${hints.map((x) => h`<li>How to ap
${deals.length ? deals.map(card) : h`<p class="empty">No product deals for ${m.name} right now.</p>`}`;
${deals.length ? deals.map(card) : h`<p class="empty">No product deals for ${m.name} right now.</p>`}`;
} else {
} else {
body = h`${best ? h`<a class="cpn-best" href="#${best.id}"><span>Best code now</span><strong>${headline(best)}</strong><code>${best.code}</code><span class="meta">${`Confidence ${Math.round(best.confidence * 100)}%`}</span></a>` : ''}
body = h`${best ? h`<a class="cpn-best" href="#${best.id}"><span>Best code now</span><strong>${headline(best)}</strong><code>${best.code}</code><span class="meta">${`Confidence ${Math.round(best.confidence * 100)}%`}</span></a>` : ''}
-${merchantTrend(success, m.name)}
${codes.length ? codes.map(card) : active.length ? h`<p class="empty">No code for the whole shop right now; ${String(deals.length)} product deal${deals.length === 1 ? '' : 's'} <a href="${base}?tab=deals">in Product deals</a>.</p>` : h`<p class="empty">No active codes for ${m.name} right now.</p>`}
${codes.length ? codes.map(card) : active.length ? h`<p class="empty">No code for the whole shop right now; ${String(deals.length)} product deal${deals.length === 1 ? '' : 's'} <a href="${base}?tab=deals">in Product deals</a>.</p>` : h`<p class="empty">No active codes for ${m.name} right now.</p>`}
<p>${k(kit.button({ href: `/submit?merchant=${encodeURIComponent(m.slug)}`, label: `Submit a code for ${m.name}`, icon: 'plus', kind: 'quiet', small: true }))}</p>
<p>${k(kit.button({ href: `/submit?merchant=${encodeURIComponent(m.slug)}`, label: `Submit a code for ${m.name}`, icon: 'plus', kind: 'quiet', small: true }))}</p>
${ended.length ? k(kit.fold({ title: 'Recently ended (not in active results)', meta: String(ended.length), body: String(h`<ul class="ended">${ended.map((v) => h`<li><code>${v.code}</code> — ${v.title} · ${v.status === 'expired' ? 'expired' : 'past its expiry'} ${v.expired_at ? v.expired_at.slice(0, 10) : v.expiry.expires_at ? v.expiry.expires_at.slice(0, 10) : ''}</li>`)}</ul>`) })) : ''}`;
${ended.length ? k(kit.fold({ title: 'Recently ended (not in active results)', meta: String(ended.length), body: String(h`<ul class="ended">${ended.map((v) => h`<li><code>${v.code}</code> — ${v.title} · ${v.status === 'expired' ? 'expired' : 'past its expiry'} ${v.expired_at ? v.expired_at.slice(0, 10) : v.expiry.expires_at ? v.expiry.expires_at.slice(0, 10) : ''}</li>`)}</ul>`) })) : ''}`;
}
}
return h`${k(head)}
return h`${k(head)}
${flash(flashMsg)}
${flash(flashMsg)}
+${tab === 'about' ? '' : merchantTrend(success, m.name)}
${body}`;
${body}`;
}
}
@@ -63,6 +63,9 @@ const forbidden = /reporter|install|channel|^day$|reporter_key|install_id/i;
@@ -63,6 +63,9 @@ const forbidden = /reporter|install|channel|^day$|reporter_key|install_id/i;
assert.match(page.text, /class="ovk-chart ovk-chart--line"/);
assert.match(page.text, /class="ovk-chart ovk-chart--line"/);
assert.match(page.text, /\/shared\/kit-data\.css\?v=/);
assert.match(page.text, /\/shared\/kit-data\.css\?v=/);
assert.match(page.text, /\/shared\/kit-data-web\.js\?v=/);
assert.match(page.text, /\/shared\/kit-data-web\.js\?v=/);
+ const deals = await t.get(`/m/${shop.slug}?tab=deals`);
+ assert.match(deals.text, /shop-trend-h/, 'the shop-wide chart is on the Product deals tab too');
+ assert.doesNotMatch((await t.get(`/m/${shop.slug}?tab=about`)).text, /shop-trend-h/, 'About stays About');
const j = (await t.get(`/api/v1/stores/${shop.slug}/success`)).json();
const j = (await t.get(`/api/v1/stores/${shop.slug}/success`)).json();
assert.strictEqual(j.weeks.length, 12);
assert.strictEqual(j.weeks.length, 12);
assert.deepStrictEqual(j.weeks.filter(Boolean).map((w) => [w.worked, w.failed]), [[0, 3], [2, 1]]);
assert.deepStrictEqual(j.weeks.filter(Boolean).map((w) => [w.worked, w.failed]), [[0, 3], [2, 1]]);