diff --git a/app/assets/javascripts/shopify_app/enable_cookies.js b/app/assets/javascripts/shopify_app/enable_cookies.js deleted file mode 100644 index 46ed369d7..000000000 --- a/app/assets/javascripts/shopify_app/enable_cookies.js +++ /dev/null @@ -1,3 +0,0 @@ -//= require ./itp_helper.js -//= require ./storage_access.js -//= require ./partition_cookies.js \ No newline at end of file diff --git a/app/assets/javascripts/shopify_app/itp_helper.js b/app/assets/javascripts/shopify_app/itp_helper.js deleted file mode 100644 index 1f8b282f8..000000000 --- a/app/assets/javascripts/shopify_app/itp_helper.js +++ /dev/null @@ -1,40 +0,0 @@ -(function() { - function ITPHelper(opts) { - this.itpContent = document.getElementById('TopLevelInteractionContent'); - this.itpAction = document.getElementById('TopLevelInteractionButton'); - this.redirectUrl = opts.redirectUrl; - } - - ITPHelper.prototype.redirect = function() { - sessionStorage.setItem('shopify.top_level_interaction', true); - window.location.href = this.redirectUrl; - } - - ITPHelper.prototype.userAgentIsAffected = function() { - return Boolean(document.hasStorageAccess); - } - - ITPHelper.prototype.canPartitionCookies = function() { - var versionRegEx = /Version\/12\.0\.?\d? Safari/; - return versionRegEx.test(navigator.userAgent); - } - - ITPHelper.prototype.setUpContent = function(onClick) { - this.itpContent.style.display = 'block'; - this.itpAction.addEventListener('click', this.redirect.bind(this)); - } - - ITPHelper.prototype.execute = function() { - if (!this.itpContent) { - return; - } - - if (this.userAgentIsAffected()) { - this.setUpContent(); - } else { - this.redirect(); - } - } - - this.ITPHelper = ITPHelper; -})(window); diff --git a/app/assets/javascripts/shopify_app/partition_cookies.js b/app/assets/javascripts/shopify_app/partition_cookies.js deleted file mode 100644 index ee1c867f5..000000000 --- a/app/assets/javascripts/shopify_app/partition_cookies.js +++ /dev/null @@ -1,8 +0,0 @@ -(function() { - document.addEventListener("DOMContentLoaded", function() { - var redirectTargetElement = document.getElementById("redirection-target"); - var targetInfo = JSON.parse(redirectTargetElement.dataset.target) - var storageAccessHelper = new StorageAccessHelper(targetInfo); - storageAccessHelper.execute(); - }); -})(); diff --git a/app/assets/javascripts/shopify_app/post_redirect.js b/app/assets/javascripts/shopify_app/post_redirect.js deleted file mode 100644 index 7d418068e..000000000 --- a/app/assets/javascripts/shopify_app/post_redirect.js +++ /dev/null @@ -1,9 +0,0 @@ -(function() { - function redirect() { - var form = document.getElementById("redirect-form"); - if (form) { - form.submit(); - } - } - document.addEventListener("DOMContentLoaded", redirect); -})(); diff --git a/app/assets/javascripts/shopify_app/request_storage_access.js b/app/assets/javascripts/shopify_app/request_storage_access.js deleted file mode 100644 index e5f37a2ab..000000000 --- a/app/assets/javascripts/shopify_app/request_storage_access.js +++ /dev/null @@ -1,3 +0,0 @@ -//= require ./itp_helper.js -//= require ./storage_access.js -//= require ./storage_access_redirect.js \ No newline at end of file diff --git a/app/assets/javascripts/shopify_app/storage_access.js b/app/assets/javascripts/shopify_app/storage_access.js deleted file mode 100644 index c4b8d9214..000000000 --- a/app/assets/javascripts/shopify_app/storage_access.js +++ /dev/null @@ -1,148 +0,0 @@ -//= require ./app_bridge_redirect.js - -(function() { - var ACCESS_GRANTED_STATUS = 'storage_access_granted'; - var ACCESS_DENIED_STATUS = 'storage_access_denied'; - - function StorageAccessHelper(redirectData) { - this.redirectData = redirectData; - } - - StorageAccessHelper.prototype.setNormalizedLink = function(storageAccessStatus) { - return storageAccessStatus === ACCESS_GRANTED_STATUS ? this.redirectData.hasStorageAccessUrl : this.redirectData.doesNotHaveStorageAccessUrl; - } - - StorageAccessHelper.prototype.redirectToAppTLD = function(storageAccessStatus) { - var normalizedLink = document.createElement('a'); - - window.appBridgeRedirect(this.setNormalizedLink(storageAccessStatus)); - } - - StorageAccessHelper.prototype.redirectToAppsIndex = function() { - window.parent.location.href = this.redirectData.myshopifyUrl + '/admin/apps'; - } - - StorageAccessHelper.prototype.redirectToAppTargetUrl = function() { - window.location.href = this.redirectData.appTargetUrl; - } - - StorageAccessHelper.prototype.sameSiteNoneIncompatible = function(ua) { - return ua.includes("iPhone OS 12_") || ua.includes("iPad; CPU OS 12_") || //iOS 12 - (ua.includes("UCBrowser/") - ? this.isOlderUcBrowser(ua) //UC Browser < 12.13.2 - : (ua.includes("Chrome/5") || ua.includes("Chrome/6"))) || - ua.includes("Chromium/5") || ua.includes("Chromium/6") || - (ua.includes(" OS X 10_14_") && - ((ua.includes("Version/") && ua.includes("Safari")) || //Safari on MacOS 10.14 - ua.endsWith("(KHTML, like Gecko)"))); //Web view on MacOS 10.14 - } - - StorageAccessHelper.prototype.isOlderUcBrowser = function(ua) { - var match = ua.match(/UCBrowser\/(\d+)\.(\d+)\.(\d+)\./); - if (!match) return false; - var major = parseInt(match[1]); - var minor = parseInt(match[2]); - var build = parseInt(match[3]); - if (major != 12) return major < 12; - if (minor != 13) return minor < 13; - return build < 2; - } - - StorageAccessHelper.prototype.setCookie = function(value) { - if(!this.sameSiteNoneIncompatible(navigator.userAgent)) { - value += '; secure; SameSite=None' - } - document.cookie = value; - } - - StorageAccessHelper.prototype.grantedStorageAccess = function() { - try { - sessionStorage.setItem('shopify.granted_storage_access', true); - this.setCookie('shopify.granted_storage_access=true'); - if (!document.cookie) { - throw 'Cannot set third-party cookie.' - } - this.redirectToAppTargetUrl(); - } catch (error) { - console.warn('Third party cookies may be blocked.', error); - this.redirectToAppTLD(ACCESS_DENIED_STATUS); - } - } - - StorageAccessHelper.prototype.handleRequestStorageAccess = function() { - return document.requestStorageAccess().then(this.grantedStorageAccess.bind(this), this.redirectToAppsIndex.bind(this, ACCESS_DENIED_STATUS)); - } - - StorageAccessHelper.prototype.setupRequestStorageAccess = function() { - var requestContent = document.getElementById('RequestStorageAccess'); - var requestButton = document.getElementById('TriggerAllowCookiesPrompt'); - - requestButton.addEventListener('click', this.handleRequestStorageAccess.bind(this)); - requestContent.style.display = 'block'; - } - - StorageAccessHelper.prototype.handleHasStorageAccess = function() { - if (sessionStorage.getItem('shopify.granted_storage_access')) { - // If app was classified by ITP and used Storage Access API to acquire access - this.redirectToAppTargetUrl(); - } else { - // If app has not been classified by ITP and still has storage access - this.redirectToAppTLD(ACCESS_GRANTED_STATUS); - } - } - - StorageAccessHelper.prototype.handleGetStorageAccess = function() { - if (sessionStorage.getItem('shopify.top_level_interaction')) { - // If merchant has been redirected to interact with TLD (requirement for prompting request to gain storage access) - this.setupRequestStorageAccess(); - } else { - // If merchant has not been redirected to interact with TLD (requirement for prompting request to gain storage access) - this.redirectToAppTLD(ACCESS_DENIED_STATUS); - } - } - - StorageAccessHelper.prototype.manageStorageAccess = function() { - return document.hasStorageAccess().then(function(hasAccess) { - if (hasAccess) { - this.handleHasStorageAccess(); - } else { - this.handleGetStorageAccess(); - } - }.bind(this)); - } - - StorageAccessHelper.prototype.execute = function() { - if (ITPHelper.prototype.canPartitionCookies()) { - this.setUpCookiePartitioning(); - return; - } - - if (ITPHelper.prototype.userAgentIsAffected()) { - this.manageStorageAccess(); - } else { - this.grantedStorageAccess(); - } - } - - /* ITP 2.0 solution: handles cookie partitioning */ - StorageAccessHelper.prototype.setUpHelper = function() { - var shopifyData = document.body.dataset; - return new ITPHelper({redirectUrl: "https://" + shopifyData.shopOrigin + "/admin/apps/" + shopifyData.apiKey + shopifyData.returnTo}); - } - - StorageAccessHelper.prototype.setCookieAndRedirect = function() { - this.setCookie('shopify.cookies_persist=true'); - var helper = this.setUpHelper(); - helper.redirect(); - } - - StorageAccessHelper.prototype.setUpCookiePartitioning = function() { - var itpContent = document.getElementById('CookiePartitionPrompt'); - itpContent.style.display = 'block'; - - var button = document.getElementById('AcceptCookies'); - button.addEventListener('click', this.setCookieAndRedirect.bind(this)); - } - - this.StorageAccessHelper = StorageAccessHelper; -})(window); diff --git a/app/assets/javascripts/shopify_app/storage_access_redirect.js b/app/assets/javascripts/shopify_app/storage_access_redirect.js deleted file mode 100644 index fbbbb8130..000000000 --- a/app/assets/javascripts/shopify_app/storage_access_redirect.js +++ /dev/null @@ -1,17 +0,0 @@ -(function() { - function redirect() { - var redirectTargetElement = document.getElementById("redirection-target"); - - var targetInfo = JSON.parse(redirectTargetElement.dataset.target) - - if (window.top == window.self) { - // If the current window is the 'parent', change the URL by setting location.href - window.top.location.href = targetInfo.hasStorageAccessUrl; - } else { - var storageAccessHelper = new StorageAccessHelper(targetInfo); - storageAccessHelper.execute(); - } - } - - document.addEventListener("DOMContentLoaded", redirect); -})(); diff --git a/app/assets/javascripts/shopify_app/top_level.js b/app/assets/javascripts/shopify_app/top_level.js deleted file mode 100644 index d8a0ee15b..000000000 --- a/app/assets/javascripts/shopify_app/top_level.js +++ /dev/null @@ -1,2 +0,0 @@ -//= require ./itp_helper.js -//= require ./top_level_interaction.js \ No newline at end of file diff --git a/app/assets/javascripts/shopify_app/top_level_interaction.js b/app/assets/javascripts/shopify_app/top_level_interaction.js deleted file mode 100644 index 3dc6f1882..000000000 --- a/app/assets/javascripts/shopify_app/top_level_interaction.js +++ /dev/null @@ -1,11 +0,0 @@ -(function() { - function setUpTopLevelInteraction() { - var TopLevelInteraction = new ITPHelper({ - redirectUrl: document.body.dataset.redirectUrl, - }); - - TopLevelInteraction.execute(); - } - - document.addEventListener("DOMContentLoaded", setUpTopLevelInteraction); -})(); diff --git a/app/views/shopify_app/sessions/enable_cookies.html.erb b/app/views/shopify_app/sessions/enable_cookies.html.erb deleted file mode 100644 index eb99bf98a..000000000 --- a/app/views/shopify_app/sessions/enable_cookies.html.erb +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - Redirecting… - <%= render 'shopify_app/partials/layout_styles' %> - <%= render 'shopify_app/partials/typography_styles' %> - <%= render 'shopify_app/partials/card_styles' %> - <%= render 'shopify_app/partials/button_styles' %> - - - <%= javascript_include_tag('shopify_app/enable_cookies', crossorigin: 'anonymous', integrity: true) %> - - - <%= - content_tag( - :div, nil, - id: 'redirection-target', - data: { - target: { - myshopifyUrl: "https://#{current_shopify_domain}", - hasStorageAccessUrl: "#{has_storage_access_url}", - doesNotHaveStorageAccessUrl: "#{does_not_have_storage_access_url}", - appTargetUrl: "#{app_target_url}" - }, - }, - ) - %> -
-
-
-
-
-
-
-
-
-

