From 4610e1aa92a522189e637cb4fa49f71ef8d6f94e Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Mon, 23 Jan 2023 17:26:08 +0100 Subject: [PATCH] Add tests for subscription expiring message --- src/apps/vpn/inspector/inspectorhandler.cpp | 18 +++++ tests/functional/helper.js | 8 ++ .../functional/servers/guardian_endpoints.js | 2 + tests/functional/setupVpn.js | 2 + tests/functional/testAddons.js | 74 +++++++++++++++++++ 5 files changed, 104 insertions(+) diff --git a/src/apps/vpn/inspector/inspectorhandler.cpp b/src/apps/vpn/inspector/inspectorhandler.cpp index 86f770f4eb..c02c0968c6 100644 --- a/src/apps/vpn/inspector/inspectorhandler.cpp +++ b/src/apps/vpn/inspector/inspectorhandler.cpp @@ -567,6 +567,24 @@ static QList s_commands{ return obj; }}, + InspectorCommand{"messages", "Returns a list of the loaded messages ids", 0, + [](InspectorHandler*, const QList&) { + QJsonObject obj; + + AddonManager* am = AddonManager::instance(); + Q_ASSERT(am); + + QJsonArray messages; + am->forEach([&](Addon* addon) { + if (addon->type() == "message") { + messages.append(addon->id()); + } + }); + + obj["value"] = messages; + return obj; + }}, + InspectorCommand{"translate", "Translate a string", 1, [](InspectorHandler*, const QList& arguments) { QJsonObject obj; diff --git a/tests/functional/helper.js b/tests/functional/helper.js index 99d8582a84..b6522b2bce 100644 --- a/tests/functional/helper.js +++ b/tests/functional/helper.js @@ -506,6 +506,14 @@ module.exports = { return json.value; }, + async messages() { + const json = await this._writeCommand('messages'); + assert( + json.type === 'messages' && !('error' in json), + `Command failed: ${json.error}`); + return json.value; + }, + async screenCapture() { const json = await this._writeCommand('screen_capture'); assert( diff --git a/tests/functional/servers/guardian_endpoints.js b/tests/functional/servers/guardian_endpoints.js index 0468b73307..dffabb0711 100644 --- a/tests/functional/servers/guardian_endpoints.js +++ b/tests/functional/servers/guardian_endpoints.js @@ -39,6 +39,8 @@ const SubscriptionDetails = { }, }; +exports.SubscriptionDetails = SubscriptionDetails; + const VALIDATORS = { guardianLoginVerify: { type: 'object', diff --git a/tests/functional/setupVpn.js b/tests/functional/setupVpn.js index f72d38fde0..7b2d143128 100644 --- a/tests/functional/setupVpn.js +++ b/tests/functional/setupVpn.js @@ -46,6 +46,8 @@ async function startAndConnect() { await vpn.connect(vpnWS, {hostname: '127.0.0.1'}); } +exports.startAndConnect = startAndConnect; + exports.mochaHooks = { async beforeAll() { // Check VPN app exists. If not, bail. diff --git a/tests/functional/testAddons.js b/tests/functional/testAddons.js index 181ceef07a..40e8592363 100644 --- a/tests/functional/testAddons.js +++ b/tests/functional/testAddons.js @@ -5,6 +5,8 @@ const assert = require('assert'); const queries = require('./queries.js'); const vpn = require('./helper.js'); +const { SubscriptionDetails } = require('./servers/guardian_endpoints.js') +const { startAndConnect } = require('./setupVpn.js') describe('Addons', function() { this.ctx.authenticationNeeded = true; @@ -127,4 +129,76 @@ describe('Addons', function() { await vpn.getVPNProperty('VPNCurrentServer', 'exitCountryCode') === exitCountryCode); }); + + describe('test message_subscription_expiring addon condition', async () => { + async function checkForSubscriptionExpiringMessage(ctx, subscriptionExpirationCases, shouldBeAvailable) { + for (const expiresOn of subscriptionExpirationCases) { + const mockDetails = { ...SubscriptionDetails }; + // We are faking a Stripe subscription, so this value is expected to be in seconds. + mockDetails.subscription.current_period_end = expiresOn / 1000; + ctx.guardianSubscriptionDetailsCallback = () => { + ctx.guardianOverrideEndpoints.GETs['/api/v1/vpn/subscriptionDetails'].status = 200; + ctx.guardianOverrideEndpoints + .GETs['/api/v1/vpn/subscriptionDetails'] + .body = mockDetails; + }; + + // Restart the VPN to load the new sub details. + await vpn.quit(); + await startAndConnect(); + + // Load all production addons. + // These are loaded all together, so we don't know the exact number of addons. + await vpn.resetAddons('prod'); + await vpn.waitForCondition(async () => ( + parseInt(await vpn.getVPNProperty('VPNAddonManager', 'count'), 10) > 0 + )); + + const loadedMessages = await vpn.messages(); + const isSubscriptionExpiringMessageAvailable = loadedMessages.includes("message_subscription_expiring"); + + if (shouldBeAvailable) { + assert(isSubscriptionExpiringMessageAvailable); + } else { + assert(!isSubscriptionExpiringMessageAvailable); + } + } + } + + it('message is enabled when subscription is about to expire', async () => { + // 1 to 7 days out from expiring. + const subscriptionExpirationCases = Array.from( + { length: 7 }, + (_, i) => Date.now() + 1000 * 60 * 60 * 24 * (i + 1) + ); + + await checkForSubscriptionExpiringMessage(this.ctx, subscriptionExpirationCases, true); + }); + + it('message is not enabled when subscription is not about to expire', async () => { + const subscriptionExpirationCases = [ + // Seven days out + a minute from expiring. + Date.now() + 1000 * 60 * 60 * 24 * 7 + 1000 * 60, + // Eight days from expiring. + Date.now() + 1000 * 60 * 60 * 24 * 8, + // One month from expiring. + Date.now() + 1000 * 60 * 60 * 24 * 30, + ] + + await checkForSubscriptionExpiringMessage(this.ctx, subscriptionExpirationCases, false); + }); + + it('message is not enabled when subscription is already expired', async () => { + const subscriptionExpirationCases = [ + // Literally, has just expired. + Date.now(), + // Has been expired for a day. + Date.now() - 1000 * 60 * 60 * 24, + // Has been expired for 30 days. + Date.now() - 1000 * 60 * 60 * 24 * 30, + ] + + await checkForSubscriptionExpiringMessage(this.ctx, subscriptionExpirationCases, false); + }); + }); });