-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AG-32457 Add new scriptlet — 'trusted-set-session-storage-item'. #426
Squashed commit of the following: commit 8edeb7a Merge: 9bd05a6 b9c439e Author: Adam Wróblewski <adam@adguard.com> Date: Wed Jul 10 12:40:38 2024 +0200 Merge branch 'master' into feature/AG-32457 commit 9bd05a6 Author: Adam Wróblewski <adam@adguard.com> Date: Wed Jul 10 12:19:36 2024 +0200 Fix docs commit 5800e89 Author: Adam Wróblewski <adam@adguard.com> Date: Wed Jul 10 11:48:37 2024 +0200 Add trusted-set-session-storage-item scriptlet
- Loading branch information
Showing
5 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { | ||
hit, | ||
logMessage, | ||
nativeIsNaN, | ||
setStorageItem, | ||
parseKeywordValue, | ||
} from '../helpers/index'; | ||
|
||
/* eslint-disable max-len */ | ||
/** | ||
* @trustedScriptlet trusted-set-session-storage-item | ||
* | ||
* @description | ||
* Adds item with arbitrary key and value to sessionStorage object, or updates the value of the key if it already exists. | ||
* Scriptlet won't set item if storage is full. | ||
* | ||
* ### Syntax | ||
* | ||
* ```adblock | ||
* example.com#%#//scriptlet('trusted-set-session-storage-item', 'key', 'value') | ||
* ``` | ||
* | ||
* - `key` — required, key name to be set. | ||
* - `value` — required, key value; possible values: | ||
* - arbitrary value | ||
* - `$now$` keyword for setting current time in ms, corresponds to `Date.now()` and `(new Date).getTime()` calls | ||
* - `$currentDate$` keyword for setting string representation of the current date and time, | ||
* corresponds to `Date()` and `(new Date).toString()` calls | ||
* | ||
* ### Examples | ||
* | ||
* 1. Set session storage item | ||
* | ||
* <!-- markdownlint-disable line-length --> | ||
* | ||
* ```adblock | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.mute', 'false') | ||
* | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'COOKIE_CONSENTS', '{"preferences":3,"flag":false}') | ||
* | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'providers', '[16364,88364]') | ||
* | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'providers', '{"providers":[123,456],"consent":"all"}') | ||
* ``` | ||
* | ||
* <!-- markdownlint-enable line-length --> | ||
* | ||
* 1. Set item with current time since unix epoch in ms | ||
* | ||
* ```adblock | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.play', '$now$') | ||
* ``` | ||
* | ||
* 1. Set item with current date, e.g 'Tue Nov 08 2022 13:53:19 GMT+0300' | ||
* | ||
* ```adblock | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.play', '$currentDate$') | ||
* ``` | ||
* | ||
* 1. Set item without value | ||
* | ||
* ```adblock | ||
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'ppu_main_none', '') | ||
* ``` | ||
* | ||
* @added unknown. | ||
*/ | ||
/* eslint-enable max-len */ | ||
|
||
export function trustedSetSessionStorageItem( | ||
source: Source, | ||
key: string, | ||
value: string, | ||
) { | ||
if (typeof key === 'undefined') { | ||
logMessage(source, 'Item key should be specified'); | ||
return; | ||
} | ||
|
||
if (typeof value === 'undefined') { | ||
logMessage(source, 'Item value should be specified'); | ||
return; | ||
} | ||
|
||
const parsedValue = parseKeywordValue(value); | ||
|
||
const { sessionStorage } = window; | ||
setStorageItem(source, sessionStorage, key, parsedValue); | ||
hit(source); | ||
} | ||
|
||
trustedSetSessionStorageItem.names = [ | ||
'trusted-set-session-storage-item', | ||
// trusted scriptlets support no aliases | ||
]; | ||
|
||
trustedSetSessionStorageItem.injections = [ | ||
hit, | ||
logMessage, | ||
nativeIsNaN, | ||
setStorageItem, | ||
parseKeywordValue, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
tests/scriptlets/trusted-set-session-storage-item.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/* eslint-disable no-underscore-dangle */ | ||
import { runScriptlet, clearGlobalProps, isSafariBrowser } from '../helpers'; | ||
|
||
const { test, module } = QUnit; | ||
const name = 'trusted-set-session-storage-item'; | ||
|
||
const beforeEach = () => { | ||
window.__debug = () => { | ||
window.hit = 'FIRED'; | ||
}; | ||
}; | ||
|
||
const afterEach = () => { | ||
clearGlobalProps('hit', '__debug'); | ||
}; | ||
|
||
module(name, { beforeEach, afterEach }); | ||
|
||
const clearStorageItem = (iName) => { | ||
window.sessionStorage.removeItem(iName); | ||
}; | ||
|
||
if (isSafariBrowser()) { | ||
test('unsupported', (assert) => { | ||
assert.ok(true, 'does not work in Safari 10 while browserstack auto tests run'); | ||
}); | ||
} else { | ||
test('Set sessionStorage item', (assert) => { | ||
let iName = '__test-item_true'; | ||
let iValue = 'true'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), 'true', 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_false'; | ||
iValue = 'false'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), 'false', 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_null'; | ||
iValue = 'null'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), 'null', 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_undefined'; | ||
iValue = 'undefined'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), 'undefined', 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_emptyStr'; | ||
iValue = ''; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), '', 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_object'; | ||
iValue = '{"preferences":3,"marketing":false}'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_array'; | ||
iValue = '[1, 2, "test"]'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_string'; | ||
iValue = 'some arbitrary item value 111'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_numbers'; | ||
iValue = '123123'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
|
||
iName = '__test-item_mix'; | ||
iValue = '123string_!!:;@#$'; | ||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set'); | ||
clearStorageItem(iName); | ||
}); | ||
|
||
test('Set sessionStorage item with $now$ keyword value', (assert) => { | ||
const iName = '__test-item_now'; | ||
const iValue = '$now$'; | ||
|
||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
|
||
// Some time will pass between calling scriptlet | ||
// and qunit running assertion | ||
const tolerance = 20; | ||
const itemValue = window.sessionStorage.getItem(iName); | ||
const currentTime = Date.now(); | ||
const timeDiff = currentTime - itemValue; | ||
|
||
assert.ok(timeDiff < tolerance, 'Item value has been set to current time'); | ||
|
||
clearStorageItem(iName); | ||
}); | ||
|
||
test('Set sessionStorage item with $currentDate$ keyword value', (assert) => { | ||
const iName = '__test-item_current_date'; | ||
const iValue = '$currentDate$'; | ||
|
||
runScriptlet(name, [iName, iValue]); | ||
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired'); | ||
|
||
const value = sessionStorage.getItem(iName); | ||
const currentDate = new Date(); | ||
const currentYear = currentDate.getFullYear(); | ||
const currentMonth = currentDate.getMonth(); | ||
const currentHour = currentDate.getHours(); | ||
|
||
const currentValue = new Date(value); | ||
|
||
assert.strictEqual(currentValue.getFullYear(), currentYear, 'Year matched'); | ||
assert.strictEqual(currentValue.getMonth(), currentMonth, 'Month matched'); | ||
assert.strictEqual(currentValue.getHours(), currentHour, 'Hour matched'); | ||
|
||
clearStorageItem(iName); | ||
}); | ||
} |