<%= I18n.t('enable_cookies_heading', app: ShopifyApp.configuration.application_name) %>

-
-
-

<%= I18n.t('enable_cookies_body', app: ShopifyApp.configuration.application_name) %>

-
-
-

<%= I18n.t('enable_cookies_footer') %>

-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- - diff --git a/app/views/shopify_app/sessions/request_storage_access.html.erb b/app/views/shopify_app/sessions/request_storage_access.html.erb deleted file mode 100644 index c6c8d7221..000000000 --- a/app/views/shopify_app/sessions/request_storage_access.html.erb +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - Redirecting… - <%= render 'shopify_app/partials/layout_styles' %> - <%= render 'shopify_app/partials/typography_styles' %> - <%= render 'shopify_app/partials/card_styles' %> - <%= render 'shopify_app/partials/button_styles' %> - - - -<%= - content_tag(:div, nil, - id: 'redirection-target', - data: { - target: { - myshopifyUrl: "https://#{current_shopify_domain}", - hasStorageAccessUrl: "#{has_storage_access_url}", - doesNotHaveStorageAccessUrl: "#{does_not_have_storage_access_url}", - appTargetUrl: "#{app_target_url}" - }, - }, - ) -%> -
-
-
-
-
-
-
-
-
-

<%= I18n.t('request_storage_access_heading', app: ShopifyApp.configuration.application_name) %>

