From 94fde9fb10559a3239c43e2a4d3af9923afb2636 Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Mon, 23 Jan 2023 16:32:46 +0100 Subject: [PATCH] Add tests for subscription expiring message --- .../screens/messaging/ViewMessagesInbox.qml | 2 + tests/functional/helper.js | 13 ++++ tests/functional/queries.js | 1 + .../functional/servers/guardian_endpoints.js | 2 + tests/functional/setupVpn.js | 2 + tests/functional/testAddons.js | 78 +++++++++++++++++++ 6 files changed, 98 insertions(+) diff --git a/src/apps/vpn/ui/screens/messaging/ViewMessagesInbox.qml b/src/apps/vpn/ui/screens/messaging/ViewMessagesInbox.qml index dfbe49798ac..b7948c696f9 100644 --- a/src/apps/vpn/ui/screens/messaging/ViewMessagesInbox.qml +++ b/src/apps/vpn/ui/screens/messaging/ViewMessagesInbox.qml @@ -183,6 +183,8 @@ VPNViewBase { VPNSwipeDelegate { id: swipeDelegate + objectName: typeof(addon) !== "undefined" ? addon.id : "" + property real deleteLabelWidth: 0.0 //avoids qml warnings when addon messages get disabled via condition diff --git a/tests/functional/helper.js b/tests/functional/helper.js index 99d8582a848..0a44d1c3aec 100644 --- a/tests/functional/helper.js +++ b/tests/functional/helper.js @@ -176,6 +176,19 @@ module.exports = { }); }, + async checkForFailedQuery(query, tries = 3, interval = 300) { + let attempts = 0; + while(attempts < tries) { + try { + await this.query(query); + throw new Error(`Query '${query}' was expected to fail!`); + } catch(e) { + attempts++; + await this.wait(interval); + } + }; + }, + async clickOnQuery(id) { assert(await this.query(id), 'Clicking on an non-existing element?!?'); const json = await this._writeCommand(`click ${encodeURIComponent(id)}`); diff --git a/tests/functional/queries.js b/tests/functional/queries.js index 12bdc78b75e..11dc9880d8b 100644 --- a/tests/functional/queries.js +++ b/tests/functional/queries.js @@ -377,6 +377,7 @@ const global = { }; module.exports = { + QmlQueryComposer, screenHome, screenInitialize, screenInitializeMobileOnBoarding, diff --git a/tests/functional/servers/guardian_endpoints.js b/tests/functional/servers/guardian_endpoints.js index 0468b733077..dffabb0711a 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 f72d38fde0b..7b2d1431289 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 181ceef07ae..fef8dd8273f 100644 --- a/tests/functional/testAddons.js +++ b/tests/functional/testAddons.js @@ -5,6 +5,9 @@ const assert = require('assert'); const queries = require('./queries.js'); const vpn = require('./helper.js'); +const { SubscriptionDetails } = require('./servers/guardian_endpoints.js') +const { QmlQueryComposer } = require('./queries.js') +const { startAndConnect } = require('./setupVpn.js') describe('Addons', function() { this.ctx.authenticationNeeded = true; @@ -127,4 +130,79 @@ 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 + )); + + // Enter messages screen. + await vpn.waitForQueryAndClick(queries.navBar.MESSAGES); + await vpn.waitForQuery(queries.screenMessaging.SCREEN.visible()); + + // Check that the subscription expiry message is there or not. + const query = new QmlQueryComposer("//message_subscription_expiring"); + if (shouldBeAvailable) { + await vpn.waitForQuery(query); + } else { + await vpn.checkForFailedQuery(query); + } + } + } + + 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); + }); + }); });