-
-
-

<%= I18n.t('request_storage_access_body', app: ShopifyApp.configuration.application_name) %>

-
-
-

<%= I18n.t('request_storage_access_footer') %>

-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-<%= javascript_include_tag('shopify_app/request_storage_access', crossorigin: 'anonymous', integrity: true) %> - - diff --git a/app/views/shopify_app/sessions/top_level_interaction.html.erb b/app/views/shopify_app/sessions/top_level_interaction.html.erb deleted file mode 100644 index 130bb9cbd..000000000 --- a/app/views/shopify_app/sessions/top_level_interaction.html.erb +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Redirecting… - <%= render 'shopify_app/partials/card_styles' %> - <%= render 'shopify_app/partials/layout_styles' %> - <%= render 'shopify_app/partials/typography_styles' %> - <%= render 'shopify_app/partials/button_styles' %> - <%= render 'shopify_app/partials/empty_state_styles' %> - - - <%= javascript_include_tag('shopify_app/top_level', crossorigin: 'anonymous', integrity: true) %> - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-

<%= I18n.t('top_level_interaction_heading', app: ShopifyApp.configuration.application_name) %>

-
-

<%= I18n.t('top_level_interaction_body', app: ShopifyApp.configuration.application_name) %>

-
-
-
-
-
-
-
-
-
-
- <%= image_tag 'storage_access.svg', role: "presentation", alt: "", class: "Polaris-EmptyState__Image" %> -
-
-
-
-
-
-
-
-
-
-
-
- - diff --git a/app/views/shopify_app/shared/post_redirect_to_auth_shopify.html.erb b/app/views/shopify_app/shared/post_redirect_to_auth_shopify.html.erb deleted file mode 100644 index 465f03bc3..000000000 --- a/app/views/shopify_app/shared/post_redirect_to_auth_shopify.html.erb +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Redirecting… - <%= javascript_include_tag('shopify_app/post_redirect', crossorigin: 'anonymous', integrity: true) %> - - - <%= form_tag '/auth/shopify', id: 'redirect-form' %> - - diff --git a/test/javascripts/shopify_app/itp_helper_test.js b/test/javascripts/shopify_app/itp_helper_test.js deleted file mode 100644 index 4f68e62c1..000000000 --- a/test/javascripts/shopify_app/itp_helper_test.js +++ /dev/null @@ -1,108 +0,0 @@ -suite('ITPHelper', () => { - const ITPHelperSandbox = sinon.createSandbox(); - let contentContainer; - let button; - - setup(() => { - contentContainer = document.createElement('div'); - button = document.createElement('button'); - - contentContainer.setAttribute('id', 'TopLevelInteractionContent'); - button.setAttribute('id', 'TopLevelInteractionButton'); - button.setAttribute('type', 'button'); - - contentContainer.appendChild(button); - document.body.appendChild(contentContainer); - ITPHelperSandbox.stub(ITPHelper.prototype, 'redirect'); - }); - - teardown(() => { - document.body.removeChild(contentContainer); - ITPHelperSandbox.restore(); - }); - - suite('userAgentIsAffected', () => { - test('returns false if document.hasStorageAccess is undefined', () => { - navigator.__defineGetter__('userAgent', function(){ - return ''; - }); - - document.hasStorageAccess = undefined; - - sinon.assert.match(ITPHelper.prototype.userAgentIsAffected(), false); - }); - - test('returns true if document.hasStorageAccess is defined', () => { - navigator.__defineGetter__('userAgent', function(){ - return ''; - }); - - document.hasStorageAccess = function() { - return true; - } - - sinon.assert.match(ITPHelper.prototype.userAgentIsAffected(), true); - }); - }); - - suite('canPartitionCookies', () => { - test('returns true if the user agent is a version of Safari 12.0', () => { - navigator.__defineGetter__('userAgent', function(){ - return 'Version/12.0 Safari'; - }); - - sinon.assert.match(ITPHelper.prototype.canPartitionCookies(), true); - - navigator.__defineGetter__('userAgent', function(){ - return 'Version/12.0.1 Safari'; - }); - - sinon.assert.match(ITPHelper.prototype.canPartitionCookies(), true); - }); - - test('returns false if the user agent is a version of Safari 12.0', () => { - navigator.__defineGetter__('userAgent', function(){ - return 'Version/12.1 Safari'; - }); - - sinon.assert.match(ITPHelper.prototype.canPartitionCookies(), false); - - navigator.__defineGetter__('userAgent', function(){ - return 'Version/12.1.2 Safari'; - }); - - sinon.assert.match(ITPHelper.prototype.canPartitionCookies(), false); - - navigator.__defineGetter__('userAgent', function(){ - return 'Version/11.0 Safari'; - }); - - sinon.assert.match(ITPHelper.prototype.canPartitionCookies(), false); - }); - }); - - suite('setUpContent', () => { - test('adds an event listener to the #TopLevelInteractionButton node that calls redirect on click', () => { - const helper = new ITPHelper({ - redirectUrl: 'https://test', - }); - - helper.setUpContent(); - - button = document.querySelector('#TopLevelInteractionButton'); - button.click(); - - sinon.assert.called(ITPHelper.prototype.redirect); - }); - - test('sets display property of the #TopLevelInteractionContent node to "block"', () => { - const helper = new ITPHelper({ - redirectUrl: 'https://test', - }); - - helper.setUpContent(); - contentContainer = document.querySelector('#TopLevelInteractionContent'); - sinon.assert.match(contentContainer.style.display, 'block'); - }); - }); -}); diff --git a/test/javascripts/shopify_app/storage_access_test.js b/test/javascripts/shopify_app/storage_access_test.js deleted file mode 100644 index e0af9312e..000000000 --- a/test/javascripts/shopify_app/storage_access_test.js +++ /dev/null @@ -1,306 +0,0 @@ -suite('StorageAccessHelper', () => { - const storageAccessHelperSandbox = sinon.createSandbox(); - let storageAccessHelper; - const redirectDataStub = { - hasStorageAccessUrl: 'https://hasStorageAccess.com', - doesNotHaveStorageAccessUrl: 'https://doesNotHaveStorageAccess.com', - myShopifyUrl: 'https://shop1.myshopify.io', - home: 'https://app.io', - }; - - let contentContainer; - let button; - - setup(() => { - contentContainer = document.createElement('div'); - button = document.createElement('button'); - - contentContainer.setAttribute('id', 'RequestStorageAccess'); - button.setAttribute('id', 'TriggerAllowCookiesPrompt'); - button.setAttribute('type', 'button'); - - contentContainer.appendChild(button); - document.body.appendChild(contentContainer); - storageAccessHelper = new StorageAccessHelper(redirectDataStub); - storageAccessHelperSandbox.stub(ITPHelper.prototype, 'redirect'); - }); - - teardown(() => { - document.body.removeChild(contentContainer); - storageAccessHelperSandbox.restore(); - }); - - suite('redirectToAppTLD', () => { - test('calls appBridgeRedirect with the normalized storage access link', () => { - const normalizedLink = 'some_link'; - storageAccessHelperSandbox.stub(window, 'appBridgeRedirect').callsFake(() => {}); - storageAccessHelperSandbox.stub(storageAccessHelper, 'setNormalizedLink').callsFake(() => normalizedLink); - - storageAccessHelper.redirectToAppTLD('storage_access_granted'); - - sinon.assert.calledWith( - appBridgeRedirect, - normalizedLink, - ); - }); - }); - - suite('execute', () => { - test('calls setUpCookiePartitioning if ITPHelper.canPartitionCookies returns true', () => { - storageAccessHelperSandbox.stub(ITPHelper.prototype, 'canPartitionCookies').callsFake(() => true); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'setUpCookiePartitioning'); - - storageAccessHelper.execute(); - - sinon.assert.called(storageAccessHelper.setUpCookiePartitioning); - }); - - test('calls redirectToAppTargetUrl instead of manageStorageAccess or setUpCookiePartitioningStub if ITPHelper.userAgentIsAffected returns true', async () => { - storageAccessHelperSandbox.stub(storageAccessHelper, 'sameSiteNoneIncompatible').callsFake(() => true); - storageAccessHelperSandbox.stub(ITPHelper.prototype, 'userAgentIsAffected').callsFake(() => false); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'manageStorageAccess').callsFake(() => true); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTargetUrl'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'setUpCookiePartitioning'); - - storageAccessHelper.execute(); - - sinon.assert.notCalled(storageAccessHelper.manageStorageAccess); - sinon.assert.called(storageAccessHelper.redirectToAppTargetUrl); - sinon.assert.notCalled(storageAccessHelper.setUpCookiePartitioning); - }); - - test('calls manageStorageAccess instead of redirectToAppTargetUrl if ITPHelper.userAgentIsAffected returns true', async () => { - storageAccessHelperSandbox.stub(ITPHelper.prototype, 'userAgentIsAffected').callsFake(() => true); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'manageStorageAccess').callsFake(() => true); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTargetUrl'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'setUpCookiePartitioning'); - - storageAccessHelper.execute(); - - sinon.assert.called(storageAccessHelper.manageStorageAccess); - sinon.assert.notCalled(storageAccessHelper.redirectToAppTargetUrl); - sinon.assert.notCalled(storageAccessHelper.setUpCookiePartitioning); - }); - }); - - suite('manageStorageAccess', () => { - test('calls handleHasStorageAccess instead of handleGetStorageAccess if document.hasStorageAccess returns true', async () => { - document.hasStorageAccess = () => { - return new Promise((resolve) => { - resolve(true); - }); - }; - - storageAccessHelperSandbox.stub(storageAccessHelper, 'handleGetStorageAccess'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'handleHasStorageAccess'); - - storageAccessHelper.manageStorageAccess().then(() => { - sinon.assert.called(storageAccessHelper.handleHasStorageAccess); - sinon.assert.notCalled(storageAccessHelper.handleGetStorageAccess); - }); - }); - - test('calls handleGetStorageAccess instead of handleHasStorageAccess if document.hasStorageAccess returns false', async () => { - document.hasStorageAccess = () => { - return new Promise((resolve) => { - resolve(false); - }); - }; - - storageAccessHelperSandbox.stub(storageAccessHelper, 'handleGetStorageAccess'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'handleHasStorageAccess'); - - storageAccessHelper.manageStorageAccess().then(() => { - sinon.assert.called(storageAccessHelper.handleGetStorageAccess); - sinon.assert.notCalled(storageAccessHelper.handleHasStorageAccess); - }); - }); - }); - - suite('handleGetStorageAccess', () => { - test('calls setupRequestStorageAccess instead of redirectToAppTLD if shopify.top_level_interaction is defined in sessionStorage', () => { - storageAccessHelperSandbox.stub(storageAccessHelper, 'setupRequestStorageAccess'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTLD'); - - sessionStorage.setItem('shopify.top_level_interaction', 'true'); - - storageAccessHelper.handleGetStorageAccess(); - - sinon.assert.called(storageAccessHelper.setupRequestStorageAccess); - sinon.assert.notCalled(storageAccessHelper.redirectToAppTLD); - }); - - test('calls redirectToAppTLD instead of setupRequestStorageAccess if shopify.top_level_interaction is defined in sessionStorage', () => { - storageAccessHelperSandbox.stub(storageAccessHelper, 'setupRequestStorageAccess'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTLD'); - - sessionStorage.removeItem('shopify.top_level_interaction'); - - storageAccessHelper.handleGetStorageAccess(); - - sinon.assert.notCalled(storageAccessHelper.setupRequestStorageAccess); - sinon.assert.called(storageAccessHelper.redirectToAppTLD); - }); - }); - - suite('setupRequestStorageAccess', () => { - test('adds an event listener to the expected button that calls requestStorageAccess on click', () => { - document.requestStorageAccess = () => { - return new Promise((resolve) => { - resolve(true); - }); - }; - - storageAccessHelperSandbox.spy(storageAccessHelper, 'handleRequestStorageAccess'); - - storageAccessHelper.setupRequestStorageAccess(); - button = document.querySelector('#TriggerAllowCookiesPrompt'); - button.click(); - - sinon.assert.called(storageAccessHelper.handleRequestStorageAccess); - }); - - test('sets display property of the expected node to "block"', () => { - storageAccessHelper.setupRequestStorageAccess(); - contentContainer = document.querySelector('#RequestStorageAccess'); - sinon.assert.match(contentContainer.style.display, 'block'); - }); - }); - - suite('handleRequestStorageAccess', () => { - test('calls redirectToAppTargetUrl instead of redirectToAppsIndex when document.requestStorageAccess resolves', () => { - document.requestStorageAccess = () => { - return new Promise((resolve) => { - resolve(); - }); - }; - - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTargetUrl'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppsIndex'); - - storageAccessHelper.handleRequestStorageAccess().then(() => { - sinon.assert.called(storageAccessHelper.redirectToAppTargetUrl); - sinon.assert.notCalled(storageAccessHelper.redirectToAppsIndex); - }); - }); - - test('calls redirectToAppsIndex with "storage_access_denied" instead of calling redirectToAppTargetUrl when document.requestStorageAccess fails', () => { - document.requestStorageAccess = () => { - return new Promise((resolve, reject) => { - reject(); - }); - }; - - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppTargetUrl'); - storageAccessHelperSandbox.stub(storageAccessHelper, 'redirectToAppsIndex'); - - storageAccessHelper.handleRequestStorageAccess().then(() => { - sinon.assert.notCalled(storageAccessHelper.redirectToAppTargetUrl); - sinon.assert.calledWith(storageAccessHelper.redirectToAppsIndex, 'storage_access_denied'); - }); - }); - }); - - suite('setNormalizedLink', () => { - test('returns redirectData.hasStorageAccessUrl if storage access is granted', () => { - const link = storageAccessHelper.setNormalizedLink('storage_access_granted'); - sinon.assert.match(link, redirectDataStub.hasStorageAccessUrl); - }); - - test('returns redirectData.doesNotHaveStorageAccessUrl if storage access is denied', () => { - const link = storageAccessHelper.setNormalizedLink('storage_access_denied'); - sinon.assert.match(link, redirectDataStub.doesNotHaveStorageAccessUrl); - }); - }); - - suite('setUpCookiePartitioning', () => { - test('sets the display property of the #CookiePartitionPrompt node to "block"', () => { - const node = document.createElement('div'); - node.id = 'CookiePartitionPrompt'; - node.style.display = 'none'; - - const button = document.createElement('button'); - button.type = 'button'; - button.id = 'AcceptCookies'; - - node.appendChild(button); - document.body.appendChild(node); - - storageAccessHelper.setUpCookiePartitioning(); - - sinon.assert.match(node.style.display, 'block'); - - document.body.removeChild(node); - }); - - test('adds an event listener to the #AcceptCookies button that calls setCookieAndRedirect on click', () => { - const node = document.createElement('div'); - node.id = 'CookiePartitionPrompt'; - node.style.display = 'none'; - - const button = document.createElement('button'); - button.type = 'button'; - button.id = 'AcceptCookies'; - - node.appendChild(button); - document.body.appendChild(node); - - storageAccessHelperSandbox.stub(storageAccessHelper, 'setCookieAndRedirect'); - - storageAccessHelper.setUpCookiePartitioning(); - - button.click(); - sinon.assert.called(storageAccessHelper.setCookieAndRedirect); - - document.body.removeChild(node); - }); - }); - - suite('sameSiteNoneIncompatible', () => { - test('matches the correct user agents', () => { - var incompatibleUserAgents = [ - "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/87.0.279142407 Mobile/15E148 Safari/605.1", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15", - "Mozilla/5.0 (Linux; U; Android 7.0; en-US; SM-G935F Build/NRD90M) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/11.3.8.976 U3/0.8.0 Mobile Safari/534.30", - ] - for (var i = 0; i < incompatibleUserAgents.length; i++) { - sinon.assert.match(true, storageAccessHelper.sameSiteNoneIncompatible(incompatibleUserAgents[i])) - } - }); - - test('doesnt match the same shite agents', () => { - var compatibleUserAgents = [ - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15", - ] - - for (var i = 0; i < compatibleUserAgents.length; i++) { - sinon.assert.match(false, storageAccessHelper.sameSiteNoneIncompatible(compatibleUserAgents[i])) - } - }); - }) - - suite('setCookieAndRedirect', () => { - test('sets the shopify.cookies_persist cookie', () => { - storageAccessHelperSandbox.stub(storageAccessHelper, 'sameSiteNoneIncompatible').callsFake(() => true); - storageAccessHelper.setCookieAndRedirect(); - sinon.assert.match(document.cookie.match('shopify.cookies_persist').length, 1); - }); - }); - - suite('setUpHelper', () => { - test('passes the correct redirectUrl to the ITPHelper constructor', () => { - document.body.dataset.apiKey = '123'; - document.body.dataset.shopOrigin = 'test-shop.myshopify.io'; - - const itpHelper = storageAccessHelper.setUpHelper(); - sinon.assert.match(itpHelper.redirectUrl, 'https://test-shop.myshopify.io/admin/apps/123'); - }) - }); -});