Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
20
gaia/apps/settings/test/unit/.jshintrc
Executable file
20
gaia/apps/settings/test/unit/.jshintrc
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"predef": [
|
||||
"assert",
|
||||
"suite",
|
||||
"test",
|
||||
"define",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"require",
|
||||
"requireApp",
|
||||
"testRequire",
|
||||
"sinon",
|
||||
"mocha",
|
||||
"loadBodyHTML",
|
||||
"Promise"
|
||||
]
|
||||
}
|
||||
7
gaia/apps/settings/test/unit/_achievements.html
Executable file
7
gaia/apps/settings/test/unit/_achievements.html
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
<gaia-header action="back" data-href="#root">
|
||||
<h1 data-l10n-id="achievements"></h1>
|
||||
</gaia-header>
|
||||
|
||||
<div>
|
||||
<ul class="achievements-list"></ul>
|
||||
</div>
|
||||
14
gaia/apps/settings/test/unit/_addons.html
Executable file
14
gaia/apps/settings/test/unit/_addons.html
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
<gaia-header action="back" data-href="#root">
|
||||
<h1 data-l10n-id="addons-header"></h1>
|
||||
</gaia-header>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<a class="menu-item get-more-addons" href="#">
|
||||
<span></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="addon-list"></ul>
|
||||
</div>
|
||||
22
gaia/apps/settings/test/unit/_application_storage.html
Executable file
22
gaia/apps/settings/test/unit/_application_storage.html
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<progress class="apps-space-bar" min="0" value="0" max="100"></progress>
|
||||
</li>
|
||||
<li>
|
||||
<a> Total Space
|
||||
<span class="apps-total-space"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a> Used
|
||||
<span class="apps-used-space"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a> Left
|
||||
<span class="apps-free-space"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
21
gaia/apps/settings/test/unit/_browsing_privacy.html
Executable file
21
gaia/apps/settings/test/unit/_browsing_privacy.html
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
<gaia-header action="back" data-href="#root">
|
||||
<h1 data-l10n-id="browsingPrivacy-header"></h1>
|
||||
</gaia-header>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="clear-history-button"
|
||||
data-l10n-id="clear-browsing-history">
|
||||
Clear browsing history
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="clear-private-data-button"
|
||||
data-l10n-id="clear-cookies-and-stored-data">
|
||||
Clear cookies and stored data
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
56
gaia/apps/settings/test/unit/_call_barring.html
Executable file
56
gaia/apps/settings/test/unit/_call_barring.html
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
<gaia-header action="back" data-href="#root">
|
||||
<h1 data-l10n-id="callBarring-header"></h1>
|
||||
</gaia-header>
|
||||
|
||||
<div>
|
||||
<header id="header-cb-outgoing">
|
||||
<h2 data-l10n-id="callBarring-outgoing"> Outgoing calls </h2>
|
||||
</header>
|
||||
<ul id="list-callBarring-outgoing">
|
||||
<li id="li-cb-baoc" data-state="off">
|
||||
<gaia-switch>
|
||||
<label data-l10n-id="callBarring-baoc">All</label>
|
||||
<details id="baoc-desc"></details>
|
||||
</label>
|
||||
</li>
|
||||
<li id="li-cb-boic" data-state="off">
|
||||
<gaia-switch>
|
||||
<label data-l10n-id="callBarring-boic">International</label>
|
||||
<details id="boic-desc"></details>
|
||||
</label>
|
||||
</li>
|
||||
<li id="li-cb-boicExhc" data-state="off">
|
||||
<gaia-switch>
|
||||
<label data-l10n-id="callBarring-boicExhc">International except Home Country</label>
|
||||
<details id="boicExhc-desc"></details>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header id="header-cb-incoming">
|
||||
<h2 data-l10n-id="callBarring-incoming"> Incoming calls </h2>
|
||||
</header>
|
||||
<ul id="list-callBarring-incoming">
|
||||
<li id="li-cb-baic" data-state="off">
|
||||
<gaia-switch>
|
||||
<label data-l10n-id="callBarring-baic">All</label>
|
||||
<details id="baic-desc"></details>
|
||||
</label>
|
||||
</li>
|
||||
<li id="li-cb-baicR" data-state="off">
|
||||
<gaia-switch>
|
||||
<label data-l10n-id="callBarring-baicR">All while roaming</label>
|
||||
<details id="bairR-desc"></details>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header id="header-cb-passcode">
|
||||
<h2 data-l10n-id="callBarring-passcode"> Passcode </h2>
|
||||
</header>
|
||||
<ul id="list-callBarring-passcode">
|
||||
<li id="li-cb-pswd">
|
||||
<a class="bb-button" data-href="#call-barring-passcode-change" data-l10n-id="callBarring-change-passcode">Change passcode</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
22
gaia/apps/settings/test/unit/_call_fdn_settings.html
Executable file
22
gaia/apps/settings/test/unit/_call_fdn_settings.html
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<gaia-menu hidden class="call-fdnList-action">
|
||||
<button class="fdnContact"></button>
|
||||
<button class="fdnAction-call"></button>
|
||||
<button class="fdnAction-edit"></button>
|
||||
</gaia-menu>
|
||||
<button class="fdnAction-delete"></button>
|
||||
<li class="fdn-enabled">
|
||||
<gaia-switch>
|
||||
<label></label>
|
||||
<details></details>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
<li class="fdn-resetPIN2">
|
||||
<label>
|
||||
<button type="checkbox"></button>
|
||||
</label>
|
||||
</li>
|
||||
<button class="fdnContact-submit"></button>
|
||||
<h1 class="fdnContact-title"></h1>
|
||||
<input class="fdnContact-name"/>
|
||||
<input class="fdnContact-number"/>
|
||||
|
||||
51
gaia/apps/settings/test/unit/_date_time.html
Executable file
51
gaia/apps/settings/test/unit/_date_time.html
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
<div>
|
||||
<ul class="time-auto"></ul>
|
||||
<ul class="time-manual">
|
||||
<li>
|
||||
<label>
|
||||
<input type="date" class="date-picker" min="1970-1-1" max="2037-12-31"/>
|
||||
</label>
|
||||
<span class="clock-date"></span>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="time" class="time-picker" />
|
||||
</label>
|
||||
<span class="clock-time"></span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="timezone">
|
||||
<li class="timezone-picker">
|
||||
<span class="button icon icon-dialog">
|
||||
<select class="timezone-region"></select>
|
||||
</span>
|
||||
</li>
|
||||
<li class="timezone-picker">
|
||||
<span class="button icon icon-dialog">
|
||||
<select class="timezone-city"></select>
|
||||
</span>
|
||||
</li>
|
||||
<li class="timezone-info" hidden>
|
||||
<span class="timezone-info-text"></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header>
|
||||
<h2 data-l10n-id="time-format"></h2>
|
||||
</header>
|
||||
<ul class="time-format-auto" data-state="auto">
|
||||
<li>
|
||||
<gaia-switch checked>
|
||||
<label data-l10n-id="useDefaultTimeFormat"></label>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="timeformat disabled">
|
||||
<li>
|
||||
<p data-l10n-id="time-format-time"></p>
|
||||
<span class="button icon icon-dialog">
|
||||
<select class="time-format-time"></select>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
31
gaia/apps/settings/test/unit/_developer.html
Executable file
31
gaia/apps/settings/test/unit/_developer.html
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
<div>
|
||||
<ul>
|
||||
<li class="software-home-button">
|
||||
<gaia-checkbox name="software-button.enabled">
|
||||
<label data-l10n-id="software-home-button"></label>
|
||||
</gaia-checkbox>
|
||||
</li>
|
||||
<li class="homegesture">
|
||||
<gaia-checkbox name="homegesture.enabled">
|
||||
<label data-l10n-id="home-gesture"></label>
|
||||
</gaia-checkbox>
|
||||
</li>
|
||||
<li>
|
||||
<gaia-checkbox class="homescreen-paging">
|
||||
<label data-l10n-id="homescreen-paging"></label>
|
||||
</gaia-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="ftuLauncher" data-l10n-id="launch-ftu"></button>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<gaia-switch name="devtools.unrestricted" class="reset-devtools">
|
||||
<label data-l10n-id="full-devtools"></label>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
6
gaia/apps/settings/test/unit/_display.html
Executable file
6
gaia/apps/settings/test/unit/_display.html
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
<div>
|
||||
<ul>
|
||||
<li class="brightness-auto"></li>
|
||||
<li class="brightness-manual"></li>
|
||||
</ul>
|
||||
</div>
|
||||
91
gaia/apps/settings/test/unit/_firefox_sync.html
Executable file
91
gaia/apps/settings/test/unit/_firefox_sync.html
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
<gaia-header action="back" data-href="#root">
|
||||
<h1 data-l10n-id="fxsync"></h1>
|
||||
</gaia-header>
|
||||
|
||||
<div class="fxsync-logged-out" hidden>
|
||||
<ul role="presentation">
|
||||
<li role="presentation" class="description">
|
||||
<div class="fxsync-intro"></div>
|
||||
<p data-l10n-id="fxsync-overview" id="fxsync-logged-out-description"></p>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<button class="recommend fxsync-login">
|
||||
<span data-l10n-id="fxsync-get-started"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fxsync-logged-in" hidden>
|
||||
<ul role="presentation">
|
||||
<li role="presentation">
|
||||
<p class="description" data-l10n-id="fxsync-sync-user"></p>
|
||||
<p class="explanation">
|
||||
<span class="fxsync-user"></span>
|
||||
</p>
|
||||
</li>
|
||||
<li role="presentation" class="fxsync-unverified description" hidden>
|
||||
<p class="fxsync-warning" data-l10n-id="fxa-please-verify"></p>
|
||||
</li>
|
||||
<li role="presentation" class="fxsync-empty-account description" hidden>
|
||||
<p class="fxsync-warning" data-l10n-id="fxsync-empty-account"></p>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<label>
|
||||
<button class="fxsync-logout">
|
||||
<span data-l10n-id="fxsync-disable"></span>
|
||||
</button>
|
||||
</label>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<button class="fxsync-sync-now" data-l10n-id="fxsync-sync-now"></button>
|
||||
<p class="explanation fxsync-last-sync hidden">
|
||||
<span data-l10n-id="fxsync-last-synced"></span>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header>
|
||||
<h2 data-l10n-id="fxsync-collections">Collections</h2>
|
||||
</header>
|
||||
<ul role="presentation">
|
||||
<li role="presentation" hidden>
|
||||
<gaia-switch class="fxsync-collections-bookmarks"
|
||||
name="sync.collections.bookmarks.enabled">
|
||||
<label data-l10n-id="fxsync-collections-bookmarks"></label>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<gaia-switch class="fxsync-collections-history"
|
||||
name="sync.collections.history.enabled">
|
||||
<label data-l10n-id="fxsync-collections-history"></label>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
<li role="presentation" hidden>
|
||||
<gaia-switch class="fxsync-collections-passwords"
|
||||
name="sync.collections.passwords.enabled">
|
||||
<label data-l10n-id="fxsync-collections-passwords"></label>
|
||||
</gaia-switch>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header>
|
||||
<h2 data-l10n-id="fxsync-legal"></h2>
|
||||
</header>
|
||||
<ul role="presentation">
|
||||
<li role="presentation">
|
||||
<label>
|
||||
<button class="fxsync-tos">
|
||||
<span data-l10n-id="fxsync-tos"></span>
|
||||
</button>
|
||||
</label>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<label>
|
||||
<button class="fxsync-privacy">
|
||||
<span data-l10n-id="fxsync-privacy"></span>
|
||||
</button>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
15
gaia/apps/settings/test/unit/_full_developer_mode.html
Executable file
15
gaia/apps/settings/test/unit/_full_developer_mode.html
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
<div class="full-dev-mode-warning" hidden>
|
||||
<gaia-confirm>
|
||||
<gaia-buttons>
|
||||
<button type="reset"></button>
|
||||
<button type="submit"></button>
|
||||
</gaia-buttons>
|
||||
</gaia-confirm>
|
||||
</div>
|
||||
<div class="dev-menu-disabled-warning" hidden>
|
||||
<gaia-confirm>
|
||||
<gaia-buttons>
|
||||
<button type="submit"></button>
|
||||
</gaia-buttons>
|
||||
</gaia-confirm>
|
||||
</div>
|
||||
9
gaia/apps/settings/test/unit/_full_developer_mode_final_warning.html
Executable file
9
gaia/apps/settings/test/unit/_full_developer_mode_final_warning.html
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<div class="warning-dialog">
|
||||
<gaia-confirm>
|
||||
<p class="warning-info"></p>
|
||||
<gaia-buttons>
|
||||
<button type="reset"></button>
|
||||
<button type="submit"></button>
|
||||
</gaia-buttons>
|
||||
</gaia-confirm>
|
||||
</div>
|
||||
9
gaia/apps/settings/test/unit/_homescreens.html
Executable file
9
gaia/apps/settings/test/unit/_homescreens.html
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<div>
|
||||
<div class="wallpaper">
|
||||
<img class="wallpaper-preview"/>
|
||||
</div>
|
||||
<select name="grid.layout.cols"></select>
|
||||
<div>
|
||||
<span class="current-homescreen"></span>
|
||||
</div>
|
||||
</div>
|
||||
24
gaia/apps/settings/test/unit/_improve_browser_os.html
Executable file
24
gaia/apps/settings/test/unit/_improve_browser_os.html
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
<div>
|
||||
<li>
|
||||
<a id="appUsageByRegion">
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<gaia-radio name="metricsGroup" id="metrics-basic" value="Basic">
|
||||
<label data-l10n-id="basicMetricsRadio"></label>
|
||||
<p data-l10n-id="basicMetricsExplain" class="metrics-explain"></p>
|
||||
</gaia-radio>
|
||||
</li>
|
||||
<li>
|
||||
<gaia-radio name="metricsGroup" id="metrics-enhanced" value="Enhanced">
|
||||
<label data-l10n-id="enhancedMetricsRadio"></label>
|
||||
<p data-l10n-id="enhancedMetricsExplain" class="metrics-explain"></p>
|
||||
</gaia-radio>
|
||||
</li>
|
||||
<li>
|
||||
<gaia-radio name="metricsGroup" id="metrics-none" value="None">
|
||||
<label data-l10n-id="noneMetricsRadio"></label>
|
||||
<p data-l10n-id="noneMetricsExplain" class="metrics-explain"></p>
|
||||
</gaia-radio>
|
||||
</li>
|
||||
</div>
|
||||
19
gaia/apps/settings/test/unit/_root.html
Executable file
19
gaia/apps/settings/test/unit/_root.html
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
<div id="root">
|
||||
<gaia-header id="main-header">
|
||||
<h1 id="main-list-title"></h1>
|
||||
<a id="activityDoneButton"></a>
|
||||
</gaia-header>
|
||||
<li id="call-settings"></li>
|
||||
<li id="data-connectivity"></li>
|
||||
<li id="messaging-settings"></li>
|
||||
<li id="simSecurity-settings"></li>
|
||||
<li id="simCardManager-settings"></li>
|
||||
<li><a class="menuItem-bluetooth"</a></li>
|
||||
<li class="nfc-settings" hidden></li>
|
||||
<small id="fxa-desc" class="menu-item-desc"></small>
|
||||
<a id="menuItem-fxa" class="menu-item" href="#fxa">Firefox Accounts</a>
|
||||
<header id="icc-mainheader"></header>
|
||||
<ul id="icc-entries"></ul>
|
||||
<span id="menuItem-enableStorage"></span>
|
||||
<li data-show-name="developer.menu.enabled" hidden></li>
|
||||
</div>
|
||||
36
gaia/apps/settings/test/unit/_send_feedback.html
Executable file
36
gaia/apps/settings/test/unit/_send_feedback.html
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
<gaia-header action="back" id="feedback-header">
|
||||
<h1 id="feedback-title"></h1>
|
||||
</gaia-header>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<textarea id="feedback-description" name="description" x-inputmode="latin-prose" dir="auto"></textarea>
|
||||
</li>
|
||||
<li>
|
||||
<input id="email-enable" type="checkbox" />
|
||||
</li>
|
||||
<li id="feedback-emailbar" class="description" hidden="false">
|
||||
<input id="feedback-email" type="email" />
|
||||
</li>
|
||||
<li>
|
||||
<button id="feedback-send-btn" data-l10n-id="feedback-sendbtn"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<form role="dialog" data-type="confirm" hidden id="feedback-alert">
|
||||
<section>
|
||||
<p>
|
||||
<strong id="feedback-alert-msg"></strong>
|
||||
</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button class="full" id="feedback-alert-btn" data-l10n-id="ok">OK</button>
|
||||
</menu>
|
||||
</form>
|
||||
<form role="dialog" data-type="confirm" hidden id="feedback-done">
|
||||
<section>
|
||||
</section>
|
||||
<menu>
|
||||
<button id="feedback-done-btn" class="full" data-l10n-id="done"></button>
|
||||
</menu>
|
||||
</form>
|
||||
6
gaia/apps/settings/test/unit/_themes.html
Executable file
6
gaia/apps/settings/test/unit/_themes.html
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
<div id="themes">
|
||||
<div>
|
||||
<ul class="theme-list">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
31
gaia/apps/settings/test/unit/_wifi_utils.html
Executable file
31
gaia/apps/settings/test/unit/_wifi_utils.html
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
<div id="wifi-auth">
|
||||
<div>
|
||||
<input type="text" name="identity">
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="password">
|
||||
</div>
|
||||
<div>
|
||||
<li class="auth-phase2">
|
||||
<select></select>
|
||||
</li>
|
||||
</div>
|
||||
<div>
|
||||
<li class="server-certificate">
|
||||
<select></select>
|
||||
</li>
|
||||
</div>
|
||||
<li class="eap">
|
||||
<select>
|
||||
<option value="SIM"></option>
|
||||
<option value="PEAP"></option>
|
||||
<option value="TLS"></option>
|
||||
<option value="TTLS"></option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="server-certificate-description"></li>
|
||||
</div>
|
||||
<div id="wifi">
|
||||
<ul class="wifi-availableNetworks">
|
||||
</ul>
|
||||
</div>
|
||||
195
gaia/apps/settings/test/unit/activity_handler_test.js
Executable file
195
gaia/apps/settings/test/unit/activity_handler_test.js
Executable file
|
|
@ -0,0 +1,195 @@
|
|||
/* global ActivityHandler */
|
||||
'use strict';
|
||||
|
||||
require('/js/activity_handler.js');
|
||||
mocha.globals(['ActivityHandler']);
|
||||
|
||||
suite('ActivityHandler', function() {
|
||||
var originalMozSetMessageHandler;
|
||||
var originalMozMobileConnections;
|
||||
|
||||
suiteSetup(function() {
|
||||
originalMozSetMessageHandler = navigator.mozSetMessageHandler;
|
||||
originalMozMobileConnections = navigator.mozMobileConnections;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
navigator.mozSetMessageHandler = function() {};
|
||||
navigator.mozMobileConnections = [{}, {}];
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozSetMessageHandler = originalMozSetMessageHandler;
|
||||
navigator.mozMobileConnections = originalMozMobileConnections;
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
ActivityHandler._readyPromise = null;
|
||||
ActivityHandler._targetPanel = null;
|
||||
ActivityHandler._currentActivity = null;
|
||||
});
|
||||
|
||||
suite('ready', function() {
|
||||
test('has pending messages', function(done) {
|
||||
var mockSectionId = 'mockSection';
|
||||
var mockActivity = {
|
||||
source: {
|
||||
data: {
|
||||
section: mockSectionId
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.sinon.stub(navigator, 'mozSetMessageHandler',
|
||||
function(name, callback) {
|
||||
callback(mockActivity);
|
||||
});
|
||||
this.sinon.stub(ActivityHandler, '_handleActivity', function() {
|
||||
return { targetPanelId: mockSectionId };
|
||||
});
|
||||
this.sinon.stub(ActivityHandler, '_registerListener');
|
||||
|
||||
ActivityHandler.ready().then(function() {
|
||||
assert.ok(navigator.mozSetMessageHandler.called,
|
||||
'mozSetMessageHandler should be called');
|
||||
assert.ok(ActivityHandler._handleActivity.calledWith(
|
||||
mockActivity.source), '_handleActivity should be called');
|
||||
assert.ok(ActivityHandler._registerListener.called,
|
||||
'_registerListener should be called');
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_handleActivity', function() {
|
||||
var mockSectionId = 'mockSection';
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(ActivityHandler._handlers, 'configure', function() {
|
||||
return { targetPanelId: mockSectionId };
|
||||
});
|
||||
});
|
||||
|
||||
test('should call to corresponding handler and set _targetPanelId ' +
|
||||
'correctly', function() {
|
||||
var mockActivitySource = {
|
||||
name: 'configure'
|
||||
};
|
||||
ActivityHandler._handleActivity(mockActivitySource);
|
||||
assert.equal(ActivityHandler._targetPanelId, mockSectionId);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_handlers', function() {
|
||||
suite('configure', function() {
|
||||
var handler;
|
||||
var mockSectionId = 'mockSection';
|
||||
var mockOptions = { option: 'test' };
|
||||
var mockSection;
|
||||
|
||||
setup(function() {
|
||||
handler = ActivityHandler._handlers.configure;
|
||||
mockSection = document.createElement('section');
|
||||
mockSection.id = mockSectionId;
|
||||
document.body.appendChild(mockSection);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('without section specified', function() {
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: null
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === 'root', 'should return "root"');
|
||||
});
|
||||
|
||||
test('with section other than root specified', function() {
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: mockSectionId
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === mockSectionId,
|
||||
'should return the specified section id');
|
||||
assert.ok(mockSection.dataset.dialog, 'the dialog mode should be set');
|
||||
});
|
||||
|
||||
test('with section other than root and options specified', function() {
|
||||
var {targetPanelId, options} = handler({
|
||||
data: {
|
||||
section: mockSectionId,
|
||||
options: mockOptions
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === mockSectionId,
|
||||
'should return the specified section id');
|
||||
assert.ok(options === mockOptions,
|
||||
'should return the specified options');
|
||||
assert.ok(mockSection.dataset.dialog, 'the dialog mode should be set');
|
||||
});
|
||||
|
||||
test('with root specified but without filter by', function() {
|
||||
var rootSection = document.createElement('section');
|
||||
rootSection.id = 'root';
|
||||
document.body.appendChild(rootSection);
|
||||
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: 'root'
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === 'root', 'should "return root"');
|
||||
assert.ok(document.body.dataset.filterBy === 'all',
|
||||
'body.filterBy should be set');
|
||||
});
|
||||
|
||||
test('with root specified and with filter by', function() {
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: 'root',
|
||||
filterBy: 'connectivity'
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === 'root', 'should "return root"');
|
||||
assert.ok(document.body.dataset.filterBy === 'connectivity',
|
||||
'body.filterBy should be set');
|
||||
});
|
||||
|
||||
test('with invalid section id specified', function() {
|
||||
var rootSection = document.createElement('section');
|
||||
rootSection.id = 'root';
|
||||
document.body.appendChild(rootSection);
|
||||
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: 'invalid'
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === 'root', 'should "return root"');
|
||||
assert.ok(document.body.dataset.filterBy === 'all',
|
||||
'body.filterBy should be set');
|
||||
});
|
||||
|
||||
test('with valid section id but invalid section element', function() {
|
||||
var invalidSection = document.createElement('div');
|
||||
invalidSection.id = 'valid';
|
||||
document.body.appendChild(invalidSection);
|
||||
|
||||
var {targetPanelId} = handler({
|
||||
data: {
|
||||
section: 'valid'
|
||||
}
|
||||
});
|
||||
assert.ok(targetPanelId === 'root', 'should "return root"');
|
||||
assert.ok(document.body.dataset.filterBy === 'all',
|
||||
'body.filterBy should be set');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
264
gaia/apps/settings/test/unit/airplane_mode_helper_test.js
Executable file
264
gaia/apps/settings/test/unit/airplane_mode_helper_test.js
Executable file
|
|
@ -0,0 +1,264 @@
|
|||
/* global MockNavigatorSettings, AirplaneModeHelper, Promise
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
requireApp(
|
||||
'settings/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
|
||||
suite('AirplaneModeHelper > ', function() {
|
||||
var realMozSettings;
|
||||
var kEventName = 'statechange';
|
||||
var kCommunicationKey = 'airplaneMode.enabled';
|
||||
var kStatusKey = 'airplaneMode.status';
|
||||
|
||||
suiteSetup(function() {
|
||||
realMozSettings = window.navigator.mozSettings;
|
||||
window.navigator.mozSettings = MockNavigatorSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.navigator.mozSettings = realMozSettings;
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
window.navigator.mozSettings.mTeardown();
|
||||
AirplaneModeHelper._callbacks = [];
|
||||
// After |mozSettings.mTeardown| is called, observers are cleared, we
|
||||
// need to re-initialize the AirplaneModeHelper to add them back.
|
||||
AirplaneModeHelper.init();
|
||||
});
|
||||
|
||||
suite('init > ', function() {
|
||||
setup(function(done) {
|
||||
this.sinon.spy(navigator.mozSettings, 'addObserver');
|
||||
require('/shared/js/airplane_mode_helper.js', done);
|
||||
});
|
||||
|
||||
test('we added observers on ' + kStatusKey, function() {
|
||||
assert.isFunction(navigator.mozSettings.mObservers[kStatusKey][0]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('ready > ', function() {
|
||||
var fakeCallback = sinon.spy();
|
||||
|
||||
suite('without _cachedStatus', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = '';
|
||||
this.sinon.stub(AirplaneModeHelper, 'addEventListener');
|
||||
AirplaneModeHelper.ready(fakeCallback);
|
||||
});
|
||||
test('we would register on eventListener', function() {
|
||||
assert.ok(AirplaneModeHelper.addEventListener.called);
|
||||
assert.isFalse(fakeCallback.called);
|
||||
});
|
||||
});
|
||||
suite('with _cachedStatus', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'enabled';
|
||||
AirplaneModeHelper.ready(fakeCallback);
|
||||
});
|
||||
test('we would execute the callback directly', function() {
|
||||
assert.ok(fakeCallback.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('invoked times', function() {
|
||||
function runTestSuite(withCachedStatus) {
|
||||
return function() {
|
||||
var readyCallback = sinon.spy();
|
||||
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus =
|
||||
withCachedStatus ? 'disabled' : '';
|
||||
AirplaneModeHelper.ready(readyCallback);
|
||||
});
|
||||
|
||||
test('we would execute the callback only once', function(done) {
|
||||
function updateSettings(enabled, status) {
|
||||
return new Promise(function(resolve) {
|
||||
var obj = {};
|
||||
obj[kCommunicationKey] = enabled;
|
||||
obj[kStatusKey] = status;
|
||||
var req = window.navigator.mozSettings.createLock().set(obj);
|
||||
req.onsuccess = function() {
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Enable airplane mode.
|
||||
updateSettings(true, 'enabled').then(function() {
|
||||
// Disable airplane mode.
|
||||
return updateSettings(false, 'disabled');
|
||||
}).then(function() {
|
||||
assert.isTrue(readyCallback.calledOnce);
|
||||
}).then(done, done);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
suite('with _cachedStatus', runTestSuite(true));
|
||||
suite('without _cachedStatus', runTestSuite(false));
|
||||
});
|
||||
});
|
||||
|
||||
suite('getStatus > ', function() {
|
||||
var fakeStatus;
|
||||
setup(function() {
|
||||
fakeStatus = 'disabling';
|
||||
AirplaneModeHelper._cachedStatus = fakeStatus;
|
||||
});
|
||||
test('getCurrentStatus returns right status', function() {
|
||||
assert.equal(AirplaneModeHelper.getStatus(), fakeStatus);
|
||||
});
|
||||
});
|
||||
|
||||
suite('addEventListener > ', function() {
|
||||
var fakeEventName = 'thisIsFakeEventName';
|
||||
var fakeCallback = function() {};
|
||||
|
||||
setup(function() {
|
||||
AirplaneModeHelper._callbacks = [];
|
||||
});
|
||||
|
||||
suite('add event with wrong keyword', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper.addEventListener(fakeEventName, fakeCallback);
|
||||
});
|
||||
test('can\'t add callbacks', function() {
|
||||
assert.equal(AirplaneModeHelper._callbacks.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
suite('add event with right keyword', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper.addEventListener(kEventName, fakeCallback);
|
||||
});
|
||||
test('can add callbacks', function() {
|
||||
assert.equal(AirplaneModeHelper._callbacks.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('removeEventListener > ', function() {
|
||||
var fakeEventName = 'thisIsFakeEventName';
|
||||
var fakeCallback = function() {};
|
||||
|
||||
setup(function() {
|
||||
AirplaneModeHelper._callbacks = [fakeCallback];
|
||||
});
|
||||
|
||||
suite('remove event with wrong keyword', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper.removeEventListener(fakeEventName, fakeCallback);
|
||||
});
|
||||
test('can\'t remove callbacks', function() {
|
||||
assert.equal(AirplaneModeHelper._callbacks.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
suite('remove event with right keyword', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper.removeEventListener(kEventName, fakeCallback);
|
||||
});
|
||||
test('can remove callbacks', function() {
|
||||
assert.equal(AirplaneModeHelper._callbacks.length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('setEnabled > ', function() {
|
||||
suite('we would call ready first', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(AirplaneModeHelper, 'ready');
|
||||
AirplaneModeHelper._cachedStatus = 'enabled';
|
||||
AirplaneModeHelper.setEnabled(true);
|
||||
});
|
||||
test('to make sure _cachedStatus is ready', function() {
|
||||
assert.ok(AirplaneModeHelper.ready.called);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(true) when enabling', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'enabling';
|
||||
AirplaneModeHelper.setEnabled(true);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(false) when enabling', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'enabling';
|
||||
AirplaneModeHelper.setEnabled(false);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(true) when disabling', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'disabling';
|
||||
AirplaneModeHelper.setEnabled(true);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(false) when disabling', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'disabling';
|
||||
AirplaneModeHelper.setEnabled(false);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(true) when enabled', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'enabled';
|
||||
AirplaneModeHelper.setEnabled(true);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(false) when disabled', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'disabled';
|
||||
AirplaneModeHelper.setEnabled(false);
|
||||
});
|
||||
test('will do nothing', function() {
|
||||
assert.isUndefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(true) when disabled', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'disabled';
|
||||
AirplaneModeHelper.setEnabled(true);
|
||||
});
|
||||
test('will change airplane mode status', function() {
|
||||
assert.isDefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
suite('setEnabled(false) when enabled', function() {
|
||||
setup(function() {
|
||||
AirplaneModeHelper._cachedStatus = 'enabled';
|
||||
AirplaneModeHelper.setEnabled(false);
|
||||
});
|
||||
test('will change airplane mode status', function() {
|
||||
assert.isDefined(
|
||||
window.navigator.mozSettings.mSettings[kCommunicationKey]);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
93
gaia/apps/settings/test/unit/app_starter_test.js
Executable file
93
gaia/apps/settings/test/unit/app_starter_test.js
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
/* global AppStarter, MockL10n */
|
||||
'use strict';
|
||||
require('/shared/test/unit/mocks/mock_l20n.js');
|
||||
|
||||
mocha.globals([
|
||||
'InitialPanelHandler',
|
||||
'LaunchContext',
|
||||
'ActivityHandler'
|
||||
]);
|
||||
|
||||
Object.defineProperty(document, 'readyState', {
|
||||
value: 'loading',
|
||||
configurable: true
|
||||
});
|
||||
require('/js/startup.js');
|
||||
|
||||
suite('AppStarter', function() {
|
||||
var appStarter, realL10n;
|
||||
|
||||
suiteSetup(function() {
|
||||
realL10n = document.l10n;
|
||||
document.l10n = MockL10n;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
document.l10n = realL10n;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
appStarter = AppStarter();
|
||||
});
|
||||
|
||||
suite('start', function() {
|
||||
var fakeInitialPanelId = 'fakePanelId';
|
||||
var fakeInitialPanelHandler = {};
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(appStarter, '_getInitialPanelId', function() {
|
||||
return Promise.resolve(fakeInitialPanelId);
|
||||
});
|
||||
this.sinon.stub(appStarter, '_showInitialPanel');
|
||||
this.sinon.stub(appStarter, '_createLaunchContext');
|
||||
this.sinon.stub(appStarter, '_loadAlameda');
|
||||
|
||||
this.sinon.stub(window, 'InitialPanelHandler', function() {
|
||||
return fakeInitialPanelHandler;
|
||||
});
|
||||
});
|
||||
|
||||
test('should show correct initial panel', function(done) {
|
||||
appStarter.start().then(function() {
|
||||
sinon.assert.calledWith(
|
||||
appStarter._showInitialPanel, fakeInitialPanelId);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false, 'panel does not called with the correct panel id');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should define launch context correctly', function(done) {
|
||||
var fakeActivityHandler = {};
|
||||
var realActivityHandler = window.ActivityHandler;
|
||||
window.ActivityHandler = fakeActivityHandler;
|
||||
|
||||
appStarter.start().then(function() {
|
||||
sinon.assert.calledWith(
|
||||
appStarter._createLaunchContext, fakeInitialPanelId,
|
||||
fakeInitialPanelHandler, fakeActivityHandler);
|
||||
window.ActivityHandler = realActivityHandler;
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false, 'launch context is not defined correctly');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should load alameda', function(done) {
|
||||
appStarter.start().then(function() {
|
||||
sinon.assert.called(appStarter._loadAlameda);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false, 'failed to load alameda');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should only be executed once', function() {
|
||||
this.sinon.spy(appStarter._getInitialPanelId);
|
||||
appStarter.start();
|
||||
appStarter.start();
|
||||
|
||||
sinon.assert.calledOnce(appStarter._getInitialPanelId);
|
||||
});
|
||||
});
|
||||
});
|
||||
99
gaia/apps/settings/test/unit/firefox_accounts_menu_test.js
Executable file
99
gaia/apps/settings/test/unit/firefox_accounts_menu_test.js
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
/* globals FxaMenu, loadBodyHTML, MockFxAccountsIACHelper, MockL10n */
|
||||
|
||||
'use strict';
|
||||
|
||||
// require helpers for managing html
|
||||
require('/shared/test/unit/load_body_html_helper.js');
|
||||
require('/shared/js/html_imports.js');
|
||||
|
||||
// mocks and globals
|
||||
require('mock_fx_accounts_iac_helper.js');
|
||||
require('/shared/js/text_normalizer.js');
|
||||
require('/shared/test/unit/mocks/mock_l20n.js');
|
||||
|
||||
// source the code we care about
|
||||
requireApp('settings/js/firefox_accounts/menu.js');
|
||||
|
||||
suite('firefox accounts menu item > ', function() {
|
||||
var suiteSandbox = sinon.sandbox.create(),
|
||||
fxaDescEl,
|
||||
setAttributesSpy,
|
||||
realL10n;
|
||||
|
||||
suiteSetup(function() {
|
||||
// attach mock html to page, so it inits without complaint
|
||||
loadBodyHTML('./_root.html');
|
||||
realL10n = document.l10n;
|
||||
document.l10n = MockL10n;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
suiteSandbox.restore();
|
||||
document.l10n = realL10n;
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
setAttributesSpy = sinon.spy(document.l10n, 'setAttributes');
|
||||
fxaDescEl = document.getElementById('fxa-desc');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockFxAccountsIACHelper.resetListeners();
|
||||
document.l10n.setAttributes.restore();
|
||||
});
|
||||
|
||||
test('check the html loaded correctly', function() {
|
||||
assert.isNotNull(fxaDescEl, 'failed to load settings page html');
|
||||
});
|
||||
|
||||
test('show the correct status on FxaMenu init', function() {
|
||||
MockFxAccountsIACHelper.setCurrentState({
|
||||
email: 'init@ialization.com',
|
||||
verified: true
|
||||
});
|
||||
// init app code
|
||||
FxaMenu.init(MockFxAccountsIACHelper);
|
||||
// test setAttributes was called with correct args
|
||||
assert.deepEqual(setAttributesSpy.args[0], [
|
||||
fxaDescEl,
|
||||
'fxa-logged-in-text',
|
||||
{ email: 'init@ialization.com' }
|
||||
]);
|
||||
});
|
||||
|
||||
test('show the correct status after onlogout event', function() {
|
||||
MockFxAccountsIACHelper.setCurrentState(null);
|
||||
FxaMenu.init(MockFxAccountsIACHelper);
|
||||
MockFxAccountsIACHelper.fireEvent('onlogout');
|
||||
assert.equal(fxaDescEl.getAttribute('data-l10n-id'), 'fxa-invitation');
|
||||
});
|
||||
|
||||
test('show the correct status after onlogin event', function() {
|
||||
MockFxAccountsIACHelper.setCurrentState({
|
||||
email: 'on@log.in',
|
||||
verified: false
|
||||
});
|
||||
FxaMenu.init(MockFxAccountsIACHelper);
|
||||
MockFxAccountsIACHelper.fireEvent('onlogin');
|
||||
assert.deepEqual(setAttributesSpy.args[0], [
|
||||
fxaDescEl,
|
||||
'fxa-confirm-email',
|
||||
{ email: 'on@log.in' }
|
||||
]);
|
||||
});
|
||||
|
||||
test('show the correct status after onverified event', function() {
|
||||
MockFxAccountsIACHelper.setCurrentState({
|
||||
email: 'on@verifiedlog.in',
|
||||
verified: true
|
||||
});
|
||||
FxaMenu.init(MockFxAccountsIACHelper);
|
||||
MockFxAccountsIACHelper.fireEvent('onverified');
|
||||
assert.deepEqual(setAttributesSpy.args[0], [
|
||||
fxaDescEl,
|
||||
'fxa-logged-in-text',
|
||||
{ email: 'on@verifiedlog.in' }
|
||||
]);
|
||||
});
|
||||
});
|
||||
51
gaia/apps/settings/test/unit/initial_panel_handler_test.js
Executable file
51
gaia/apps/settings/test/unit/initial_panel_handler_test.js
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
/* global InitialPanelHandler */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/load_body_html_helper.js');
|
||||
|
||||
mocha.globals([
|
||||
'InitialPanelHandler'
|
||||
]);
|
||||
|
||||
Object.defineProperty(document, 'readyState', {
|
||||
value: 'loading',
|
||||
configurable: true
|
||||
});
|
||||
require('/js/startup.js');
|
||||
|
||||
suite('InitialPanelHandler', function() {
|
||||
var realMozSettings;
|
||||
|
||||
var initialPanelHandler;
|
||||
|
||||
var rootElement;
|
||||
var callSettingsItem;
|
||||
var callSettingsItemLink;
|
||||
|
||||
setup(function() {
|
||||
loadBodyHTML('./_root.html');
|
||||
rootElement = document.getElementById('root');
|
||||
callSettingsItem = document.getElementById('call-settings');
|
||||
callSettingsItemLink = document.createElement('a');
|
||||
callSettingsItemLink.href = '#call';
|
||||
callSettingsItem.appendChild(callSettingsItemLink);
|
||||
|
||||
realMozSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = null;
|
||||
|
||||
initialPanelHandler = InitialPanelHandler(rootElement);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.innerHTML = '';
|
||||
navigator.mozSettings = realMozSettings;
|
||||
});
|
||||
|
||||
test('should save correct pending target panel', function() {
|
||||
initialPanelHandler._addClickListeners();
|
||||
callSettingsItemLink.onclick({
|
||||
preventDefault: function() {}
|
||||
});
|
||||
assert.equal(initialPanelHandler.pendingTargetPanel, 'call');
|
||||
});
|
||||
});
|
||||
24
gaia/apps/settings/test/unit/mock_addon_manager.js
Executable file
24
gaia/apps/settings/test/unit/mock_addon_manager.js
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
function MockObservableArray() {
|
||||
return {
|
||||
array: []
|
||||
};
|
||||
}
|
||||
|
||||
var AddonManager = {
|
||||
_addons: MockObservableArray(),
|
||||
get addons() {
|
||||
return this._addons;
|
||||
},
|
||||
getAddonTargets: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
canDelete: function(addon) {
|
||||
return addon.instance.removable === true;
|
||||
}
|
||||
};
|
||||
|
||||
return AddonManager;
|
||||
});
|
||||
31
gaia/apps/settings/test/unit/mock_airplane_mode_helper.js
Executable file
31
gaia/apps/settings/test/unit/mock_airplane_mode_helper.js
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
/* exported MockAirplaneModeHelper */
|
||||
'use strict';
|
||||
|
||||
var MockAirplaneModeHelper = {
|
||||
_enabled: false,
|
||||
_status: 'disabled',
|
||||
_callbacks: [],
|
||||
setEnabled: function(enabled) {
|
||||
if (enabled) {
|
||||
this._status = 'enabled';
|
||||
}
|
||||
else {
|
||||
this._status = 'disabled';
|
||||
}
|
||||
this._enabled = enabled;
|
||||
},
|
||||
ready: function(cb) {
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
// mock with your own status
|
||||
getStatus: function() {
|
||||
return this._status;
|
||||
},
|
||||
addEventListener: function(callback) {
|
||||
this._callbacks.push(callback);
|
||||
},
|
||||
removeEventListener: function() {
|
||||
}
|
||||
};
|
||||
14
gaia/apps/settings/test/unit/mock_apps_cache.js
Executable file
14
gaia/apps/settings/test/unit/mock_apps_cache.js
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var AppsCache = {
|
||||
_apps: [],
|
||||
apps: function() {
|
||||
return Promise.resolve(this._apps);
|
||||
},
|
||||
addEventListener: function() {},
|
||||
removeEventListener: function() {}
|
||||
};
|
||||
|
||||
return AppsCache;
|
||||
});
|
||||
13
gaia/apps/settings/test/unit/mock_async_storage.js
Executable file
13
gaia/apps/settings/test/unit/mock_async_storage.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
/* exported MockAsyncStorage */
|
||||
'use strict';
|
||||
var MockAsyncStorage = {
|
||||
user_data: {},
|
||||
|
||||
getItem: function(key, callback) {
|
||||
callback(MockAsyncStorage.user_data[key]);
|
||||
},
|
||||
|
||||
setItem: function(key, value) {
|
||||
MockAsyncStorage.user_data[key] = value;
|
||||
}
|
||||
};
|
||||
11
gaia/apps/settings/test/unit/mock_dialog_service.js
Executable file
11
gaia/apps/settings/test/unit/mock_dialog_service.js
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var DialogService = {
|
||||
alert: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
return DialogService;
|
||||
});
|
||||
49
gaia/apps/settings/test/unit/mock_download_store.js
Executable file
49
gaia/apps/settings/test/unit/mock_download_store.js
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
/*exported MockDownloadStore */
|
||||
|
||||
'use strict';
|
||||
|
||||
var MockDownloadStore = {
|
||||
error: false,
|
||||
downloads: [],
|
||||
listeners: [],
|
||||
getAll: function() {
|
||||
var request = {
|
||||
onsuccess: null
|
||||
};
|
||||
setTimeout(function() {
|
||||
var event = {
|
||||
target: {
|
||||
result: this.downloads
|
||||
}
|
||||
};
|
||||
request.onsuccess(event);
|
||||
|
||||
}.bind(this), 0);
|
||||
return request;
|
||||
},
|
||||
add: function() {
|
||||
},
|
||||
remove: function() {
|
||||
},
|
||||
addListener: function(listener) {
|
||||
var request = {
|
||||
onsuccess: null
|
||||
};
|
||||
|
||||
if (this.listeners.indexOf(listener) == -1) {
|
||||
this.listeners.push(listener);
|
||||
}
|
||||
setTimeout(function() {
|
||||
var event = { target: { result: {} }};
|
||||
request.onsuccess(event);
|
||||
}.bind(this), 0);
|
||||
|
||||
return request;
|
||||
},
|
||||
removeListener: function(listener) {
|
||||
var index = this.listeners.indexOf(listener);
|
||||
if (index > -1) {
|
||||
this.listeners.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
32
gaia/apps/settings/test/unit/mock_download_ui.js
Executable file
32
gaia/apps/settings/test/unit/mock_download_ui.js
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
/* exported MockDownloadUI */
|
||||
var MockDownloadUI = {
|
||||
|
||||
show: function() {
|
||||
return {
|
||||
set onconfirm(cb) {cb();},
|
||||
get onconfirm() {return;}
|
||||
};
|
||||
},
|
||||
|
||||
showActions: function() {
|
||||
return {
|
||||
set onconfirm(cb) {cb();},
|
||||
get onconfirm() {return;},
|
||||
get result() {
|
||||
return {
|
||||
name: 'open'
|
||||
};
|
||||
},
|
||||
set result(value) {}
|
||||
};
|
||||
},
|
||||
|
||||
TYPE: {
|
||||
STOP: 'stop',
|
||||
STOPPED: 'stopped'
|
||||
}
|
||||
|
||||
};
|
||||
18
gaia/apps/settings/test/unit/mock_dsds_settings.js
Executable file
18
gaia/apps/settings/test/unit/mock_dsds_settings.js
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
window.MockDsdsSettings = (function() {
|
||||
var _iccCardIndexForCallSettings = 2;
|
||||
|
||||
function ds_getIccCardIndexForCallSettings() {
|
||||
return _iccCardIndexForCallSettings;
|
||||
}
|
||||
|
||||
function ds_setIccCardIndexForCallSettings(iccCardIndexForCallSettings) {
|
||||
_iccCardIndexForCallSettings = iccCardIndexForCallSettings;
|
||||
}
|
||||
|
||||
return {
|
||||
getIccCardIndexForCallSettings: ds_getIccCardIndexForCallSettings,
|
||||
setIccCardIndexForCallSettings: ds_setIccCardIndexForCallSettings
|
||||
};
|
||||
})();
|
||||
75
gaia/apps/settings/test/unit/mock_fx_accounts_iac_helper.js
Executable file
75
gaia/apps/settings/test/unit/mock_fx_accounts_iac_helper.js
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
/* exported MockFxAccountsIACHelper */
|
||||
|
||||
'use strict';
|
||||
|
||||
var MockFxAccountsIACHelper = (function() {
|
||||
var listeners = {
|
||||
'onlogin': [],
|
||||
'onverified': [],
|
||||
'onlogout': []
|
||||
};
|
||||
|
||||
var currentState = null;
|
||||
|
||||
function getAccount(cb) {
|
||||
cb(currentState);
|
||||
}
|
||||
|
||||
function resendVerificationEmail(email, cb) {
|
||||
cb();
|
||||
}
|
||||
|
||||
function resetListeners() {
|
||||
listeners.onlogin = [];
|
||||
listeners.onverified = [];
|
||||
listeners.onlogout = [];
|
||||
}
|
||||
|
||||
function addEventListener(eventType, cb) {
|
||||
if (!(eventType in listeners)) {
|
||||
throw new Error('tried to add wrong event type');
|
||||
}
|
||||
listeners[eventType].push(cb);
|
||||
}
|
||||
|
||||
function removeEventListener(eventType, cb) {
|
||||
if (!(eventType in listeners)) {
|
||||
throw new Error('tried to remove wrong event type');
|
||||
}
|
||||
for (var i = 0; i < listeners[eventType].length; i++) {
|
||||
if (cb == listeners[eventType][i]) {
|
||||
listeners[eventType].splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fireEvent(eventType) {
|
||||
if (!(eventType in listeners)) {
|
||||
throw new Error('tried to fire wrong event type');
|
||||
}
|
||||
|
||||
for (var i = 0; i < listeners[eventType].length; i++) {
|
||||
listeners[eventType][i](eventType);
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentState(x) {
|
||||
currentState = x;
|
||||
}
|
||||
|
||||
function getCurrentState() {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
return {
|
||||
getAccount: getAccount,
|
||||
resendVerificationEmail: resendVerificationEmail,
|
||||
setCurrentState: setCurrentState,
|
||||
getCurrentState: getCurrentState,
|
||||
addEventListener: addEventListener,
|
||||
removeEventListener: removeEventListener,
|
||||
fireEvent: fireEvent,
|
||||
listeners: listeners,
|
||||
resetListeners: resetListeners
|
||||
};
|
||||
})();
|
||||
20
gaia/apps/settings/test/unit/mock_homescreen_settings.js
Executable file
20
gaia/apps/settings/test/unit/mock_homescreen_settings.js
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
define(function() {
|
||||
var MockHomescreenSettings = {
|
||||
addEventListener: function(key, callback) {
|
||||
if (!this._eventHandlers) {
|
||||
this._eventHandlers = {};
|
||||
}
|
||||
this._eventHandlers[key] = callback;
|
||||
},
|
||||
put: () => {
|
||||
},
|
||||
get: () => {
|
||||
return Promise.resolve('3');
|
||||
},
|
||||
setStoreName: () => {}
|
||||
};
|
||||
|
||||
return MockHomescreenSettings;
|
||||
});
|
||||
25
gaia/apps/settings/test/unit/mock_keyboard_context.js
Executable file
25
gaia/apps/settings/test/unit/mock_keyboard_context.js
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var MockKeyboardContext = {
|
||||
mKeyboards: null,
|
||||
mEnabledLayouts: null,
|
||||
mTeardown: function() {
|
||||
this.mKeyboards = null;
|
||||
this.mEnabledLayouts = null;
|
||||
},
|
||||
init: function(callback) {
|
||||
callback();
|
||||
},
|
||||
keyboards: function(callback) {
|
||||
callback(this.mKeyboards);
|
||||
},
|
||||
enabledLayouts: function(callback) {
|
||||
callback(this.mEnabledLayouts);
|
||||
},
|
||||
defaultKeyboardEnabled: function(callback) {}
|
||||
};
|
||||
|
||||
return MockKeyboardContext;
|
||||
});
|
||||
21
gaia/apps/settings/test/unit/mock_list_view.js
Executable file
21
gaia/apps/settings/test/unit/mock_list_view.js
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var ctor = function mockListView() {
|
||||
if (ctor.mInnerFunction) {
|
||||
return ctor.mInnerFunction.apply(this, arguments);
|
||||
} else {
|
||||
return {
|
||||
set: function(newArray) {},
|
||||
destroy: function() {}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
ctor.mTeardown = function mockListViewTeardown() {
|
||||
ctor.mInnerFunction = null;
|
||||
};
|
||||
|
||||
return ctor;
|
||||
});
|
||||
11
gaia/apps/settings/test/unit/mock_messaging.js
Executable file
11
gaia/apps/settings/test/unit/mock_messaging.js
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var Messaging = {
|
||||
injectCBSTemplate: function() {},
|
||||
initCBS: function() {},
|
||||
disableItems: function() {}
|
||||
};
|
||||
|
||||
return Messaging;
|
||||
});
|
||||
8
gaia/apps/settings/test/unit/mock_mime_mapper.js
Executable file
8
gaia/apps/settings/test/unit/mock_mime_mapper.js
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
/* exported MockMimeMapper */
|
||||
var MockMimeMapper = {
|
||||
guessTypeFromFileProperties: function(filename, mimetype) {
|
||||
return mimetype;
|
||||
}
|
||||
};
|
||||
63
gaia/apps/settings/test/unit/mock_moz_apps.js
Executable file
63
gaia/apps/settings/test/unit/mock_moz_apps.js
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
'use strict';
|
||||
|
||||
/* exported MockMozApps */
|
||||
var MockMozApps = {
|
||||
mGetCurrentAppCallback: {
|
||||
onsuccess: null
|
||||
},
|
||||
mGetAllAppsCallback: {
|
||||
onsuccess: null
|
||||
},
|
||||
mApps: [],
|
||||
mCurrentApp: null,
|
||||
mAddToCurrentApp: function(app) {
|
||||
MockMozApps.mCurrentApp = app;
|
||||
MockMozApps.mApps.push(app);
|
||||
},
|
||||
mSetApps: function(apps) {
|
||||
MockMozApps.mApps = apps;
|
||||
},
|
||||
mgmt: {
|
||||
getAll: function() {
|
||||
return MockMozApps.mGetAllAppsCallback;
|
||||
},
|
||||
mUninstallCallback: {
|
||||
set onsuccess(callback) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
uninstall: function(app) {
|
||||
for (var i = 0; i < MockMozApps.mApps.length; i++) {
|
||||
if (MockMozApps.mApps[i].manifest.name && app.manifest.name &&
|
||||
MockMozApps.mApps[i].manifest.name == app.manifest.name) {
|
||||
MockMozApps.mApps.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.mUninstallCallback;
|
||||
},
|
||||
setEnabled: function(app, enabled) {
|
||||
app.enabled = enabled;
|
||||
},
|
||||
addEventListener: function() {},
|
||||
removeEventListener: function() {},
|
||||
getIcon: function() { return Promise.resolve(); }
|
||||
},
|
||||
getSelf: function() {
|
||||
return MockMozApps.mGetCurrentAppCallback;
|
||||
},
|
||||
mTriggerGetCurrentAppCallback: function() {
|
||||
MockMozApps.mGetCurrentAppCallback.onsuccess({
|
||||
target: {
|
||||
result: MockMozApps.mCurrentApp
|
||||
}
|
||||
});
|
||||
},
|
||||
mTriggerGetAllAppsCallback: function() {
|
||||
MockMozApps.mGetAllAppsCallback.onsuccess({
|
||||
target: {
|
||||
result: MockMozApps.mApps
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
17
gaia/apps/settings/test/unit/mock_navigator_moz_mobile_message.js
Executable file
17
gaia/apps/settings/test/unit/mock_navigator_moz_mobile_message.js
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
/*exported MockNavigatormozMobileMessage */
|
||||
|
||||
'use strict';
|
||||
|
||||
var MockNavigatormozMobileMessage = {
|
||||
SMSC: '+4400000000',
|
||||
getSmscAddress: function() {
|
||||
return {
|
||||
result: this.SMSC || '0',
|
||||
set onsuccess(callback) {
|
||||
callback.call(this);
|
||||
},
|
||||
set onerror(e) {}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
90
gaia/apps/settings/test/unit/mock_navigator_settings.js
Executable file
90
gaia/apps/settings/test/unit/mock_navigator_settings.js
Executable file
|
|
@ -0,0 +1,90 @@
|
|||
'use strict';
|
||||
|
||||
(() => {
|
||||
var observers = {};
|
||||
var settings = {};
|
||||
var removedObservers = {};
|
||||
|
||||
function mns_mLockSet(obj) {
|
||||
var settingsRequest = {};
|
||||
|
||||
for (var key in obj) {
|
||||
settings[key] = obj[key];
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
if (settingsRequest.onsuccess) {
|
||||
settingsRequest.onsuccess();
|
||||
}
|
||||
});
|
||||
|
||||
return settingsRequest;
|
||||
}
|
||||
|
||||
function mns_mLockGet(name) {
|
||||
var settingsRequest = {
|
||||
result: settings
|
||||
};
|
||||
|
||||
setTimeout(function() {
|
||||
if (settingsRequest.onsuccess) {
|
||||
settingsRequest.onsuccess();
|
||||
}
|
||||
});
|
||||
|
||||
return settingsRequest;
|
||||
}
|
||||
|
||||
function mns_addObserver(name, cb) {
|
||||
observers[name] = observers[name] || [];
|
||||
observers[name].push(cb);
|
||||
}
|
||||
|
||||
function mns_removeObserver(name, cb) {
|
||||
removedObservers[name] = removedObservers[name] || [];
|
||||
removedObservers[name].push(cb);
|
||||
}
|
||||
|
||||
function mns_createLock() {
|
||||
return {
|
||||
set: mns_mLockSet,
|
||||
get: mns_mLockGet
|
||||
};
|
||||
}
|
||||
|
||||
function mns_mTriggerObservers(name, args) {
|
||||
var theseObservers = observers[name];
|
||||
|
||||
if (! theseObservers) {
|
||||
return;
|
||||
}
|
||||
|
||||
theseObservers.forEach(function(func) {
|
||||
func(args);
|
||||
});
|
||||
}
|
||||
|
||||
function mns_teardown() {
|
||||
observers = {};
|
||||
settings = {};
|
||||
removedObservers = {};
|
||||
}
|
||||
|
||||
window.MockNavigatorSettings = {
|
||||
addObserver: mns_addObserver,
|
||||
removeObserver: mns_removeObserver,
|
||||
createLock: mns_createLock,
|
||||
|
||||
mTriggerObservers: mns_mTriggerObservers,
|
||||
mTeardown: mns_teardown,
|
||||
get mObservers() {
|
||||
return observers;
|
||||
},
|
||||
get mSettings() {
|
||||
return settings;
|
||||
},
|
||||
get mRemovedObservers() {
|
||||
return removedObservers;
|
||||
}
|
||||
};
|
||||
})();
|
||||
12
gaia/apps/settings/test/unit/mock_page_transitions.js
Executable file
12
gaia/apps/settings/test/unit/mock_page_transitions.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
return {
|
||||
oneColumn: function(oldPanel, newPanel, callback) {
|
||||
setTimeout(callback);
|
||||
},
|
||||
twoColumn: function(oldPanel, newPanel, callback) {
|
||||
setTimeout(callback);
|
||||
}
|
||||
};
|
||||
});
|
||||
14
gaia/apps/settings/test/unit/mock_settings.js
Executable file
14
gaia/apps/settings/test/unit/mock_settings.js
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
/* exported MockSettings */
|
||||
/* global MockNavigatorSettings */
|
||||
'use strict';
|
||||
requireApp('settings/test/unit/mock_navigator_settings.js');
|
||||
|
||||
var MockSettings = {
|
||||
currentPanel: '',
|
||||
mSuiteSetup: function() {
|
||||
this.mozSettings = MockNavigatorSettings;
|
||||
},
|
||||
mSetup: function() {
|
||||
this.currentPanel = '';
|
||||
}
|
||||
};
|
||||
22
gaia/apps/settings/test/unit/mock_settings_cache.js
Executable file
22
gaia/apps/settings/test/unit/mock_settings_cache.js
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
var _settings = {};
|
||||
|
||||
var ctor = {
|
||||
getSettings: function(callback) {
|
||||
callback(_settings);
|
||||
},
|
||||
|
||||
// custom settings
|
||||
mockSettings: function(value) {
|
||||
_settings = value;
|
||||
},
|
||||
|
||||
mTeardown: function() {
|
||||
_settings = {};
|
||||
}
|
||||
};
|
||||
|
||||
return ctor;
|
||||
});
|
||||
19
gaia/apps/settings/test/unit/mock_settings_panel.js
Executable file
19
gaia/apps/settings/test/unit/mock_settings_panel.js
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
// As this module is simply a function, we are not able to mock the function
|
||||
// in our tests after the module loaded. mInnerFunction provides a way that
|
||||
// allows one loads the module be able to mock the behavior of the function.
|
||||
var ctor = function mock_settings_panel() {
|
||||
if (ctor.mInnerFunction) {
|
||||
return ctor.mInnerFunction.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
ctor.mTeardown = function mock_settings_panel_teardown() {
|
||||
ctor.mInnerFunction = null;
|
||||
};
|
||||
|
||||
return ctor;
|
||||
});
|
||||
15
gaia/apps/settings/test/unit/mock_settings_service.js
Executable file
15
gaia/apps/settings/test/unit/mock_settings_service.js
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
var MockSettingsService = {
|
||||
navigate: function(panelId, options, callback) {
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
},
|
||||
back: function() {}
|
||||
};
|
||||
|
||||
return MockSettingsService;
|
||||
});
|
||||
11
gaia/apps/settings/test/unit/mock_settings_utils.js
Executable file
11
gaia/apps/settings/test/unit/mock_settings_utils.js
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var MockSettingsUtils = {
|
||||
loadTemplate: function(templatePanelId, callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
return MockSettingsUtils;
|
||||
});
|
||||
7
gaia/apps/settings/test/unit/mock_sim_pin_dialog.js
Executable file
7
gaia/apps/settings/test/unit/mock_sim_pin_dialog.js
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
function MockSimPinDialog(idOrNode) {}
|
||||
|
||||
MockSimPinDialog.prototype.show = function(options) {
|
||||
return options;
|
||||
};
|
||||
42
gaia/apps/settings/test/unit/mock_sim_ui_model.js
Executable file
42
gaia/apps/settings/test/unit/mock_sim_ui_model.js
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
function MockSimUIModel(cardIndex) {
|
||||
this._cardIndex = cardIndex;
|
||||
// state list
|
||||
this._enabled = true;
|
||||
this._absent = false;
|
||||
this._locked = false;
|
||||
this._name = {
|
||||
id: 'simWithIndex',
|
||||
args: {
|
||||
index: this._cardIndex + 1
|
||||
}
|
||||
};
|
||||
this._number = '0123456789';
|
||||
this._operator = {
|
||||
text: 'Taiwan telecom'
|
||||
};
|
||||
}
|
||||
|
||||
MockSimUIModel.prototype = {
|
||||
getInfo: function() {
|
||||
return {
|
||||
enabled: this._enabled,
|
||||
absent: this._absent,
|
||||
locked: this._locked,
|
||||
name: this._name,
|
||||
number: this._number,
|
||||
operator: this._operator
|
||||
};
|
||||
},
|
||||
setState: function(key, options) {
|
||||
// we can use this to make sure we setState successfully
|
||||
this._state = key;
|
||||
}
|
||||
};
|
||||
|
||||
return function ctor_mockSimUIModel(cardIndex) {
|
||||
return new MockSimUIModel(cardIndex);
|
||||
};
|
||||
});
|
||||
13
gaia/apps/settings/test/unit/mock_template.js
Executable file
13
gaia/apps/settings/test/unit/mock_template.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
function MockTemplate(idOrNode) {
|
||||
|
||||
}
|
||||
|
||||
MockTemplate.prototype.interpolate = function(data, options) {
|
||||
return data;
|
||||
};
|
||||
|
||||
return MockTemplate;
|
||||
});
|
||||
30
gaia/apps/settings/test/unit/mock_test_panel.js
Executable file
30
gaia/apps/settings/test/unit/mock_test_panel.js
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var _mInnerFunction = null;
|
||||
var ctor = function mock_panel_module() {
|
||||
if (_mInnerFunction) {
|
||||
return _mInnerFunction.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
// As this module is simply a function, we are not able to mock the function
|
||||
// in our tests after the module loaded. mInnerFunction provides a way that
|
||||
// allows one loads the module be able to mock the behavior of the function.
|
||||
Object.defineProperty(ctor, 'mInnerFunction', {
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return _mInnerFunction;
|
||||
},
|
||||
set: function(value) {
|
||||
_mInnerFunction = value;
|
||||
}
|
||||
});
|
||||
|
||||
ctor.mTeardown = function mock_panel_module_teardown() {
|
||||
ctor._mInnerFunction = null;
|
||||
};
|
||||
|
||||
return ctor;
|
||||
});
|
||||
21
gaia/apps/settings/test/unit/mock_toaster.js
Executable file
21
gaia/apps/settings/test/unit/mock_toaster.js
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
var MockToaster = {
|
||||
_mInited: false,
|
||||
_lastToast: undefined,
|
||||
isInitialized: function mt_isInitialized() {
|
||||
return this._mInited;
|
||||
},
|
||||
showToast: function mt_showToast(options) {
|
||||
this._lastToast = options;
|
||||
},
|
||||
mSetup: function mt_mSetup() {
|
||||
this._mInited = true;
|
||||
},
|
||||
mTeardown: function mt_mTeardown() {
|
||||
this._mInited = false;
|
||||
}
|
||||
};
|
||||
exports.MockToaster = MockToaster;
|
||||
}(window));
|
||||
12
gaia/apps/settings/test/unit/mock_wifi.js
Executable file
12
gaia/apps/settings/test/unit/mock_wifi.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
var Wifi = {
|
||||
_elements: {
|
||||
wifiAvailableNetworks: document.createElement('div'),
|
||||
infoItem: document.createElement('div'),
|
||||
scanItem: document.createElement('div')
|
||||
}
|
||||
};
|
||||
|
||||
return Wifi;
|
||||
});
|
||||
20
gaia/apps/settings/test/unit/mock_wifi_context.js
Executable file
20
gaia/apps/settings/test/unit/mock_wifi_context.js
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var MockWifiContext = {
|
||||
_callbacks: [],
|
||||
currentNetwork: {},
|
||||
wps: {
|
||||
selectedAp: '',
|
||||
selectedMethod: '',
|
||||
pin: ''
|
||||
},
|
||||
associateNetwork: function(network) {},
|
||||
forgetNetwork: function(network) {},
|
||||
addEventListener: function(callback) {
|
||||
this._callbacks.push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
return MockWifiContext;
|
||||
});
|
||||
35
gaia/apps/settings/test/unit/mock_wifi_utils.js
Executable file
35
gaia/apps/settings/test/unit/mock_wifi_utils.js
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
define(function() {
|
||||
'use strict';
|
||||
var MockWifiUtils = {
|
||||
_network: {},
|
||||
wifiDialog: function(dialogID, options) {
|
||||
var self = this;
|
||||
if (options.callback) {
|
||||
setTimeout(function() {
|
||||
options.callback(self._network);
|
||||
});
|
||||
}
|
||||
},
|
||||
wifiConnect: function() {},
|
||||
wifiDisconnect: function() {},
|
||||
newExplanationItem: function(message) {
|
||||
return document.createElement('div');
|
||||
},
|
||||
newListItem: function(options) {
|
||||
var item = document.createElement('li');
|
||||
item.setAttribute('network', options.network);
|
||||
return item;
|
||||
},
|
||||
checkPassword: function() {
|
||||
|
||||
},
|
||||
changeDisplay: function() {
|
||||
|
||||
},
|
||||
getNetworkKey: function(network) {
|
||||
return network ? network.ssid : '';
|
||||
}
|
||||
};
|
||||
|
||||
return MockWifiUtils;
|
||||
});
|
||||
35
gaia/apps/settings/test/unit/mock_xml_http_request.js
Executable file
35
gaia/apps/settings/test/unit/mock_xml_http_request.js
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
/* global define */
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var MockXMLHttpRequest = function() {
|
||||
this.data = {};
|
||||
this.timeout = null;
|
||||
};
|
||||
MockXMLHttpRequest.prototype = {
|
||||
triggerReadyStateChange: function(status) {
|
||||
this.status = status;
|
||||
this.onreadystatechange();
|
||||
},
|
||||
triggerOnLoad: function(status) {
|
||||
this.status = status;
|
||||
this.onload();
|
||||
},
|
||||
open: function(requestType, requestUrl) {
|
||||
this.data.requestType = requestType;
|
||||
this.data.requestUrl = requestUrl;
|
||||
},
|
||||
|
||||
setRequestHeader: function(type, value) {
|
||||
this.data.header = {
|
||||
type: type,
|
||||
value: value
|
||||
};
|
||||
},
|
||||
|
||||
send: function(value) {
|
||||
this.data.value = value;
|
||||
}
|
||||
};
|
||||
return MockXMLHttpRequest;
|
||||
});
|
||||
661
gaia/apps/settings/test/unit/modules/addon_manager_test.js
Executable file
661
gaia/apps/settings/test/unit/modules/addon_manager_test.js
Executable file
|
|
@ -0,0 +1,661 @@
|
|||
'use strict';
|
||||
|
||||
suite('addons manager test > ', function() {
|
||||
var realMozActivity;
|
||||
|
||||
var mockAppsCache;
|
||||
var mockXMLHttpRequest;
|
||||
var mockMozApps;
|
||||
var mockMozActivity;
|
||||
var AddonManager;
|
||||
var MockApp;
|
||||
|
||||
var modules = [
|
||||
'unit/mock_moz_apps',
|
||||
'shared_mocks/mock_moz_activity',
|
||||
'modules/addon_manager',
|
||||
'shared_mocks/mock_xml_http_request',
|
||||
'MockApp'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'modules/addon_manager': {
|
||||
'modules/navigator/mozApps': 'unit/mock_moz_apps',
|
||||
'modules/apps_cache': 'unit/mock_apps_cache',
|
||||
'mdoules/app': 'MockApp'
|
||||
}
|
||||
};
|
||||
|
||||
MockApp = function(app) {
|
||||
return {
|
||||
get enabled() {
|
||||
return app.enabled;
|
||||
},
|
||||
get instance() {
|
||||
return app;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Check if an array of wrapped addons contains a specific un-wrapped addon.
|
||||
function containsAddon(wrappedAddons, addon) {
|
||||
return wrappedAddons.some((wrappedAddon) => {
|
||||
return wrappedAddon.instance === addon;
|
||||
});
|
||||
}
|
||||
|
||||
var app1 = {
|
||||
manifest: {
|
||||
name: 'testAppName1',
|
||||
},
|
||||
manifestURL: 'testManifestURL_app1',
|
||||
origin: 'app://testorigin1'
|
||||
};
|
||||
|
||||
var app2 = {
|
||||
manifest: {
|
||||
name: 'testAppName2',
|
||||
},
|
||||
manifestURL: 'testManifestURL_app2',
|
||||
origin: 'app://testorigin2'
|
||||
};
|
||||
|
||||
var privilegedApp = {
|
||||
manifest: {
|
||||
type: 'privileged',
|
||||
name: 'privilegedAppName',
|
||||
},
|
||||
manifestURL: 'testManifestURL_priv_app',
|
||||
origin: 'app://privilegedorigin'
|
||||
};
|
||||
|
||||
var certifiedApp = {
|
||||
manifest: {
|
||||
type: 'certified',
|
||||
role: 'system',
|
||||
name: 'certifiedAppName',
|
||||
},
|
||||
manifestURL: 'testManifestURL_cert_app',
|
||||
origin: 'app://certifiedorigin'
|
||||
};
|
||||
|
||||
var settingsApp = {
|
||||
manifest: {
|
||||
type: 'certified',
|
||||
name: 'Settings',
|
||||
launch_path: '/index.html#',
|
||||
},
|
||||
manifestURL: 'testManifestURL_settings_app',
|
||||
origin: 'app://settings.gaiamobile.org'
|
||||
};
|
||||
|
||||
var addon1 = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
name: 'testAddonName1',
|
||||
// content_scripts field is internally copied from manifest.json to
|
||||
// manifest.webapp
|
||||
content_scripts: []
|
||||
},
|
||||
manifestURL: 'testManifestURL_addon1',
|
||||
origin: 'app://testaddonorigin1'
|
||||
};
|
||||
|
||||
var addon2 = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
name: 'testAddonName2',
|
||||
// content_scripts field is internally copied from manifest.json to
|
||||
// manifest.webapp
|
||||
content_scripts: [{
|
||||
matches: '<all_urls>',
|
||||
js: [],
|
||||
css: ['foo.css']
|
||||
}]
|
||||
},
|
||||
manifestURL: 'testManifestURL_addon2',
|
||||
origin: 'app://testaddonorigin2'
|
||||
};
|
||||
|
||||
var obsoleteAddon = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
name: 'obsoleteAddon',
|
||||
customizations: [{
|
||||
css: ['foo.css'],
|
||||
scripts: []
|
||||
}]
|
||||
},
|
||||
manifestURL: 'testManifestURL_obsoleteAddon',
|
||||
origin: 'app://testobsoleteaddonorigin'
|
||||
};
|
||||
|
||||
var privilegedAddon = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
type: 'privileged',
|
||||
name: 'privilegedAddonName',
|
||||
// content_scripts field is internally copied from manifest.json to
|
||||
// manifest.webapp
|
||||
content_scripts: [{
|
||||
matches: '<all_urls>',
|
||||
js: ['addon.js'],
|
||||
css: []
|
||||
}]
|
||||
},
|
||||
manifestURL: 'testManifestURL_priv_addon',
|
||||
origin: 'app://privilegedaddonorigin'
|
||||
};
|
||||
|
||||
var certifiedAddon = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
type: 'certified',
|
||||
name: 'certifiedAddonName',
|
||||
// content_scripts field is internally copied from manifest.json to
|
||||
// manifest.webapp
|
||||
content_scripts: [{
|
||||
matches: '<all_urls>',
|
||||
js: ['addon.js'],
|
||||
css: []
|
||||
}]
|
||||
},
|
||||
manifestURL: 'testManifestURL_cert_addon',
|
||||
origin: 'app://certifiedaddonorigin'
|
||||
};
|
||||
|
||||
var settingsAddon = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
type: 'certified',
|
||||
name: 'settingAddonName',
|
||||
content_scripts: [{
|
||||
matches: 'app://settings.gaiamobile.org/index.html*',
|
||||
js: [],
|
||||
css: []
|
||||
}]
|
||||
},
|
||||
manifestURL: 'testManifestURL_settings_addon',
|
||||
origin: 'app://settingsaddonorigin'
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire(['unit/mock_apps_cache'], map,
|
||||
(MockAppsCache) => {
|
||||
mockAppsCache = MockAppsCache;
|
||||
mockAppsCache._apps = [
|
||||
app1, app2, addon1, addon2, obsoleteAddon,
|
||||
privilegedApp, privilegedAddon,
|
||||
certifiedApp, certifiedAddon,
|
||||
settingsApp, settingsAddon
|
||||
];
|
||||
this.sinon.spy(mockAppsCache, 'addEventListener');
|
||||
this.sinon.spy(mockAppsCache, 'removeEventListener');
|
||||
|
||||
define('MockApp', function() {
|
||||
return MockApp;
|
||||
});
|
||||
|
||||
requireCtx(modules,
|
||||
(MockMozApps, MockMozActivity, _AddonManager, MockXMLHttpRequest) => {
|
||||
mockMozApps = MockMozApps;
|
||||
mockMozActivity = MockMozActivity;
|
||||
mockXMLHttpRequest = MockXMLHttpRequest;
|
||||
|
||||
mockMozApps.mSetApps([
|
||||
app1, app2, addon1, addon2, obsoleteAddon,
|
||||
privilegedApp, privilegedAddon,
|
||||
certifiedApp, certifiedAddon,
|
||||
settingsApp, settingsAddon
|
||||
]);
|
||||
|
||||
this.sinon.spy(mockMozApps.mgmt, 'uninstall');
|
||||
this.sinon.spy(mockMozApps.mgmt, 'setEnabled');
|
||||
|
||||
realMozActivity = window.MozActivity;
|
||||
window.MozActivity = window.MockMozActivity;
|
||||
window.MozActivity.mSetup();
|
||||
|
||||
AddonManager = _AddonManager;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
window.MockMozActivity.mTeardown();
|
||||
window.MozActivity = realMozActivity;
|
||||
});
|
||||
|
||||
test('AddonManager functions are all defined', function() {
|
||||
assert.isFunction(AddonManager.isEnabled);
|
||||
assert.isFunction(AddonManager.enableAddon);
|
||||
assert.isFunction(AddonManager.disableAddon);
|
||||
assert.isFunction(AddonManager.canDelete);
|
||||
assert.isFunction(AddonManager.deleteAddon);
|
||||
assert.isFunction(AddonManager.shareAddon);
|
||||
assert.isFunction(AddonManager.getAddonTargets);
|
||||
});
|
||||
|
||||
suite('AddonManager.addons', function() {
|
||||
test('contains all the addons and no apps', function(done) {
|
||||
function doCheck() {
|
||||
var containsAll = [addon1, addon2, obsoleteAddon, privilegedAddon,
|
||||
certifiedAddon, settingsAddon].every(addon =>
|
||||
containsAddon(AddonManager.addons.array, addon));
|
||||
if (containsAll && AddonManager.length === 6) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
if (doCheck()) {
|
||||
done();
|
||||
} else {
|
||||
AddonManager.addons.observe('insert', doCheck);
|
||||
AddonManager.addons.observe('remove', doCheck);
|
||||
AddonManager.addons.observe('reset', doCheck);
|
||||
AddonManager.addons.observe('replace', doCheck);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('_isAddon', function() {
|
||||
test('returns true for addons', function() {
|
||||
assert.isTrue(AddonManager._isAddon(addon1));
|
||||
assert.isTrue(AddonManager._isAddon(addon2));
|
||||
assert.isTrue(AddonManager._isAddon(certifiedAddon));
|
||||
assert.isTrue(AddonManager._isAddon(privilegedAddon));
|
||||
assert.isTrue(AddonManager._isAddon(settingsAddon));
|
||||
});
|
||||
|
||||
test('returns false for non-addons', function() {
|
||||
assert.isFalse(AddonManager._isAddon(app1));
|
||||
assert.isFalse(AddonManager._isAddon(app2));
|
||||
assert.isFalse(AddonManager._isAddon(certifiedApp));
|
||||
assert.isFalse(AddonManager._isAddon(privilegedApp));
|
||||
assert.isFalse(AddonManager._isAddon(settingsApp));
|
||||
});
|
||||
});
|
||||
|
||||
suite('_isEnabled', function() {
|
||||
test('only returns true for enabled addons', function() {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
var wrappedApp = MockApp(app1);
|
||||
|
||||
addon1.enabled = true;
|
||||
assert.isTrue(AddonManager.isEnabled(wrappedAddon));
|
||||
|
||||
addon1.enabled = false;
|
||||
assert.isFalse(AddonManager.isEnabled(wrappedAddon));
|
||||
|
||||
delete addon1.enabled;
|
||||
assert.isFalse(AddonManager.isEnabled(wrappedAddon));
|
||||
|
||||
app1.enabled = true;
|
||||
assert.isFalse(AddonManager.isEnabled(wrappedApp));
|
||||
delete app1.enabled;
|
||||
});
|
||||
});
|
||||
|
||||
suite('_updateAddons', function() {
|
||||
test('add the new addon to addons from WebIDE', function() {
|
||||
// Installed with WebIDE, manifest exists
|
||||
var newAddon = {
|
||||
manifest: {
|
||||
role: 'addon',
|
||||
name: 'newAddon'
|
||||
},
|
||||
manifestURL: 'newAddonManifestURL',
|
||||
origin: 'app://newAddonManifestURL',
|
||||
addEventListener: function(evt, cb) {
|
||||
cb({
|
||||
type: evt,
|
||||
application: this
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
assert.isFalse(containsAddon(AddonManager.addons.array, newAddon));
|
||||
// Trigger an install event
|
||||
mockAppsCache.addEventListener.args.forEach(listener => {
|
||||
if (listener[0] === 'oninstall') {
|
||||
// evt for the callback function
|
||||
listener[1]({
|
||||
application: newAddon,
|
||||
type: 'install'
|
||||
});
|
||||
}
|
||||
});
|
||||
assert.isTrue(containsAddon(AddonManager.addons.array, newAddon));
|
||||
});
|
||||
|
||||
test('add the new addon to addons from Marketplace', function() {
|
||||
// Installed with Marketplace, manifest does not exist yet
|
||||
var newAddon = {
|
||||
manifestURL: 'newAddonManifestURL',
|
||||
origin: 'app://newAddonManifestURL',
|
||||
addEventListener: function(evt, cb) {
|
||||
cb({
|
||||
type: evt,
|
||||
application: this
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
assert.isFalse(containsAddon(AddonManager.addons.array, newAddon));
|
||||
// Trigger an install event
|
||||
mockAppsCache.addEventListener.args.forEach(listener => {
|
||||
if (listener[0] === 'oninstall') {
|
||||
// evt for the callback function
|
||||
// Once downloadsuccess is fired, manifest would be available
|
||||
newAddon.manifest = {
|
||||
role: 'addon',
|
||||
name: 'newAddon'
|
||||
};
|
||||
listener[1]({
|
||||
application: newAddon,
|
||||
type: 'downloadsuccess'
|
||||
});
|
||||
}
|
||||
});
|
||||
assert.isTrue(containsAddon(AddonManager.addons.array, newAddon));
|
||||
});
|
||||
|
||||
test('remove the addon from addons when "uninstall', function() {
|
||||
assert.isTrue(containsAddon(AddonManager.addons.array, addon1));
|
||||
// Trigger an uninstall event.
|
||||
mockAppsCache.addEventListener.args.forEach(listener => {
|
||||
if (listener[0] === 'onuninstall') {
|
||||
listener[1]({
|
||||
application: addon1,
|
||||
type: 'uninstall'
|
||||
});
|
||||
}
|
||||
});
|
||||
assert.isFalse(containsAddon(AddonManager.addons.array, addon1));
|
||||
});
|
||||
|
||||
test('only add the same addon once', function() {
|
||||
assert.isTrue(containsAddon(AddonManager.addons.array, addon1));
|
||||
AddonManager._updateAddons({
|
||||
application: addon1,
|
||||
type: 'install'
|
||||
});
|
||||
assert.ok(AddonManager.addons.array.filter((addon) => {
|
||||
return addon.instance === addon1;
|
||||
}).length === 1);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_privilegeCheck', function() {
|
||||
test('should return correct result', function() {
|
||||
assert.isTrue(AddonManager._privilegeCheck(addon1, app1));
|
||||
assert.isFalse(AddonManager._privilegeCheck(addon1, privilegedApp));
|
||||
assert.isFalse(AddonManager._privilegeCheck(addon1, certifiedApp));
|
||||
|
||||
assert.isTrue(AddonManager._privilegeCheck(privilegedAddon, app1));
|
||||
assert.isTrue(
|
||||
AddonManager._privilegeCheck(privilegedAddon, privilegedApp));
|
||||
assert.isTrue(
|
||||
AddonManager._privilegeCheck(privilegedAddon, certifiedApp));
|
||||
|
||||
assert.isTrue(AddonManager._privilegeCheck(certifiedAddon, app1));
|
||||
assert.isTrue(
|
||||
AddonManager._privilegeCheck(certifiedAddon, privilegedApp));
|
||||
assert.isTrue(
|
||||
AddonManager._privilegeCheck(certifiedAddon, certifiedApp));
|
||||
});
|
||||
});
|
||||
|
||||
suite('enableAddon', function() {
|
||||
test('does nothing for non-addons', function() {
|
||||
var wrappedApp = MockApp(app1);
|
||||
AddonManager.enableAddon(wrappedApp);
|
||||
assert.equal(mockMozApps.mgmt.setEnabled.callCount, 0);
|
||||
});
|
||||
|
||||
test('calls setEnabled for addons', function() {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
app1.enabled = false;
|
||||
AddonManager.enableAddon(wrappedAddon);
|
||||
assert.isTrue(mockMozApps.mgmt.setEnabled.calledWith(addon1, true));
|
||||
});
|
||||
});
|
||||
|
||||
suite('disableAddon', function() {
|
||||
test('does nothing for non-addons',
|
||||
function() {
|
||||
var wrappedApp = MockApp(app1);
|
||||
AddonManager.disableAddon(wrappedApp);
|
||||
assert.equal(mockMozApps.mgmt.setEnabled.callCount, 0);
|
||||
});
|
||||
|
||||
test('synchronously calls setEnabled for addons', function() {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
addon1.enabled = true;
|
||||
AddonManager.disableAddon(wrappedAddon);
|
||||
assert.isTrue(mockMozApps.mgmt.setEnabled.calledWith(addon1, false));
|
||||
});
|
||||
});
|
||||
|
||||
suite('canDelete', function() {
|
||||
test('only returns true for removable addons', function() {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
var wrappedApp = MockApp(app1);
|
||||
|
||||
addon1.removable = true;
|
||||
assert.isTrue(AddonManager.canDelete(wrappedAddon));
|
||||
addon1.removable = false;
|
||||
assert.isFalse(AddonManager.canDelete(wrappedAddon));
|
||||
delete addon1.removable;
|
||||
assert.isFalse(AddonManager.canDelete(wrappedAddon));
|
||||
|
||||
app1.removable = true;
|
||||
assert.isFalse(AddonManager.canDelete(wrappedApp));
|
||||
delete app1.removable;
|
||||
});
|
||||
});
|
||||
|
||||
suite('deleteAddon', function() {
|
||||
test('rejects non-addons', function(done) {
|
||||
var wrappedApp = MockApp(app1);
|
||||
assert.isRejected(AddonManager.deleteAddon(wrappedApp)).notify(done);
|
||||
});
|
||||
|
||||
test('rejects for non-removable addons', function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
addon1.removable = false;
|
||||
assert.isRejected(AddonManager.deleteAddon(wrappedAddon)).notify(done);
|
||||
});
|
||||
|
||||
test('resolves for removable addons and calls uninstall', function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
addon1.removable = true;
|
||||
AddonManager.deleteAddon(wrappedAddon).then(function resolve() {
|
||||
assert.isTrue(mockMozApps.mgmt.uninstall.calledWith(addon1));
|
||||
done();
|
||||
}, function reject(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('shareAddon', function() {
|
||||
test('rejects non-addons', function(done) {
|
||||
var wrappedApp = MockApp(app1);
|
||||
assert.isRejected(AddonManager.shareAddon(wrappedApp)).notify(done);
|
||||
});
|
||||
|
||||
test('starts a share activity and resolves', function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
var promise = AddonManager.shareAddon(wrappedAddon);
|
||||
var activityRequest = window.MockMozActivity.calls.pop();
|
||||
assert.equal(activityRequest.name, 'share');
|
||||
assert.equal(activityRequest.data.type, 'app');
|
||||
assert.equal(activityRequest.data.app, addon1.manifestURL);
|
||||
|
||||
assert.isFulfilled(promise).notify(done);
|
||||
});
|
||||
|
||||
test('rejects if share activity fails', function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
var promise = AddonManager.shareAddon(wrappedAddon);
|
||||
window.MockMozActivity.mTriggerOnError();
|
||||
assert.isRejected(promise).notify(done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAddonTargets', function() {
|
||||
test('rejects non-addons', function(done) {
|
||||
var wrappedApp = MockApp(app1);
|
||||
assert.isRejected(AddonManager.getAddonTargets(wrappedApp)).notify(done);
|
||||
});
|
||||
|
||||
test('returns no targets for obsolete addons',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(obsoleteAddon);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('returns no targets for addons with no content scripts',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('returns only unprivileged apps for unprivileged addons',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [app1, app2])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('does returns certified + privileged apps for privileged addons',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(privilegedAddon);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon),
|
||||
[app1, app2, privilegedApp, certifiedApp, settingsApp]).notify(done);
|
||||
});
|
||||
|
||||
test('returns any apps for certified addons', function(done) {
|
||||
var wrappedAddon = MockApp(certifiedAddon);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon),
|
||||
[app1, app2, privilegedApp, certifiedApp, settingsApp]).notify(done);
|
||||
});
|
||||
|
||||
test('honors specific addon filters', function(done) {
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
addon2.manifest.content_scripts[0].matches = 'app://testorigin1/';
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [app1])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('honors regexp addon filters', function(done) {
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
addon2.manifest.content_scripts[0].matches = 'app://*/';
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [app1, app2])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('honors settings regexp addon filters', function(done) {
|
||||
var wrappedAddon = MockApp(settingsAddon);
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [settingsApp])
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('does not return addons even explicitly targeted', function(done) {
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
addon2.manifest.content_scripts[0].matches = 'app://testaddonorigin1/';
|
||||
assert.becomes(AddonManager.getAddonTargets(wrappedAddon), [])
|
||||
.notify(done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAddonDisableType', function() {
|
||||
test('resolves to an empty string if no targets', function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
assert.becomes(AddonManager.getAddonDisableType(wrappedAddon), '')
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('obsolete addon always resolves to an empty string if no targets',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(obsoleteAddon);
|
||||
assert.becomes(AddonManager.getAddonDisableType(wrappedAddon), '')
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('resolves to an empty string if no scripts', function(done) {
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
assert.becomes(AddonManager.getAddonDisableType(wrappedAddon), '')
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('resolves to "restart" if it injects scripts', function(done) {
|
||||
var wrappedAddon = MockApp(privilegedAddon);
|
||||
privilegedAddon.manifest.content_scripts[0].exclude_matches =
|
||||
'app://certifiedorigin/';
|
||||
assert.becomes(AddonManager.getAddonDisableType(wrappedAddon), 'restart')
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('resolves to "reboot" if addon injects into a system app',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(certifiedAddon);
|
||||
assert.becomes(AddonManager.getAddonDisableType(wrappedAddon), 'reboot')
|
||||
.notify(done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('findAddonByManifestURL', function() {
|
||||
test('resolves to the correct addon object when matches', function(done) {
|
||||
var targetManifestURL = 'testManifestURL_priv_addon';
|
||||
var privAddon = AddonManager.addons.array.find((addon) => {
|
||||
return addon.instance.manifestURL === targetManifestURL;
|
||||
});
|
||||
|
||||
assert.becomes(AddonManager
|
||||
.findAddonByManifestURL(targetManifestURL), privAddon).notify(done);
|
||||
});
|
||||
|
||||
test('resolves to undefined when no addon matches', function(done) {
|
||||
assert.becomes(AddonManager
|
||||
.findAddonByManifestURL('fakeManifestURL'), undefined).notify(done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('addonAffectsApp', function() {
|
||||
test('resolves to true when an addon affects an app', function(done) {
|
||||
addon2.manifest.content_scripts[0].matches = 'app://testorigin1/';
|
||||
var wrappedAddon = MockApp(addon2);
|
||||
assert.becomes(AddonManager
|
||||
.addonAffectsApp(wrappedAddon, 'testManifestURL_app1'), true)
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('obsolete addon always resolves to false', function(done) {
|
||||
var wrappedAddon = MockApp(obsoleteAddon);
|
||||
assert.becomes(AddonManager
|
||||
.addonAffectsApp(wrappedAddon, 'testManifestURL_app1'), false)
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('resolves to false when an addon does not affect an app',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(addon1);
|
||||
assert.becomes(AddonManager
|
||||
.addonAffectsApp(wrappedAddon, 'testManifestURL_app1'), false)
|
||||
.notify(done);
|
||||
});
|
||||
|
||||
test('resolves to true when an addon match pattern matches an app',
|
||||
function(done) {
|
||||
var wrappedAddon = MockApp(settingsAddon);
|
||||
assert.becomes(AddonManager
|
||||
.addonAffectsApp(wrappedAddon, 'testManifestURL_settings_app'), true)
|
||||
.notify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
335
gaia/apps/settings/test/unit/modules/apn/apn_list_test.js
Executable file
335
gaia/apps/settings/test/unit/modules/apn/apn_list_test.js
Executable file
|
|
@ -0,0 +1,335 @@
|
|||
'use strict';
|
||||
|
||||
suite('ApnList', function() {
|
||||
var FAKE_APN_LIST_KEY = 'fakeKey';
|
||||
var mockAsyncStorage;
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/async_storage': 'MockAsyncStorage',
|
||||
'modules/apn/apn_utils': 'MockApnUtils'
|
||||
}
|
||||
};
|
||||
var modules = [
|
||||
'modules/apn/apn_list',
|
||||
'modules/apn/apn_item',
|
||||
'modules/async_storage',
|
||||
'modules/apn/apn_utils'
|
||||
];
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
mockAsyncStorage = {};
|
||||
|
||||
define('MockAsyncStorage', function() {
|
||||
return {
|
||||
setItem: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
getItem: function(key) {
|
||||
return Promise.resolve(mockAsyncStorage[key]);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
define('MockApnUtils', function() {
|
||||
return {
|
||||
generateId: function() {},
|
||||
clone: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
requireCtx(modules,
|
||||
function(ApnList, ApnItem, MockAsyncStorage, MockApnUtils) {
|
||||
this.ApnList = ApnList;
|
||||
this.ApnItem = ApnItem;
|
||||
this.MockAsyncStorage = MockAsyncStorage;
|
||||
this.MockApnUtils = MockApnUtils;
|
||||
|
||||
// Create mock apn items.
|
||||
this.mockApnItems = [
|
||||
{
|
||||
id: '0',
|
||||
category: 'category0'
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
category: 'category1'
|
||||
}
|
||||
];
|
||||
this.apnList = new this.ApnList(FAKE_APN_LIST_KEY);
|
||||
mockAsyncStorage = {};
|
||||
mockAsyncStorage[FAKE_APN_LIST_KEY] = this.mockApnItems;
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
suite('_add', function() {
|
||||
test('add with category specified', function(done) {
|
||||
var apn = {};
|
||||
var category = 'category';
|
||||
var randomId = 'randomId';
|
||||
|
||||
mockAsyncStorage = {};
|
||||
this.sinon.stub(this.MockApnUtils, 'generateId', function() {
|
||||
return randomId;
|
||||
});
|
||||
|
||||
this.apnList._add(apn, category)
|
||||
.then(function(apnId) {
|
||||
var addedApnItem = this.apnList._apnItems[0];
|
||||
assert.deepEqual(addedApnItem.apn, apn);
|
||||
assert.equal(addedApnItem.id, randomId);
|
||||
assert.equal(addedApnItem.category, category);
|
||||
assert.equal(apnId, randomId);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('add without category specified', function(done) {
|
||||
var apn = {};
|
||||
var randomId = 'randomId';
|
||||
|
||||
mockAsyncStorage = {};
|
||||
this.sinon.stub(this.MockApnUtils, 'generateId', function() {
|
||||
return randomId;
|
||||
});
|
||||
|
||||
this.apnList._add(apn)
|
||||
.then(function(apnId) {
|
||||
var addedApnItem = this.apnList._apnItems[0];
|
||||
assert.deepEqual(addedApnItem.apn, apn);
|
||||
assert.equal(addedApnItem.id, randomId);
|
||||
assert.equal(addedApnItem.category, this.ApnItem.APN_CATEGORY.CUSTOM);
|
||||
assert.equal(apnId, randomId);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_remove', function() {
|
||||
test('no existing apn items', function(done) {
|
||||
mockAsyncStorage = {};
|
||||
|
||||
this.apnList._remove('000')
|
||||
.then(function() {
|
||||
// Should not resolve.
|
||||
assert.isTrue(false);
|
||||
}.bind(this), function(err) {
|
||||
assert.equal(err, 'no apn items');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('remove with valid id', function(done) {
|
||||
var removedApnId = this.mockApnItems[0].id;
|
||||
|
||||
this.apnList._remove(removedApnId)
|
||||
.then(function() {
|
||||
assert.ok(!this.apnList._apnItems.some(
|
||||
(apnItem) => apnItem.id === removedApnId));
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('remove with invalid id', function(done) {
|
||||
var removedApnId = 'invalidId';
|
||||
|
||||
this.apnList._remove(removedApnId)
|
||||
.then(function() {
|
||||
// Should not resolve.
|
||||
assert.isTrue(false);
|
||||
}.bind(this), function(err) {
|
||||
assert.equal(err, 'apn not found');
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_update', function() {
|
||||
test('no existing apn items', function(done) {
|
||||
mockAsyncStorage = {};
|
||||
|
||||
this.apnList._update('000', {})
|
||||
.then(function() {
|
||||
// Should not resolve.
|
||||
assert.isTrue(false);
|
||||
}.bind(this), function(err) {
|
||||
assert.equal(err, 'no apn items');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('update with valid id', function(done) {
|
||||
var updatedApnId = this.mockApnItems[0].id;
|
||||
var apn = {
|
||||
fakeKey: 'fakeValue'
|
||||
};
|
||||
|
||||
this.apnList._update(updatedApnId, apn)
|
||||
.then(function() {
|
||||
assert.equal(this.apnList._apnItems[0].apn.fakeKey, apn.fakeKey);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('update with invalid id', function(done) {
|
||||
var updatedApnId = 'invalidId';
|
||||
|
||||
this.apnList._update(updatedApnId, {})
|
||||
.then(function() {
|
||||
// Should not resolve.
|
||||
assert.isTrue(false);
|
||||
}.bind(this), function(err) {
|
||||
assert.equal(err, 'apn not found');
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('items', function() {
|
||||
test('with cached apn items', function(done) {
|
||||
var that = this;
|
||||
this.apnList._apnItems = this.mockApnItems;
|
||||
|
||||
this.apnList.items()
|
||||
.then(function(result) {
|
||||
assert.equal(result, that.mockApnItems);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('without cached apn items', function(done) {
|
||||
var that = this;
|
||||
this.apnList._apnItems = null;
|
||||
mockAsyncStorage = {};
|
||||
mockAsyncStorage[FAKE_APN_LIST_KEY] = this.mockApnItems;
|
||||
|
||||
this.apnList.items()
|
||||
.then(function(apnItems) {
|
||||
apnItems.forEach(function(apnItem, index) {
|
||||
var mockApnItem = that.mockApnItems[index];
|
||||
assert.equal(apnItem.id, mockApnItem.id);
|
||||
assert.equal(apnItem.category, mockApnItem.category);
|
||||
assert.equal(apnItem.apn, mockApnItem);
|
||||
});
|
||||
assert.equal(apnItems, that.apnList._apnItems);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('item', function() {
|
||||
test('without id specified', function(done) {
|
||||
this.apnList.item()
|
||||
.then(function(apnItem) {
|
||||
assert.isNull(apnItem);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('without existing apn items', function(done) {
|
||||
mockAsyncStorage = {};
|
||||
this.apnList.item('1')
|
||||
.then(function(apnItem) {
|
||||
assert.isNull(apnItem);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('with existing apn items', function(done) {
|
||||
this.apnList._apnItems = this.mockApnItems;
|
||||
|
||||
this.apnList.item('1')
|
||||
.then(function(apnItem) {
|
||||
assert.equal(apnItem.id, '1');
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('add', function() {
|
||||
test('should call to _schedule and _add correctly', function(done) {
|
||||
var apn = {};
|
||||
var category = 'category';
|
||||
var apnClone = {};
|
||||
this.sinon.stub(this.MockApnUtils, 'clone', function() {
|
||||
return apnClone;
|
||||
});
|
||||
this.sinon.stub(this.apnList, '_add', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.spy(this.apnList, '_schedule');
|
||||
|
||||
this.apnList.add(apn, category)
|
||||
.then(function() {
|
||||
sinon.assert.calledWith(this.MockApnUtils.clone, apn);
|
||||
sinon.assert.called(this.apnList._schedule);
|
||||
sinon.assert.calledWith(this.apnList._add, apnClone, category);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('remove', function() {
|
||||
test('should call to _schedule and _remove correctly', function(done) {
|
||||
var apnId = '000';
|
||||
this.sinon.stub(this.apnList, '_remove', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.spy(this.apnList, '_schedule');
|
||||
|
||||
this.apnList.remove(apnId)
|
||||
.then(function() {
|
||||
sinon.assert.called(this.apnList._schedule);
|
||||
sinon.assert.calledWith(this.apnList._remove, apnId);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('update', function() {
|
||||
test('should call to _schedule and _update correctly', function(done) {
|
||||
var apnId = '000';
|
||||
var apn = {};
|
||||
var apnClone = {};
|
||||
this.sinon.stub(this.MockApnUtils, 'clone', function() {
|
||||
return apnClone;
|
||||
});
|
||||
this.sinon.stub(this.apnList, '_update', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.spy(this.apnList, '_schedule');
|
||||
|
||||
this.apnList.update(apnId, apn)
|
||||
.then(function() {
|
||||
sinon.assert.calledWith(this.MockApnUtils.clone, apn);
|
||||
sinon.assert.called(this.apnList._schedule);
|
||||
sinon.assert.calledWith(this.apnList._update, apnId, apnClone);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
186
gaia/apps/settings/test/unit/modules/apn/apn_selections_test.js
Executable file
186
gaia/apps/settings/test/unit/modules/apn/apn_selections_test.js
Executable file
|
|
@ -0,0 +1,186 @@
|
|||
'use strict';
|
||||
|
||||
suite('ApnSelections', function() {
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/settings_cache': 'MockSettingsCache'
|
||||
}
|
||||
};
|
||||
var modules = [
|
||||
'modules/apn/apn_selections',
|
||||
'modules/apn/apn_const',
|
||||
'modules/settings_cache'
|
||||
];
|
||||
|
||||
var realMozSettings;
|
||||
var mockMozSettings;
|
||||
var realMobileConnections;
|
||||
var mockMobileConnections;
|
||||
|
||||
function createMockApnSelections(apnTypes) {
|
||||
var mockApnSelections = [];
|
||||
function addMockApnSelection(apnType, i) {
|
||||
mockApnSelection[apnType] = apnType + '_' + i + '_id';
|
||||
}
|
||||
|
||||
for (var i = 0; i < mockMobileConnections.length; i++) {
|
||||
var mockApnSelection = {};
|
||||
|
||||
apnTypes.forEach(addMockApnSelection);
|
||||
mockApnSelections.push(mockApnSelection);
|
||||
}
|
||||
return mockApnSelections;
|
||||
}
|
||||
|
||||
suiteSetup(function() {
|
||||
mockMozSettings = {
|
||||
_mObservers: {},
|
||||
createLock: function() {
|
||||
return {
|
||||
set: function() {
|
||||
var obj = {};
|
||||
setTimeout(function() {
|
||||
obj.onsuccess();
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
},
|
||||
addObserver: function(name, callback) {
|
||||
this._mObservers[name] = this._mObservers[name] || [];
|
||||
this._mObservers[name].push(callback);
|
||||
},
|
||||
mTriggerObservers: function(name, value) {
|
||||
this._mObservers[name].forEach(function(callback) {
|
||||
callback({
|
||||
settingValue: value
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
realMozSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = mockMozSettings;
|
||||
|
||||
mockMobileConnections = [{}, {}];
|
||||
realMobileConnections = navigator.mozMobileConnections;
|
||||
navigator.mozMobileConnections = mockMobileConnections;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozSettings = realMozSettings;
|
||||
navigator.mozMobileConnections = realMobileConnections;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
var that = this;
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
this.mockSettingsDB = {};
|
||||
define('MockSettingsCache', function() {
|
||||
return {
|
||||
getSettings: function(callback) {
|
||||
callback(that.mockSettingsDB);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
requireCtx(modules,
|
||||
function(ApnSelections, ApnConst, MockSettingsCache) {
|
||||
this.ApnSelections = ApnSelections;
|
||||
this.ApnConst = ApnConst;
|
||||
this.MockSettingsCache = MockSettingsCache;
|
||||
|
||||
this.apnSelections = new this.ApnSelections();
|
||||
this.mockApnSelections =
|
||||
createMockApnSelections(this.ApnConst.APN_TYPES);
|
||||
this.mockSettingsDB[this.ApnConst.APN_SELECTIONS_KEY] =
|
||||
this.mockApnSelections;
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
suite('get', function() {
|
||||
test('should get correct apn selections', function(done) {
|
||||
var isTheSameSelection = (function(selection1, selection2) {
|
||||
return this.ApnConst.APN_TYPES.every(function(apnType) {
|
||||
return selection1[apnType] === selection2[apnType];
|
||||
});
|
||||
}).bind(this);
|
||||
|
||||
var promises = [];
|
||||
for (var i = 0; i < mockMobileConnections.length; i++) {
|
||||
promises.push(this.apnSelections.get(i));
|
||||
}
|
||||
Promise.all(promises).then(function(results) {
|
||||
results.forEach(function(result, index) {
|
||||
assert.ok(isTheSameSelection(result, this.mockApnSelections[index]));
|
||||
}, this);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should get empty apn selections when apn selections is unavailable',
|
||||
function(done) {
|
||||
this.mockSettingsDB[this.ApnConst.APN_SELECTIONS_KEY] = null;
|
||||
var isEmptySelection = (function(selection) {
|
||||
return this.ApnConst.APN_TYPES.every(function(apnType) {
|
||||
return selection[apnType] == null;
|
||||
});
|
||||
}).bind(this);
|
||||
|
||||
var promises = [];
|
||||
for (var i = 0; i < mockMobileConnections.length; i++) {
|
||||
promises.push(this.apnSelections.get(i));
|
||||
}
|
||||
Promise.all(promises).then(function(results) {
|
||||
results.forEach(function(result) {
|
||||
assert.ok(isEmptySelection(result));
|
||||
}, this);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should commit when the selection is changed', function(done) {
|
||||
var FAKE_ACTIVE_APN_ID = '000';
|
||||
this.sinon.spy(this.apnSelections, '_commit');
|
||||
|
||||
this.apnSelections.get(0).then(function(apnSelection) {
|
||||
apnSelection['default'] = FAKE_ACTIVE_APN_ID;
|
||||
sinon.assert.called(this.apnSelections._commit);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('clear', function() {
|
||||
test('should clear selection correctly', function(done) {
|
||||
this.apnSelections.clear(0).then(function() {
|
||||
this.ApnConst.APN_TYPES.forEach(function(apnType) {
|
||||
assert.isTrue(this.mockApnSelections[apnType] == null);
|
||||
}, this);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
test('The ready promise should be set to null when the field of ' +
|
||||
'apn.selections is cleared', function(done) {
|
||||
this.apnSelections._ready().then(function() {
|
||||
mockMozSettings
|
||||
.mTriggerObservers(this.ApnConst.APN_SELECTIONS_KEY, null);
|
||||
assert.equal(this._readyPromise, null);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
1151
gaia/apps/settings/test/unit/modules/apn/apn_settings_manager_test.js
Executable file
1151
gaia/apps/settings/test/unit/modules/apn/apn_settings_manager_test.js
Executable file
File diff suppressed because it is too large
Load diff
205
gaia/apps/settings/test/unit/modules/apn/apn_settings_test.js
Executable file
205
gaia/apps/settings/test/unit/modules/apn/apn_settings_test.js
Executable file
|
|
@ -0,0 +1,205 @@
|
|||
'use strict';
|
||||
|
||||
suite('ApnSettings', function() {
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/apn/apn_utils': 'MockApnUtils',
|
||||
'modules/settings_cache': 'MockSettingsCache'
|
||||
}
|
||||
};
|
||||
var modules = [
|
||||
'modules/apn/apn_settings',
|
||||
'modules/apn/apn_const',
|
||||
'modules/apn/apn_utils',
|
||||
'modules/settings_cache'
|
||||
];
|
||||
|
||||
var findTargetSettings = function(apnSettings, serviceId, apnType) {
|
||||
return apnSettings._apnSettings[serviceId].find(function(apn) {
|
||||
return apn.types.some((type) => apnType === type);
|
||||
});
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
var that = this;
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
this.mockSettingsDB = {};
|
||||
define('MockSettingsCache', function() {
|
||||
return {
|
||||
getSettings: function(callback) {
|
||||
callback(that.mockSettingsDB);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
define('MockApnUtils', function() {
|
||||
return {
|
||||
clone: function() {},
|
||||
isMatchedApn: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
requireCtx(modules,
|
||||
function(ApnSettings, ApnConst, MockApnUtils, MockSettingsCache) {
|
||||
this.ApnSettings = ApnSettings;
|
||||
this.ApnConst = ApnConst;
|
||||
this.MockApnUtils = MockApnUtils;
|
||||
this.MockSettingsCache = MockSettingsCache;
|
||||
|
||||
this.apnSettings = new this.ApnSettings();
|
||||
this.mockApnSettings = [
|
||||
[{ carrier: 'fakeCarrier1', types: ['default'] }],
|
||||
[{ carrier: 'fakeCarrier2', types: ['mms'] }]
|
||||
];
|
||||
this.mockSettingsDB = {};
|
||||
this.mockSettingsDB[this.ApnConst.APN_SETTINGS_KEY] =
|
||||
this.mockApnSettings;
|
||||
done();
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
suite('_ready', function() {
|
||||
test('should init the settings correctly', function(done) {
|
||||
this.sinon.stub(this.apnSettings, '_addObservers');
|
||||
|
||||
this.apnSettings._ready()
|
||||
.then(function() {
|
||||
assert.ok(this.apnSettings._isReady);
|
||||
assert.deepEqual(this.apnSettings._apnSettings, this.mockApnSettings);
|
||||
sinon.assert.called(this.apnSettings._addObservers);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_update', function() {
|
||||
var serviceId = 0;
|
||||
var apnType = 'default';
|
||||
|
||||
test('update with apn', function(done) {
|
||||
this.sinon.stub(this.MockApnUtils, 'isMatchedApn', function() {
|
||||
return false;
|
||||
});
|
||||
var newApnSetting = { carrier: 'newCarrier', types: [apnType] };
|
||||
|
||||
this.apnSettings._update(serviceId, apnType, newApnSetting)
|
||||
.then(function() {
|
||||
var targetApnSettings =
|
||||
findTargetSettings(this.apnSettings, serviceId, apnType);
|
||||
assert.deepEqual(targetApnSettings, newApnSetting);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('update with null', function(done) {
|
||||
this.apnSettings._update(serviceId, apnType, null)
|
||||
.then(function() {
|
||||
var targetApnSettings =
|
||||
findTargetSettings(this.apnSettings, serviceId, apnType);
|
||||
assert.ok(targetApnSettings === undefined);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAll', function() {
|
||||
var serviceId = 0;
|
||||
|
||||
test('should return correct apn setting', function(done) {
|
||||
this.apnSettings.getAll(serviceId)
|
||||
.then(function(apnSetting) {
|
||||
assert.deepEqual(apnSetting, this.mockApnSettings[serviceId]);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('get', function() {
|
||||
var serviceId = 0;
|
||||
var apnType = 'default';
|
||||
|
||||
test('should return correct apn setting', function(done) {
|
||||
this.apnSettings.get(serviceId, apnType)
|
||||
.then(function(apnSetting) {
|
||||
var targetApnSettings =
|
||||
findTargetSettings(this.apnSettings, serviceId, apnType);
|
||||
assert.deepEqual(targetApnSettings, apnSetting);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should return null if no existing setting', function(done) {
|
||||
this.mockSettingsDB[this.ApnConst.APN_SETTINGS_KEY] = {};
|
||||
this.apnSettings.get(serviceId, apnType)
|
||||
.then(function(apnSetting) {
|
||||
assert.isNull(apnSetting);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('update', function() {
|
||||
var serviceId = 0;
|
||||
var apnType = 'default';
|
||||
|
||||
test('should call to _schedule and _update correctly', function(done) {
|
||||
var apn = {};
|
||||
var apnClone = {};
|
||||
this.sinon.stub(this.MockApnUtils, 'clone', function() {
|
||||
return apnClone;
|
||||
});
|
||||
this.sinon.stub(this.apnSettings, '_commit', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.stub(this.apnSettings, '_update', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.spy(this.apnSettings, '_schedule');
|
||||
|
||||
this.apnSettings.update(serviceId, apnType, apn)
|
||||
.then(function(apnSetting) {
|
||||
sinon.assert.calledWith(this.MockApnUtils.clone, apn);
|
||||
sinon.assert.called(this.apnSettings._schedule);
|
||||
sinon.assert.calledWith(this.apnSettings._update, serviceId, apnType,
|
||||
apnClone);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('restore', function() {
|
||||
var serviceId = 0;
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(this.apnSettings, '_schedule', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
test('should restore to default apn settings correctly', function(done) {
|
||||
this.apnSettings._apnSettings = [];
|
||||
this.apnSettings.restore(serviceId)
|
||||
.then(function() {
|
||||
assert.deepEqual(this.apnSettings._apnSettings, this.mockApnSettings);
|
||||
}.bind(this), function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
50
gaia/apps/settings/test/unit/modules/app_storage_test.js
Executable file
50
gaia/apps/settings/test/unit/modules/app_storage_test.js
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
/* global MockGetDeviceStorage */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_event_target.js');
|
||||
require('/shared/test/unit/mocks/mock_dom_request.js');
|
||||
require('/shared/test/unit/mocks/mock_navigator_getdevicestorage.js');
|
||||
|
||||
suite('AppStorage > ', function() {
|
||||
var AppStorage;
|
||||
var realDeviceStorage;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
realDeviceStorage = navigator.getDeviceStorage;
|
||||
navigator.getDeviceStorage = MockGetDeviceStorage;
|
||||
|
||||
testRequire(['modules/app_storage'], function(app_storage) {
|
||||
AppStorage = app_storage;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.getDeviceStorage = realDeviceStorage;
|
||||
realDeviceStorage = null;
|
||||
});
|
||||
|
||||
suite('_getSpaceInfo', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(AppStorage._appStorage, 'freeSpace');
|
||||
this.sinon.spy(AppStorage._appStorage, 'usedSpace');
|
||||
AppStorage._getSpaceInfo();
|
||||
});
|
||||
|
||||
test('we would call freeSpace and usedSpace in _getSpaceInfo',
|
||||
function() {
|
||||
assert.ok(AppStorage._appStorage.freeSpace.called);
|
||||
|
||||
var req = AppStorage._appStorage.freeSpace.getCall(0).returnValue;
|
||||
req.fireSuccess(100);
|
||||
assert.equal(100, AppStorage.freeSize);
|
||||
|
||||
assert.ok(AppStorage._appStorage.usedSpace.called);
|
||||
var req2 = AppStorage._appStorage.usedSpace.getCall(0).returnValue;
|
||||
req2.fireSuccess(300);
|
||||
assert.equal(300, AppStorage.usedSize);
|
||||
assert.equal(400, AppStorage.totalSize);
|
||||
assert.equal(75, AppStorage.usedPercentage);
|
||||
});
|
||||
});
|
||||
});
|
||||
156
gaia/apps/settings/test/unit/modules/apps_cache_test.js
Executable file
156
gaia/apps/settings/test/unit/modules/apps_cache_test.js
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
/* global MockMozApps */
|
||||
'use strict';
|
||||
|
||||
requireApp('settings/test/unit/mock_moz_apps.js');
|
||||
|
||||
suite('AppsCache', function() {
|
||||
var modules = [
|
||||
'modules/apps_cache'
|
||||
];
|
||||
|
||||
var realMozApps;
|
||||
var appsCache;
|
||||
|
||||
suiteSetup(function() {
|
||||
realMozApps = window.navigator.mozApps;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.navigator.mozApps = realMozApps;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
window.navigator.mozApps = MockMozApps;
|
||||
var requireCtx = testRequire([], {}, function() {});
|
||||
requireCtx(modules, function(AppsCache) {
|
||||
appsCache = AppsCache;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('apps', function() {
|
||||
var apps = [
|
||||
{ manifest: { role : 'homescreen' } },
|
||||
{ manifest: { role : 'homescreen' } }
|
||||
];
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(appsCache, '_init', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
appsCache._apps = apps;
|
||||
});
|
||||
|
||||
test('we can get the same apps back', function(done) {
|
||||
appsCache.apps().then(function(foundApps) {
|
||||
assert.equal(foundApps, apps);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_init', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(appsCache, '_initApps', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
this.sinon.stub(appsCache, '_initEvents');
|
||||
});
|
||||
|
||||
test('related functions are executed', function(done) {
|
||||
appsCache._init().then(function() {
|
||||
assert.isTrue(appsCache._initApps.called);
|
||||
assert.isTrue(appsCache._initEvents.called);
|
||||
}, function() {
|
||||
// This function does not reject.
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_initEvents', function() {
|
||||
var apps = [
|
||||
{ manifestURL: 'http://example.org/abc/manifest.webapp' },
|
||||
{ manifestURL: 'http://example.com/manifest.webapp' },
|
||||
{ manifestURL: 'http://example.com/manifest.webapp' }
|
||||
];
|
||||
|
||||
setup(function() {
|
||||
MockMozApps.mgmt.oninstall = this.sinon.spy();
|
||||
MockMozApps.mgmt.onuninstall = this.sinon.spy();
|
||||
appsCache._initEvents();
|
||||
appsCache._apps = apps;
|
||||
});
|
||||
|
||||
test('we will register two necessary events', function() {
|
||||
assert.equal(MockMozApps.mgmt.oninstall.called);
|
||||
assert.equal(MockMozApps.mgmt.onuninstall.called);
|
||||
});
|
||||
|
||||
test('install should not add the same app multiple times', function() {
|
||||
appsCache._apps = [
|
||||
{ manifestURL: 'http://example.org/abc/manifest.webapp', name: 'Abc' }
|
||||
];
|
||||
MockMozApps.mgmt.oninstall({
|
||||
application: {
|
||||
manifestURL: 'http://example.org/abc/manifest.webapp',
|
||||
name: 'Def'
|
||||
}
|
||||
});
|
||||
assert.equal(appsCache._apps.length, 1);
|
||||
assert.equal(appsCache._apps[0].name, 'Def');
|
||||
});
|
||||
|
||||
test('uninstall should remove all apps with the same manifest', function() {
|
||||
assert.equal(appsCache._apps.length, 3);
|
||||
MockMozApps.mgmt.onuninstall({
|
||||
application: { manifestURL: 'http://example.com/manifest.webapp' }
|
||||
});
|
||||
assert.equal(appsCache._apps.length, 1);
|
||||
assert.equal(appsCache._apps[0].manifestURL,
|
||||
'http://example.org/abc/manifest.webapp');
|
||||
});
|
||||
});
|
||||
|
||||
suite('_initApps', function() {
|
||||
var testApps = [{}, {}];
|
||||
|
||||
setup(function() {
|
||||
MockMozApps.mSetApps(testApps);
|
||||
});
|
||||
|
||||
test('we will get apps', function(done) {
|
||||
appsCache._initApps().then(function() {
|
||||
assert.equal(appsCache._apps, testApps);
|
||||
}).then(done, done);
|
||||
MockMozApps.mTriggerGetAllAppsCallback();
|
||||
});
|
||||
});
|
||||
|
||||
suite('addEventListener', function() {
|
||||
var testFunction = function() {};
|
||||
|
||||
setup(function() {
|
||||
appsCache.addEventListener('oninstall', testFunction);
|
||||
});
|
||||
|
||||
test('we did cache it', function() {
|
||||
assert.equal(appsCache._eventHandlers.oninstall[0], testFunction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('removeEventListener', function() {
|
||||
var testFunction = function() {};
|
||||
|
||||
setup(function() {
|
||||
appsCache._eventHandlers.oninstall.push(testFunction);
|
||||
appsCache.removeEventListener('oninstall', testFunction);
|
||||
});
|
||||
|
||||
test('we did remove it', function() {
|
||||
assert.equal(appsCache._eventHandlers.oninstall.length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
82
gaia/apps/settings/test/unit/modules/base/dependency_graph_test.js
Executable file
82
gaia/apps/settings/test/unit/modules/base/dependency_graph_test.js
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
'use strict';
|
||||
|
||||
suite('DependencyGraph', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/dependency_graph'], (DependencyGraph) => {
|
||||
this.DependencyGraph = DependencyGraph;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.graph = this.DependencyGraph();
|
||||
});
|
||||
|
||||
suite('getAllDependent', function() {
|
||||
test('a->b, b->c', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
this.graph.addDependency('b', 'c');
|
||||
assert.sameMembers(this.graph.getAllDependent('a'), []);
|
||||
assert.sameMembers(this.graph.getAllDependent('b'), ['a']);
|
||||
assert.sameMembers(this.graph.getAllDependent('c'), ['a', 'b']);
|
||||
});
|
||||
|
||||
test('b->c, c->a', function() {
|
||||
this.graph.addDependency('b', 'c');
|
||||
this.graph.addDependency('a', 'b');
|
||||
assert.sameMembers(this.graph.getAllDependent('a'), []);
|
||||
assert.sameMembers(this.graph.getAllDependent('b'), ['a']);
|
||||
assert.sameMembers(this.graph.getAllDependent('c'), ['a', 'b']);
|
||||
});
|
||||
|
||||
test('a->b, b->c, d->b', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
this.graph.addDependency('b', 'c');
|
||||
this.graph.addDependency('d', 'b');
|
||||
assert.sameMembers(this.graph.getAllDependent('a'), []);
|
||||
assert.sameMembers(this.graph.getAllDependent('b'), ['a', 'd']);
|
||||
assert.sameMembers(this.graph.getAllDependent('c'), ['a', 'b', 'd']);
|
||||
});
|
||||
|
||||
test('a->b, b->c, b->d, b->e, d->f, e->f', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
this.graph.addDependency('b', 'c');
|
||||
this.graph.addDependency('b', 'd');
|
||||
this.graph.addDependency('b', 'e');
|
||||
this.graph.addDependency('d', 'f');
|
||||
this.graph.addDependency('e', 'f');
|
||||
assert.sameMembers(this.graph.getAllDependent('a'), []);
|
||||
assert.sameMembers(this.graph.getAllDependent('b'), ['a']);
|
||||
assert.sameMembers(this.graph.getAllDependent('c'), ['a', 'b']);
|
||||
assert.sameMembers(this.graph.getAllDependent('d'), ['a', 'b']);
|
||||
assert.sameMembers(this.graph.getAllDependent('e'), ['a', 'b']);
|
||||
assert.sameMembers(this.graph.getAllDependent('f'), ['a', 'b', 'd', 'e']);
|
||||
});
|
||||
});
|
||||
|
||||
suite('throws when a circular dependency is detected', function() {
|
||||
test('a->b, b->a', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
assert.throw(() => {
|
||||
this.graph.addDependency('b', 'a');
|
||||
}, Error, 'circular dependency detected! b -> a -> b');
|
||||
});
|
||||
|
||||
test('a->b, c->a, b->c', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
this.graph.addDependency('c', 'a');
|
||||
assert.throw(() => {
|
||||
this.graph.addDependency('b', 'c');
|
||||
}, Error, 'circular dependency detected! b -> c -> a -> b');
|
||||
});
|
||||
|
||||
test('a->b, c->d, d->a, b->c', function() {
|
||||
this.graph.addDependency('a', 'b');
|
||||
this.graph.addDependency('c', 'd');
|
||||
this.graph.addDependency('d', 'a');
|
||||
assert.throw(() => {
|
||||
this.graph.addDependency('b', 'c');
|
||||
}, Error, 'circular dependency detected! b -> c -> d -> a -> b');
|
||||
});
|
||||
});
|
||||
});
|
||||
98
gaia/apps/settings/test/unit/modules/base/event_emitter_test.js
Executable file
98
gaia/apps/settings/test/unit/modules/base/event_emitter_test.js
Executable file
|
|
@ -0,0 +1,98 @@
|
|||
'use strict';
|
||||
|
||||
suite('EventEmitter', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/event_emitter'], (EventEmitter) => {
|
||||
this.EventEmitter = EventEmitter;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('constructor', function() {
|
||||
test('should have an array for each event', function() {
|
||||
var emitter = this.EventEmitter(['event1', 'event2']);
|
||||
assert.isArray(emitter._eventListeners.event1);
|
||||
assert.isArray(emitter._eventListeners.event2);
|
||||
});
|
||||
|
||||
test('should throw when no valid event names', function() {
|
||||
assert.throw(() => {
|
||||
this.EventEmitter();
|
||||
}, Error, 'no valid registered events');
|
||||
});
|
||||
});
|
||||
|
||||
suite('addEventListener', function() {
|
||||
setup(function() {
|
||||
this.emitter = this.EventEmitter(['event1', 'event2']);
|
||||
});
|
||||
|
||||
suite('should call to the listener when emitting the event', function() {
|
||||
test('register a function', function() {
|
||||
var listener = sinon.spy();
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledWith(listener, sinon.match({
|
||||
type: 'event1',
|
||||
detail: 'value1'
|
||||
}));
|
||||
});
|
||||
|
||||
test('register an object', function() {
|
||||
var eventHandler = {
|
||||
handleEvent: sinon.spy()
|
||||
};
|
||||
this.emitter.addEventListener('event1', eventHandler);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledWith(eventHandler.handleEvent, sinon.match({
|
||||
type: 'event1',
|
||||
detail: 'value1'
|
||||
}));
|
||||
});
|
||||
|
||||
test('should only call once when registering multiple times', function() {
|
||||
var listener = sinon.spy();
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledWith(listener, sinon.match({
|
||||
type: 'event1',
|
||||
detail: 'value1'
|
||||
}));
|
||||
sinon.assert.calledOnce(listener);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('removeEventListener', function() {
|
||||
setup(function() {
|
||||
this.emitter = this.EventEmitter(['event1', 'event2']);
|
||||
});
|
||||
|
||||
suite('should not call to the listener when it is removed', function() {
|
||||
test('the listener is a function', function() {
|
||||
var listener = sinon.spy();
|
||||
this.emitter.addEventListener('event1', listener);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledOnce(listener);
|
||||
this.emitter.removeEventListener('event1', listener);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledOnce(listener);
|
||||
});
|
||||
|
||||
test('the listener is an object', function() {
|
||||
var eventHandler = {
|
||||
handleEvent: sinon.spy()
|
||||
};
|
||||
this.emitter.addEventListener('event1', eventHandler);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledOnce(eventHandler.handleEvent);
|
||||
this.emitter.removeEventListener('event1', eventHandler);
|
||||
this.emitter._emitEvent('event1', 'value1');
|
||||
sinon.assert.calledOnce(eventHandler.handleEvent);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
207
gaia/apps/settings/test/unit/modules/base/module_test.js
Executable file
207
gaia/apps/settings/test/unit/modules/base/module_test.js
Executable file
|
|
@ -0,0 +1,207 @@
|
|||
'use strict';
|
||||
|
||||
suite('Module', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/module'], (Module) => {
|
||||
this.Module = Module;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('create', function() {
|
||||
test('constructor is called when instantiation', function() {
|
||||
var constructor = sinon.spy();
|
||||
var Module = this.Module.create(constructor);
|
||||
Module();
|
||||
assert.ok(constructor.called);
|
||||
});
|
||||
|
||||
test('throws when the constructor is invalid', function() {
|
||||
assert.throw(function() {
|
||||
this.Module.create({});
|
||||
}, Error);
|
||||
});
|
||||
|
||||
test('name of the module is the name of the constructor', function() {
|
||||
var constructor = function FakeModule() {};
|
||||
var Module = this.Module.create(constructor);
|
||||
assert.equal(Module().$name, constructor.name);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Extendibility', function() {
|
||||
suite('extend', function() {
|
||||
var A, B, C;
|
||||
var instanceOfA, instanceOfB, instanceOfC;
|
||||
|
||||
function executeTest() {
|
||||
test('have individual properties', function() {
|
||||
// Default values are the same
|
||||
assert.equal(instanceOfC.propertyA, instanceOfA.propertyA);
|
||||
assert.equal(instanceOfC.propertyB, instanceOfB.propertyB);
|
||||
|
||||
// Check whether they are individual.
|
||||
instanceOfC.propertyA = 'valueA2';
|
||||
instanceOfC.propertyB = 'valueB2';
|
||||
assert.equal(instanceOfA.propertyA, 'valueA');
|
||||
assert.equal(instanceOfB.propertyB, 'valueB');
|
||||
});
|
||||
|
||||
test('share the same function ', function() {
|
||||
assert.equal(instanceOfC.funcA, instanceOfA.funcA);
|
||||
assert.equal(instanceOfC.funcB, instanceOfB.funcB);
|
||||
});
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
instanceOfA = A();
|
||||
instanceOfB = B();
|
||||
instanceOfC = C();
|
||||
});
|
||||
|
||||
suite('extend from a single module', function() {
|
||||
suiteSetup(function() {
|
||||
A = this.Module.create(function() {
|
||||
this.propertyA = 'valueA';
|
||||
});
|
||||
A.prototype.funcA = function() { return this.propertyA; };
|
||||
|
||||
B = this.Module.create(function() {
|
||||
this.super(A).call(this);
|
||||
this.propertyB = 'valueB';
|
||||
}).extend(A);
|
||||
B.prototype.funcB = function() { return this.propertyB; };
|
||||
|
||||
C = this.Module.create(function() {
|
||||
this.super(B).call(this);
|
||||
}).extend(B);
|
||||
});
|
||||
|
||||
executeTest();
|
||||
});
|
||||
|
||||
suite('extend from multiple modules', function() {
|
||||
suiteSetup(function() {
|
||||
A = this.Module.create(function() {
|
||||
this.propertyA = 'valueA';
|
||||
});
|
||||
A.prototype.funcA = function() { return this.propertyA; };
|
||||
|
||||
B = this.Module.create(function() {
|
||||
this.propertyB = 'valueB';
|
||||
});
|
||||
B.prototype.funcB = function() { return this.propertyB; };
|
||||
|
||||
C = this.Module.create(function() {
|
||||
this.super(A).call(this);
|
||||
this.super(B).call(this);
|
||||
}).extend(A, B);
|
||||
});
|
||||
|
||||
executeTest();
|
||||
});
|
||||
});
|
||||
|
||||
suite('super', function() {
|
||||
var ctorA, ctorB;
|
||||
var A, B;
|
||||
|
||||
setup(function() {
|
||||
ctorA = sinon.spy();
|
||||
ctorB = sinon.spy();
|
||||
A = this.Module.create(ctorA);
|
||||
B = this.Module.create(ctorB).extend(A);
|
||||
});
|
||||
|
||||
test('able to call to the constructors of the extended modules',
|
||||
function() {
|
||||
var C = this.Module.create(function() {
|
||||
this.super(A).call(this);
|
||||
this.super(B).call(this);
|
||||
}).extend(A, B);
|
||||
C();
|
||||
|
||||
assert.ok(ctorA.called);
|
||||
assert.ok(ctorB.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('logging', function() {
|
||||
var module;
|
||||
|
||||
function doLog(obj) {
|
||||
obj.debug('debug');
|
||||
obj.info('info');
|
||||
obj.warn('warn');
|
||||
obj.error('error');
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(console, 'log');
|
||||
this.sinon.stub(console, 'info');
|
||||
this.sinon.stub(console, 'warn');
|
||||
this.sinon.stub(console, 'error');
|
||||
var Module = this.Module.create(function A() {});
|
||||
module = Module();
|
||||
});
|
||||
|
||||
test('NONE', function() {
|
||||
module._logLevel = this.Module.LOG_LEVEL.NONE;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.notCalled);
|
||||
assert.ok(console.info.notCalled);
|
||||
assert.ok(console.warn.notCalled);
|
||||
assert.ok(console.error.notCalled);
|
||||
});
|
||||
|
||||
test('DEBUG', function() {
|
||||
module._logLevel = this.Module.LOG_LEVEL.DEBUG;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.called);
|
||||
assert.ok(console.info.notCalled);
|
||||
assert.ok(console.warn.notCalled);
|
||||
assert.ok(console.error.notCalled);
|
||||
});
|
||||
|
||||
test('INFO', function() {
|
||||
module._logLevel = this.Module.LOG_LEVEL.INFO;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.called);
|
||||
assert.ok(console.info.called);
|
||||
assert.ok(console.warn.notCalled);
|
||||
assert.ok(console.error.notCalled);
|
||||
});
|
||||
|
||||
test('WARN', function() {
|
||||
module._logLevel = this.Module.LOG_LEVEL.WARN;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.called);
|
||||
assert.ok(console.info.called);
|
||||
assert.ok(console.warn.called);
|
||||
assert.ok(console.error.notCalled);
|
||||
});
|
||||
|
||||
test('ERROR && ALL', function() {
|
||||
module._logLevel = this.Module.LOG_LEVEL.ERROR;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.called);
|
||||
assert.ok(console.info.called);
|
||||
assert.ok(console.warn.called);
|
||||
assert.ok(console.error.called);
|
||||
|
||||
module._logLevel = this.Module.LOG_LEVEL.ALL;
|
||||
doLog(module);
|
||||
|
||||
assert.ok(console.log.called);
|
||||
assert.ok(console.info.called);
|
||||
assert.ok(console.warn.called);
|
||||
assert.ok(console.error.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
135
gaia/apps/settings/test/unit/modules/base/task_scheduler_test.js
Executable file
135
gaia/apps/settings/test/unit/modules/base/task_scheduler_test.js
Executable file
|
|
@ -0,0 +1,135 @@
|
|||
'use strict';
|
||||
|
||||
suite('TaskScheduler >', function() {
|
||||
setup(function(done) {
|
||||
testRequire(['modules/base/task_scheduler'], (TaskScheduler) => {
|
||||
this.taskScheduler = TaskScheduler();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('_lock()', function() {
|
||||
this.taskScheduler._lock();
|
||||
assert.ok(this.taskScheduler.isLocked,
|
||||
'we will set internal lock to make sure it\'s locked');
|
||||
});
|
||||
|
||||
test('_unlock()', function() {
|
||||
this.sinon.stub(this.taskScheduler, '_executeNextTask');
|
||||
this.taskScheduler._unlock();
|
||||
assert.ok(this.taskScheduler._executeNextTask.called,
|
||||
'we will release internal lock');
|
||||
});
|
||||
|
||||
suite('_executeNextTask()', function() {
|
||||
suite('if isLocked', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(this.taskScheduler._tasks, 'shift');
|
||||
this.taskScheduler.isLocked = true;
|
||||
this.taskScheduler._executeNextTask();
|
||||
});
|
||||
|
||||
test('do nothing', function() {
|
||||
assert.isFalse(this.taskScheduler._tasks.shift.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('if not locked, and task is resolved here', function() {
|
||||
setup(function() {
|
||||
this.taskScheduler.isLocked = false;
|
||||
this.sinon.stub(this.taskScheduler, '_unlock');
|
||||
this.taskScheduler._tasks = [{
|
||||
func: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
defer: {
|
||||
resolve: Promise.resolve.bind(Promise),
|
||||
reject: Promise.reject.bind(Promise)
|
||||
}
|
||||
}];
|
||||
});
|
||||
|
||||
test('we will do following works', function(done) {
|
||||
this.taskScheduler._executeNextTask().then(() => {
|
||||
assert.isTrue(this.taskScheduler._unlock.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('if not locked, and task is rejected here', function() {
|
||||
setup(function() {
|
||||
this.taskScheduler.isLocked = false;
|
||||
this.sinon.stub(this.taskScheduler, '_unlock');
|
||||
this.taskScheduler._tasks = [{
|
||||
func: function() {
|
||||
return Promise.reject();
|
||||
},
|
||||
defer: {
|
||||
resolve: Promise.resolve.bind(Promise),
|
||||
reject: Promise.reject.bind(Promise)
|
||||
}
|
||||
}];
|
||||
});
|
||||
|
||||
test('we will do following works', function(done) {
|
||||
this.taskScheduler._executeNextTask().then(() => {
|
||||
assert.isTrue(this.taskScheduler._unlock.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_removeRedundantTasks()', function() {
|
||||
test('we will drop same-type tasks', function() {
|
||||
this.taskScheduler._tasks = [
|
||||
{ cancelable: true, type: 'type1' },
|
||||
{ cancelable: true, type: 'type1' },
|
||||
{ cancelable: true, type: 'type1' },
|
||||
{ cancelable: true, type: 'type2' }
|
||||
];
|
||||
var leftTasks = this.taskScheduler._removeRedundantTasks('type1');
|
||||
assert.equal(leftTasks.length, 1);
|
||||
assert.equal(leftTasks[0].type, 'type2');
|
||||
});
|
||||
|
||||
test('we will keep cancelable:false tasks and drop same-type tasks',
|
||||
function() {
|
||||
this.taskScheduler._tasks = [
|
||||
{ cancelable: false, type: 'type1' },
|
||||
{ cancelable: false, type: 'type1' },
|
||||
{ cancelable: true, type: 'type1' }, // this will be dropped
|
||||
{ cancelable: true, type: 'type2' }
|
||||
];
|
||||
var leftTasks = this.taskScheduler._removeRedundantTasks('type1');
|
||||
assert.equal(leftTasks.length, 3);
|
||||
});
|
||||
});
|
||||
|
||||
suite('enqueue()', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(this.taskScheduler, '_executeNextTask');
|
||||
this.sinon.spy(this.taskScheduler, '_removeRedundantTasks');
|
||||
});
|
||||
suite('if no task.func', function() {
|
||||
test('we will do nothing', function(done) {
|
||||
this.taskScheduler.enqueue({}).then(() => {
|
||||
assert.isFalse(this.taskScheduler._executeNextTask.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('if we have task.func', function() {
|
||||
test('we will do following works', function(done) {
|
||||
this.taskScheduler.enqueue({
|
||||
type: 'type1',
|
||||
func: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}).then(() => {
|
||||
assert.isTrue(this.taskScheduler._executeNextTask.called);
|
||||
assert.isTrue(this.taskScheduler._removeRedundantTasks.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
157
gaia/apps/settings/test/unit/modules/battery_test.js
Executable file
157
gaia/apps/settings/test/unit/modules/battery_test.js
Executable file
|
|
@ -0,0 +1,157 @@
|
|||
/* global define */
|
||||
'use strict';
|
||||
|
||||
suite('Battery', function() {
|
||||
var sandbox = sinon.sandbox.create();
|
||||
var MockPlatformBattery;
|
||||
var map = {
|
||||
'modules/battery': {
|
||||
'modules/navigator/battery': 'MockPlatformBattery'
|
||||
}
|
||||
};
|
||||
|
||||
// Load a new Batery instance
|
||||
var loadBattery = function(callback) {
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
define('MockPlatformBattery', function() {
|
||||
return MockPlatformBattery;
|
||||
});
|
||||
requireCtx(['modules/battery'], callback);
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
MockPlatformBattery = {
|
||||
charging: null,
|
||||
level: null,
|
||||
addEventListener: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
suite('return correct values when initialized', function() {
|
||||
test('charging', function(done) {
|
||||
MockPlatformBattery.charging = true;
|
||||
MockPlatformBattery.level = 0.5;
|
||||
MockPlatformBattery.chargingTime = 13337;
|
||||
MockPlatformBattery.dischargingTime = Infinity;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
assert.equal(Battery.level, 50);
|
||||
assert.equal(Battery.state, 'charging');
|
||||
assert.equal(Battery.chargingTime, 13337);
|
||||
assert.equal(Battery.dischargingTime, Infinity);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('charged', function(done) {
|
||||
MockPlatformBattery.charging = true;
|
||||
MockPlatformBattery.level = 1;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
assert.equal(Battery.level, 100);
|
||||
assert.equal(Battery.state, 'charged');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('unplugged', function(done) {
|
||||
MockPlatformBattery.charging = false;
|
||||
MockPlatformBattery.level = 1;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
assert.equal(Battery.level, 100);
|
||||
assert.equal(Battery.state, 'unplugged');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('status changes', function() {
|
||||
test('should reflect level changes', function(done) {
|
||||
sandbox.spy(MockPlatformBattery, 'addEventListener');
|
||||
MockPlatformBattery.level = 0.5;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
assert.equal(Battery.level, 50);
|
||||
// change the level
|
||||
MockPlatformBattery.level = 0.51;
|
||||
// emit the event
|
||||
MockPlatformBattery.addEventListener.args.some(function(arg) {
|
||||
if (arg[0] === 'levelchange') {
|
||||
arg[1].call();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
assert.equal(Battery.level, 51);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should reflect state changes', function(done) {
|
||||
sandbox.spy(MockPlatformBattery, 'addEventListener');
|
||||
MockPlatformBattery.charging = false;
|
||||
MockPlatformBattery.level = 1;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
assert.equal(Battery.state, 'unplugged');
|
||||
// change the state
|
||||
MockPlatformBattery.charging = true;
|
||||
// emit the event
|
||||
MockPlatformBattery.addEventListener.args.some(function(arg) {
|
||||
if (arg[0] === 'chargingchange') {
|
||||
arg[1].call();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
assert.equal(Battery.state, 'charged');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should reflect chargingTime changes', function(done) {
|
||||
sandbox.spy(MockPlatformBattery, 'addEventListener');
|
||||
MockPlatformBattery.charging = true;
|
||||
MockPlatformBattery.level = 10;
|
||||
MockPlatformBattery.chargingTime = 13337;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
// change the state
|
||||
MockPlatformBattery.chargingTime = 13337 - 1337;
|
||||
// emit the event
|
||||
MockPlatformBattery.addEventListener.args.some(function(arg) {
|
||||
if (arg[0] === 'chargingtimechange') {
|
||||
arg[1].call();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
assert.equal(Battery.chargingTime, 13337 - 1337);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should reflect dischargingTime changes', function(done) {
|
||||
sandbox.spy(MockPlatformBattery, 'addEventListener');
|
||||
MockPlatformBattery.charging = false;
|
||||
MockPlatformBattery.level = 9;
|
||||
MockPlatformBattery.dischargingTime = 13337;
|
||||
|
||||
loadBattery(function(Battery) {
|
||||
// change the state
|
||||
MockPlatformBattery.dischargingTime = 13337 - 1337;
|
||||
// emit the event
|
||||
MockPlatformBattery.addEventListener.args.some(function(arg) {
|
||||
if (arg[0] === 'dischargingtimechange') {
|
||||
arg[1].call();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
assert.equal(Battery.dischargingTime, 13337 - 1337);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
suite('BluetoothAdapterManager', function() {
|
||||
var adapterManager;
|
||||
|
||||
setup(function(done) {
|
||||
var modules = [
|
||||
'modules/bluetooth/bluetooth_adapter_manager'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'modules/bluetooth': {
|
||||
'modules/navigator/mozBluetooth': 'MockNavigatorBluetooth'
|
||||
}
|
||||
};
|
||||
|
||||
this.MockNavigatorBluetooth = {
|
||||
defaultAdapter: {},
|
||||
callbacks: {
|
||||
'attributechanged': []
|
||||
},
|
||||
addEventListener: function(eventName, callback) {
|
||||
this.callbacks[eventName].push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
define('MockNavigatorBluetooth', function() {
|
||||
return this.MockNavigatorBluetooth;
|
||||
}.bind(this));
|
||||
|
||||
testRequire(modules, map, function(AdapterManager) {
|
||||
adapterManager = AdapterManager;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('_init > ', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(adapterManager, '_watchMozBluetoothAttributechanged');
|
||||
this.sinon.stub(adapterManager, '_initDefaultAdapter');
|
||||
});
|
||||
|
||||
test('mozBluetooth attributechanged should be watched, ' +
|
||||
'defaultAdapter should be inited ', function() {
|
||||
adapterManager._init();
|
||||
assert.isTrue(adapterManager._watchMozBluetoothAttributechanged.called);
|
||||
assert.isTrue(adapterManager._initDefaultAdapter.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_watchMozBluetoothAttributechanged > ', function() {
|
||||
var eventName, mockEvent;
|
||||
setup(function() {
|
||||
this.sinon.spy(this.MockNavigatorBluetooth, 'addEventListener');
|
||||
eventName = 'attributechanged';
|
||||
mockEvent = {
|
||||
attrs: ['defaultAdapter']
|
||||
};
|
||||
});
|
||||
|
||||
test('"attributechanged" event should be watched ' +
|
||||
'defaultAdapter should be inited while event is coming ', function() {
|
||||
adapterManager._watchMozBluetoothAttributechanged();
|
||||
assert.isTrue(
|
||||
this.MockNavigatorBluetooth.addEventListener.calledWith(eventName));
|
||||
// test 'attributechanged' event coming
|
||||
this.MockNavigatorBluetooth.callbacks[eventName][0](mockEvent);
|
||||
assert.equal(adapterManager.defaultAdapter,
|
||||
this.MockNavigatorBluetooth.defaultAdapter);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_initDefaultAdapter > ', function() {
|
||||
setup(function() {
|
||||
adapterManager.defaultAdapter = null;
|
||||
});
|
||||
|
||||
test('defaultAdapter should be defined ', function() {
|
||||
adapterManager._initDefaultAdapter();
|
||||
assert.equal(adapterManager.defaultAdapter,
|
||||
this.MockNavigatorBluetooth.defaultAdapter);
|
||||
});
|
||||
});
|
||||
});
|
||||
126
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_cod_mapper_test.js
Executable file
126
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_cod_mapper_test.js
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
'use strict';
|
||||
|
||||
suite('BluetoothClassOfDeviceMapper > ', function() {
|
||||
setup(function(done) {
|
||||
var module = [
|
||||
'modules/bluetooth/bluetooth_cod_mapper'
|
||||
];
|
||||
var map = {};
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
requireCtx(module, function(BtClassOfDeviceMapper) {
|
||||
this.BtClassOfDeviceMapper = BtClassOfDeviceMapper;
|
||||
done();
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
suite('getDeviceType > major device class: computer, phone, audio/video, ' +
|
||||
'peripheral, imaging > ', function() {
|
||||
var mockCodInput, expectedType;
|
||||
suite('mapping in minor device class which is defined ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 4,
|
||||
majorServiceClass: 555,
|
||||
minorDeviceClass: 3
|
||||
};
|
||||
expectedType = 'audio-card';
|
||||
});
|
||||
|
||||
test('should return device type = "audio-card" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
|
||||
suite('mapping in minor device class which is reserved ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 4,
|
||||
majorServiceClass: 555,
|
||||
minorDeviceClass: 23
|
||||
};
|
||||
expectedType = 'audio-card';
|
||||
});
|
||||
|
||||
test('should return device type = "audio-card" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
|
||||
suite('mapping in minor device class which is not defined ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 6,
|
||||
majorServiceClass: 555,
|
||||
minorDeviceClass: 2
|
||||
};
|
||||
expectedType = '';
|
||||
});
|
||||
|
||||
test('should return device type = "" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getDeviceType > major device class: network-wireless ', function() {
|
||||
var mockCodInput, expectedType;
|
||||
suite('mapping in major device class ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 3,
|
||||
majorServiceClass: 555,
|
||||
minorDeviceClass: 10
|
||||
};
|
||||
expectedType = 'network-wireless';
|
||||
});
|
||||
|
||||
test('should return device type = "network-wireless" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getDeviceType > major device class: wearable, toy, health > ',
|
||||
function() {
|
||||
var mockCodInput, expectedType;
|
||||
suite('not mapping in major device class, but mapping in ' +
|
||||
'major service class: audio ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 8,
|
||||
majorServiceClass: 256,
|
||||
minorDeviceClass: 3
|
||||
};
|
||||
expectedType = 'audio-card';
|
||||
});
|
||||
|
||||
test('should return device type = "audio-card" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getDeviceType > not mapping in any class ', function() {
|
||||
var mockCodInput, expectedType;
|
||||
suite('not mapping in any class ', function() {
|
||||
setup(function() {
|
||||
mockCodInput = {
|
||||
majorDeviceClass: 8,
|
||||
majorServiceClass: 555,
|
||||
minorDeviceClass: 10
|
||||
};
|
||||
expectedType = '';
|
||||
});
|
||||
|
||||
test('should return device type = "" ', function() {
|
||||
assert.equal(this.BtClassOfDeviceMapper.getDeviceType(mockCodInput),
|
||||
expectedType);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,553 @@
|
|||
'use strict';
|
||||
|
||||
suite('BluetoothContext', function() {
|
||||
var adapterManager;
|
||||
var asyncStorage;
|
||||
var connectionManager;
|
||||
|
||||
setup(function(done) {
|
||||
var modules = [
|
||||
'modules/bluetooth/bluetooth_adapter_manager',
|
||||
'shared/async_storage',
|
||||
'modules/bluetooth/bluetooth_connection_manager'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/bluetooth/bluetooth_adapter_manager': 'MockAdapterManager',
|
||||
'shared/async_storage': 'MockAsyncStorage'
|
||||
}
|
||||
};
|
||||
|
||||
this.MockAdapterManager = {
|
||||
defaultAdapter: {
|
||||
state: 'enabled',
|
||||
addEventListener: function() {},
|
||||
removeEventListener: function() {},
|
||||
getPairedDevices: function() {return [];},
|
||||
stopDiscovery: function() {},
|
||||
connect: function() {},
|
||||
disconnect: function() {},
|
||||
getConnectedDevices: function() {}
|
||||
},
|
||||
observe: function() {}
|
||||
};
|
||||
|
||||
define('MockAdapterManager', function() {
|
||||
return this.MockAdapterManager;
|
||||
}.bind(this));
|
||||
|
||||
this.MockAsyncStorage = {
|
||||
getItem: function() {},
|
||||
setItem: function() {},
|
||||
removeItem: function() {}
|
||||
};
|
||||
|
||||
define('MockAsyncStorage', function() {
|
||||
return this.MockAsyncStorage;
|
||||
}.bind(this));
|
||||
|
||||
testRequire(modules, map, function(AdapterManager, AsyncStorage,
|
||||
ConnectionManager) {
|
||||
adapterManager = AdapterManager;
|
||||
asyncStorage = AsyncStorage;
|
||||
connectionManager = ConnectionManager;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('Init > ', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(adapterManager, 'observe');
|
||||
this.sinon.stub(connectionManager, '_onDefaultAdapterChanged');
|
||||
});
|
||||
|
||||
test('AdapterManager "defaultAdapter" property should be observed, ' +
|
||||
'and access defaultAdapter from AdapterManager manually ', function() {
|
||||
connectionManager._init();
|
||||
assert.isTrue(adapterManager.observe.calledWith('defaultAdapter'));
|
||||
assert.isTrue(connectionManager._onDefaultAdapterChanged.calledWith(
|
||||
adapterManager.defaultAdapter));
|
||||
});
|
||||
});
|
||||
|
||||
suite('_onDefaultAdapterChanged > ', function() {
|
||||
var newAdapter, oldAdapter;
|
||||
setup(function() {
|
||||
oldAdapter = {};
|
||||
connectionManager._defaultAdapter = null;
|
||||
this.sinon.stub(connectionManager, '_unwatchProfilesStatuschanged');
|
||||
this.sinon.stub(connectionManager,
|
||||
'_unwatchDefaultAdapterOnattributechanged');
|
||||
this.sinon.stub(connectionManager, '_watchProfilesStatuschanged');
|
||||
this.sinon.stub(connectionManager,
|
||||
'_watchDefaultAdapterOnattributechanged');
|
||||
this.sinon.stub(connectionManager, '_restoreConnection');
|
||||
this.sinon.stub(connectionManager, '_resetConnectionInfo');
|
||||
});
|
||||
|
||||
suite('changed with new/old adapter, ' +
|
||||
'in case of having new adapter > ', function() {
|
||||
suiteSetup(function() {
|
||||
newAdapter = {
|
||||
state: 'enabled'
|
||||
};
|
||||
});
|
||||
|
||||
test('should unwatch events from old adapter, ' +
|
||||
'then watch events from new adapter ', function() {
|
||||
connectionManager._onDefaultAdapterChanged(newAdapter, oldAdapter);
|
||||
// test default adapter updated
|
||||
assert.equal(connectionManager._defaultAdapter, newAdapter);
|
||||
// test unwatch events
|
||||
assert.isTrue(
|
||||
connectionManager._unwatchProfilesStatuschanged.calledWith(
|
||||
oldAdapter));
|
||||
assert.isTrue(
|
||||
connectionManager._unwatchDefaultAdapterOnattributechanged.calledWith(
|
||||
oldAdapter));
|
||||
// test watch events
|
||||
assert.isTrue(
|
||||
connectionManager._watchProfilesStatuschanged.calledWith(newAdapter));
|
||||
assert.isTrue(
|
||||
connectionManager._watchDefaultAdapterOnattributechanged.calledWith(
|
||||
newAdapter));
|
||||
// test restore connection
|
||||
assert.isTrue(connectionManager._restoreConnection.called);
|
||||
// test reset properties
|
||||
assert.isFalse(connectionManager._resetConnectionInfo.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('changed with new/old adapter, ' +
|
||||
'in case of new adapter is null > ', function() {
|
||||
suiteSetup(function() {
|
||||
newAdapter = null;
|
||||
});
|
||||
|
||||
test('should unwatch events from old adapter, ' +
|
||||
'then watch events from new adapter ', function() {
|
||||
connectionManager._onDefaultAdapterChanged(newAdapter, oldAdapter);
|
||||
// test default adapter updated
|
||||
assert.isNull(connectionManager._defaultAdapter);
|
||||
// test unwatch events
|
||||
assert.isTrue(
|
||||
connectionManager._unwatchProfilesStatuschanged.calledWith(
|
||||
oldAdapter));
|
||||
assert.isTrue(
|
||||
connectionManager._unwatchDefaultAdapterOnattributechanged.calledWith(
|
||||
oldAdapter));
|
||||
// test watch events
|
||||
assert.isFalse(
|
||||
connectionManager._watchProfilesStatuschanged.calledWith(newAdapter));
|
||||
assert.isFalse(
|
||||
connectionManager._watchDefaultAdapterOnattributechanged.calledWith(
|
||||
newAdapter));
|
||||
// test restore connection
|
||||
assert.isFalse(connectionManager._restoreConnection.called);
|
||||
// test reset properties
|
||||
assert.isTrue(connectionManager._resetConnectionInfo.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_initConnectedDevicesInfo > ', function() {
|
||||
suite('has default adapter, init connected devices info ', function() {
|
||||
var mockAdapter, mockGetConnectedDevicesFromPlatformPromise,
|
||||
mockConnectedDevicesByProfile;
|
||||
setup(function() {
|
||||
mockAdapter = {};
|
||||
connectionManager._defaultAdapter = mockAdapter;
|
||||
|
||||
mockConnectedDevicesByProfile = {};
|
||||
mockGetConnectedDevicesFromPlatformPromise =
|
||||
Promise.resolve(mockConnectedDevicesByProfile);
|
||||
this.sinon.stub(connectionManager,
|
||||
'_getConnectedDevicesFromPlatform').returns(
|
||||
mockGetConnectedDevicesFromPlatformPromise);
|
||||
this.sinon.stub(connectionManager, '_constructDeviceItemsMap');
|
||||
});
|
||||
|
||||
test('_constructDeviceItemsMap() should be called while ' +
|
||||
'_getConnectedDevicesFromPlatform is resolved ',
|
||||
function(done) {
|
||||
connectionManager._initConnectedDevicesInfo().then(function() {
|
||||
assert.isTrue(
|
||||
connectionManager._getConnectedDevicesFromPlatform.called);
|
||||
mockGetConnectedDevicesFromPlatformPromise.then(() => {
|
||||
assert.isTrue(
|
||||
connectionManager._constructDeviceItemsMap.calledWith(
|
||||
mockConnectedDevicesByProfile));
|
||||
}, () => {
|
||||
//reject case
|
||||
});
|
||||
}, function() {
|
||||
// reject case
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('has no default adapter, init connected devices info ', function() {
|
||||
setup(function() {
|
||||
connectionManager._defaultAdapter = null;
|
||||
this.sinon.stub(connectionManager, '_getConnectedDevicesFromPlatform');
|
||||
this.sinon.stub(connectionManager, '_constructDeviceItemsMap');
|
||||
});
|
||||
|
||||
test('_getConnectedDevicesFromPlatform() should not be called, ' +
|
||||
'_constructDeviceItemsMap() should not be called',
|
||||
function(done) {
|
||||
connectionManager._initConnectedDevicesInfo().then(function() {
|
||||
// resolve case
|
||||
}, function() {
|
||||
assert.isFalse(
|
||||
connectionManager._getConnectedDevicesFromPlatform.called);
|
||||
assert.isFalse(
|
||||
connectionManager._constructDeviceItemsMap.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_constructDeviceItemsMap > ', function() {
|
||||
var mockConnectedDevices, expectedConectionDeviceInfo;
|
||||
setup(function() {
|
||||
mockConnectedDevices = {
|
||||
'hfp': [{address: 'AA:BB:CC:00:11:22'}],
|
||||
'a2dp': [{address: 'AA:BB:CC:00:11:22'}]
|
||||
};
|
||||
|
||||
expectedConectionDeviceInfo = {
|
||||
address: mockConnectedDevices.hfp[0].address,
|
||||
connected: true,
|
||||
profileID: 'hfp',
|
||||
device: mockConnectedDevices.hfp[0]
|
||||
};
|
||||
this.sinon.stub(connectionManager, '_initConnectedDevicesCache');
|
||||
});
|
||||
|
||||
test('_initConnectedDevicesCache should be called ', function() {
|
||||
connectionManager._constructDeviceItemsMap(mockConnectedDevices);
|
||||
assert.isTrue(connectionManager._initConnectedDevicesCache.called);
|
||||
assert.deepEqual(connectionManager._initConnectedDevicesCache.args[0][0],
|
||||
expectedConectionDeviceInfo);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_initConnectedDevicesCache > ', function() {
|
||||
var mockConnectedDevicesInfo, options;
|
||||
suite('the updating device has info > ', function() {
|
||||
setup(function() {
|
||||
mockConnectedDevicesInfo = {
|
||||
'AA:BB:CC:00:11:22': {
|
||||
'device': {},
|
||||
'connectedProfiles': {
|
||||
'hfp': false,
|
||||
'a2dp': true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
options = {
|
||||
address: 'AA:BB:CC:00:11:22',
|
||||
connected: true,
|
||||
profileID: 'hfp',
|
||||
device: {}
|
||||
};
|
||||
connectionManager._connectedDevicesInfo = mockConnectedDevicesInfo;
|
||||
this.sinon.stub(connectionManager,
|
||||
'_hasConnectedProfileByAddress').returns(true);
|
||||
});
|
||||
|
||||
test('the specific profile of connected device info should be ' +
|
||||
'updated, Ex: "hfp": true ', function() {
|
||||
var newCache = connectionManager._initConnectedDevicesCache(options);
|
||||
assert.isTrue(newCache[options.address].connectedProfiles.hfp);
|
||||
});
|
||||
});
|
||||
|
||||
suite('the updating device has no info > ', function() {
|
||||
setup(function() {
|
||||
mockConnectedDevicesInfo = {};
|
||||
|
||||
options = {
|
||||
address: 'AA:BB:CC:00:11:22',
|
||||
connected: true,
|
||||
profileID: 'hfp',
|
||||
device: {}
|
||||
};
|
||||
connectionManager._connectedDevicesInfo = mockConnectedDevicesInfo;
|
||||
this.sinon.stub(connectionManager,
|
||||
'_hasConnectedProfileByAddress').returns(true);
|
||||
});
|
||||
|
||||
test('the specific profile of connected device info should be ' +
|
||||
'updated, Ex: "hfp": true, "device": options.device ', function() {
|
||||
var newCache = connectionManager._initConnectedDevicesCache(options);
|
||||
assert.isTrue(newCache[options.address].connectedProfiles.hfp);
|
||||
assert.equal(newCache[options.address].device, options.device);
|
||||
});
|
||||
});
|
||||
|
||||
suite('the updating device has no connected profile > ', function() {
|
||||
setup(function() {
|
||||
mockConnectedDevicesInfo = {
|
||||
'AA:BB:CC:00:11:22': {
|
||||
'device': {},
|
||||
'connectedProfiles': {
|
||||
'hfp': true,
|
||||
'a2dp': false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
options = {
|
||||
address: 'AA:BB:CC:00:11:22',
|
||||
connected: false,
|
||||
profileID: 'hfp',
|
||||
device: {}
|
||||
};
|
||||
connectionManager._connectedDevicesInfo = mockConnectedDevicesInfo;
|
||||
this.sinon.stub(connectionManager,
|
||||
'_hasConnectedProfileByAddress').returns(false);
|
||||
});
|
||||
|
||||
test('the device info should be removed from cache ', function() {
|
||||
var newCache = connectionManager._initConnectedDevicesCache(options);
|
||||
assert.isUndefined(newCache[options.address]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getConnectedDevices > ', function() {
|
||||
suite('already requested getConnectedDevices() with promise > ',
|
||||
function() {
|
||||
var mockPromise;
|
||||
setup(function() {
|
||||
mockPromise = new Promise(function() {});
|
||||
connectionManager._getConnectedDevicesPromise = mockPromise;
|
||||
});
|
||||
|
||||
test('should return the requested promise..', function() {
|
||||
assert.equal(connectionManager.getConnectedDevices(), mockPromise);
|
||||
});
|
||||
});
|
||||
|
||||
suite('have not requested getConnectedDevices() with promise > ',
|
||||
function() {
|
||||
var mockConnectedDevicesInfoPromise, mockConnectedDevicesInfo;
|
||||
setup(function() {
|
||||
connectionManager._getConnectedDevicesPromise = null;
|
||||
mockConnectedDevicesInfo = {'AA:BB:CC:00:11:22': {}};
|
||||
connectionManager._connectedDevicesInfo = mockConnectedDevicesInfo;
|
||||
mockConnectedDevicesInfoPromise = Promise.resolve();
|
||||
this.sinon.stub(connectionManager,
|
||||
'_initConnectedDevicesInfo').returns(mockConnectedDevicesInfoPromise);
|
||||
});
|
||||
|
||||
test('should return connected device cached while promise resolve ',
|
||||
function(done) {
|
||||
connectionManager.getConnectedDevices().then((connectedDevicesInfo) => {
|
||||
assert.equal(connectedDevicesInfo, mockConnectedDevicesInfo);
|
||||
}, () => {
|
||||
// reject case
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('have not requested getConnectedDevices() with promise > ',
|
||||
function() {
|
||||
var mockConnectedDevicesInfoPromise;
|
||||
setup(function() {
|
||||
connectionManager._getConnectedDevicesPromise = null;
|
||||
mockConnectedDevicesInfoPromise = Promise.reject();
|
||||
this.sinon.stub(connectionManager,
|
||||
'_initConnectedDevicesInfo').returns(mockConnectedDevicesInfoPromise);
|
||||
});
|
||||
|
||||
test('should clean up instance of cache while promise reject ',
|
||||
function(done) {
|
||||
connectionManager.getConnectedDevices().then(() => {
|
||||
assert.isNull(connectionManager._getConnectedDevicesPromise);
|
||||
}, () => {
|
||||
// reject case
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_resetConnectionInfo > ', function() {
|
||||
setup(function() {
|
||||
connectionManager.connectingAddress = 'AA:BB:CC:00:11:22';
|
||||
connectionManager._getConnectedDevicesPromise = Promise.resolve();
|
||||
});
|
||||
|
||||
test('connecting address, instance of cache should be reset ', function() {
|
||||
connectionManager._resetConnectionInfo();
|
||||
assert.isNull(connectionManager.connectingAddress);
|
||||
assert.isNull(connectionManager._getConnectedDevicesPromise);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_watchDefaultAdapterOnattributechanged > ', function() {
|
||||
var mockAdapter;
|
||||
setup(function() {
|
||||
mockAdapter = {
|
||||
addEventListener: function() {}
|
||||
};
|
||||
this.sinon.stub(mockAdapter, 'addEventListener');
|
||||
this.sinon.stub(connectionManager, '_onAdapterAttributeChanged');
|
||||
});
|
||||
|
||||
test('attributechanged should be registered callback function', function() {
|
||||
connectionManager._watchDefaultAdapterOnattributechanged(mockAdapter);
|
||||
assert.equal(mockAdapter.addEventListener.args[0][0], 'attributechanged');
|
||||
mockAdapter.addEventListener.args[0][1]();
|
||||
assert.isTrue(connectionManager._onAdapterAttributeChanged.calledWith(
|
||||
mockAdapter));
|
||||
});
|
||||
});
|
||||
|
||||
suite('_unwatchDefaultAdapterOnattributechanged > ', function() {
|
||||
var mockAdapter;
|
||||
setup(function() {
|
||||
mockAdapter = {
|
||||
removeEventListener: function() {}
|
||||
};
|
||||
this.sinon.stub(mockAdapter, 'removeEventListener');
|
||||
this.sinon.stub(connectionManager, '_onAdapterAttributeChanged');
|
||||
});
|
||||
|
||||
test('onattributechanged should be unregistered ', function() {
|
||||
connectionManager._unwatchDefaultAdapterOnattributechanged(mockAdapter);
|
||||
assert.equal(mockAdapter.removeEventListener.args[0][0],
|
||||
'attributechanged');
|
||||
assert.equal(mockAdapter.removeEventListener.args[0][1],
|
||||
connectionManager._onAdapterAttributeChanged);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_onAdapterAttributeChanged > ', function() {
|
||||
var mockAdapter, evt;
|
||||
setup(function() {
|
||||
mockAdapter = {
|
||||
state: 'enabled'
|
||||
};
|
||||
});
|
||||
|
||||
suite('state changed in enabled ', function() {
|
||||
setup(function() {
|
||||
evt = {
|
||||
attrs: ['state']
|
||||
};
|
||||
this.sinon.stub(connectionManager, '_restoreConnection');
|
||||
});
|
||||
|
||||
test('_restoreConnection() should be called ', function() {
|
||||
connectionManager._onAdapterAttributeChanged(mockAdapter, evt);
|
||||
assert.isTrue(connectionManager._restoreConnection.called);
|
||||
});
|
||||
|
||||
['enabling', 'disabling', 'disabled'].forEach(function(state) {
|
||||
test('_restoreConnection() should not be called when ' + state,
|
||||
function() {
|
||||
mockAdapter.state = state;
|
||||
connectionManager._onAdapterAttributeChanged(mockAdapter, evt);
|
||||
assert.isTrue(connectionManager._restoreConnection.notCalled);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_watchProfilesStatuschanged > ', function() {
|
||||
var mockAdapter;
|
||||
setup(function() {
|
||||
mockAdapter = {};
|
||||
});
|
||||
|
||||
test('profile status callback of adapter should be registered', function() {
|
||||
connectionManager._watchProfilesStatuschanged(mockAdapter);
|
||||
assert.isDefined(mockAdapter.onhfpstatuschanged);
|
||||
assert.isDefined(mockAdapter.ona2dpstatuschanged);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_unwatchProfilesStatuschanged > ', function() {
|
||||
var mockAdapter;
|
||||
setup(function() {
|
||||
mockAdapter = {
|
||||
onhfpstatuschanged: function() {},
|
||||
ona2dpstatuschanged: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
test('profile status callback of adapter should be null ', function() {
|
||||
connectionManager._unwatchProfilesStatuschanged(mockAdapter);
|
||||
assert.isNull(mockAdapter.onhfpstatuschanged);
|
||||
assert.isNull(mockAdapter.ona2dpstatuschanged);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_onProfileStatuschangeHandler > ', function() {
|
||||
var mockProfileID, mockEvt, resultOptions;
|
||||
setup(function() {
|
||||
mockProfileID = 'hfp';
|
||||
mockEvt = {
|
||||
address: 'AA:BB:CC:00:11:22',
|
||||
status: true
|
||||
};
|
||||
resultOptions = {
|
||||
address: mockEvt.address,
|
||||
connected: mockEvt.status,
|
||||
profileID: mockProfileID
|
||||
};
|
||||
this.sinon.stub(connectionManager, '_updateConnectionStatus');
|
||||
});
|
||||
|
||||
test('_updateConnectionStatus() should be called with options', function() {
|
||||
connectionManager._onProfileStatuschangeHandler(mockProfileID, mockEvt);
|
||||
assert.isTrue(
|
||||
connectionManager._updateConnectionStatus.calledWith(resultOptions));
|
||||
});
|
||||
});
|
||||
|
||||
suite('_recordConnection > ', function() {
|
||||
var action, address;
|
||||
var itemKey = 'device.connected';
|
||||
suite('action: set > ', function() {
|
||||
setup(function() {
|
||||
action = 'set';
|
||||
address = 'AA:BB:CC:00:11:22';
|
||||
this.sinon.stub(asyncStorage, 'setItem');
|
||||
this.sinon.stub(asyncStorage, 'removeItem');
|
||||
});
|
||||
|
||||
test('should set item in async storage ', function() {
|
||||
connectionManager._recordConnection(action, address);
|
||||
assert.equal(asyncStorage.setItem.args[0][0], itemKey);
|
||||
assert.equal(asyncStorage.setItem.args[0][1], address);
|
||||
assert.isFalse(asyncStorage.removeItem.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('action: remove > ', function() {
|
||||
var mockAdapter;
|
||||
setup(function() {
|
||||
action = 'remove';
|
||||
address = 'AA:BB:CC:00:11:22';
|
||||
mockAdapter = {
|
||||
state: 'enabled'
|
||||
};
|
||||
connectionManager._defaultAdapter = mockAdapter;
|
||||
this.sinon.stub(asyncStorage, 'setItem');
|
||||
this.sinon.stub(asyncStorage, 'removeItem');
|
||||
});
|
||||
|
||||
test('should remove item in async storage ', function() {
|
||||
connectionManager._recordConnection(action, address);
|
||||
assert.isTrue(asyncStorage.removeItem.calledWith(itemKey));
|
||||
assert.isFalse(asyncStorage.setItem.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
1697
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_context_test.js
Executable file
1697
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_context_test.js
Executable file
File diff suppressed because it is too large
Load diff
195
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_device_test.js
Executable file
195
gaia/apps/settings/test/unit/modules/bluetooth/bluetooth_device_test.js
Executable file
|
|
@ -0,0 +1,195 @@
|
|||
'use strict';
|
||||
|
||||
suite('BluetoothDevice', function() {
|
||||
var bluetoothDevice, mockBtClassOfDeviceMapper, mockDeviceObj,
|
||||
defaultConnectionStatus;
|
||||
|
||||
setup(function(done) {
|
||||
var modules = [
|
||||
'modules/bluetooth/bluetooth_device',
|
||||
'modules/bluetooth/bluetooth_cod_mapper'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'modules/bluetooth': {
|
||||
'modules/bluetooth/bluetooth_cod_mapper': 'MockBtClassOfDeviceMapper'
|
||||
}
|
||||
};
|
||||
|
||||
mockBtClassOfDeviceMapper = {
|
||||
getDeviceType: function() {return '';}
|
||||
};
|
||||
|
||||
define('MockBtClassOfDeviceMapper', function() {
|
||||
return mockBtClassOfDeviceMapper;
|
||||
});
|
||||
|
||||
mockDeviceObj = {
|
||||
onattributechanged: {},
|
||||
name: 'device-01',
|
||||
paired: false,
|
||||
address: 'AA:BB:CC:00:11:22',
|
||||
cod: {}
|
||||
};
|
||||
|
||||
defaultConnectionStatus = 'disconnected';
|
||||
|
||||
testRequire(modules, map, function(BluetoothDevice) {
|
||||
bluetoothDevice = BluetoothDevice;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('ctor > ', function() {
|
||||
var bluetoothDeviceCreated;
|
||||
setup(function() {
|
||||
bluetoothDeviceCreated = bluetoothDevice(mockDeviceObj);
|
||||
});
|
||||
|
||||
suite('create > ', function() {
|
||||
test('Will create BluetoothDevice with "name", "paired", ' +
|
||||
'"address", "type", "connectionStatus", "profiles", ' +
|
||||
'and "descriptionText" properties. Define getter "data", ' +
|
||||
'function "updateConnectionInfo", "updateDescriptionText".',
|
||||
function() {
|
||||
assert.equal(bluetoothDeviceCreated.name, mockDeviceObj.name);
|
||||
assert.equal(bluetoothDeviceCreated.paired, mockDeviceObj.paired);
|
||||
assert.equal(bluetoothDeviceCreated.address, mockDeviceObj.address);
|
||||
assert.isDefined(bluetoothDeviceCreated.type);
|
||||
assert.equal(bluetoothDeviceCreated.connectionStatus,
|
||||
defaultConnectionStatus);
|
||||
assert.isNull(bluetoothDeviceCreated.profiles);
|
||||
assert.isDefined(bluetoothDeviceCreated.descriptionText);
|
||||
assert.isDefined(bluetoothDeviceCreated.data);
|
||||
assert.isDefined(bluetoothDeviceCreated.updateConnectionInfo);
|
||||
assert.isDefined(bluetoothDeviceCreated.updateDescriptionText);
|
||||
});
|
||||
});
|
||||
|
||||
suite('updateConnectionInfo > ', function() {
|
||||
var mockOptions;
|
||||
setup(function() {
|
||||
mockOptions = {
|
||||
connectionStatus: 'connected',
|
||||
profiles: {
|
||||
'hfp': true,
|
||||
'a2dp': false
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
test('"connectionStatus" property should be "connected"', function() {
|
||||
bluetoothDeviceCreated.updateConnectionInfo(mockOptions);
|
||||
assert.equal(bluetoothDeviceCreated.connectionStatus,
|
||||
mockOptions.connectionStatus);
|
||||
assert.deepEqual(bluetoothDeviceCreated.profiles,
|
||||
mockOptions.profiles);
|
||||
});
|
||||
});
|
||||
|
||||
suite('updateDescriptionText > ', function() {
|
||||
suite('"paired" property changed > ', function() {
|
||||
var newPairedState;
|
||||
setup(function() {
|
||||
newPairedState = 'pairing';
|
||||
bluetoothDeviceCreated.paired = newPairedState;
|
||||
});
|
||||
|
||||
test('"descriptionText" property should be "pairing" ', function() {
|
||||
assert.equal(bluetoothDeviceCreated.descriptionText, newPairedState);
|
||||
});
|
||||
});
|
||||
|
||||
suite('"connectionStatus" property changed > ', function() {
|
||||
var newConnectionStatus;
|
||||
setup(function() {
|
||||
newConnectionStatus = 'connecting';
|
||||
bluetoothDeviceCreated.paired = true;
|
||||
bluetoothDeviceCreated.connectionStatus = newConnectionStatus;
|
||||
});
|
||||
|
||||
test('"descriptionText" property should be "connecting" ', function() {
|
||||
assert.equal(bluetoothDeviceCreated.descriptionText,
|
||||
newConnectionStatus);
|
||||
});
|
||||
});
|
||||
|
||||
suite('"profiles" property changed > ', function() {
|
||||
var newProfiles, expectedDescriptionText;
|
||||
setup(function() {
|
||||
newProfiles = {
|
||||
'hfp': true,
|
||||
'a2dp': true
|
||||
};
|
||||
expectedDescriptionText = 'connectedWithDeviceMedia';
|
||||
bluetoothDeviceCreated.paired = true;
|
||||
bluetoothDeviceCreated.connectionStatus = 'connected';
|
||||
bluetoothDeviceCreated.profiles = newProfiles;
|
||||
});
|
||||
|
||||
test('"descriptionText" property should be "connectedWithDeviceMedia" ',
|
||||
function() {
|
||||
assert.equal(bluetoothDeviceCreated.descriptionText,
|
||||
expectedDescriptionText);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('event > name ', function() {
|
||||
var mockEvt, newName;
|
||||
setup(function() {
|
||||
mockEvt = {
|
||||
attrs: ['name']
|
||||
};
|
||||
newName = 'device-02';
|
||||
mockDeviceObj.name = newName;
|
||||
});
|
||||
|
||||
test('"onattributechanged" event coming with ' +
|
||||
'name property changed ', function() {
|
||||
mockDeviceObj.onattributechanged(mockEvt);
|
||||
assert.equal(bluetoothDeviceCreated.name, newName);
|
||||
});
|
||||
});
|
||||
|
||||
suite('event > paired ', function() {
|
||||
var mockEvt, newPairedState;
|
||||
setup(function() {
|
||||
mockEvt = {
|
||||
attrs: ['paired']
|
||||
};
|
||||
newPairedState = true;
|
||||
mockDeviceObj.paired = newPairedState;
|
||||
});
|
||||
|
||||
test('"onattributechanged" event coming with ' +
|
||||
'paired property changed ', function() {
|
||||
mockDeviceObj.onattributechanged(mockEvt);
|
||||
assert.equal(bluetoothDeviceCreated.paired, newPairedState);
|
||||
});
|
||||
});
|
||||
|
||||
suite('event > cod ', function() {
|
||||
var mockEvt, newCODObject, mockType;
|
||||
setup(function() {
|
||||
mockEvt = {
|
||||
attrs: ['cod']
|
||||
};
|
||||
mockType = 'audio-card';
|
||||
newCODObject = {};
|
||||
mockDeviceObj.cod = newCODObject;
|
||||
|
||||
this.sinon.stub(mockBtClassOfDeviceMapper, 'getDeviceType').returns(
|
||||
mockType);
|
||||
});
|
||||
|
||||
test('"onattributechanged" event coming with ' +
|
||||
'cod property changed ', function() {
|
||||
mockDeviceObj.onattributechanged(mockEvt);
|
||||
assert.isTrue(mockBtClassOfDeviceMapper.getDeviceType.calledWith(
|
||||
newCODObject));
|
||||
assert.equal(bluetoothDeviceCreated.type, mockType);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
140
gaia/apps/settings/test/unit/modules/date_time_test.js
Executable file
140
gaia/apps/settings/test/unit/modules/date_time_test.js
Executable file
|
|
@ -0,0 +1,140 @@
|
|||
'use strict';
|
||||
|
||||
suite('Date & Time > ', function() {
|
||||
var realSettings, realTime;
|
||||
var DateTime;
|
||||
|
||||
// keys
|
||||
var _kClockAutoEnabled = 'time.clock.automatic-update.enabled';
|
||||
var _kClockAutoAvailable = 'time.clock.automatic-update.available';
|
||||
var _kTimezoneAutoAvailable = 'time.timezone.automatic-update.available';
|
||||
var _kTimezone = 'time.timezone';
|
||||
var _kUserSelected = 'time.timezone.user-selected';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var modules = [
|
||||
'shared_mocks/mock_navigator_moz_settings',
|
||||
'modules/date_time'
|
||||
];
|
||||
var maps = {
|
||||
'*': {}
|
||||
};
|
||||
|
||||
testRequire(modules, maps, function(
|
||||
MockNavigatorSettings, module) {
|
||||
// mock settings
|
||||
realSettings = window.navigator.mozSettings;
|
||||
window.navigator.mozSettings = MockNavigatorSettings;
|
||||
// mock time
|
||||
var MockTime = {
|
||||
set: function() {}
|
||||
};
|
||||
realTime = window.navigator.mozTime;
|
||||
window.navigator.mozTime = MockTime;
|
||||
|
||||
DateTime = module;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.navigator.mozTime = realTime;
|
||||
window.navigator.mozSettings = realSettings;
|
||||
});
|
||||
|
||||
suite('initiation', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(DateTime, '_attachListeners');
|
||||
this.sinon.stub(DateTime, '_getDefaults');
|
||||
DateTime._init();
|
||||
});
|
||||
|
||||
test('_attachListeners and _getDefaults are called ' +
|
||||
'while get the instance', function() {
|
||||
assert.ok(DateTime._attachListeners.called);
|
||||
assert.ok(DateTime._getDefaults.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('attach listeners', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(window.navigator.mozSettings, 'addObserver');
|
||||
DateTime._attachListeners();
|
||||
});
|
||||
|
||||
test('settings value observed', function() {
|
||||
assert.ok(window.navigator.mozSettings.addObserver.calledWith(
|
||||
_kClockAutoEnabled));
|
||||
assert.ok(window.navigator.mozSettings.addObserver.calledWith(
|
||||
_kClockAutoAvailable));
|
||||
assert.ok(window.navigator.mozSettings.addObserver.calledWith(
|
||||
_kTimezoneAutoAvailable));
|
||||
assert.ok(window.navigator.mozSettings.addObserver.calledWith(
|
||||
_kTimezone));
|
||||
assert.ok(window.navigator.mozSettings.addObserver.calledWith(
|
||||
_kUserSelected));
|
||||
});
|
||||
});
|
||||
|
||||
suite('Change system time', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(DateTime._mozTime, 'set');
|
||||
});
|
||||
|
||||
test('Set Date', function() {
|
||||
DateTime.setTime('date', '2013-05-21');
|
||||
var firstArg = DateTime._mozTime.set.firstCall.args[0];
|
||||
|
||||
assert.ok(firstArg.getYear(), 2013);
|
||||
assert.ok(firstArg.getMonth(), 5 - 1);
|
||||
assert.ok(firstArg.getDate(), 21);
|
||||
});
|
||||
|
||||
test('Set clock', function() {
|
||||
DateTime.setTime('time', '9:12');
|
||||
var firstArg = DateTime._mozTime.set.firstCall.args[0];
|
||||
|
||||
assert.ok(firstArg.getHours(), 9);
|
||||
assert.ok(firstArg.getMinutes(), 12);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Date and time autoUpdate', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(DateTime, '_autoUpdateDate');
|
||||
this.sinon.stub(DateTime, '_autoUpdateTime');
|
||||
});
|
||||
|
||||
test('Auto Update Date and time', function() {
|
||||
DateTime._autoUpdateDateTime();
|
||||
assert.ok(DateTime._autoUpdateDate.called);
|
||||
assert.ok(DateTime._autoUpdateTime.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Date autoUpdate', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(DateTime, '_autoUpdateDate');
|
||||
this.sinon.stub(window, 'setTimeout');
|
||||
});
|
||||
|
||||
test('Auto Update Date and time', function() {
|
||||
DateTime._autoUpdateDate();
|
||||
assert.ok(window.setTimeout.called);
|
||||
assert.ok(DateTime._autoUpdateDate.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Time autoUpdate', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(DateTime, '_autoUpdateTime');
|
||||
this.sinon.stub(window, 'setTimeout');
|
||||
});
|
||||
|
||||
test('Auto Update Date and time', function() {
|
||||
DateTime._autoUpdateTime();
|
||||
assert.ok(window.setTimeout.called);
|
||||
assert.ok(DateTime._autoUpdateTime.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
gaia/apps/settings/test/unit/modules/defer_test.js
Executable file
40
gaia/apps/settings/test/unit/modules/defer_test.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
suite('Defer > ', function() {
|
||||
var defer;
|
||||
|
||||
setup(function(done) {
|
||||
testRequire([
|
||||
'modules/defer'
|
||||
], {}, function(Defer) {
|
||||
defer = Defer();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('with promise property', function() {
|
||||
assert.isTrue(defer.promise instanceof Promise);
|
||||
});
|
||||
|
||||
test('with resolve method', function(done) {
|
||||
var message = 'Resolved';
|
||||
defer.resolve(message);
|
||||
Promise.resolve(defer.promise).then(function(resolvedMessage) {
|
||||
assert.equal(message, resolvedMessage);
|
||||
}, function() {
|
||||
// This will never be called
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('with reject method', function(done) {
|
||||
var message = 'Rejected';
|
||||
defer.reject(message);
|
||||
Promise.resolve(defer.promise).then(function() {
|
||||
// This will never be called
|
||||
assert.isTrue(false);
|
||||
}, function(rejectedMessage) {
|
||||
assert.equal(message, rejectedMessage);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
95
gaia/apps/settings/test/unit/modules/dialog/base_dialog_test.js
Executable file
95
gaia/apps/settings/test/unit/modules/dialog/base_dialog_test.js
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
'use strict';
|
||||
|
||||
suite('BaseDialog > ', function() {
|
||||
var baseDialog;
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire([], {}, function() {});
|
||||
requireCtx([
|
||||
'modules/dialog/base_dialog'
|
||||
], function(BaseDialog) {
|
||||
var panelDOM = document.createElement('div');
|
||||
baseDialog = new BaseDialog(panelDOM, {});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('_getWrapL10nObject > ', function() {
|
||||
test('input is string', function() {
|
||||
var fakeL10nId = 'Fake';
|
||||
var result = baseDialog._getWrapL10nObject(fakeL10nId);
|
||||
assert.equal(typeof result, 'object');
|
||||
assert.equal(result.id, fakeL10nId);
|
||||
assert.isNull(result.args);
|
||||
});
|
||||
|
||||
test('input is object, but forgot to put id', function() {
|
||||
this.sinon.spy(baseDialog, '_getWrapL10nObject');
|
||||
var fakeL10nObject = {args: {}};
|
||||
try {
|
||||
baseDialog._getWrapL10nObject(fakeL10nObject);
|
||||
} catch(e) {
|
||||
assert.ok(true, 'we wil throw error');
|
||||
}
|
||||
});
|
||||
|
||||
test('input is object, but no args', function() {
|
||||
var fakeL10nObject = {id: 'Fake'};
|
||||
var result = baseDialog._getWrapL10nObject(fakeL10nObject);
|
||||
assert.equal(result.id, fakeL10nObject.id);
|
||||
assert.isNull(result.args, 'we will set null on it');
|
||||
});
|
||||
|
||||
test('input is object, with id and args', function() {
|
||||
var fakeL10nObject = {id: 'Fake', args: {}};
|
||||
var result = baseDialog._getWrapL10nObject(fakeL10nObject);
|
||||
assert.equal(result.id, fakeL10nObject.id);
|
||||
assert.equal(result.args, fakeL10nObject.args);
|
||||
});
|
||||
});
|
||||
|
||||
suite('cleanup > ', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(baseDialog, '_updateTitle');
|
||||
this.sinon.stub(baseDialog, '_updateSubmitButton');
|
||||
this.sinon.stub(baseDialog, '_updateCancelButton');
|
||||
this.sinon.stub(baseDialog.panel.classList, 'remove');
|
||||
});
|
||||
|
||||
suite('if this is custom dialog', function() {
|
||||
setup(function() {
|
||||
baseDialog.DIALOG_CLASS = 'panel-dialog';
|
||||
baseDialog.cleanup();
|
||||
});
|
||||
|
||||
test('we would not restore its title and button', function() {
|
||||
assert.isFalse(baseDialog._updateTitle.called);
|
||||
assert.isFalse(baseDialog._updateSubmitButton.called);
|
||||
assert.isFalse(baseDialog._updateCancelButton.called);
|
||||
|
||||
assert.equal(baseDialog.panel.classList.remove.getCall(0).args[0],
|
||||
baseDialog.DIALOG_CLASS);
|
||||
assert.equal(baseDialog.panel.classList.remove.getCall(1).args[0],
|
||||
baseDialog.TRANSITION_CLASS);
|
||||
});
|
||||
});
|
||||
|
||||
suite('if this is system-wise dialog', function() {
|
||||
setup(function() {
|
||||
baseDialog.DIALOG_CLASS = 'alert-dialog';
|
||||
baseDialog.cleanup();
|
||||
});
|
||||
|
||||
test('we would restore its title and button', function() {
|
||||
assert.isTrue(baseDialog._updateTitle.called);
|
||||
assert.isTrue(baseDialog._updateSubmitButton.called);
|
||||
assert.isTrue(baseDialog._updateCancelButton.called);
|
||||
|
||||
assert.equal(baseDialog.panel.classList.remove.getCall(0).args[0],
|
||||
baseDialog.DIALOG_CLASS);
|
||||
assert.equal(baseDialog.panel.classList.remove.getCall(1).args[0],
|
||||
baseDialog.TRANSITION_CLASS);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
217
gaia/apps/settings/test/unit/modules/dialog_manager_test.js
Executable file
217
gaia/apps/settings/test/unit/modules/dialog_manager_test.js
Executable file
|
|
@ -0,0 +1,217 @@
|
|||
suite('DialogManager > ', function() {
|
||||
'use strict';
|
||||
|
||||
var mockLazyLoader;
|
||||
var mockPanelCache;
|
||||
var dialogManager;
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/panel_cache': 'PanelCache',
|
||||
'shared/lazy_loader': 'shared_mocks/mock_lazy_loader',
|
||||
}
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
define('PanelCache', function() {
|
||||
return {
|
||||
reset: function() {},
|
||||
get: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
testRequire([
|
||||
'PanelCache',
|
||||
'shared_mocks/mock_lazy_loader',
|
||||
'modules/dialog_manager'
|
||||
], map, function(MockPanelCache, MockLazyLoader, DialogManager) {
|
||||
mockPanelCache = MockPanelCache;
|
||||
mockLazyLoader = MockLazyLoader;
|
||||
dialogManager = DialogManager;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('_transit', function() {
|
||||
var panel;
|
||||
var dialog;
|
||||
var clock;
|
||||
|
||||
setup(function() {
|
||||
clock = this.sinon.useFakeTimers();
|
||||
panel = document.createElement('div');
|
||||
dialog = {
|
||||
panel: panel
|
||||
};
|
||||
this.sinon.spy(panel, 'addEventListener');
|
||||
this.sinon.spy(panel, 'removeEventListener');
|
||||
});
|
||||
|
||||
test('to open', function(done) {
|
||||
dialogManager._transit('open', dialog).then(function() {
|
||||
clock.tick(150);
|
||||
assert.isTrue(dialog.panel.classList.contains('current'));
|
||||
assert.isTrue(dialog.panel.removeEventListener.called);
|
||||
}).then(done, done);
|
||||
|
||||
panel.addEventListener.getCall(0).args[1]({
|
||||
propertyName: 'visibility'
|
||||
});
|
||||
});
|
||||
|
||||
test('to close', function(done) {
|
||||
dialogManager._transit('close', dialog).then(function() {
|
||||
clock.tick(150);
|
||||
assert.isFalse(dialog.panel.classList.contains('current'));
|
||||
assert.isTrue(dialog.panel.removeEventListener.called);
|
||||
}).then(done, done);
|
||||
|
||||
panel.addEventListener.getCall(0).args[1]({
|
||||
propertyName: 'visibility'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_open', function() {
|
||||
var dialog;
|
||||
var panel;
|
||||
setup(function() {
|
||||
panel = {
|
||||
beforeShow: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
show: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
dialog = {
|
||||
init: this.sinon.stub(),
|
||||
initUI: this.sinon.stub(),
|
||||
bindEvents: this.sinon.stub(),
|
||||
panel: panel
|
||||
};
|
||||
|
||||
this.sinon.stub(dialogManager, '_loadPanel', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
this.sinon.stub(dialogManager, '_getPanel', function() {
|
||||
return panel;
|
||||
});
|
||||
|
||||
this.sinon.stub(dialogManager, '_transit', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
test('we would follow the calling sequence', function(done) {
|
||||
dialogManager._open(dialog).then(function() {
|
||||
assert.isTrue(dialog.initUI.called);
|
||||
assert.isTrue(dialog.bindEvents.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_close', function() {
|
||||
var dialog;
|
||||
var panel;
|
||||
var options;
|
||||
var result;
|
||||
|
||||
setup(function() {
|
||||
options = {
|
||||
_type: 'submit'
|
||||
};
|
||||
|
||||
panel = {
|
||||
beforeHide: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
onSubmit: function() {
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
onCancel: function() {
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
hide: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
dialog = {
|
||||
panel: panel,
|
||||
cleanup: this.sinon.stub(),
|
||||
getResult: function() {
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
this.sinon.stub(dialogManager, '_loadPanel', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
this.sinon.stub(dialogManager, '_getPanel', function() {
|
||||
return panel;
|
||||
});
|
||||
|
||||
this.sinon.stub(dialogManager, '_transit', function() {
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
test('we would follow the calling sequence', function(done) {
|
||||
dialogManager._close(dialog, options).then(function() {
|
||||
assert.isTrue(dialog.cleanup.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('if validation failed, we would call reject', function(done) {
|
||||
panel.onSubmit = function() {
|
||||
return Promise.reject();
|
||||
};
|
||||
|
||||
dialogManager._close(dialog, options).then(function() {
|
||||
// This should not be called
|
||||
assert.isTrue(false);
|
||||
}, function() {
|
||||
// we will get rejected here
|
||||
assert.isTrue(true);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('if dialog is not a prompt, we would get result from hide',
|
||||
function(done) {
|
||||
result = 'This is a result from panel.hide()';
|
||||
dialogManager._close(dialog, options).then(function(gotResult) {
|
||||
assert.equal(gotResult, result);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('if dialog is a prompt, we would get result', function(done) {
|
||||
dialog.DIALOG_CLASS = 'prompt-dialog';
|
||||
result = 'This is a result from dialog.getResult()';
|
||||
dialogManager._close(dialog, options).then(function(gotResult) {
|
||||
assert.equal(gotResult, result);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('if submit button is clicked, onSubmit will get called',
|
||||
function(done) {
|
||||
options._type = 'submit';
|
||||
this.sinon.spy(panel, 'onSubmit');
|
||||
dialogManager._close(dialog, options).then(function() {
|
||||
assert.ok(panel.onSubmit.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('if cancel button is clicked, onCancel will get called',
|
||||
function(done) {
|
||||
options._type = 'cancel';
|
||||
this.sinon.spy(panel, 'onCancel');
|
||||
dialogManager._close(dialog, options).then(function() {
|
||||
assert.ok(panel.onCancel.called);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
177
gaia/apps/settings/test/unit/modules/dialog_service_test.js
Executable file
177
gaia/apps/settings/test/unit/modules/dialog_service_test.js
Executable file
|
|
@ -0,0 +1,177 @@
|
|||
suite('DialogService > ', function() {
|
||||
'use strict';
|
||||
|
||||
var mockSettings;
|
||||
var mockDialogManager;
|
||||
var dialogService;
|
||||
|
||||
var modules = [
|
||||
'unit/mock_settings',
|
||||
'DialogManager',
|
||||
'modules/dialog_service'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/dialog/panel_dialog': 'Panel',
|
||||
'modules/dialog/alert_dialog': 'Panel',
|
||||
'modules/dialog/confirm_dialog': 'Panel',
|
||||
'modules/dialog/prompt_dialog': 'Panel',
|
||||
'modules/defer': 'Defer',
|
||||
'modules/dialog_manager': 'DialogManager',
|
||||
'settings': 'unit/mock_settings'
|
||||
}
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
define('Panel', function() {
|
||||
return function() {
|
||||
return {};
|
||||
};
|
||||
});
|
||||
|
||||
define('Defer', function() {
|
||||
return function() {
|
||||
var defer = {};
|
||||
defer.promise = new Promise(function(resolve, reject) {
|
||||
defer.resolve = resolve;
|
||||
defer.reject = reject;
|
||||
});
|
||||
return defer;
|
||||
};
|
||||
});
|
||||
|
||||
define('DialogManager', function() {
|
||||
return {
|
||||
open: function() {},
|
||||
close: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
requireCtx(modules,
|
||||
function(MockSettings, MockDialogManager, DialogService) {
|
||||
mockSettings = MockSettings;
|
||||
mockDialogManager = MockDialogManager;
|
||||
dialogService = DialogService;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('show', function() {
|
||||
var panelId;
|
||||
var userOptions;
|
||||
|
||||
setup(function() {
|
||||
panelId = 'fakePanelId';
|
||||
userOptions = {};
|
||||
});
|
||||
|
||||
suite('when navigating', function() {
|
||||
setup(function() {
|
||||
dialogService._navigating = true;
|
||||
Promise.resolve(dialogService.show(panelId, userOptions));
|
||||
});
|
||||
|
||||
test('We will catch the defer object', function() {
|
||||
var pendingRequest = dialogService._pendingRequests.pop();
|
||||
assert.equal(pendingRequest.panelId, panelId);
|
||||
assert.equal(pendingRequest.userOptions, userOptions);
|
||||
});
|
||||
});
|
||||
|
||||
suite('not navigating, but there is already one same dialog', function() {
|
||||
setup(function() {
|
||||
mockSettings.currentPanel = '#' + panelId;
|
||||
dialogService._navigating = false;
|
||||
});
|
||||
|
||||
test('We will reject directly', function(done) {
|
||||
dialogService.show(panelId, userOptions)
|
||||
.then(function() {
|
||||
// this line should not be executed
|
||||
assert.isTrue(false);
|
||||
}, function(reason) {
|
||||
assert.equal(reason, 'You are showing the same panel #' + panelId);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('not navigating, would open dialog', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(document, 'getElementById', function() {
|
||||
return document.createElement('div');
|
||||
});
|
||||
this.sinon.stub(mockDialogManager, 'open');
|
||||
this.sinon.stub(mockDialogManager, 'close');
|
||||
dialogService._navigating = false;
|
||||
dialogService.show(panelId, userOptions);
|
||||
});
|
||||
|
||||
test('will do following works', function() {
|
||||
assert.isTrue(dialogService._navigating);
|
||||
assert.isTrue(mockDialogManager.open.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('not navigating, would open dialog. If click on cancel button',
|
||||
function() {
|
||||
var promise;
|
||||
var resolvedResult = 'Fake Result';
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(dialogService, '_execPendingRequest');
|
||||
this.sinon.stub(document, 'getElementById', function() {
|
||||
return document.createElement('div');
|
||||
});
|
||||
this.sinon.stub(mockDialogManager, 'close', function() {
|
||||
return Promise.resolve(resolvedResult);
|
||||
});
|
||||
dialogService._navigating = false;
|
||||
promise = dialogService.show(panelId, userOptions);
|
||||
userOptions.onWrapCancel();
|
||||
});
|
||||
|
||||
test('will do following works', function(done) {
|
||||
promise.then(function(result) {
|
||||
assert.equal(result.type, 'cancel');
|
||||
assert.equal(result.value, resolvedResult);
|
||||
assert.isTrue(dialogService._execPendingRequest.called);
|
||||
assert.isFalse(dialogService._navigating);
|
||||
}, function() {
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('not navigating, would open dialog. If click on submit button',
|
||||
function() {
|
||||
var promise;
|
||||
var resolvedResult = 'Fake Result';
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(dialogService, '_execPendingRequest');
|
||||
this.sinon.stub(document, 'getElementById', function() {
|
||||
return document.createElement('div');
|
||||
});
|
||||
this.sinon.stub(mockDialogManager, 'close', function() {
|
||||
return Promise.resolve(resolvedResult);
|
||||
});
|
||||
dialogService._navigating = false;
|
||||
promise = dialogService.show(panelId, userOptions);
|
||||
userOptions.onWrapSubmit();
|
||||
});
|
||||
|
||||
test('will do following works', function(done) {
|
||||
promise.then(function(result) {
|
||||
assert.equal(result.type, 'submit');
|
||||
assert.equal(result.value, resolvedResult);
|
||||
assert.isTrue(dialogService._execPendingRequest.called);
|
||||
assert.isFalse(dialogService._navigating);
|
||||
}, function() {
|
||||
assert.isTrue(false);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
306
gaia/apps/settings/test/unit/modules/keyboard_context_test.js
Executable file
306
gaia/apps/settings/test/unit/modules/keyboard_context_test.js
Executable file
|
|
@ -0,0 +1,306 @@
|
|||
/* globals MocksHelper, MockKeyboardHelper */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_keyboard_helper.js');
|
||||
require('/shared/test/unit/mocks/mock_manifest_helper.js');
|
||||
|
||||
suite('KeyboardContext', function() {
|
||||
var mockHelper = new MocksHelper([
|
||||
'KeyboardHelper',
|
||||
'ManifestHelper'
|
||||
]).init();
|
||||
mockHelper.attachTestHelpers();
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var map = {
|
||||
'modules/keyboard_context': {
|
||||
'shared/keyboard_helper': 'shared_mocks/mock_keyboard_helper',
|
||||
'shared/manifest_helper': 'shared_mocks/mock_manifest_helper'
|
||||
}
|
||||
};
|
||||
|
||||
testRequire(['modules/keyboard_context'], map, (function(KeyboardContext) {
|
||||
this.KeyboardContext = KeyboardContext;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
/*
|
||||
* The raw data used in this test please refer to mock_keyboard_helper.js
|
||||
*
|
||||
* Keyboards is an observable array of keyboard objects.
|
||||
* A keyboard object contains the following properties:
|
||||
* - name,
|
||||
description,
|
||||
launchPath,
|
||||
layouts,
|
||||
app: an instance of App
|
||||
*
|
||||
* A layout object is a Observable and contains the following properties:
|
||||
* - name,
|
||||
appName,
|
||||
description,
|
||||
types,
|
||||
enabled
|
||||
*/
|
||||
|
||||
var keyboards = null;
|
||||
var enabledLayouts = null;
|
||||
|
||||
var keyboardApp1 = null;
|
||||
var keyboardApp2 = null;
|
||||
var keyboardApp3 = null;
|
||||
var layouts = null;
|
||||
|
||||
setup(function(callback) {
|
||||
this.KeyboardContext.init();
|
||||
this.KeyboardContext.keyboards((function(_keyboards) {
|
||||
keyboards = _keyboards;
|
||||
|
||||
var keybordsArray = keyboards.array;
|
||||
keyboardApp1 = keybordsArray[0];
|
||||
keyboardApp2 = keybordsArray[1];
|
||||
keyboardApp3 = keybordsArray[2];
|
||||
|
||||
layouts = {
|
||||
'0': {
|
||||
'0': keyboardApp1.layouts[0],
|
||||
'1': keyboardApp1.layouts[1]
|
||||
},
|
||||
'1': {
|
||||
'0': keyboardApp2.layouts[0]
|
||||
},
|
||||
'2': {
|
||||
'0': keyboardApp3.layouts[0]
|
||||
}
|
||||
};
|
||||
|
||||
this.KeyboardContext.enabledLayouts(function(_enabledLayouts) {
|
||||
enabledLayouts = _enabledLayouts;
|
||||
callback();
|
||||
});
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
keyboards = null;
|
||||
enabledLayouts = null;
|
||||
});
|
||||
|
||||
suite('keyboards', function() {
|
||||
test('Keyboard count', function() {
|
||||
assert.isNotNull(keyboardApp1);
|
||||
assert.isNotNull(keyboardApp2);
|
||||
assert.isNotNull(keyboardApp3);
|
||||
});
|
||||
|
||||
test('Keyboard name', function() {
|
||||
assert.equal(keyboardApp1.name, 'app1');
|
||||
assert.equal(keyboardApp2.name, 'app2');
|
||||
assert.equal(keyboardApp3.name, 'app3');
|
||||
});
|
||||
|
||||
test('Keyboard description', function() {
|
||||
assert.equal(keyboardApp1.description, 'app1');
|
||||
assert.equal(keyboardApp2.description, 'app2');
|
||||
assert.equal(keyboardApp3.description, 'app3');
|
||||
});
|
||||
|
||||
test('Keyboard launch path', function() {
|
||||
assert.equal(keyboardApp1.launchPath, '/settings.html');
|
||||
assert.equal(keyboardApp2.launchPath, '/settings.html');
|
||||
assert.equal(keyboardApp3.launchPath, '/settings.html');
|
||||
});
|
||||
|
||||
test('Keyboard layout count', function() {
|
||||
assert.equal(keyboardApp1.layouts.length, 2);
|
||||
assert.equal(keyboardApp2.layouts.length, 1);
|
||||
assert.equal(keyboardApp3.layouts.length, 1);
|
||||
});
|
||||
|
||||
test('Layout count', function() {
|
||||
// app1
|
||||
assert.isNotNull(layouts[0][0]);
|
||||
assert.isNotNull(layouts[0][1]);
|
||||
// app2
|
||||
assert.isNotNull(layouts[1][0]);
|
||||
// app3
|
||||
assert.isNotNull(layouts[2][0]);
|
||||
});
|
||||
|
||||
test('Layout name', function() {
|
||||
// app1
|
||||
assert.equal(layouts[0][0].name, 'layout1');
|
||||
assert.equal(layouts[0][1].name, 'layout2');
|
||||
// app2
|
||||
assert.equal(layouts[1][0].name, 'layout1');
|
||||
// app3
|
||||
assert.equal(layouts[2][0].name, 'layout1');
|
||||
});
|
||||
|
||||
test('Layout app name', function() {
|
||||
// app1
|
||||
assert.equal(layouts[0][0].appName, 'app1');
|
||||
assert.equal(layouts[0][1].appName, 'app1');
|
||||
// app2
|
||||
assert.equal(layouts[1][0].appName, 'app2');
|
||||
// app3
|
||||
assert.equal(layouts[2][0].appName, 'app3');
|
||||
});
|
||||
|
||||
test('Layout description', function() {
|
||||
// app1
|
||||
assert.equal(layouts[0][0].description, 'layout1');
|
||||
assert.equal(layouts[0][1].description, 'layout2');
|
||||
// app2
|
||||
assert.equal(layouts[1][0].description, 'layout1');
|
||||
// app3
|
||||
assert.equal(layouts[2][0].description, 'layout1');
|
||||
});
|
||||
|
||||
test('Layout type', function() {
|
||||
// app1
|
||||
assert.equal(layouts[0][0].types.length, 2);
|
||||
assert.equal(layouts[0][0].types[0], 'url');
|
||||
assert.equal(layouts[0][0].types[1], 'text');
|
||||
assert.equal(layouts[0][1].types.length, 1);
|
||||
assert.equal(layouts[0][1].types[0], 'number');
|
||||
// app2
|
||||
assert.equal(layouts[1][0].types.length, 1);
|
||||
assert.equal(layouts[1][0].types[0], 'url');
|
||||
// app3
|
||||
assert.equal(layouts[2][0].types.length, 1);
|
||||
assert.equal(layouts[2][0].types[0], 'number');
|
||||
});
|
||||
});
|
||||
|
||||
suite('enabledLayouts', function() {
|
||||
setup(function() {
|
||||
this.checkDefaults =
|
||||
this.sinon.stub(MockKeyboardHelper, 'checkDefaults');
|
||||
});
|
||||
var isActuallyEnabled = function(targetLayout) {
|
||||
var found = false;
|
||||
enabledLayouts.forEach(function(layout) {
|
||||
if (layout === targetLayout) {
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
test('Default enabled layout', function(callback) {
|
||||
this.KeyboardContext.enabledLayouts(function(_enabledLayouts) {
|
||||
var layout1 = _enabledLayouts.get(0);
|
||||
var layout2 = _enabledLayouts.get(1);
|
||||
|
||||
assert.equal(_enabledLayouts.length, 2);
|
||||
assert.equal(layout1.appName, layouts[0][0].appName);
|
||||
assert.equal(layout1.name, layouts[0][0].name);
|
||||
assert.equal(layout2.appName, layouts[2][0].appName);
|
||||
assert.equal(layout2.name, layouts[2][0].name);
|
||||
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
// The following tests do a series of actions and check if the layouts are
|
||||
// enabled/disabled accordingly.
|
||||
test('Disable app1 layout1', function() {
|
||||
var targetLayout = layouts[0][0];
|
||||
targetLayout.enabled = false;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isFalse(isActuallyEnabled(targetLayout));
|
||||
assert.isTrue(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Enable app1 layout1', function() {
|
||||
var targetLayout = layouts[0][0];
|
||||
targetLayout.enabled = true;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isTrue(isActuallyEnabled(targetLayout));
|
||||
// don't check defaults when enabling a keyboard
|
||||
assert.isFalse(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Disable app1 layout1', function() {
|
||||
var targetLayout = layouts[0][0];
|
||||
targetLayout.enabled = false;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isFalse(isActuallyEnabled(targetLayout));
|
||||
assert.isTrue(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Enable app1 layout2', function() {
|
||||
var targetLayout = layouts[0][1];
|
||||
targetLayout.enabled = true;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isTrue(isActuallyEnabled(targetLayout));
|
||||
// don't check defaults when enabling a keyboard
|
||||
assert.isFalse(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Enable app2 layout1', function() {
|
||||
var targetLayout = layouts[1][0];
|
||||
targetLayout.enabled = true;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isTrue(isActuallyEnabled(targetLayout));
|
||||
// don't check defaults when enabling a keyboard
|
||||
assert.isFalse(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Disable app3 layout1', function() {
|
||||
var targetLayout = layouts[2][0];
|
||||
targetLayout.enabled = false;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isFalse(isActuallyEnabled(targetLayout));
|
||||
assert.isTrue(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('Disable app2 layout1', function() {
|
||||
var targetLayout = layouts[1][0];
|
||||
targetLayout.enabled = false;
|
||||
MockKeyboardHelper.saveToSettings();
|
||||
|
||||
assert.isFalse(isActuallyEnabled(targetLayout));
|
||||
assert.isTrue(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
suite('Checks defaults', function() {
|
||||
var missingTypes;
|
||||
var targetLayout;
|
||||
var targetRawLayout;
|
||||
var defaultCallback;
|
||||
|
||||
setup(function() {
|
||||
missingTypes = [];
|
||||
targetLayout = layouts[0][0];
|
||||
targetRawLayout = MockKeyboardHelper.layouts[0];
|
||||
defaultCallback = this.sinon.spy();
|
||||
|
||||
this.KeyboardContext.defaultKeyboardEnabled(defaultCallback,
|
||||
missingTypes);
|
||||
});
|
||||
|
||||
test('calls checkDefaults', function() {
|
||||
targetLayout.enabled = false;
|
||||
assert.isTrue(this.checkDefaults.called);
|
||||
});
|
||||
|
||||
test('calls callback with enabled layout', function() {
|
||||
targetLayout.enabled = false;
|
||||
this.checkDefaults.yield([targetRawLayout], [missingTypes]);
|
||||
|
||||
assert.ok(defaultCallback.calledWith(targetRawLayout));
|
||||
// The layout should be re-enabled.
|
||||
assert.isTrue(targetLayout.enabled);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
79
gaia/apps/settings/test/unit/modules/media_storage_test.js
Executable file
79
gaia/apps/settings/test/unit/modules/media_storage_test.js
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
/* global MockGetDeviceStorage, MockGetDeviceStorages, MockDOMRequest */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_event_target.js');
|
||||
require('/shared/test/unit/mocks/mock_dom_request.js');
|
||||
require('/shared/test/unit/mocks/mock_navigator_getdevicestorage.js');
|
||||
require('/shared/test/unit/mocks/mock_navigator_getdevicestorages.js');
|
||||
|
||||
suite('MediaStorage > ', function() {
|
||||
var MediaStorage;
|
||||
var realDeviceStorage, realDeviceStorages;
|
||||
var modules = [
|
||||
'modules/media_storage'
|
||||
];
|
||||
var map = {
|
||||
'*': {
|
||||
'shared/settings_listener': 'shared_mocks/mock_settings_listener'
|
||||
}
|
||||
};
|
||||
|
||||
suiteSetup(function() {
|
||||
realDeviceStorages = navigator.getDeviceStorages;
|
||||
navigator.getDeviceStorages = MockGetDeviceStorages;
|
||||
|
||||
realDeviceStorage = navigator.getDeviceStorage;
|
||||
navigator.getDeviceStorage = MockGetDeviceStorage;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.getDeviceStorages = realDeviceStorages;
|
||||
realDeviceStorages = null;
|
||||
|
||||
navigator.getDeviceStorage = realDeviceStorage;
|
||||
realDeviceStorage = null;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
requireCtx(modules, function(media_storage) {
|
||||
MediaStorage = media_storage;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('_updateMediaStorageInfo', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(MediaStorage, '_updateVolumeState');
|
||||
});
|
||||
|
||||
test('when no _defaultMediaVolume',
|
||||
function() {
|
||||
MediaStorage._defaultMediaVolume = null;
|
||||
MediaStorage._updateMediaStorageInfo();
|
||||
assert.ok(MediaStorage._updateVolumeState.calledWith(null,
|
||||
'unavailable'));
|
||||
});
|
||||
|
||||
test('when has _defaultMediaVolume', function() {
|
||||
MediaStorage._defaultMediaVolume = MockGetDeviceStorage();
|
||||
this.sinon.stub(MediaStorage._defaultMediaVolume, 'available')
|
||||
.returns(MockDOMRequest);
|
||||
MediaStorage._updateMediaStorageInfo();
|
||||
assert.ok(MediaStorage._defaultMediaVolume.available.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('_getDefaultVolume', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(navigator, 'getDeviceStorages');
|
||||
});
|
||||
|
||||
test('call navigator.getDeviceStorages to get default volume',
|
||||
function() {
|
||||
MediaStorage._getDefaultVolume();
|
||||
assert.ok(navigator.getDeviceStorages.calledWith('sdcard'));
|
||||
});
|
||||
});
|
||||
});
|
||||
71
gaia/apps/settings/test/unit/modules/messaging_test.js
Executable file
71
gaia/apps/settings/test/unit/modules/messaging_test.js
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
/* global MockNavigatorSettings */
|
||||
'use strict';
|
||||
|
||||
requireApp('settings/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
|
||||
suite('messaging', function() {
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'shared/icc_helper': 'IccHelper',
|
||||
'shared/async_storage': 'unit/mock_async_storage',
|
||||
'modules/settings_utils': 'unit/mock_settings_utils',
|
||||
'shared/settings_listener': 'shared_mocks/mock_settings_listener'
|
||||
}
|
||||
};
|
||||
|
||||
var realSettings;
|
||||
var messaging;
|
||||
var mockSettingsUtils;
|
||||
var mockIccHelper;
|
||||
|
||||
suiteSetup(function() {
|
||||
realSettings = window.navigator.mozSettings;
|
||||
window.navigator.mozSettings = MockNavigatorSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.navigator.mozSettings = realSettings;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
mockIccHelper = {
|
||||
addEventListener: function() {},
|
||||
cardState: null
|
||||
};
|
||||
define('IccHelper', function() {
|
||||
return mockIccHelper;
|
||||
});
|
||||
|
||||
requireCtx([
|
||||
'modules/messaging',
|
||||
'unit/mock_settings_utils'
|
||||
], function(Messaging, MockSettingsUtils) {
|
||||
messaging = Messaging;
|
||||
mockSettingsUtils = MockSettingsUtils;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('disable items based on card states', function() {
|
||||
var fakePanel = {};
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(messaging, '_disableItems');
|
||||
});
|
||||
|
||||
test('card state: ready would enable items', function() {
|
||||
mockIccHelper.cardState = 'ready';
|
||||
messaging.disableItems(fakePanel);
|
||||
assert.isTrue(messaging._disableItems.calledWith(fakePanel, false));
|
||||
});
|
||||
|
||||
test('card state: non-ready would disable items', function() {
|
||||
mockIccHelper.cardState = 'unknown';
|
||||
messaging.disableItems(fakePanel);
|
||||
assert.isTrue(messaging._disableItems.calledWith(fakePanel, true));
|
||||
});
|
||||
});
|
||||
});
|
||||
68
gaia/apps/settings/test/unit/modules/mobile/supported_network_info_test.js
Executable file
68
gaia/apps/settings/test/unit/modules/mobile/supported_network_info_test.js
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
/* global MockNavigatorMozMobileConnections */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
|
||||
|
||||
suite('NetworkInfo', function() {
|
||||
var supportedNetworkInfo;
|
||||
var _mobileConnection;
|
||||
var mockNetworkType;
|
||||
var realMozMobileConnections;
|
||||
var modules = [
|
||||
'modules/mobile/supported_network_info'
|
||||
];
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/mobile/supported_network_type': 'MockNetworkType'
|
||||
}
|
||||
};
|
||||
var mockSupportedNetworkTypes = [
|
||||
'lte/wcdma/gsm',
|
||||
'lte/wcdma',
|
||||
'gsm',
|
||||
'wcdma',
|
||||
'wcdma/gsm-auto',
|
||||
'wcdma/gsm',
|
||||
'lte'
|
||||
];
|
||||
|
||||
setup(function(done) {
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
|
||||
mockNetworkType = {
|
||||
SupportedNetworkTypeHelper: function(supportedNetworkTypes) {
|
||||
return mockSupportedNetworkTypes;
|
||||
}
|
||||
};
|
||||
define('MockNetworkType', function() {
|
||||
return mockNetworkType;
|
||||
});
|
||||
|
||||
realMozMobileConnections = navigator.mozMobileConnections;
|
||||
navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
|
||||
_mobileConnection = MockNavigatorMozMobileConnections[0];
|
||||
_mobileConnection.supportedNetworkTypes = mockSupportedNetworkTypes;
|
||||
|
||||
requireCtx(modules, function(SupportedNetworkInfo) {
|
||||
supportedNetworkInfo = SupportedNetworkInfo;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
_mobileConnection = null;
|
||||
navigator.mozMobileConnections = realMozMobileConnections;
|
||||
});
|
||||
|
||||
suite('SupportedNetworkTypeHelper is called', function() {
|
||||
test('single hardware support type', function() {
|
||||
this.sinon.spy(mockNetworkType, 'SupportedNetworkTypeHelper');
|
||||
this.sinon.spy(supportedNetworkInfo, '_getMobileConnectionIndex');
|
||||
supportedNetworkInfo.getSupportedNetworkInfo(_mobileConnection);
|
||||
assert.ok(supportedNetworkInfo._getMobileConnectionIndex
|
||||
.calledWith(_mobileConnection));
|
||||
assert.ok(mockNetworkType.SupportedNetworkTypeHelper
|
||||
.calledWith(_mobileConnection.supportedNetworkTypes));
|
||||
});
|
||||
});
|
||||
});
|
||||
248
gaia/apps/settings/test/unit/modules/mobile/supported_network_type_test.js
Executable file
248
gaia/apps/settings/test/unit/modules/mobile/supported_network_type_test.js
Executable file
|
|
@ -0,0 +1,248 @@
|
|||
'use strict';
|
||||
|
||||
suite('NetworkType', function() {
|
||||
var SupportedNetworkTypeHelper;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var modules = [
|
||||
'modules/mobile/supported_network_type'
|
||||
];
|
||||
var maps = {};
|
||||
|
||||
testRequire(modules, maps, function(module) {
|
||||
SupportedNetworkTypeHelper = module.SupportedNetworkTypeHelper;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('SupportedNetworkTypeHelper', function() {
|
||||
var hardwareSupportedTypes = ['gsm', 'wcdma', 'cdma', 'evdo', 'lte'];
|
||||
|
||||
suite('single hardware support type', function() {
|
||||
suite('should have correct support value', function() {
|
||||
hardwareSupportedTypes.forEach(function(hardwareSupportedType) {
|
||||
test(hardwareSupportedType, function() {
|
||||
var helper = SupportedNetworkTypeHelper([hardwareSupportedType]);
|
||||
hardwareSupportedTypes.forEach(function(targetType) {
|
||||
assert.equal(helper[targetType],
|
||||
hardwareSupportedType === targetType);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('networkTypes', function() {
|
||||
hardwareSupportedTypes.forEach(function(hardwareSupportedType) {
|
||||
test(hardwareSupportedType, function() {
|
||||
var helper = SupportedNetworkTypeHelper([hardwareSupportedType]);
|
||||
assert.deepEqual(helper.networkTypes, [hardwareSupportedType]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('l10nIdForType()', function() {
|
||||
suiteSetup(function() {
|
||||
this.expectedl10nIds = {
|
||||
'gsm': 'operator-networkType-2G',
|
||||
'wcdma': 'operator-networkType-3G',
|
||||
'cdma': 'operator-networkType-CDMA',
|
||||
'evdo': 'operator-networkType-EVDO',
|
||||
'lte': 'operator-networkType-LTE'
|
||||
};
|
||||
});
|
||||
|
||||
hardwareSupportedTypes.forEach(function(hardwareSupportedType) {
|
||||
test(hardwareSupportedType, function() {
|
||||
var helper = SupportedNetworkTypeHelper([hardwareSupportedType]);
|
||||
assert.equal(helper.l10nIdForType(hardwareSupportedType),
|
||||
this.expectedl10nIds[hardwareSupportedType]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('multiple hardware support types', function() {
|
||||
suite('networkTypes', function() {
|
||||
test('gsm, wcdma', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['gsm', 'wcdma']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'wcdma/gsm',
|
||||
'gsm',
|
||||
'wcdma',
|
||||
'wcdma/gsm-auto'
|
||||
]);
|
||||
});
|
||||
|
||||
test('evdo, cdma', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['evdo', 'cdma']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'cdma/evdo',
|
||||
'cdma',
|
||||
'evdo'
|
||||
]);
|
||||
});
|
||||
|
||||
test('gsm, wcdma, evdo, cdma', function() {
|
||||
var helper =
|
||||
SupportedNetworkTypeHelper(['gsm', 'wcdma', 'evdo', 'cdma']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'wcdma/gsm',
|
||||
'gsm',
|
||||
'wcdma',
|
||||
'wcdma/gsm-auto',
|
||||
'cdma/evdo',
|
||||
'cdma',
|
||||
'evdo',
|
||||
'wcdma/gsm/cdma/evdo'
|
||||
]);
|
||||
});
|
||||
|
||||
test('gsm, wcdma, lte', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['gsm', 'wcdma', 'lte']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'wcdma/gsm',
|
||||
'gsm',
|
||||
'wcdma',
|
||||
'wcdma/gsm-auto',
|
||||
'lte/wcdma/gsm',
|
||||
'lte',
|
||||
'lte/wcdma'
|
||||
]);
|
||||
});
|
||||
|
||||
test('evdo, cdma, lte', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['evdo', 'cdma', 'lte']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'cdma/evdo',
|
||||
'cdma',
|
||||
'evdo',
|
||||
'lte/cdma/evdo',
|
||||
'lte'
|
||||
]);
|
||||
});
|
||||
|
||||
test('gsm, wcdma, evdo, cdma, lte', function() {
|
||||
var helper =
|
||||
SupportedNetworkTypeHelper(['gsm', 'wcdma', 'evdo', 'cdma', 'lte']);
|
||||
assert.deepEqual(helper.networkTypes, [
|
||||
'wcdma/gsm',
|
||||
'gsm',
|
||||
'wcdma',
|
||||
'wcdma/gsm-auto',
|
||||
'cdma/evdo',
|
||||
'cdma',
|
||||
'evdo',
|
||||
'wcdma/gsm/cdma/evdo',
|
||||
'lte/cdma/evdo',
|
||||
'lte/wcdma/gsm',
|
||||
'lte/wcdma/gsm/cdma/evdo',
|
||||
'lte',
|
||||
'lte/wcdma'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('l10nIdForType()', function() {
|
||||
test('gsm, wcdma', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['gsm', 'wcdma']);
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm'),
|
||||
'operator-networkType-prefer3G');
|
||||
assert.equal(helper.l10nIdForType('gsm'), 'operator-networkType-2G');
|
||||
assert.equal(helper.l10nIdForType('wcdma'),
|
||||
'operator-networkType-3G');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm-auto'),
|
||||
'operator-networkType-auto');
|
||||
});
|
||||
|
||||
test('evdo, cdma', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['evdo', 'cdma']);
|
||||
assert.equal(helper.l10nIdForType('cdma/evdo'),
|
||||
'operator-networkType-auto');
|
||||
assert.equal(helper.l10nIdForType('cdma'),
|
||||
'operator-networkType-CDMA');
|
||||
assert.equal(helper.l10nIdForType('evdo'),
|
||||
'operator-networkType-EVDO');
|
||||
});
|
||||
|
||||
test('gsm, wcdma, evdo, cdma', function() {
|
||||
var helper =
|
||||
SupportedNetworkTypeHelper(['gsm', 'wcdma', 'evdo', 'cdma']);
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm'),
|
||||
'operator-networkType-preferWCDMA');
|
||||
assert.equal(helper.l10nIdForType('gsm'), 'operator-networkType-GSM');
|
||||
assert.equal(helper.l10nIdForType('wcdma'),
|
||||
'operator-networkType-WCDMA');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm-auto'),
|
||||
'operator-networkType-auto-WCDMA-GSM');
|
||||
assert.equal(helper.l10nIdForType('cdma/evdo'),
|
||||
'operator-networkType-auto-CDMA-EVDO');
|
||||
assert.equal(helper.l10nIdForType('cdma'),
|
||||
'operator-networkType-CDMA');
|
||||
assert.equal(helper.l10nIdForType('evdo'),
|
||||
'operator-networkType-EVDO');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm/cdma/evdo'),
|
||||
'operator-networkType-auto');
|
||||
});
|
||||
|
||||
test('gsm, wcdma, lte', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['gsm', 'wcdma', 'lte']);
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm'),
|
||||
'operator-networkType-prefer3G');
|
||||
assert.equal(helper.l10nIdForType('gsm'), 'operator-networkType-2G');
|
||||
assert.equal(helper.l10nIdForType('wcdma'),
|
||||
'operator-networkType-3G');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm-auto'),
|
||||
'operator-networkType-auto-2G-3G');
|
||||
assert.equal(helper.l10nIdForType('lte'), 'operator-networkType-LTE');
|
||||
assert.equal(helper.l10nIdForType('lte/wcdma/gsm'),
|
||||
'operator-networkType-auto');
|
||||
assert.equal(helper.l10nIdForType('lte/wcdma'),
|
||||
'operator-networkType-auto-3G-4G');
|
||||
});
|
||||
|
||||
test('evdo, cdma, lte', function() {
|
||||
var helper = SupportedNetworkTypeHelper(['evdo', 'cdma', 'lte']);
|
||||
assert.equal(helper.l10nIdForType('cdma/evdo'),
|
||||
'operator-networkType-auto-CDMA-EVDO');
|
||||
assert.equal(helper.l10nIdForType('cdma'),
|
||||
'operator-networkType-CDMA');
|
||||
assert.equal(helper.l10nIdForType('evdo'),
|
||||
'operator-networkType-EVDO');
|
||||
assert.equal(helper.l10nIdForType('lte'), 'operator-networkType-LTE');
|
||||
assert.equal(helper.l10nIdForType('lte/cdma/evdo'),
|
||||
'operator-networkType-auto');
|
||||
});
|
||||
|
||||
test('gsm, wcdma, evdo, cdma, lte', function() {
|
||||
var helper =
|
||||
SupportedNetworkTypeHelper(['gsm', 'wcdma', 'evdo', 'cdma', 'lte']);
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm'),
|
||||
'operator-networkType-preferWCDMA');
|
||||
assert.equal(helper.l10nIdForType('gsm'), 'operator-networkType-GSM');
|
||||
assert.equal(helper.l10nIdForType('wcdma'),
|
||||
'operator-networkType-WCDMA');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm-auto'),
|
||||
'operator-networkType-auto-WCDMA-GSM');
|
||||
assert.equal(helper.l10nIdForType('cdma/evdo'),
|
||||
'operator-networkType-auto-CDMA-EVDO');
|
||||
assert.equal(helper.l10nIdForType('cdma'),
|
||||
'operator-networkType-CDMA');
|
||||
assert.equal(helper.l10nIdForType('evdo'),
|
||||
'operator-networkType-EVDO');
|
||||
assert.equal(helper.l10nIdForType('wcdma/gsm/cdma/evdo'),
|
||||
'operator-networkType-auto-WCDMA-GSM-CDMA-EVDO');
|
||||
assert.equal(helper.l10nIdForType('lte'),
|
||||
'operator-networkType-LTE');
|
||||
assert.equal(helper.l10nIdForType('lte/wcdma'),
|
||||
'operator-networkType-auto-LTE-WCDMA');
|
||||
assert.equal(helper.l10nIdForType('lte/cdma/evdo'),
|
||||
'operator-networkType-auto-LTE-CDMA-EVDO');
|
||||
assert.equal(helper.l10nIdForType('lte/wcdma/gsm'),
|
||||
'operator-networkType-auto-LTE-WCDMA-GSM');
|
||||
assert.equal(helper.l10nIdForType('lte/wcdma/gsm/cdma/evdo'),
|
||||
'operator-networkType-auto');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
621
gaia/apps/settings/test/unit/modules/mvvm/list_view_test.js
Executable file
621
gaia/apps/settings/test/unit/modules/mvvm/list_view_test.js
Executable file
|
|
@ -0,0 +1,621 @@
|
|||
/* global define */
|
||||
'use strict';
|
||||
|
||||
// The views are very tightly coupled to models, rather than reimplement model
|
||||
// behavior in a mock, rely on tested interfaces on the model instead
|
||||
suite('ListView', function() {
|
||||
// Define a shim for ObservableArray that is to be loaded in ListView.
|
||||
// Then we are able to creat a stub on it.
|
||||
|
||||
suiteSetup(function(done) {
|
||||
// Use the shim in ListView.
|
||||
var ObservableArrayShimName = 'observable_array_shim' + Date.now();
|
||||
var map = {
|
||||
'modules/mvvm/list_view': {
|
||||
'modules/mvvm/observable_array': ObservableArrayShimName
|
||||
}
|
||||
};
|
||||
|
||||
// XXX: Create a new require context.
|
||||
// We can only define the mock module after retrieving the context.
|
||||
var requireCtx = testRequire([], map, function() {});
|
||||
// Define the mock module.
|
||||
define(ObservableArrayShimName, function() {
|
||||
var ctor = function observable_array_shim() {
|
||||
return ctor.mInnerFunction.apply(this, arguments);
|
||||
};
|
||||
ctor.mInnerFunction = function() {};
|
||||
ctor.mTeardown = function observable_array_shim_teardown() {
|
||||
ctor.mInnerFunction = function() {};
|
||||
};
|
||||
return ctor;
|
||||
});
|
||||
|
||||
requireCtx([
|
||||
'modules/mvvm/observable',
|
||||
'modules/mvvm/observable_array',
|
||||
'modules/mvvm/list_view',
|
||||
ObservableArrayShimName
|
||||
], (function(Observable, ObservableArray, ListView, ObservableArrayShim) {
|
||||
this.Observable = Observable;
|
||||
this.ListView = ListView;
|
||||
this.ObservableArrayShim = ObservableArrayShim;
|
||||
// stub the real ObservableArray to create spies on observe method
|
||||
// Redirect the shim to the ObservableArray stub.
|
||||
this.ObservableArray = sinon.stub(ObservableArrayShim,
|
||||
'mInnerFunction', function() {
|
||||
var result = ObservableArray.apply(this, arguments);
|
||||
sinon.spy(result, 'addEventListener');
|
||||
sinon.spy(result, 'removeEventListener');
|
||||
return result;
|
||||
});
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.ObservableArray.reset();
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
this.ObservableArray.restore();
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.array = [];
|
||||
this.observableArray = this.ObservableArray(this.array);
|
||||
});
|
||||
|
||||
suite('ListView(<ul>, ObservableArray, function)', function() {
|
||||
setup(function() {
|
||||
this.container = document.createElement('ul');
|
||||
this.template = (function(item, recycle) {
|
||||
if (recycle && this.template.recycle) {
|
||||
return recycle;
|
||||
}
|
||||
return document.createElement('li');
|
||||
}).bind(this);
|
||||
this.sinon.spy(this, 'template');
|
||||
this.listView = this.ListView(
|
||||
this.container, this.observableArray, this.template
|
||||
);
|
||||
});
|
||||
|
||||
test('.element', function() {
|
||||
assert.equal(this.listView.element, this.container);
|
||||
});
|
||||
|
||||
test('Listens to ObservableArray', function() {
|
||||
var addEventListener = this.observableArray.addEventListener;
|
||||
assert.ok(addEventListener.calledWith('insert'));
|
||||
assert.ok(addEventListener.calledWith('remove'));
|
||||
assert.ok(addEventListener.calledWith('replace'));
|
||||
assert.ok(addEventListener.calledWith('reset'));
|
||||
});
|
||||
|
||||
suite('Add Multiple Elements', function() {
|
||||
setup(function() {
|
||||
// add 3 items
|
||||
for (var count = 0; count < 3; count++) {
|
||||
this.observableArray.push({ count: count });
|
||||
}
|
||||
});
|
||||
|
||||
// use forEach instead of for to keep 'count' in a closure
|
||||
[0, 1, 2].forEach(function(count) {
|
||||
suite('item ' + count, function() {
|
||||
setup(function() {
|
||||
this.item = this.array[count];
|
||||
});
|
||||
test('kept order', function() {
|
||||
assert.equal(this.item.count, count);
|
||||
});
|
||||
test('called template', function() {
|
||||
assert.ok(this.template.calledWith(this.item));
|
||||
});
|
||||
test('template returned element is in correct position', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[count], li);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Replace Element', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.item = { replacement: true };
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.observableArray.set(1, this.item);
|
||||
});
|
||||
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElements[1])
|
||||
);
|
||||
});
|
||||
|
||||
test('only called template method once', function() {
|
||||
assert.equal(this.template.callCount, 1);
|
||||
});
|
||||
|
||||
test('replaced element', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[1], li);
|
||||
});
|
||||
|
||||
test('leaves other elements alone', function() {
|
||||
assert.equal(this.container.children[0], this.originalElements[0]);
|
||||
assert.equal(this.container.children[2], this.originalElements[2]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Replace Element (w/recycle)', function() {
|
||||
setup(function() {
|
||||
this.template.recycle = true;
|
||||
this.template.reset();
|
||||
this.item = { replacement: true };
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.observableArray.set(1, this.item);
|
||||
});
|
||||
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElements[1])
|
||||
);
|
||||
});
|
||||
|
||||
test('only called template method once', function() {
|
||||
assert.equal(this.template.callCount, 1);
|
||||
});
|
||||
|
||||
test('same element still in place', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(li, this.originalElements[1], 'returned original');
|
||||
assert.equal(this.container.children[1], this.originalElements[1]);
|
||||
});
|
||||
|
||||
test('leaves other elements alone', function() {
|
||||
assert.equal(this.container.children[0], this.originalElements[0]);
|
||||
assert.equal(this.container.children[2], this.originalElements[2]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Reset With Shorter Array', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.originalArray = this.array;
|
||||
this.array = [{ reset: 1 }, { reset: 2 }];
|
||||
this.observableArray.reset(this.array);
|
||||
});
|
||||
|
||||
// use forEach instead of for to store 'index' in closure
|
||||
[0, 1].forEach(function(index) {
|
||||
suite('item ' + index, function() {
|
||||
setup(function() {
|
||||
this.item = this.array[index];
|
||||
this.originalElement = this.originalElements[index];
|
||||
});
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElement)
|
||||
);
|
||||
});
|
||||
test('replaced element', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[index], li);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('removed extra elements', function() {
|
||||
assert.equal(this.container.children.length, 2);
|
||||
assert.equal(this.originalElements[2].parentNode, null);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Reset With Longer Array', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.originalArray = this.array;
|
||||
this.array = [{ reset: 1 }, { reset: 2 }, { reset: 3 }, { reset: 4 }];
|
||||
this.observableArray.reset(this.array);
|
||||
});
|
||||
|
||||
// use forEach instead of for to store 'index' in closure
|
||||
[0, 1, 2].forEach(function(index) {
|
||||
suite('item ' + index, function() {
|
||||
setup(function() {
|
||||
this.item = this.array[index];
|
||||
this.originalElement = this.originalElements[index];
|
||||
});
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElement)
|
||||
);
|
||||
});
|
||||
test('replaced element', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[index], li);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('item 3', function() {
|
||||
setup(function() {
|
||||
this.item = this.array[3];
|
||||
});
|
||||
|
||||
test('called template without recycled element', function() {
|
||||
assert.ok(this.template.calledWith(this.item));
|
||||
assert.equal(
|
||||
this.template.withArgs(this.item).args[0][1], undefined
|
||||
);
|
||||
});
|
||||
|
||||
test('added extra element', function() {
|
||||
assert.equal(this.container.children.length, 4);
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[3], li);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('reset with .set([{},{}])', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.originalArray = this.array;
|
||||
this.array = [{ reset: 1 }, { reset: 2 }];
|
||||
this.listView.set(this.array);
|
||||
});
|
||||
|
||||
test('creates and watches an ObservableArray', function() {
|
||||
var withNew = this.ObservableArray.withArgs(this.array);
|
||||
assert.ok(withNew.called);
|
||||
var addEventListener = withNew.returnValues[0].addEventListener;
|
||||
assert.ok(addEventListener.calledWith('insert'));
|
||||
assert.ok(addEventListener.calledWith('remove'));
|
||||
assert.ok(addEventListener.calledWith('replace'));
|
||||
assert.ok(addEventListener.calledWith('reset'));
|
||||
});
|
||||
|
||||
// use forEach instead of for to store 'index' in closure
|
||||
[0, 1].forEach(function(index) {
|
||||
suite('item ' + index, function() {
|
||||
setup(function() {
|
||||
this.item = this.array[index];
|
||||
this.originalElement = this.originalElements[index];
|
||||
});
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElement)
|
||||
);
|
||||
});
|
||||
test('replaced element', function() {
|
||||
var li = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[index], li);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('removed extra elements', function() {
|
||||
assert.equal(this.container.children.length, 2);
|
||||
assert.equal(this.originalElements[2].parentNode, null);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.enabled = false', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.originalElements =
|
||||
Array.prototype.slice.call(this.container.children);
|
||||
this.listView.enabled = false;
|
||||
});
|
||||
// test a bunch of things that modify the array
|
||||
[function pop() {
|
||||
this.observableArray.pop();
|
||||
}, function push() {
|
||||
this.observableArray.push({});
|
||||
}, function replace() {
|
||||
this.observableArray.set(1, {});
|
||||
}, function reset() {
|
||||
this.array = [{}];
|
||||
this.observableArray.reset(this.array);
|
||||
}, function set() {
|
||||
this.array = [{}];
|
||||
this.listView.set(this.array);
|
||||
}].forEach(function(method) {
|
||||
suite(method.name, function() {
|
||||
setup(method);
|
||||
test('does not call template', function() {
|
||||
assert.equal(this.template.called, 0);
|
||||
});
|
||||
test('does not change elements', function() {
|
||||
for (var i = 0; i < this.container.children.length; i++) {
|
||||
assert.equal(this.container.children[i],
|
||||
this.originalElements[i]);
|
||||
}
|
||||
});
|
||||
suite('.enabled = true', function() {
|
||||
setup(function() {
|
||||
this.listView.enabled = true;
|
||||
});
|
||||
test('calls template for each item in array', function() {
|
||||
this.array.forEach(function(item, index) {
|
||||
assert.ok(this.template.calledWith(
|
||||
item, this.originalElements[index]
|
||||
), 'array[' + index + ']');
|
||||
}, this);
|
||||
});
|
||||
test('elements are put in the right place', function() {
|
||||
this.array.forEach(function(item, index) {
|
||||
var template = this.template.withArgs(item);
|
||||
assert.equal(
|
||||
this.container.children[index], template.returnValues[0],
|
||||
'element[' + index + ']'
|
||||
);
|
||||
}, this);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('ListView(<div>, ObservableArray, function)', function() {
|
||||
setup(function() {
|
||||
this.container = document.createElement('div');
|
||||
// ensure content inside the container at creation doesn't interfere
|
||||
this.container.appendChild(document.createElement('span'));
|
||||
this.template = (function(item, recycle) {
|
||||
if (recycle && this.template.recycle) {
|
||||
return recycle;
|
||||
}
|
||||
return document.createElement('div');
|
||||
}).bind(this);
|
||||
this.sinon.spy(this, 'template');
|
||||
this.observableArray.push({ count: 0 });
|
||||
this.listView = this.ListView(
|
||||
this.container, this.observableArray, this.template
|
||||
);
|
||||
});
|
||||
|
||||
test('.element', function() {
|
||||
assert.equal(this.listView.element, this.container);
|
||||
});
|
||||
|
||||
test('Listens to ObservableArray', function() {
|
||||
var addEventListener = this.observableArray.addEventListener;
|
||||
assert.ok(addEventListener.calledWith('insert'));
|
||||
assert.ok(addEventListener.calledWith('remove'));
|
||||
assert.ok(addEventListener.calledWith('replace'));
|
||||
assert.ok(addEventListener.calledWith('reset'));
|
||||
});
|
||||
|
||||
test('Initial Element doesnt recycle', function() {
|
||||
var item = this.array[0];
|
||||
var filtered = this.template.withArgs(item);
|
||||
// ensures that if there happens to be an element in the creation
|
||||
// of the ListView, it is not used as a "recycled" element
|
||||
assert.ok(filtered.callCount, 1);
|
||||
assert.equal(filtered.args[0][1], undefined);
|
||||
});
|
||||
|
||||
suite('Add Multiple Elements', function() {
|
||||
setup(function() {
|
||||
// add 2 more items
|
||||
for (var count = 1; count < 3; count++) {
|
||||
this.observableArray.push({ count: count });
|
||||
}
|
||||
});
|
||||
|
||||
// use forEach instead of for to keep 'count' in a closure
|
||||
[1, 2].forEach(function(count) {
|
||||
suite('item ' + count, function() {
|
||||
setup(function() {
|
||||
this.item = this.array[count];
|
||||
});
|
||||
test('kept order', function() {
|
||||
assert.equal(this.item.count, count);
|
||||
});
|
||||
test('called template', function() {
|
||||
assert.ok(this.template.calledWith(this.item));
|
||||
});
|
||||
test('template returned element is in correct position', function() {
|
||||
var div = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[count], div);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Replace Element', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.item = { replacement: true };
|
||||
this.originalElements = [].slice.call(this.container.children);
|
||||
this.observableArray.set(1, this.item);
|
||||
});
|
||||
|
||||
test('called template with recycled element', function() {
|
||||
assert.ok(
|
||||
this.template.calledWith(this.item, this.originalElements[1])
|
||||
);
|
||||
});
|
||||
|
||||
test('only called template method once', function() {
|
||||
assert.equal(this.template.callCount, 1);
|
||||
});
|
||||
|
||||
test('replaced element', function() {
|
||||
var div = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[1], div);
|
||||
});
|
||||
|
||||
test('leaves other elements alone', function() {
|
||||
assert.equal(this.container.children[0], this.originalElements[0]);
|
||||
assert.equal(this.container.children[2], this.originalElements[2]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Remove Element', function() {
|
||||
setup(function() {
|
||||
this.template.reset();
|
||||
this.originalElements = [].slice.call(this.container.children);
|
||||
this.observableArray.pop();
|
||||
});
|
||||
|
||||
test('removed last element', function() {
|
||||
assert.equal(this.originalElements[2].parentNode, null);
|
||||
});
|
||||
|
||||
test('leaves other elements alone', function() {
|
||||
assert.equal(this.container.children[0], this.originalElements[0]);
|
||||
assert.equal(this.container.children[1], this.originalElements[1]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Insert Element', function() {
|
||||
setup(function() {
|
||||
this.originalElements = [].slice.call(this.container.children);
|
||||
this.item = {};
|
||||
this.template.reset();
|
||||
this.observableArray.splice(0, 0, this.item);
|
||||
});
|
||||
|
||||
test('only called template method once', function() {
|
||||
assert.equal(this.template.callCount, 1);
|
||||
});
|
||||
|
||||
test('inserted element', function() {
|
||||
var div = this.template.withArgs(this.item).returnValues[0];
|
||||
assert.equal(this.container.children[0], div);
|
||||
});
|
||||
|
||||
test('shifts other elements', function() {
|
||||
assert.equal(this.container.children[1], this.originalElements[0]);
|
||||
assert.equal(this.container.children[2], this.originalElements[1]);
|
||||
assert.equal(this.container.children[3], this.originalElements[2]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('observable hooks', function() {
|
||||
setup(function() {
|
||||
this.observable = this.Observable({ test: 1 });
|
||||
this.observableArray = this.ObservableArray([this.observable]);
|
||||
this.hook = this.sinon.spy();
|
||||
this.template = (function(data, recycle, helper) {
|
||||
helper.observeAndCall(data, {
|
||||
test: this.hook
|
||||
});
|
||||
return recycle || document.createElement('li');
|
||||
}).bind(this);
|
||||
this.container = document.createElement('ul');
|
||||
this.sinon.spy(this, 'template');
|
||||
this.listView = this.ListView(
|
||||
this.container, this.observableArray, this.template
|
||||
);
|
||||
});
|
||||
|
||||
test('hook called at creation', function() {
|
||||
assert.equal(this.hook.callCount, 1);
|
||||
});
|
||||
|
||||
test('hook called when observable changes', function() {
|
||||
this.hook.reset();
|
||||
this.observable.test = false;
|
||||
assert.equal(this.hook.callCount, 1);
|
||||
});
|
||||
|
||||
test('unobserves when removing', function() {
|
||||
this.sinon.spy(this.observable, 'unobserve');
|
||||
this.observableArray.splice(0, 1);
|
||||
assert.ok(this.observable.unobserve.calledWith(this.hook));
|
||||
});
|
||||
|
||||
test('unobserves when replacing', function() {
|
||||
this.sinon.spy(this.observable, 'unobserve');
|
||||
this.sinon.spy(this.observable, 'observe');
|
||||
this.observableArray.set(0, this.observable);
|
||||
// should unobserve
|
||||
assert.ok(this.observable.unobserve.calledWith(this.hook));
|
||||
// and also observe
|
||||
assert.ok(this.observable.observe.calledWith('test', this.hook));
|
||||
// but should unobserve first
|
||||
assert.ok(
|
||||
this.observable.unobserve.calledBefore(this.observable.observe)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
suite('destroy', function() {
|
||||
setup(function() {
|
||||
this.observableArray = this.ObservableArray([1, 2, 3]);
|
||||
this.container = document.createElement('div');
|
||||
this.listView = this.ListView(
|
||||
this.container, this.observableArray, function() {
|
||||
return document.createElement('div');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('removes children', function() {
|
||||
this.listView.destroy();
|
||||
assert.equal(this.container.children.length, 0);
|
||||
});
|
||||
|
||||
test('sanity check', function() {
|
||||
assert.equal(this.observableArray.removeEventListener.callCount, 0);
|
||||
assert.equal(this.container.children.length, 3);
|
||||
});
|
||||
|
||||
test('.element', function() {
|
||||
this.listView.destroy();
|
||||
assert.equal(this.listView.element, null);
|
||||
});
|
||||
|
||||
test('unbinds from observeable', function() {
|
||||
this.listView.destroy();
|
||||
// called call removeEventListener with a method
|
||||
['insert', 'remove', 'replace', 'reset'].forEach((eventName, index) => {
|
||||
assert.isTrue(
|
||||
this.observableArray.removeEventListener.calledWith(eventName));
|
||||
assert.isFunction(
|
||||
this.observableArray.removeEventListener.args[index][1]);
|
||||
});
|
||||
});
|
||||
|
||||
test('creating another ListView destroys old', function() {
|
||||
this.observableArray.reset();
|
||||
this.sinon.spy(this.listView, 'destroy');
|
||||
// create a new one, we don't care about what happens to it.
|
||||
this.ListView(
|
||||
this.container, this.observableArray, function() {
|
||||
return document.createElement('div');
|
||||
}
|
||||
);
|
||||
|
||||
// destroys old view
|
||||
assert.ok(this.listView.destroy.called);
|
||||
// unbinds from observable
|
||||
assert.ok(this.observableArray.removeEventListener.called);
|
||||
// re-observes
|
||||
assert.ok(this.observableArray.removeEventListener.called);
|
||||
// and make sure its done in the right order
|
||||
assert.ok(
|
||||
this.observableArray.removeEventListener.calledBefore(
|
||||
this.observableArray.removeEventListener
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
231
gaia/apps/settings/test/unit/modules/mvvm/observable_array_test.js
Executable file
231
gaia/apps/settings/test/unit/modules/mvvm/observable_array_test.js
Executable file
|
|
@ -0,0 +1,231 @@
|
|||
'use strict';
|
||||
|
||||
suite('ObservableArray', function() {
|
||||
var methods = [
|
||||
'forEach', 'push', 'pop', 'splice', 'set', 'get', 'reset', 'observe'
|
||||
];
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/mvvm/observable_array'], (function(ObservableArray) {
|
||||
this.ObservableArray = ObservableArray;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.array = methods.slice();
|
||||
this.observable = this.ObservableArray(this.array);
|
||||
});
|
||||
|
||||
suite('shape: ObservableArray(array)', function() {
|
||||
methods.forEach(function(method) {
|
||||
test('.' + method + ' is a function', function() {
|
||||
assert.equal(typeof this.observable[method], 'function');
|
||||
});
|
||||
});
|
||||
test('.length is a number', function() {
|
||||
assert.equal(typeof this.observable.length, 'number');
|
||||
});
|
||||
test('.array is the original array', function() {
|
||||
assert.equal(this.observable.array, this.array);
|
||||
});
|
||||
});
|
||||
|
||||
test('get()', function() {
|
||||
assert.ok(this.array.length);
|
||||
for (var index = 0; index < this.array.length; index++) {
|
||||
assert.equal(this.observable.get(index), this.array[index],
|
||||
'index: ' + index);
|
||||
}
|
||||
});
|
||||
|
||||
suite('observable actions', function() {
|
||||
var events = ['insert', 'remove', 'replace', 'reset'];
|
||||
|
||||
function checkSpies(expected) {
|
||||
events.forEach(function(event) {
|
||||
var expectedCount = expected[event] || 0;
|
||||
test(event + ' called ' + expectedCount + ' times', function() {
|
||||
assert.equal(this.spies[event].args.length, expectedCount);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkArgs(event) {
|
||||
var args = [].slice.call(arguments, 1);
|
||||
test(event + ' called with correct arguments', function() {
|
||||
var calls = this.spies[event].args;
|
||||
assert.deepEqual(calls[calls.length - 1], args);
|
||||
});
|
||||
}
|
||||
|
||||
function resetSpies(environment) {
|
||||
events.forEach(function(event) {
|
||||
this.spies[event].reset();
|
||||
}, environment);
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
this.spies = {};
|
||||
events.forEach(function(event) {
|
||||
this.spies[event] = this.sinon.spy();
|
||||
this.observable.addEventListener(event, this.spies[event]);
|
||||
}, this);
|
||||
});
|
||||
|
||||
suite('pop()', function() {
|
||||
setup(function() {
|
||||
this.observable.pop();
|
||||
});
|
||||
checkSpies({ remove: 1 });
|
||||
checkArgs('remove', {
|
||||
type: 'remove',
|
||||
detail: {
|
||||
index: methods.length - 1,
|
||||
count: 1,
|
||||
items: ['observe']
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expected = methods.slice();
|
||||
expected.pop();
|
||||
assert.deepEqual(this.array, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('push()', function() {
|
||||
setup(function() {
|
||||
this.observable.push('test');
|
||||
});
|
||||
checkSpies({ insert: 1 });
|
||||
checkArgs('insert', {
|
||||
type: 'insert',
|
||||
detail: {
|
||||
index: methods.length,
|
||||
count: 1,
|
||||
items: ['test']
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expected = methods.slice();
|
||||
expected.push('test');
|
||||
assert.deepEqual(this.array, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('splice(1, 2)', function() {
|
||||
setup(function() {
|
||||
this.observable.splice(1, 2);
|
||||
});
|
||||
checkSpies({ remove: 1 });
|
||||
checkArgs('remove', {
|
||||
type: 'remove',
|
||||
detail: {
|
||||
index: 1,
|
||||
count: 2,
|
||||
items: ['push', 'pop']
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expect = methods.slice();
|
||||
expect.splice(1, 2);
|
||||
assert.deepEqual(this.array, expect);
|
||||
});
|
||||
});
|
||||
|
||||
suite('splice(1, 2, 3, 4)', function() {
|
||||
setup(function() {
|
||||
this.observable.splice(1, 2, 3, 4);
|
||||
});
|
||||
checkSpies({ remove: 1, insert: 1 });
|
||||
checkArgs('remove', {
|
||||
type: 'remove',
|
||||
detail: {
|
||||
index: 1,
|
||||
count: 2,
|
||||
items: ['push', 'pop']
|
||||
}
|
||||
});
|
||||
checkArgs('insert', {
|
||||
type: 'insert',
|
||||
detail: {
|
||||
index: 1,
|
||||
count: 2,
|
||||
items: [3, 4]
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expected = methods.slice();
|
||||
expected.splice(1, 2, 3, 4);
|
||||
assert.deepEqual(this.array, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('splice(2, 0, 2)', function() {
|
||||
setup(function() {
|
||||
this.observable.splice(2, 0, 2);
|
||||
});
|
||||
checkSpies({ insert: 1 });
|
||||
checkArgs('insert', {
|
||||
type: 'insert',
|
||||
detail: {
|
||||
index: 2,
|
||||
count: 1,
|
||||
items: [2]
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expected = methods.slice();
|
||||
expected.splice(2, 0, 2);
|
||||
assert.deepEqual(this.array, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('set(7, true)', function() {
|
||||
setup(function() {
|
||||
this.observable.set(7, true);
|
||||
});
|
||||
checkSpies({ replace: 1 });
|
||||
checkArgs('replace', {
|
||||
type: 'replace',
|
||||
detail: {
|
||||
index: 7,
|
||||
oldValue: methods[7],
|
||||
newValue: true
|
||||
}
|
||||
});
|
||||
test('modifies array', function() {
|
||||
var expected = methods.slice();
|
||||
expected[7] = true;
|
||||
assert.deepEqual(this.array, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('reset([])', function() {
|
||||
var testArray = [true, false];
|
||||
setup(function() {
|
||||
this.observable.reset(testArray);
|
||||
});
|
||||
checkSpies({ reset: 1 });
|
||||
checkArgs('reset', {
|
||||
type: 'reset',
|
||||
detail: {
|
||||
items: testArray
|
||||
}
|
||||
});
|
||||
test('changes array', function() {
|
||||
assert.equal(this.observable.array, testArray);
|
||||
});
|
||||
});
|
||||
|
||||
suite('pop() on empty', function() {
|
||||
setup(function() {
|
||||
this.observable.reset([]);
|
||||
resetSpies(this);
|
||||
this.observable.pop();
|
||||
});
|
||||
// no events expected
|
||||
checkSpies({});
|
||||
});
|
||||
});
|
||||
});
|
||||
358
gaia/apps/settings/test/unit/modules/mvvm/observable_test.js
Executable file
358
gaia/apps/settings/test/unit/modules/mvvm/observable_test.js
Executable file
|
|
@ -0,0 +1,358 @@
|
|||
'use strict';
|
||||
|
||||
suite('Observable', function() {
|
||||
var template = {
|
||||
testBoolean: true,
|
||||
testNumber: 10,
|
||||
testString: 'test',
|
||||
'test object': {}
|
||||
// currently disabled - we don't handle functions
|
||||
// testFunction: function() {}
|
||||
};
|
||||
|
||||
function executeTest() {
|
||||
test('shape: Observable({}).observe is a function', function() {
|
||||
var observable = this.Observable({});
|
||||
assert.equal(typeof observable.observe, 'function');
|
||||
});
|
||||
test('shape: Observable({}).unobserve is a function', function() {
|
||||
var observable = this.Observable({});
|
||||
assert.equal(typeof observable.unobserve, 'function');
|
||||
});
|
||||
|
||||
suite('Creates observable properties', function() {
|
||||
var props = Object.keys(template);
|
||||
setup(function() {
|
||||
this.observable = this.Observable(template);
|
||||
});
|
||||
|
||||
// some tests for each property
|
||||
props.forEach(function(prop) {
|
||||
test('prop: "' + prop + '" copied value', function() {
|
||||
assert.equal(this.observable[prop], template[prop]);
|
||||
});
|
||||
|
||||
// test some stuff for observing
|
||||
suite('prop: "' + prop + '" observe', function() {
|
||||
setup(function() {
|
||||
this.spy = this.sinon.spy();
|
||||
this.observable.observe(prop, this.spy);
|
||||
});
|
||||
test('does not generate any callbacks when attaching', function() {
|
||||
assert.isFalse(this.spy.called);
|
||||
});
|
||||
|
||||
test('does not notify when set to same value', function() {
|
||||
this.observable[prop] = template[prop];
|
||||
assert.isFalse(this.spy.called);
|
||||
});
|
||||
|
||||
test('notifies when set to new value', function() {
|
||||
this.newValue = {};
|
||||
this.observable[prop] = this.newValue;
|
||||
assert.isTrue(this.spy.calledWith(this.newValue, template[prop]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('unobserve', function() {
|
||||
setup(function() {
|
||||
// bind some listeners
|
||||
this.spies = [this.sinon.spy(), this.sinon.spy()];
|
||||
props.forEach(function(prop) {
|
||||
this.observable.observe(prop, this.spies[0]);
|
||||
this.observable.observe(prop, this.spies[1]);
|
||||
}, this);
|
||||
});
|
||||
test('(property, handler)', function() {
|
||||
// remove handler for property
|
||||
this.observable.unobserve('testNumber', this.spies[0]);
|
||||
// change property - only other handler should be called
|
||||
this.observable.testNumber = {};
|
||||
assert.equal(this.spies[0].callCount, 0);
|
||||
assert.equal(this.spies[1].callCount, 1);
|
||||
// change a different property, both handlers should be called
|
||||
this.observable.testString = {};
|
||||
assert.equal(this.spies[0].callCount, 1);
|
||||
assert.equal(this.spies[1].callCount, 2);
|
||||
});
|
||||
test('(handler)', function() {
|
||||
// remove handler for all properties
|
||||
this.observable.unobserve(this.spies[0]);
|
||||
// change property - only other handler should be called
|
||||
this.observable.testNumber = {};
|
||||
assert.equal(this.spies[0].callCount, 0);
|
||||
assert.equal(this.spies[1].callCount, 1);
|
||||
// change a different property, only other handler should be called
|
||||
this.observable.testString = {};
|
||||
assert.equal(this.spies[0].callCount, 0);
|
||||
assert.equal(this.spies[1].callCount, 2);
|
||||
});
|
||||
test('(property)', function() {
|
||||
// remove handler for all properties
|
||||
this.observable.unobserve('testNumber');
|
||||
// change property - neither handler should be called
|
||||
this.observable.testNumber = {};
|
||||
assert.equal(this.spies[0].callCount, 0);
|
||||
assert.equal(this.spies[1].callCount, 0);
|
||||
// change a different property, both handlers should be called
|
||||
this.observable.testString = {};
|
||||
assert.equal(this.spies[0].callCount, 1);
|
||||
assert.equal(this.spies[1].callCount, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
suite('Object form', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/mvvm/observable'], (function(Observable) {
|
||||
this.Observable = Observable;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
executeTest();
|
||||
});
|
||||
|
||||
suite('Prototype form', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/module', 'modules/mvvm/observable'],
|
||||
(function(Module, Observable) {
|
||||
var NewObservable = Module.create(function() {
|
||||
this.super(Observable).call(this);
|
||||
}).extend(Observable);
|
||||
Object.keys(template).forEach(function (key) {
|
||||
Observable.defineObservableProperty(NewObservable.prototype, key, {
|
||||
value: template[key]
|
||||
});
|
||||
});
|
||||
this.Observable = NewObservable;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
executeTest();
|
||||
});
|
||||
|
||||
suite('Read-only property', function() {
|
||||
var props = ['prop1', 'prop2'];
|
||||
var defaultPropValues = ['value1', 'value2'];
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/module', 'modules/mvvm/observable'],
|
||||
(function(Module, Observable) {
|
||||
var NewObservable = Module.create(function() {
|
||||
this.super(Observable).call(this);
|
||||
}).extend(Observable);
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[0], {
|
||||
readonly: true,
|
||||
value: defaultPropValues[0]
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[1], {
|
||||
readonly: true,
|
||||
value: defaultPropValues[1]
|
||||
});
|
||||
this.Observable = NewObservable;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('unable to set the property', function() {
|
||||
var observable = this.Observable();
|
||||
assert.throw(function() {
|
||||
observable[props[0]] = 300;
|
||||
}, TypeError, 'setting a property that has only a getter');
|
||||
});
|
||||
|
||||
test('internal property exists', function() {
|
||||
var observable = this.Observable();
|
||||
assert.equal(observable['_' + props[0]], defaultPropValues[0]);
|
||||
assert.equal(observable['_' + props[1]], defaultPropValues[1]);
|
||||
});
|
||||
|
||||
test('calls to the listeners when the internal property changes',
|
||||
function(done) {
|
||||
var newPropValue = 'newFakeValue';
|
||||
var observable = this.Observable();
|
||||
observable.observe(props[1], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[1]);
|
||||
assert.equal(newValue, newPropValue);
|
||||
done();
|
||||
});
|
||||
observable['_' + props[1]] = newPropValue;
|
||||
});
|
||||
});
|
||||
|
||||
suite('Dependency property', function() {
|
||||
var props = ['prop1', 'prop2'];
|
||||
var defaultPropValues = [2, 3];
|
||||
var dependencyProps = ['dprop1', 'dprop2', 'dprop3'];
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/module', 'modules/mvvm/observable'],
|
||||
(function(Module, Observable) {
|
||||
var NewObservable = Module.create(function() {
|
||||
this.super(Observable).call(this);
|
||||
}).extend(Observable);
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[0], {
|
||||
value: defaultPropValues[0]
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[1], {
|
||||
value: defaultPropValues[1]
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[0], {
|
||||
dependency: props,
|
||||
get: function() {
|
||||
return this[props[0]] + this[props[1]];
|
||||
}
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[1], {
|
||||
dependency: [dependencyProps[0]],
|
||||
get: function() {
|
||||
return this[dependencyProps[0]];
|
||||
}
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[2], {
|
||||
dependency: [dependencyProps[0]],
|
||||
get: function() {
|
||||
return this[dependencyProps[0]];
|
||||
}
|
||||
});
|
||||
this.Observable = NewObservable;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('The property responds to the dependent property changes correctly',
|
||||
function(done) {
|
||||
var newPropValue = 100;
|
||||
var observable = this.Observable();
|
||||
observable.observe(dependencyProps[0], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
done();
|
||||
});
|
||||
observable[props[1]] = newPropValue;
|
||||
});
|
||||
|
||||
test('The property responds to the dependency property changes correctly',
|
||||
function(done) {
|
||||
var newPropValue = 100;
|
||||
var observable = this.Observable();
|
||||
var changeCount = 0;
|
||||
|
||||
observable.observe(dependencyProps[1], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
changeCount++;
|
||||
if (changeCount == 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
observable.observe(dependencyProps[2], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
changeCount++;
|
||||
if (changeCount == 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
observable[props[1]] = newPropValue;
|
||||
});
|
||||
});
|
||||
|
||||
suite('Extendibility', function() {
|
||||
var props = ['prop1', 'prop2'];
|
||||
var defaultPropValues = [2, 3];
|
||||
var dependencyProps = ['dprop1', 'dprop2', 'dprop3'];
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/base/module', 'modules/mvvm/observable'],
|
||||
(function(Module, Observable) {
|
||||
var NewObservable = Module.create(function() {
|
||||
this.super(Observable).call(this);
|
||||
}).extend(Observable);
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[0], {
|
||||
value: defaultPropValues[0]
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, props[1], {
|
||||
value: defaultPropValues[1]
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[0], {
|
||||
dependency: props,
|
||||
get: function() {
|
||||
return this[props[0]] + this[props[1]];
|
||||
}
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[1], {
|
||||
dependency: [dependencyProps[0]],
|
||||
get: function() {
|
||||
return this[dependencyProps[0]];
|
||||
}
|
||||
});
|
||||
Observable.defineObservableProperty(
|
||||
NewObservable.prototype, dependencyProps[2], {
|
||||
dependency: [dependencyProps[0]],
|
||||
get: function() {
|
||||
return this[dependencyProps[0]];
|
||||
}
|
||||
});
|
||||
|
||||
var NewObservable2 = Module.create(function() {
|
||||
this.super(NewObservable).call(this);
|
||||
}).extend(NewObservable);
|
||||
this.Observable = NewObservable2;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('The property responds to the dependent property changes correctly',
|
||||
function(done) {
|
||||
var newPropValue = 100;
|
||||
var observable = this.Observable();
|
||||
observable.observe(dependencyProps[0], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
done();
|
||||
});
|
||||
observable[props[1]] = newPropValue;
|
||||
});
|
||||
|
||||
test('The property responds to the dependency property changes correctly',
|
||||
function(done) {
|
||||
var newPropValue = 100;
|
||||
var observable = this.Observable();
|
||||
var changeCount = 0;
|
||||
|
||||
observable.observe(dependencyProps[1], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
changeCount++;
|
||||
if (changeCount == 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
observable.observe(dependencyProps[2], function(newValue, oldValue) {
|
||||
assert.equal(oldValue, defaultPropValues[0] + defaultPropValues[1]);
|
||||
assert.equal(newValue, defaultPropValues[0] + newPropValue);
|
||||
changeCount++;
|
||||
if (changeCount == 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
observable[props[1]] = newPropValue;
|
||||
});
|
||||
});
|
||||
});
|
||||
116
gaia/apps/settings/test/unit/modules/panel_cache_test.js
Executable file
116
gaia/apps/settings/test/unit/modules/panel_cache_test.js
Executable file
|
|
@ -0,0 +1,116 @@
|
|||
'use strict';
|
||||
|
||||
suite('PanelCache', function() {
|
||||
suiteSetup(function(done) {
|
||||
navigator.addIdleObserver = sinon.spy();
|
||||
|
||||
var modules = [
|
||||
'modules/panel_cache',
|
||||
'unit/mock_settings_panel',
|
||||
'unit/mock_test_panel'
|
||||
];
|
||||
|
||||
// Use map to mock the dependencies.
|
||||
// In this case for modules/panel_cache, we use unit/mock_settings_panel to
|
||||
// replace modules/settings_panel.
|
||||
var map = {
|
||||
'modules/panel_cache': {
|
||||
'modules/settings_panel': 'unit/mock_settings_panel'
|
||||
}
|
||||
};
|
||||
|
||||
testRequire(modules, map, (function(PanelCache, MockSettingsPanel,
|
||||
MockTestPanel) {
|
||||
this.PanelCache = PanelCache;
|
||||
// Mock of the SettingsPanel function
|
||||
this.MockSettingsPanel = MockSettingsPanel;
|
||||
// Mock of the TestPanel function
|
||||
this.MockTestPanel = MockTestPanel;
|
||||
|
||||
// XXX: As we use 'require' function of requirejs in PanelCache and it
|
||||
// conflicts to the original require function, we replace it here.
|
||||
this.originalRequire = window.require;
|
||||
window.require = testRequire;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.require = this.originalRequire;
|
||||
this.originalRequire = null;
|
||||
});
|
||||
|
||||
suite('get()', function() {
|
||||
setup(function() {
|
||||
// create mock panel element
|
||||
this.panelID = 'id';
|
||||
this.panelElement = document.createElement('div');
|
||||
this.panelElement.id = this.panelID;
|
||||
document.body.appendChild(this.panelElement);
|
||||
// create mock panel instance
|
||||
this.mockPanelInstance = {};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.removeChild(this.panelElement);
|
||||
this.panelID = null;
|
||||
this.panelElement = null;
|
||||
this.mockPanelInstance = null;
|
||||
|
||||
this.PanelCache.reset();
|
||||
this.MockSettingsPanel.mTeardown();
|
||||
this.MockTestPanel.mTeardown();
|
||||
});
|
||||
|
||||
test('should return a SettingsPanel when without specifying a panel module',
|
||||
function(done) {
|
||||
this.MockSettingsPanel.mInnerFunction =
|
||||
sinon.stub().returns(this.mockPanelInstance);
|
||||
|
||||
this.PanelCache.get(this.panelID, (function(panelInstance) {
|
||||
// ensure the returned panel instance is a SettingsPanel
|
||||
assert.equal(panelInstance, this.mockPanelInstance);
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should return correct panel instance when with a specified panel' +
|
||||
'module', function(done) {
|
||||
this.MockTestPanel.mInnerFunction =
|
||||
sinon.stub().returns(this.mockPanelInstance);
|
||||
|
||||
/**
|
||||
* Make the dom element like:
|
||||
* <div>
|
||||
* <panel data-path="unit/mock_test_panel"></panel>
|
||||
* </div>
|
||||
*/
|
||||
var pathElement = document.createElement('panel');
|
||||
pathElement.dataset.path = 'unit/mock_test_panel';
|
||||
this.panelElement.appendChild(pathElement);
|
||||
|
||||
this.PanelCache.get(this.panelID, (function(panelInstance) {
|
||||
// ensure the returned panel instance is a TestPanel
|
||||
assert.equal(panelInstance, this.mockPanelInstance);
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should return the same panel instance when inquiring with the ' +
|
||||
'same panel id', function(done) {
|
||||
var settingsPanelStub = sinon.stub().returns(this.mockPanelInstance);
|
||||
this.MockSettingsPanel.mInnerFunction = settingsPanelStub;
|
||||
|
||||
this.PanelCache.get(this.panelID, (function(panelInstance) {
|
||||
assert.equal(panelInstance, this.mockPanelInstance);
|
||||
this.PanelCache.get(this.panelID, function(newPanelInstance) {
|
||||
// ensure there is only one instance created
|
||||
sinon.assert.calledOnce(settingsPanelStub);
|
||||
// ensure the returned instance is the original instance
|
||||
assert.equal(panelInstance, newPanelInstance);
|
||||
done();
|
||||
});
|
||||
}).bind(this));
|
||||
});
|
||||
});
|
||||
});
|
||||
152
gaia/apps/settings/test/unit/modules/panel_test.js
Executable file
152
gaia/apps/settings/test/unit/modules/panel_test.js
Executable file
|
|
@ -0,0 +1,152 @@
|
|||
'use strict';
|
||||
|
||||
suite('Panel', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire(['modules/panel'], (function(panelFunc) {
|
||||
this.Panel = panelFunc;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
suite('Basic functions', function() {
|
||||
setup(function() {
|
||||
this.panel = this.Panel();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.panel = null;
|
||||
});
|
||||
|
||||
test('init()', function(done) {
|
||||
// initialized shoule be false by default.
|
||||
assert.isFalse(this.panel.initialized);
|
||||
|
||||
Promise.resolve(this.panel.init())
|
||||
.then(function() {
|
||||
// initialized shoule be true after initialized.
|
||||
assert.isTrue(this.panel.initialized);
|
||||
}.bind(this)).then(done, done);
|
||||
});
|
||||
|
||||
test('uninit()', function(done) {
|
||||
Promise.resolve(this.panel.init())
|
||||
.then(function() {
|
||||
assert.isTrue(this.panel.initialized);
|
||||
|
||||
this.panel.uninit();
|
||||
// initialized shoule be false after uninitialized.
|
||||
assert.isFalse(this.panel.initialized);
|
||||
}.bind(this)).then(done, done);
|
||||
});
|
||||
|
||||
test('beforeShow()', function(done) {
|
||||
var initSpy = sinon.spy(this.panel, 'init');
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
|
||||
Promise.resolve(this.panel.beforeShow(panelElement, options))
|
||||
.then(function() {
|
||||
// init should be called when beforeShow is called at the first time.
|
||||
sinon.assert.calledWith(initSpy, panelElement, options);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('show()', function(done) {
|
||||
var initSpy = sinon.spy(this.panel, 'init');
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
|
||||
Promise.resolve(this.panel.show(panelElement, options))
|
||||
.then(function() {
|
||||
// init should be called when show is called at the first time.
|
||||
sinon.assert.calledWith(initSpy, panelElement, options);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Internal functions', function() {
|
||||
setup(function() {
|
||||
this.mockOptions = {
|
||||
onInit: function() {},
|
||||
onUninit: function() {},
|
||||
onShow: function() {},
|
||||
onHide: function() {},
|
||||
onBeforeShow: function() {},
|
||||
onBeforeHide: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.mockOptions = null;
|
||||
});
|
||||
|
||||
function convertToInternalFuncName(name) {
|
||||
return 'on' + name.charAt(0).toUpperCase() + name.slice(1);
|
||||
}
|
||||
|
||||
['init', 'show', 'beforeShow'].forEach(function(funcName) {
|
||||
var internalFuncName = convertToInternalFuncName(funcName);
|
||||
test(internalFuncName + ' should be called when ' +
|
||||
funcName + ' is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, internalFuncName);
|
||||
var panel = this.Panel(this.mockOptions);
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
|
||||
Promise.resolve(panel[funcName](panelElement, options))
|
||||
.then(function() {
|
||||
sinon.assert.calledWith(spy, panelElement, options);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
['hide', 'beforeHide'].forEach(function(funcName) {
|
||||
var internalFuncName = convertToInternalFuncName(funcName);
|
||||
test(internalFuncName + ' should be called when ' +
|
||||
funcName + ' is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, internalFuncName);
|
||||
var panel = this.Panel(this.mockOptions);
|
||||
|
||||
Promise.resolve(panel[funcName]())
|
||||
.then(function() {
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
test('onUninit should be called when uninit is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, 'onUninit');
|
||||
var panel = this.Panel(this.mockOptions);
|
||||
|
||||
Promise.resolve(panel.init())
|
||||
.then(function() {
|
||||
panel.uninit();
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('onInit should be called only once', function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, 'onInit');
|
||||
var panel = this.Panel(this.mockOptions);
|
||||
|
||||
Promise.resolve(panel.init())
|
||||
.then(panel.init())
|
||||
.then(function() {
|
||||
// onInit should be called only once.
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('onUninit should not be called if the panel is not initialized',
|
||||
function() {
|
||||
var spy = sinon.spy(this.mockOptions, 'onUninit');
|
||||
var panel = this.Panel(this.mockOptions);
|
||||
|
||||
panel.uninit();
|
||||
sinon.assert.notCalled(spy);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
gaia/apps/settings/test/unit/modules/panel_utils_test.js
Executable file
40
gaia/apps/settings/test/unit/modules/panel_utils_test.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
suite('PanelUtils', function() {
|
||||
var modules = [
|
||||
'modules/panel_utils'
|
||||
];
|
||||
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/settings_cache': 'unit/mock_settings_cache'
|
||||
}
|
||||
};
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(modules, map, (function(PanelUtils) {
|
||||
this.PanelUtils = PanelUtils;
|
||||
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
suite('activate', function() {
|
||||
setup(function() {
|
||||
this.targetElement = document.createElement('div');
|
||||
this.targetLink = document.createElement('a');
|
||||
this.targetElement.appendChild(this.targetLink);
|
||||
this.sinon.spy(this.targetLink, 'addEventListener');
|
||||
});
|
||||
|
||||
test('The navigated url should be the current url', function() {
|
||||
var originalLink = 'http://www.originallink/';
|
||||
var newLink = 'http://www.newlink/';
|
||||
|
||||
this.targetLink.href = originalLink;
|
||||
this.PanelUtils.activate(this.targetElement);
|
||||
this.targetLink.href = newLink;
|
||||
assert.ok(this.targetLink.addEventListener.calledWith('click'));
|
||||
});
|
||||
});
|
||||
});
|
||||
174
gaia/apps/settings/test/unit/modules/settings_cache_test.js
Executable file
174
gaia/apps/settings/test/unit/modules/settings_cache_test.js
Executable file
|
|
@ -0,0 +1,174 @@
|
|||
'use strict';
|
||||
|
||||
suite('SettingsCache', function() {
|
||||
suiteSetup(function(done) {
|
||||
this.keyValuePairs = {
|
||||
'key1': 'value1',
|
||||
'key2': 'value2',
|
||||
'key3': 'value3'
|
||||
};
|
||||
|
||||
testRequire(['shared_mocks/mock_navigator_moz_settings'],
|
||||
(function(MockNavigatorSettings) {
|
||||
this.MockNavigatorSettings = MockNavigatorSettings;
|
||||
this.realSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = MockNavigatorSettings;
|
||||
|
||||
// require settings cache after the mock of mozSettings loaded.
|
||||
testRequire(['modules/settings_cache'], (function(SettingsCache) {
|
||||
this.SettingsCache = SettingsCache;
|
||||
done();
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
this.keyValuePairs = null;
|
||||
|
||||
navigator.mozSettings = this.realSettings;
|
||||
this.realSettings = null;
|
||||
this.MockNavigatorSettings = null;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
// init mozSettings
|
||||
var settings = this.MockNavigatorSettings.mSettings;
|
||||
for (var key in this.keyValuePairs) {
|
||||
settings[key] = this.keyValuePairs[key];
|
||||
}
|
||||
// reset SettingsCache to its initial state
|
||||
this.SettingsCache.reset();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.MockNavigatorSettings.mTeardown();
|
||||
});
|
||||
|
||||
suite('getSettings()', function() {
|
||||
test('should return the same value as mozSettings',
|
||||
function(done) {
|
||||
this.SettingsCache.getSettings((function(settings) {
|
||||
for (var key in this.keyValuePairs) {
|
||||
assert.ok(settings[key] === this.keyValuePairs[key]);
|
||||
}
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should queue the settings requests before the cache being ready',
|
||||
function(done) {
|
||||
this.MockNavigatorSettings.mSyncRepliesOnly = true;
|
||||
|
||||
var callCount = 10;
|
||||
var count = 0;
|
||||
var checkDone = function() {
|
||||
count++;
|
||||
if (callCount === count) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
var gotSettings = (function(settings) {
|
||||
for (var key in this.keyValuePairs) {
|
||||
assert.ok(settings[key] === this.keyValuePairs[key]);
|
||||
}
|
||||
checkDone();
|
||||
}).bind(this);
|
||||
|
||||
// query the settings
|
||||
for (var i = 0; i < callCount; i++) {
|
||||
this.SettingsCache.getSettings(gotSettings);
|
||||
}
|
||||
|
||||
// trigger the mozSettings onsuccess 1s later
|
||||
setTimeout(function() {
|
||||
this.MockNavigatorSettings.mReplyToRequests();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
test('should reflect mozSettings changes', function(done) {
|
||||
var key = 'key2';
|
||||
var newValue = 'value2_1';
|
||||
// make the cache as the current mozSettings.
|
||||
this.SettingsCache.getSettings((function() {
|
||||
var obj = {};
|
||||
obj[key] = newValue;
|
||||
|
||||
// modify the value
|
||||
var req = this.MockNavigatorSettings.createLock().set(obj);
|
||||
req.onsuccess = (function() {
|
||||
this.SettingsCache.getSettings(function(settings) {
|
||||
assert.ok(settings[key] === newValue);
|
||||
done();
|
||||
});
|
||||
}).bind(this);
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should reflect newly created mozSettings fields', function(done) {
|
||||
var newKey = 'key4';
|
||||
var value = 'value4';
|
||||
// make the cache as the current mozSettings.
|
||||
this.SettingsCache.getSettings((function() {
|
||||
var obj = {};
|
||||
obj[newKey] = value;
|
||||
|
||||
// set the value
|
||||
var req = this.MockNavigatorSettings.createLock().set(obj);
|
||||
req.onsuccess = (function() {
|
||||
this.SettingsCache.getSettings(function(settings) {
|
||||
assert.ok(settings[newKey] === value);
|
||||
done();
|
||||
});
|
||||
}).bind(this);
|
||||
}).bind(this));
|
||||
});
|
||||
});
|
||||
|
||||
suite('event listeners', function() {
|
||||
suiteSetup(function() {
|
||||
// helper function to mutate setting
|
||||
this.mutateSetting = (function(key, value, callback) {
|
||||
var obj = {};
|
||||
obj[key] = value;
|
||||
|
||||
var req = this.MockNavigatorSettings.createLock().set(obj);
|
||||
req.onsuccess = callback;
|
||||
}).bind(this);
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
this.mutateSetting = null;
|
||||
});
|
||||
|
||||
test('addEventListener()', function(done) {
|
||||
var key = 'key2';
|
||||
var newValue = 'value2_1';
|
||||
var onSettingsChange = function(event) {
|
||||
assert.ok(event.settingName === key);
|
||||
assert.ok(event.settingValue === newValue);
|
||||
done();
|
||||
};
|
||||
|
||||
this.SettingsCache.addEventListener('settingsChange', onSettingsChange);
|
||||
this.mutateSetting(key, newValue);
|
||||
});
|
||||
|
||||
test('removeEventListener()', function(done) {
|
||||
var onSettingsChangeSpy = sinon.spy();
|
||||
|
||||
this.SettingsCache.addEventListener('settingsChange',
|
||||
onSettingsChangeSpy);
|
||||
this.mutateSetting('key2', 'value2_1', (function() {
|
||||
// ensure the event listener has been added
|
||||
sinon.assert.calledOnce(onSettingsChangeSpy);
|
||||
this.SettingsCache.removeEventListener('settingsChange',
|
||||
onSettingsChangeSpy);
|
||||
this.mutateSetting('key2', 'value2_2', function() {
|
||||
sinon.assert.calledOnce(onSettingsChangeSpy);
|
||||
done();
|
||||
});
|
||||
}).bind(this));
|
||||
});
|
||||
});
|
||||
});
|
||||
225
gaia/apps/settings/test/unit/modules/settings_panel_test.js
Executable file
225
gaia/apps/settings/test/unit/modules/settings_panel_test.js
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
'use strict';
|
||||
|
||||
suite('SettingsPanel', function() {
|
||||
suiteSetup(function(done) {
|
||||
testRequire([
|
||||
'modules/settings_panel',
|
||||
'modules/panel_utils',
|
||||
'modules/settings_cache',
|
||||
], (function(settingsPanelFunc, PanelUtils, SettingsCache) {
|
||||
this.realL10n = document.l10n;
|
||||
|
||||
this.PanelUtils = PanelUtils;
|
||||
this.SettingsCache = SettingsCache;
|
||||
this.SettingsPanel = settingsPanelFunc;
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
suite('Basic functions', function() {
|
||||
setup(function() {
|
||||
this.panel = this.SettingsPanel();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.panel = null;
|
||||
});
|
||||
|
||||
test('init()', function() {
|
||||
var panelElement = document.createElement('div');
|
||||
var activateSpy = sinon.spy(this.PanelUtils, 'activate');
|
||||
|
||||
// initialized should be false by default.
|
||||
assert.isFalse(this.panel.initialized);
|
||||
|
||||
this.panel.init(panelElement);
|
||||
|
||||
// initialized should be true after initialized.
|
||||
assert.isTrue(this.panel.initialized);
|
||||
// PanelUtils.activate should be called with the panel element.
|
||||
sinon.assert.calledWith(activateSpy, panelElement);
|
||||
|
||||
activateSpy.restore();
|
||||
});
|
||||
|
||||
test('uninit()', function(done) {
|
||||
var panelElement = document.createElement('div');
|
||||
var settingsCacheRemoveEventListenerSpy =
|
||||
this.sinon.spy(this.SettingsCache, 'removeEventListener');
|
||||
var panelRemoveEventListenerSpy =
|
||||
this.sinon.spy(panelElement, 'removeEventListener');
|
||||
|
||||
Promise.resolve(this.panel.init(panelElement))
|
||||
.then(function() {
|
||||
assert.isTrue(this.panel.initialized);
|
||||
|
||||
this.panel.uninit();
|
||||
// initialized is false after uninitialized.
|
||||
assert.isFalse(this.panel.initialized);
|
||||
|
||||
// Added listeners should be removed when uninit.
|
||||
sinon.assert.calledWith(settingsCacheRemoveEventListenerSpy,
|
||||
'settingsChange');
|
||||
sinon.assert.calledWith(panelRemoveEventListenerSpy, 'change',
|
||||
this.PanelUtils.onInputChange);
|
||||
sinon.assert.calledWith(panelRemoveEventListenerSpy, 'click',
|
||||
this.PanelUtils.onLinkClick);
|
||||
|
||||
settingsCacheRemoveEventListenerSpy.restore();
|
||||
panelRemoveEventListenerSpy.restore();
|
||||
}.bind(this)).then(done, done);
|
||||
});
|
||||
|
||||
test('beforeShow()', function(done) {
|
||||
var initSpy = sinon.spy(this.panel, 'init');
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
var presetSpy = sinon.spy(this.PanelUtils, 'preset');
|
||||
var settingsCacheAddEventListenerSpy =
|
||||
sinon.spy(this.SettingsCache, 'addEventListener');
|
||||
var panelAddEventListenerSpy =
|
||||
sinon.spy(panelElement, 'addEventListener');
|
||||
|
||||
Promise.resolve(this.panel.beforeShow(panelElement, options))
|
||||
.then(function() {
|
||||
// init should be called when beforeShow is called at the first time.
|
||||
sinon.assert.calledWith(initSpy, panelElement, options);
|
||||
// PanelUtils.preset should be called with the panel element.
|
||||
sinon.assert.calledWith(presetSpy, panelElement);
|
||||
// Related listeners should be added.
|
||||
sinon.assert.calledWith(settingsCacheAddEventListenerSpy,
|
||||
'settingsChange');
|
||||
sinon.assert.calledWith(panelAddEventListenerSpy, 'change',
|
||||
this.PanelUtils.onInputChange);
|
||||
sinon.assert.calledWith(panelAddEventListenerSpy, 'click',
|
||||
this.PanelUtils.onLinkClick);
|
||||
|
||||
presetSpy.restore();
|
||||
settingsCacheAddEventListenerSpy.restore();
|
||||
panelAddEventListenerSpy.restore();
|
||||
}.bind(this)).then(done, done);
|
||||
});
|
||||
|
||||
test('show()', function(done) {
|
||||
var initSpy = sinon.spy(this.panel, 'init');
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
|
||||
Promise.resolve(this.panel.show(panelElement, options))
|
||||
.then(function() {
|
||||
// init should be called when show is called at the first time.
|
||||
sinon.assert.calledWith(initSpy, panelElement, options);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('hide()', function(done) {
|
||||
var panelElement = document.createElement('div');
|
||||
var settingsCacheRemoveEventListenerSpy =
|
||||
this.sinon.spy(this.SettingsCache, 'removeEventListener');
|
||||
var panelRemoveEventListenerSpy =
|
||||
this.sinon.spy(panelElement, 'removeEventListener');
|
||||
|
||||
Promise.resolve(this.panel.init(panelElement))
|
||||
.then(this.panel.hide())
|
||||
.then(function() {
|
||||
// Added listeners should be removed when hiding.
|
||||
sinon.assert.calledWith(settingsCacheRemoveEventListenerSpy,
|
||||
'settingsChange');
|
||||
sinon.assert.calledWith(panelRemoveEventListenerSpy, 'change',
|
||||
this.PanelUtils.onInputChange);
|
||||
sinon.assert.calledWith(panelRemoveEventListenerSpy, 'click',
|
||||
this.PanelUtils.onLinkClick);
|
||||
|
||||
settingsCacheRemoveEventListenerSpy.restore();
|
||||
panelRemoveEventListenerSpy.restore();
|
||||
}.bind(this)).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Internal functions', function() {
|
||||
setup(function() {
|
||||
this.mockOptions = {
|
||||
onInit: function() {},
|
||||
onUninit: function() {},
|
||||
onShow: function() {},
|
||||
onHide: function() {},
|
||||
onBeforeShow: function() {},
|
||||
onBeforeHide: function() {}
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.mockOptions = null;
|
||||
});
|
||||
|
||||
function convertToInternalFuncName(name) {
|
||||
return 'on' + name.charAt(0).toUpperCase() + name.slice(1);
|
||||
}
|
||||
|
||||
['init', 'show', 'beforeShow'].forEach(function(funcName) {
|
||||
var internalFuncName = convertToInternalFuncName(funcName);
|
||||
test(internalFuncName + ' should be called when ' +
|
||||
funcName + ' is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, internalFuncName);
|
||||
var panel = this.SettingsPanel(this.mockOptions);
|
||||
var panelElement = document.createElement('div');
|
||||
var options = {};
|
||||
|
||||
Promise
|
||||
.resolve(panel[funcName](panelElement, options))
|
||||
.then(function() {
|
||||
sinon.assert.calledWith(spy, panelElement, options);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
['hide', 'beforeHide'].forEach(function(funcName) {
|
||||
var internalFuncName = convertToInternalFuncName(funcName);
|
||||
test(internalFuncName + ' shoule be called when ' +
|
||||
funcName + ' is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, internalFuncName);
|
||||
var panel = this.SettingsPanel(this.mockOptions);
|
||||
|
||||
Promise
|
||||
.resolve(panel[funcName]())
|
||||
.then(function() {
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
test('onUninit should be called when uninit is called',
|
||||
function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, 'onUninit');
|
||||
var panel = this.SettingsPanel(this.mockOptions);
|
||||
|
||||
Promise.resolve(panel.init())
|
||||
.then(function() {
|
||||
panel.uninit();
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('onInit should be called only once', function(done) {
|
||||
var spy = sinon.spy(this.mockOptions, 'onInit');
|
||||
var panel = this.SettingsPanel(this.mockOptions);
|
||||
var panelElement = document.createElement('div');
|
||||
|
||||
Promise.resolve(panel.init(panelElement))
|
||||
.then(panel.init(panelElement))
|
||||
.then(function() {
|
||||
sinon.assert.calledOnce(spy);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('onUninit should not be called if it is not initialized', function() {
|
||||
var spy = sinon.spy(this.mockOptions, 'onUninit');
|
||||
var panel = this.SettingsPanel(this.mockOptions);
|
||||
|
||||
panel.uninit();
|
||||
sinon.assert.notCalled(spy);
|
||||
});
|
||||
});
|
||||
});
|
||||
279
gaia/apps/settings/test/unit/modules/settings_service_test.js
Executable file
279
gaia/apps/settings/test/unit/modules/settings_service_test.js
Executable file
|
|
@ -0,0 +1,279 @@
|
|||
'use strict';
|
||||
|
||||
suite('SettingsService', function() {
|
||||
suiteSetup(function(done) {
|
||||
navigator.addIdleObserver = sinon.spy();
|
||||
|
||||
var modules = [
|
||||
'modules/settings_service',
|
||||
'modules/panel_cache',
|
||||
'unit/mock_settings_panel',
|
||||
'settings'
|
||||
];
|
||||
|
||||
// Use map to mock the dependencies.
|
||||
// In this case for modules/panel_cache, we use unit/mock_settings_panel to
|
||||
// replace modules/settings_panel.
|
||||
var map = {
|
||||
'modules/panel_cache': {
|
||||
'modules/settings_panel': 'unit/mock_settings_panel'
|
||||
},
|
||||
'modules/settings_service': {
|
||||
'modules/page_transitions': 'unit/mock_page_transitions'
|
||||
},
|
||||
'settings': 'unit/mock_settings'
|
||||
};
|
||||
|
||||
testRequire(modules, map,
|
||||
(function(SettingsService, PanelCache,
|
||||
MockSettingsPanel, MockSettings) {
|
||||
this.SettingsService = SettingsService;
|
||||
this.PanelCache = PanelCache;
|
||||
// Mock of the SettingsPanel function
|
||||
this.MockSettingsPanel = MockSettingsPanel;
|
||||
this.MockSettings = MockSettings;
|
||||
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.SettingsService.reset();
|
||||
this.PanelCache.reset();
|
||||
|
||||
this.options = [];
|
||||
this.panelElements = [];
|
||||
this.mockSettingsPanelInstances = [];
|
||||
|
||||
var panelInstance = function() {
|
||||
return {
|
||||
init: function() {},
|
||||
uninit: function() {},
|
||||
show: function() {},
|
||||
hide: function() {},
|
||||
beforeShow: function() {},
|
||||
beforeHide: function() {}
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < 4; i++) {
|
||||
this.options.push({ value: i });
|
||||
this.mockSettingsPanelInstances.push(panelInstance());
|
||||
|
||||
// create panel elements
|
||||
var panelElement = document.createElement('div');
|
||||
panelElement.id = 'id' + i;
|
||||
document.body.appendChild(panelElement);
|
||||
this.panelElements.push(panelElement);
|
||||
}
|
||||
|
||||
// create additional frame panel
|
||||
var framePanelElement = document.createElement('div');
|
||||
framePanelElement.id = 'frame';
|
||||
document.body.appendChild(framePanelElement);
|
||||
this.panelElements.push(framePanelElement);
|
||||
|
||||
this.callCount = 0;
|
||||
this.MockSettingsPanel.mInnerFunction = (function() {
|
||||
return this.mockSettingsPanelInstances[this.callCount++];
|
||||
}).bind(this);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.panelElements.forEach(function(panelElement) {
|
||||
document.body.removeChild(panelElement);
|
||||
});
|
||||
});
|
||||
|
||||
suite('navigate()', function() {
|
||||
test('should call to panel functions correctly', function(done) {
|
||||
var mockInstances = [];
|
||||
|
||||
this.SettingsService.init();
|
||||
|
||||
mockInstances[0] = sinon.mock(this.mockSettingsPanelInstances[0]);
|
||||
// Expect only calls to beforeShow and show of panel0.
|
||||
mockInstances[0].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('show').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('beforeHide').never();
|
||||
mockInstances[0].expects('hide').never();
|
||||
this.SettingsService.navigate('id0', this.options[0], (function() {
|
||||
mockInstances[0].verify();
|
||||
|
||||
mockInstances[0] = sinon.mock(this.mockSettingsPanelInstances[0]);
|
||||
// Expect only calls to beforeHide and hide of panel0.
|
||||
mockInstances[0].expects('beforeShow').never();
|
||||
mockInstances[0].expects('show').never();
|
||||
mockInstances[0].expects('beforeHide').once();
|
||||
mockInstances[0].expects('hide').once();
|
||||
mockInstances[1] = sinon.mock(this.mockSettingsPanelInstances[1]);
|
||||
// Expect only calls to beforeShow and show of panel1.
|
||||
mockInstances[1].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[1], this.options[1]);
|
||||
mockInstances[1].expects('show').once()
|
||||
.withExactArgs(this.panelElements[1], this.options[1]);
|
||||
mockInstances[1].expects('beforeHide').never();
|
||||
mockInstances[1].expects('hide').never();
|
||||
this.SettingsService.navigate('id1', this.options[1], function() {
|
||||
mockInstances[0].verify();
|
||||
mockInstances[1].verify();
|
||||
done();
|
||||
});
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should not deactivate the root panel', function(done) {
|
||||
var mockInstances = [];
|
||||
|
||||
this.SettingsService.init({
|
||||
rootPanelId: 'id0',
|
||||
context: {
|
||||
initialPanelId: 'id0',
|
||||
activityHandler: null
|
||||
}
|
||||
});
|
||||
|
||||
mockInstances[0] = sinon.mock(this.mockSettingsPanelInstances[0]);
|
||||
// Expect only calls to beforeShow and show of panel0.
|
||||
mockInstances[0].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('show').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('beforeHide').never();
|
||||
mockInstances[0].expects('hide').never();
|
||||
this.SettingsService.navigate('id0', this.options[0], (function() {
|
||||
mockInstances[0].verify();
|
||||
|
||||
mockInstances[0] = sinon.mock(this.mockSettingsPanelInstances[0]);
|
||||
// Expect only calls to beforeHide and hide of panel0.
|
||||
mockInstances[0].expects('beforeShow').never();
|
||||
mockInstances[0].expects('show').never();
|
||||
mockInstances[0].expects('beforeHide').never();
|
||||
mockInstances[0].expects('hide').never();
|
||||
mockInstances[1] = sinon.mock(this.mockSettingsPanelInstances[1]);
|
||||
// Expect only calls to beforeShow and show of panel1.
|
||||
mockInstances[1].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[1], this.options[1]);
|
||||
mockInstances[1].expects('show').once()
|
||||
.withExactArgs(this.panelElements[1], this.options[1]);
|
||||
mockInstances[1].expects('beforeHide').never();
|
||||
mockInstances[1].expects('hide').never();
|
||||
this.SettingsService.navigate('id1', this.options[1], function() {
|
||||
mockInstances[0].verify();
|
||||
mockInstances[1].verify();
|
||||
done();
|
||||
});
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should process the pending navigations correctly', function(done) {
|
||||
var mockInstances = [];
|
||||
for (var i = 0; i < 4; i++) {
|
||||
mockInstances[i] = sinon.mock(this.mockSettingsPanelInstances[i]);
|
||||
}
|
||||
|
||||
// Expect only calls to beforeShow and show of panel0.
|
||||
mockInstances[0].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('show').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
mockInstances[0].expects('beforeHide').once();
|
||||
mockInstances[0].expects('hide').once();
|
||||
// Expect only calls to beforeShow and show of panel3.
|
||||
mockInstances[1].expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[3], this.options[3]);
|
||||
mockInstances[1].expects('show').once()
|
||||
.withExactArgs(this.panelElements[3], this.options[3]);
|
||||
mockInstances[1].expects('beforeHide').never();
|
||||
mockInstances[1].expects('hide').never();
|
||||
|
||||
// With the following calling sequence, the navigation to 'id1' and 'id2'
|
||||
// will be ignored. We will only get two panel instances for panel0 and
|
||||
// panel3 correspondingly.
|
||||
this.SettingsService.navigate('id0', this.options[0]);
|
||||
this.SettingsService.navigate('id1', this.options[1]);
|
||||
this.SettingsService.navigate('id2', this.options[2]);
|
||||
this.SettingsService.navigate('id3', this.options[3], (function() {
|
||||
mockInstances.forEach(function(mockInstance) {
|
||||
mockInstance.verify();
|
||||
});
|
||||
// The third and fourth panel instances should not be created.
|
||||
assert.ok(this.callCount == 2,
|
||||
'only two panel instances should be created');
|
||||
done();
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('should override Settings._currentPanel', function() {
|
||||
var fakePanelId = 'id0';
|
||||
this.SettingsService.navigate(fakePanelId, {}, (function() {
|
||||
assert.equal(this.MockSettings._currentPanel, '#' + fakePanelId);
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('can navigate to frame panel if panelId is app:app_name', function() {
|
||||
var fakePanelId = 'app:bluetooth';
|
||||
this.SettingsService.navigate(fakePanelId, {}, (function() {
|
||||
assert.equal(this.MockSettings._currentPanel, '#frame');
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
test('can\'t navigate to non-trust apps', function() {
|
||||
var fakePanelId = 'app:unknownApp';
|
||||
this.sinon.spy(console, 'error');
|
||||
this.SettingsService.navigate(fakePanelId, {});
|
||||
console.error.calledWith('We only embed trust apps.');
|
||||
});
|
||||
});
|
||||
|
||||
suite('visibility change', function() {
|
||||
var originalDocumentHidden;
|
||||
|
||||
setup(function(done) {
|
||||
originalDocumentHidden = document.hidden;
|
||||
|
||||
this.SettingsService.init();
|
||||
this.SettingsService.navigate('id0', this.options[0], function() {
|
||||
this.mockInstance = sinon.mock(this.mockSettingsPanelInstances[0]);
|
||||
done();
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
Object.defineProperty(document, 'hidden', {
|
||||
value: originalDocumentHidden,
|
||||
configurable: true
|
||||
});
|
||||
});
|
||||
|
||||
test('visible', function() {
|
||||
Object.defineProperty(document, 'hidden', {
|
||||
value: false,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
this.mockInstance.expects('beforeShow').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
this.mockInstance.expects('show').once()
|
||||
.withExactArgs(this.panelElements[0], this.options[0]);
|
||||
|
||||
window.dispatchEvent(new CustomEvent('visibilitychange'));
|
||||
this.mockInstance.verify();
|
||||
});
|
||||
|
||||
test('invisible', function() {
|
||||
Object.defineProperty(document, 'hidden', {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
this.mockInstance.expects('beforeHide').once();
|
||||
this.mockInstance.expects('hide').once();
|
||||
|
||||
window.dispatchEvent(new CustomEvent('visibilitychange'));
|
||||
this.mockInstance.verify();
|
||||
});
|
||||
});
|
||||
});
|
||||
59
gaia/apps/settings/test/unit/modules/settings_utils_test.js
Executable file
59
gaia/apps/settings/test/unit/modules/settings_utils_test.js
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
/* global MockSettings */
|
||||
requireApp('settings/test/unit/mock_settings.js');
|
||||
|
||||
suite('SettingsUtils', function() {
|
||||
'use strict';
|
||||
|
||||
var realSettings;
|
||||
var settingsUtils;
|
||||
var settingsService;
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/settings_service': 'unit/mock_settings_service',
|
||||
'shared/lazy_loader': 'shared_mocks/mock_lazy_loader'
|
||||
}
|
||||
};
|
||||
|
||||
suiteSetup(function() {
|
||||
realSettings = window.Settings;
|
||||
window.Settings = MockSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.Settings = realSettings;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
testRequire([
|
||||
'modules/settings_utils',
|
||||
'unit/mock_settings_service'
|
||||
], map, function(SettingsUtils, MockSettingsService) {
|
||||
settingsUtils = SettingsUtils;
|
||||
settingsService = MockSettingsService;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('loadTemplate', function() {
|
||||
var spyCallback;
|
||||
|
||||
setup(function() {
|
||||
spyCallback = this.sinon.spy();
|
||||
});
|
||||
|
||||
test('with element', function() {
|
||||
var element = {
|
||||
innerHTML: 'html'
|
||||
};
|
||||
this.sinon.stub(document, 'getElementById').returns(element);
|
||||
settingsUtils.loadTemplate('real', spyCallback);
|
||||
assert.isTrue(spyCallback.calledWith(element.innerHTML));
|
||||
});
|
||||
|
||||
test('without element', function() {
|
||||
this.sinon.stub(document, 'getElementById').returns(null);
|
||||
settingsUtils.loadTemplate('fake', spyCallback);
|
||||
assert.isTrue(spyCallback.calledWith(null));
|
||||
});
|
||||
});
|
||||
});
|
||||
68
gaia/apps/settings/test/unit/modules/sim_security_test.js
Executable file
68
gaia/apps/settings/test/unit/modules/sim_security_test.js
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
suite('SimSecurity', function() {
|
||||
'use strict';
|
||||
|
||||
var simSecurity;
|
||||
|
||||
setup(function(done) {
|
||||
testRequire([
|
||||
'modules/sim_security'
|
||||
], {}, function(SimSecurity) {
|
||||
simSecurity = SimSecurity;
|
||||
simSecurity._getIccByCardIndex = function(cardIndex) {
|
||||
var func = function() {
|
||||
return Promise.resolve();
|
||||
};
|
||||
return {
|
||||
unlockCardLock: func,
|
||||
setCardLock: func,
|
||||
updateContact: func,
|
||||
getCardLock: func,
|
||||
getCardLockRetryCount: func
|
||||
};
|
||||
};
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
['pin', 'pin2', 'fdn'].forEach(function(lockType) {
|
||||
[true, false].forEach(function(enabled) {
|
||||
var fakeCardIndex = 0;
|
||||
var status = enabled ? 'enabled' : 'disabled';
|
||||
var eventName = lockType + '-' + status;
|
||||
test(eventName + ' works', function(done) {
|
||||
simSecurity.addEventListener(eventName, function(evt) {
|
||||
var cardIndex = evt.detail;
|
||||
assert.equal(cardIndex, fakeCardIndex);
|
||||
done();
|
||||
});
|
||||
|
||||
var apiName = enabled ? 'setCardLock' : 'unlockCardLock';
|
||||
simSecurity[apiName](fakeCardIndex, {
|
||||
lockType: lockType,
|
||||
pin: '1234',
|
||||
enabled: enabled
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
['pin', 'pin2', 'puk2'].forEach(function(lockType) {
|
||||
var fakeCardIndex = 0;
|
||||
var eventName = lockType + '-changed';
|
||||
|
||||
test(eventName + ' works', function(done) {
|
||||
simSecurity.addEventListener(eventName, function(evt) {
|
||||
var cardIndex = evt.detail;
|
||||
assert.equal(cardIndex, fakeCardIndex);
|
||||
done();
|
||||
});
|
||||
|
||||
simSecurity.setCardLock(fakeCardIndex, {
|
||||
lockType: lockType,
|
||||
pin: '1234',
|
||||
newPin: '0000'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
175
gaia/apps/settings/test/unit/modules/state_model_test.js
Executable file
175
gaia/apps/settings/test/unit/modules/state_model_test.js
Executable file
|
|
@ -0,0 +1,175 @@
|
|||
'use strict';
|
||||
|
||||
suite('StateModel', function() {
|
||||
var StateModel;
|
||||
|
||||
var modules = [
|
||||
'modules/state_model'
|
||||
];
|
||||
|
||||
suiteSetup(function(done) {
|
||||
testRequire(modules, (stateModel) => {
|
||||
StateModel = stateModel;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('initial state', function() {
|
||||
test('the state should change from the initial state to the first state',
|
||||
function(done) {
|
||||
var initialState = 'initialState';
|
||||
var firstState = 'firstState';
|
||||
|
||||
var model = StateModel({
|
||||
_state: initialState,
|
||||
onInit: function() {
|
||||
return this._state;
|
||||
},
|
||||
onGetState: function() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
this._state = firstState;
|
||||
resolve(this._state);
|
||||
});
|
||||
});
|
||||
},
|
||||
onSetState: function() {}
|
||||
});
|
||||
model.observe('currentState', function() {
|
||||
// Ensure the first state.
|
||||
if (model.currentState === firstState) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
// Ensure the initial state.
|
||||
assert.equal(model.targetState, initialState);
|
||||
assert.equal(model.currentState, initialState);
|
||||
});
|
||||
});
|
||||
|
||||
suite('set target state', function() {
|
||||
test('the final state should be the last state if success', function(done) {
|
||||
var initialState = 'initialState';
|
||||
var finalTargetState = 'finalState';
|
||||
|
||||
// Note that OPERATION_TIME should be larger than the total time required
|
||||
// for performing the random user actions.
|
||||
var OPERATION_TIME = 300;
|
||||
var USER_ACTION_TIME = 10;
|
||||
|
||||
var model = StateModel({
|
||||
_state: initialState,
|
||||
onInit: function() {
|
||||
return this._state;
|
||||
},
|
||||
onGetState: function() {
|
||||
return Promise.resolve(this._state);
|
||||
},
|
||||
onSetState: function(newState) {
|
||||
// a fake time consuming operation
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
this._state = newState;
|
||||
resolve(this._state);
|
||||
}, OPERATION_TIME);
|
||||
});
|
||||
}
|
||||
});
|
||||
model.observe('transitioning', function(transitioning) {
|
||||
if (transitioning) {
|
||||
return;
|
||||
}
|
||||
assert.equal(model.targetState, finalTargetState);
|
||||
assert.equal(model.currentState, finalTargetState);
|
||||
done();
|
||||
});
|
||||
|
||||
// The following code tries to simulate random actions from the user and
|
||||
// stop at `finalTargetState`.
|
||||
var count = 0;
|
||||
var intervalId = setInterval(function() {
|
||||
count++;
|
||||
if (count === 11) {
|
||||
clearInterval(intervalId);
|
||||
model.targetState = finalTargetState;
|
||||
} else {
|
||||
// Some random actions.
|
||||
model.targetState = (Math.random() * 10) % 10;
|
||||
}
|
||||
}, USER_ACTION_TIME);
|
||||
});
|
||||
|
||||
test('the final state should be the reported state if failed',
|
||||
function(done) {
|
||||
var initialState = 'initialState';
|
||||
var targetState = 'targetState';
|
||||
var realState = 'realState';
|
||||
|
||||
var model = StateModel({
|
||||
_state: initialState,
|
||||
onInit: function() {
|
||||
return this._state;
|
||||
},
|
||||
onGetState: function() {
|
||||
return Promise.resolve(this._state);
|
||||
},
|
||||
onSetState: function(newState) {
|
||||
// a fake time consuming operation
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
this._state = realState;
|
||||
reject(this._state);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
model.observe('transitioning', function(transitioning) {
|
||||
if (transitioning) {
|
||||
return;
|
||||
}
|
||||
assert.equal(model.targetState, realState);
|
||||
assert.equal(model.currentState, realState);
|
||||
done();
|
||||
});
|
||||
model.targetState = targetState;
|
||||
});
|
||||
});
|
||||
|
||||
suite('state change', function() {
|
||||
test('the final state should change to the real state', function(done) {
|
||||
var initialState = 'initialState';
|
||||
var realState = 'realState';
|
||||
|
||||
var _onStateChange = null;
|
||||
var model = StateModel({
|
||||
_state: initialState,
|
||||
onInit: function(onStateChange) {
|
||||
_onStateChange = onStateChange;
|
||||
return this._state;
|
||||
},
|
||||
onGetState: function() {
|
||||
return Promise.resolve(this._state);
|
||||
},
|
||||
onSetState: function() {}
|
||||
});
|
||||
|
||||
var targetStateChecked = false;
|
||||
var currentStateChecked = false;
|
||||
|
||||
model.observe('targetState', function() {
|
||||
targetStateChecked = model.targetState == realState;
|
||||
if (targetStateChecked && currentStateChecked) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
model.observe('currentState', function() {
|
||||
currentStateChecked = model.currentState == realState;
|
||||
if (targetStateChecked && currentStateChecked) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
// trigger the state change
|
||||
_onStateChange('realState');
|
||||
});
|
||||
});
|
||||
});
|
||||
196
gaia/apps/settings/test/unit/modules/sync_manager_bridge_test.js
Executable file
196
gaia/apps/settings/test/unit/modules/sync_manager_bridge_test.js
Executable file
|
|
@ -0,0 +1,196 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
suite('settings/SyncManagerBridge >', () => {
|
||||
var subject;
|
||||
var realMozApps;
|
||||
var port;
|
||||
var app;
|
||||
var onmessageData;
|
||||
|
||||
suiteSetup(done => {
|
||||
navigator.addIdleObserver = sinon.spy();
|
||||
|
||||
realMozApps = navigator.mozApps;
|
||||
port = {
|
||||
postMessage: function() {},
|
||||
set onmessage(callback) {
|
||||
setTimeout(() => {
|
||||
callback({ data: onmessageData });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
app = {
|
||||
connect: function() {
|
||||
return Promise.resolve([port]);
|
||||
}
|
||||
};
|
||||
|
||||
var onsuccess = {
|
||||
set onsuccess(callback) {
|
||||
setTimeout(() => {
|
||||
callback({ target: { result: app } });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
navigator.mozApps = {
|
||||
getSelf: function() {
|
||||
return onsuccess;
|
||||
}
|
||||
};
|
||||
|
||||
testRequire(['modules/sync_manager_bridge'], SyncManagerBridge => {
|
||||
subject = SyncManagerBridge;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
navigator.mozApps = realMozApps;
|
||||
});
|
||||
|
||||
suite('Initial state', () => {
|
||||
test('Integrity', () => {
|
||||
assert.ok(subject !== null);
|
||||
assert.isNull(subject._port);
|
||||
assert.equal(subject._requests.size, 0);
|
||||
});
|
||||
});
|
||||
|
||||
['enable',
|
||||
'disable',
|
||||
'sync'].forEach(method => {
|
||||
suite(method, () => {
|
||||
var getSelfSpy;
|
||||
var connectSpy;
|
||||
var postMessageSpy;
|
||||
|
||||
setup(() => {
|
||||
getSelfSpy = this.sinon.spy(navigator.mozApps, 'getSelf');
|
||||
connectSpy = this.sinon.spy(app, 'connect');
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
getSelfSpy.restore();
|
||||
connectSpy.restore();
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
subject._port = null;
|
||||
});
|
||||
|
||||
test(method + ' - no previous connection', done => {
|
||||
subject[method]();
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.calledOnce(getSelfSpy);
|
||||
this.sinon.assert.calledOnce(connectSpy);
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, method);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test(method + ' - previous connection', done => {
|
||||
subject[method]();
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.notCalled(getSelfSpy);
|
||||
this.sinon.assert.notCalled(connectSpy);
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, method);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getInfo', () => {
|
||||
var postMessageSpy;
|
||||
var dateNowStub;
|
||||
var onsyncchangeSpy;
|
||||
var now;
|
||||
|
||||
setup(() => {
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
dateNowStub = this.sinon.stub(Date, 'now', () => {
|
||||
return now;
|
||||
});
|
||||
subject.onsyncchange = () => {};
|
||||
onsyncchangeSpy = this.sinon.spy(subject, '_onsyncchange');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
postMessageSpy.restore();
|
||||
dateNowStub.restore();
|
||||
onsyncchangeSpy.restore();
|
||||
});
|
||||
|
||||
test('getInfo', done => {
|
||||
now = 'now';
|
||||
var expectedMessage = {
|
||||
data: {
|
||||
id: now,
|
||||
result: 'whatever'
|
||||
}
|
||||
};
|
||||
subject.getInfo().then(message => {
|
||||
assert.equal(message.id, expectedMessage.data.id);
|
||||
assert.equal(message.result, expectedMessage.data.result);
|
||||
this.sinon.assert.notCalled(onsyncchangeSpy);
|
||||
done();
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.calledOnce(postMessageSpy);
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].name, 'getInfo');
|
||||
assert.equal(postMessageSpy.getCall(0).args[0].id, now);
|
||||
assert.ok(subject._requests.has(now));
|
||||
subject.onmessage(expectedMessage);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('onsyncchange', () => {
|
||||
var postMessageSpy;
|
||||
var onsyncchangeSpy;
|
||||
var now;
|
||||
|
||||
setup(() => {
|
||||
postMessageSpy = this.sinon.spy(port, 'postMessage');
|
||||
subject.onsyncchange = () => {};
|
||||
onsyncchangeSpy = this.sinon.spy(subject, '_onsyncchange');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
postMessageSpy.restore();
|
||||
onsyncchangeSpy.restore();
|
||||
});
|
||||
|
||||
test('getInfo', done => {
|
||||
var expectedMessage = {
|
||||
data: {
|
||||
name: 'onsyncchange',
|
||||
result: 'whatever'
|
||||
}
|
||||
};
|
||||
|
||||
subject.onmessage(expectedMessage);
|
||||
setTimeout(() => {
|
||||
this.sinon.assert.notCalled(postMessageSpy);
|
||||
assert.ok(!(subject._requests.has(now)));
|
||||
this.sinon.assert.calledOnce(onsyncchangeSpy);
|
||||
assert.equal(onsyncchangeSpy.getCall(0).args[0].result,
|
||||
expectedMessage.data.result);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
245
gaia/apps/settings/test/unit/modules/wifi_context_test.js
Executable file
245
gaia/apps/settings/test/unit/modules/wifi_context_test.js
Executable file
|
|
@ -0,0 +1,245 @@
|
|||
/* global MockNavigatorSettings, MockNavigatorMozWifiManager */
|
||||
requireApp('settings/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
requireApp(
|
||||
'settings/shared/test/unit/mocks/mock_navigator_moz_wifi_manager.js');
|
||||
|
||||
suite('WifiContext', function() {
|
||||
'use strict';
|
||||
|
||||
var realSettings;
|
||||
var wifiHelper;
|
||||
var wifiContext;
|
||||
var wifiManager;
|
||||
|
||||
var modules = [
|
||||
'modules/wifi_context',
|
||||
'shared/wifi_helper'
|
||||
];
|
||||
var maps = {
|
||||
'*': {
|
||||
'modules/settings_cache': 'unit/mock_settings_cache',
|
||||
'shared/wifi_helper': 'shared_mocks/mock_wifi_helper'
|
||||
}
|
||||
};
|
||||
|
||||
suiteSetup(function() {
|
||||
realSettings = window.navigator.mozSettings;
|
||||
window.navigator.mozSettings = MockNavigatorSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.navigator.mozSettings = realSettings;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
testRequire(modules, maps,
|
||||
function(WifiContext, MockWifiHelper) {
|
||||
wifiContext = WifiContext;
|
||||
wifiHelper = MockWifiHelper;
|
||||
wifiManager = wifiHelper.getWifiManager();
|
||||
|
||||
MockNavigatorMozWifiManager.mSetup();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suite('WifiStatusTextChange', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
wifiContext.addEventListener('wifiStatusTextChange', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiStatusTextChange', fakeCb);
|
||||
});
|
||||
|
||||
test('when wifiManger.onenabled, trigger cb', function() {
|
||||
wifiManager.onenabled();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
|
||||
test('when wifiManger.ondisabled, trigger cb', function() {
|
||||
wifiManager.ondisabled();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
|
||||
test('when wifiManger.onstatuschange, trigger cb', function() {
|
||||
wifiManager.onstatuschange();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('WifiEnabled', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
wifiContext.addEventListener('wifiEnabled', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiEnabled', fakeCb);
|
||||
});
|
||||
|
||||
test('when wifiManager.onenabled, trigger cb', function() {
|
||||
wifiManager.onenabled();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('WifiStatusChange', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
wifiContext.addEventListener('wifiStatusChange', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiStatusChange', fakeCb);
|
||||
});
|
||||
|
||||
test('when wifiManager.onstatuschange, trigger cb', function() {
|
||||
wifiManager.onstatuschange();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('WifiConnectionInfoUpdate', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
wifiContext.addEventListener('wifiConnectionInfoUpdate', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiConnectionInfoUpdate', fakeCb);
|
||||
});
|
||||
|
||||
test('when wifiManager.onconnectioninfoupdate, trigger cb', function() {
|
||||
wifiManager.onconnectioninfoupdate();
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('WifiNetworkForgotten', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
wifiContext.addEventListener('wifiNetworkForgotten', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiNetworkForgotten', fakeCb);
|
||||
});
|
||||
|
||||
test('when wifiContext.forgetNetwork callback, trigger cb', function() {
|
||||
wifiContext.forgetNetwork({}, () => {
|
||||
assert.isTrue(fakeCb.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('wifiStatusText', function() {
|
||||
suiteTeardown(function() {
|
||||
delete(wifiManager.connection.status);
|
||||
});
|
||||
|
||||
test('wifiManager is enabled, get fullstatus', function() {
|
||||
wifiManager.enabled = true;
|
||||
wifiManager.connection.status = 'disconnected';
|
||||
wifiManager.onstatuschange();
|
||||
assert.equal(wifiContext.wifiStatusText.id, 'full-status-disconnected');
|
||||
});
|
||||
|
||||
test('wifiManager is disabled, get disabled string', function() {
|
||||
wifiManager.enabled = false;
|
||||
wifiManager.onstatuschange();
|
||||
assert.equal(wifiContext.wifiStatusText.id, 'disabled');
|
||||
});
|
||||
});
|
||||
|
||||
suite('forgetNetwork', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(wifiManager, 'forget');
|
||||
});
|
||||
test('will bypass to wifiManager', function() {
|
||||
wifiContext.forgetNetwork({});
|
||||
assert.isTrue(wifiManager.forget.called);
|
||||
assert.isNull(wifiContext.currentNetwork);
|
||||
});
|
||||
});
|
||||
|
||||
suite('associateNetwork', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
this.sinon.spy(wifiManager, 'associate');
|
||||
this.sinon.spy(wifiManager, 'forget');
|
||||
wifiContext.addEventListener('wifiWrongPassword', fakeCb);
|
||||
});
|
||||
|
||||
test('will bypass to wifiManager', function() {
|
||||
var fakeNetwork = {
|
||||
known: false,
|
||||
password: '1234',
|
||||
ssid: 'fake-network'
|
||||
};
|
||||
wifiContext.associateNetwork(fakeNetwork);
|
||||
|
||||
assert.isTrue(wifiManager.associate.calledWith(fakeNetwork));
|
||||
assert.equal(wifiContext.currentNetwork, fakeNetwork);
|
||||
|
||||
wifiManager.enabled = true;
|
||||
wifiManager.connection.status = 'connected';
|
||||
wifiManager.onstatuschange({
|
||||
network: {
|
||||
ssid: fakeNetwork.ssid
|
||||
},
|
||||
status: wifiManager.connection.status
|
||||
});
|
||||
assert.isFalse(fakeCb.calledWith());
|
||||
assert.isFalse(wifiManager.forget.calledWith(fakeNetwork));
|
||||
});
|
||||
});
|
||||
|
||||
suite('Connecting failed', function() {
|
||||
var fakeCb;
|
||||
|
||||
setup(function() {
|
||||
fakeCb = sinon.spy();
|
||||
this.sinon.spy(wifiManager, 'associate');
|
||||
this.sinon.spy(wifiManager, 'forget');
|
||||
wifiContext.addEventListener('wifiWrongPassword', fakeCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
wifiContext.removeEventListener('wifiWrongPassword', fakeCb);
|
||||
});
|
||||
|
||||
test('when connectingfailed, trigger cb', function() {
|
||||
var fakeNetwork = {
|
||||
known: false,
|
||||
password: '1234',
|
||||
ssid: 'fake-network'
|
||||
};
|
||||
wifiContext.associateNetwork(fakeNetwork);
|
||||
|
||||
wifiManager.enabled = true;
|
||||
wifiManager.connection.status = 'connectingfailed';
|
||||
wifiManager.onstatuschange({
|
||||
network: {
|
||||
ssid: fakeNetwork.ssid
|
||||
},
|
||||
status: wifiManager.connection.status
|
||||
});
|
||||
assert.isTrue(fakeCb.calledWith());
|
||||
assert.isTrue(wifiManager.forget.calledWith(fakeNetwork));
|
||||
});
|
||||
});
|
||||
});
|
||||
439
gaia/apps/settings/test/unit/modules/wifi_utils_test.js
Executable file
439
gaia/apps/settings/test/unit/modules/wifi_utils_test.js
Executable file
|
|
@ -0,0 +1,439 @@
|
|||
/* global MockL10n, MockNavigatorSettings, MockNavigatorMozWifiManager,
|
||||
MockNavigatorSettings */
|
||||
require('/shared/test/unit/mocks/mock_l20n.js');
|
||||
requireApp('settings/shared/test/unit/mocks/mock_navigator_moz_settings.js');
|
||||
requireApp('settings/shared/test/unit/load_body_html_helper.js');
|
||||
requireApp(
|
||||
'settings/shared/test/unit/mocks/mock_navigator_moz_wifi_manager.js');
|
||||
|
||||
suite('WifiUtils', function() {
|
||||
'use strict';
|
||||
|
||||
var realL10n;
|
||||
var realSettings;
|
||||
var wifiUtils;
|
||||
var settingsUtils;
|
||||
var map = {
|
||||
'*': {
|
||||
'modules/settings_utils': 'unit/mock_settings_utils',
|
||||
'shared/wifi_helper': 'shared_mocks/mock_wifi_helper'
|
||||
}
|
||||
};
|
||||
|
||||
suiteSetup(function() {
|
||||
realL10n = document.l10n;
|
||||
document.l10n = MockL10n;
|
||||
|
||||
realSettings = window.navigator.mozSettings;
|
||||
window.navigator.mozSettings = MockNavigatorSettings;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
document.l10n = realL10n;
|
||||
window.navigator.mozSettings = realSettings;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
testRequire([
|
||||
'modules/wifi_utils',
|
||||
'unit/mock_settings_utils',
|
||||
], map, function(WifiUtils, MockSettingsUtils) {
|
||||
wifiUtils = WifiUtils;
|
||||
settingsUtils = MockSettingsUtils;
|
||||
|
||||
MockNavigatorSettings.mSetup();
|
||||
MockNavigatorMozWifiManager.mSetup();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('newExplanationItem', function() {
|
||||
var li = wifiUtils.newExplanationItem('test');
|
||||
assert.equal(li.className, 'explanation');
|
||||
assert.equal(li.getAttribute('data-l10n-id'), 'test');
|
||||
});
|
||||
|
||||
suite('updateListItemStatus', function() {
|
||||
var fakeNetworkKey = 'network1';
|
||||
var fakeListItems;
|
||||
var fakeListItemDOM;
|
||||
var fakeActiveItemDOM;
|
||||
|
||||
setup(function() {
|
||||
this.sinon.stub(wifiUtils, 'getNetworkKey').returns(fakeNetworkKey);
|
||||
|
||||
fakeListItems = {};
|
||||
fakeListItemDOM = document.createElement('div');
|
||||
fakeListItemDOM.appendChild(document.createElement('small'));
|
||||
fakeListItemDOM.appendChild(document.createElement('aside'));
|
||||
|
||||
fakeActiveItemDOM = document.createElement('div');
|
||||
fakeActiveItemDOM.appendChild(document.createElement('small'));
|
||||
fakeActiveItemDOM.appendChild(document.createElement('aside'));
|
||||
|
||||
fakeListItems[fakeNetworkKey] = fakeListItemDOM;
|
||||
});
|
||||
|
||||
suite('with no needed parameters', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(window.console, 'log');
|
||||
wifiUtils.updateListItemStatus();
|
||||
});
|
||||
test('we will get error message', function() {
|
||||
assert.isTrue(window.console.log.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('if we are connecting to an AP with `connecting` status', function() {
|
||||
setup(function() {
|
||||
wifiUtils.updateListItemStatus({
|
||||
network: {},
|
||||
networkStatus: 'connecting',
|
||||
listItems: fakeListItems,
|
||||
activeItemDOM: fakeActiveItemDOM
|
||||
});
|
||||
});
|
||||
|
||||
test('activeItemDOM is cleaned up to normal status', function() {
|
||||
assert.isFalse(fakeActiveItemDOM.classList.contains('active'));
|
||||
assert.equal(fakeActiveItemDOM.querySelector('small').dataset.l10nId,
|
||||
'short-status-disconnected');
|
||||
assert.isFalse(fakeActiveItemDOM.querySelector(
|
||||
'aside').classList.contains('connecting'));
|
||||
assert.isFalse(fakeActiveItemDOM.querySelector(
|
||||
'aside').classList.contains('connected'));
|
||||
});
|
||||
|
||||
test('listItemDOM is in right status', function() {
|
||||
assert.isTrue(fakeListItemDOM.classList.contains('active'));
|
||||
assert.equal(fakeListItemDOM.querySelector('small').dataset.l10nId,
|
||||
'short-status-connecting');
|
||||
assert.isTrue(fakeListItemDOM.querySelector(
|
||||
'aside').classList.contains('connecting'));
|
||||
assert.isFalse(fakeListItemDOM.querySelector(
|
||||
'aside').classList.contains('connected'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('if we are connecting to an AP with `connected` status', function() {
|
||||
setup(function() {
|
||||
wifiUtils.updateListItemStatus({
|
||||
network: {},
|
||||
networkStatus: 'connected',
|
||||
listItems: fakeListItems,
|
||||
activeItemDOM: fakeActiveItemDOM
|
||||
});
|
||||
});
|
||||
|
||||
test('listItemDOM is in right status', function() {
|
||||
assert.isTrue(fakeListItemDOM.classList.contains('active'));
|
||||
assert.equal(fakeListItemDOM.querySelector('small').dataset.l10nId,
|
||||
'short-status-connected');
|
||||
assert.isTrue(fakeListItemDOM.querySelector(
|
||||
'aside').classList.contains('connected'));
|
||||
assert.isFalse(fakeListItemDOM.querySelector(
|
||||
'aside').classList.contains('connecting'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('changeDisplay', function() {
|
||||
var dialog;
|
||||
var eap;
|
||||
var identity;
|
||||
var password;
|
||||
var authPhase2;
|
||||
var certificate;
|
||||
var description;
|
||||
|
||||
setup(function() {
|
||||
loadBodyHTML('./_wifi_utils.html');
|
||||
|
||||
dialog = document.getElementById('wifi-auth');
|
||||
eap = dialog.querySelector('li.eap select');
|
||||
identity = dialog.querySelector('input[name=identity]');
|
||||
password = dialog.querySelector('input[name=password]');
|
||||
authPhase2 = dialog.querySelector('li.auth-phase2 select');
|
||||
certificate = dialog.querySelector('li.server-certificate select');
|
||||
description = dialog.querySelector('li.server-certificate-description');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WEP', function() {
|
||||
wifiUtils.changeDisplay(dialog, 'WEP');
|
||||
assert.equal(identity.parentNode.style.display, 'none');
|
||||
assert.equal(password.parentNode.style.display, 'block');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(description.style.display, 'none');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WPA-PSK', function() {
|
||||
wifiUtils.changeDisplay(dialog, 'WPA-PSK');
|
||||
assert.equal(identity.parentNode.style.display, 'none');
|
||||
assert.equal(password.parentNode.style.display, 'block');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(description.style.display, 'none');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WPA-EAP, eap is SIM', function() {
|
||||
eap.value = 'SIM';
|
||||
wifiUtils.changeDisplay(dialog, 'WPA-EAP');
|
||||
assert.equal(identity.parentNode.style.display, 'none');
|
||||
assert.equal(password.parentNode.style.display, 'none');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'none');
|
||||
assert.equal(description.style.display, 'none');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WPA-EAP, eap is PEAP', function() {
|
||||
eap.value = 'PEAP';
|
||||
wifiUtils.changeDisplay(dialog, 'WPA-EAP');
|
||||
assert.equal(identity.parentNode.style.display, 'block');
|
||||
assert.equal(password.parentNode.style.display, 'block');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(description.style.display, 'block');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WPA-EAP, eap is TLS', function() {
|
||||
eap.value = 'TLS';
|
||||
wifiUtils.changeDisplay(dialog, 'WPA-EAP');
|
||||
assert.equal(identity.parentNode.style.display, 'block');
|
||||
assert.equal(password.parentNode.style.display, 'block');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(description.style.display, 'block');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is WPA-EAP, eap is TTLS', function() {
|
||||
eap.value = 'TTLS';
|
||||
wifiUtils.changeDisplay(dialog, 'WPA-EAP');
|
||||
assert.equal(identity.parentNode.style.display, 'block');
|
||||
assert.equal(password.parentNode.style.display, 'block');
|
||||
assert.equal(authPhase2.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(certificate.parentNode.parentNode.style.display, 'block');
|
||||
assert.equal(description.style.display, 'block');
|
||||
});
|
||||
|
||||
test('panel is wifi-auth, security is none', function() {
|
||||
wifiUtils.changeDisplay(dialog, 'none');
|
||||
assert.equal(identity.parentNode.style.display, 'none');
|
||||
assert.equal(password.parentNode.style.display, 'none');
|
||||
});
|
||||
});
|
||||
|
||||
test('loadImportedCertificateOptions', function() {
|
||||
var selectDOM = document.createElement('select');
|
||||
selectDOM.appendChild(createOption('--'));
|
||||
selectDOM.appendChild(createOption('1'));
|
||||
selectDOM.appendChild(createOption('2'));
|
||||
|
||||
MockNavigatorMozWifiManager._certificateList = [
|
||||
'cert1', 'cert2', 'cert3'
|
||||
];
|
||||
|
||||
// the total options would be one default item and certificates
|
||||
var expectedLengthOfOptions =
|
||||
1 + MockNavigatorMozWifiManager._certificateList.length;
|
||||
|
||||
this.sinon.spy(selectDOM, 'remove');
|
||||
this.sinon.spy(selectDOM, 'add');
|
||||
wifiUtils.loadImportedCertificateOptions(selectDOM);
|
||||
|
||||
// we have three options, but we would keep the first one
|
||||
assert.isTrue(selectDOM.remove.calledTwice);
|
||||
// and we would add three options back based on the number of our fake
|
||||
// certificates
|
||||
assert.isTrue(selectDOM.add.calledThrice);
|
||||
// and the total options should be one default item and certificates
|
||||
assert.equal(selectDOM.options.length, expectedLengthOfOptions);
|
||||
});
|
||||
|
||||
suite('newListItem', function() {
|
||||
test('WPA-PSK network - not configured, in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: ['WPA-PSK'],
|
||||
relSignalStrength: 40,
|
||||
known: false,
|
||||
};
|
||||
var l10nSpy = this.sinon.spy(document.l10n, 'setAttributes');
|
||||
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.ok(l10nSpy.calledWith(small, 'securedBy',
|
||||
{capabilities: 'WPA-PSK'}));
|
||||
});
|
||||
|
||||
test('WPA-PSK network - configured, in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: ['WPA-PSK'],
|
||||
relSignalStrength: 40,
|
||||
known: true,
|
||||
};
|
||||
var l10nSpy = this.sinon.spy(document.l10n, 'setAttributes');
|
||||
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.ok(l10nSpy.calledWith(small, 'securedBy',
|
||||
{capabilities: 'WPA-PSK'}));
|
||||
});
|
||||
|
||||
test('WPA-PSK network - configured, not in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: ['WPA-PSK'],
|
||||
relSignalStrength: 0,
|
||||
known: true,
|
||||
};
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork,
|
||||
showNotInRange: true
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.equal(small.getAttribute('data-l10n-id'), 'notInRange');
|
||||
});
|
||||
|
||||
test('Open network - not configured, in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: [],
|
||||
relSignalStrength: 40,
|
||||
known: false,
|
||||
};
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(!icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.equal(small.getAttribute('data-l10n-id'), 'securityOpen');
|
||||
});
|
||||
|
||||
test('OPEN network - configured, in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: [],
|
||||
relSignalStrength: 40,
|
||||
known: true,
|
||||
};
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(!icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.equal(small.getAttribute('data-l10n-id'), 'securityOpen');
|
||||
});
|
||||
|
||||
test('OPEN network - configured, not in range', function() {
|
||||
var testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: [],
|
||||
relSignalStrength: 0,
|
||||
known: true,
|
||||
};
|
||||
var listItem = wifiUtils.newListItem({
|
||||
network: testNetwork,
|
||||
showNotInRange: true
|
||||
});
|
||||
|
||||
var icon = listItem.querySelector('aside');
|
||||
assert.ok(!icon.classList.contains('secured'));
|
||||
|
||||
var a = listItem.querySelector('a');
|
||||
var ssid = a.querySelector('span');
|
||||
assert.equal(ssid.textContent, testNetwork.ssid);
|
||||
|
||||
var small = a.querySelector('small');
|
||||
assert.equal(small.getAttribute('data-l10n-id'), 'notInRange');
|
||||
});
|
||||
});
|
||||
|
||||
suite('updateNetworkSignal', function() {
|
||||
var testNetwork;
|
||||
var availableNetworks;
|
||||
var listItem;
|
||||
var networkIcon;
|
||||
|
||||
setup(function() {
|
||||
loadBodyHTML('./_wifi_utils.html');
|
||||
testNetwork = {
|
||||
ssid: 'Dummy network',
|
||||
security: ['WPA-PSK'],
|
||||
relSignalStrength: 40,
|
||||
known: false,
|
||||
};
|
||||
listItem = wifiUtils.newListItem({
|
||||
network: testNetwork
|
||||
});
|
||||
networkIcon = listItem.querySelector('aside');
|
||||
|
||||
availableNetworks = document.querySelector('ul.wifi-availableNetworks');
|
||||
availableNetworks.appendChild(listItem);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('Signal Strength changes', function() {
|
||||
assert.isTrue(networkIcon.classList.contains('level-2'));
|
||||
wifiUtils.updateNetworkSignal(testNetwork, 100);
|
||||
assert.isTrue(networkIcon.classList.contains('level-4'));
|
||||
});
|
||||
});
|
||||
|
||||
function createOption(value) {
|
||||
var dom = document.createElement('option');
|
||||
dom.text = value;
|
||||
dom.value = value;
|
||||
return dom;
|
||||
}
|
||||
});
|
||||
127
gaia/apps/settings/test/unit/panels/about/factory_reset_test.js
Executable file
127
gaia/apps/settings/test/unit/panels/about/factory_reset_test.js
Executable file
|
|
@ -0,0 +1,127 @@
|
|||
'use strict';
|
||||
|
||||
suite('about > factory_reset', function() {
|
||||
var factoryReset;
|
||||
var realNavigatorPower;
|
||||
var modules = [
|
||||
'panels/about/factory_reset'
|
||||
];
|
||||
var maps = {};
|
||||
|
||||
var MockPower = {
|
||||
factoryReset: function() {}
|
||||
};
|
||||
|
||||
var elements = {
|
||||
resetButton: document.createElement('button'),
|
||||
resetDialog: document.createElement('form'),
|
||||
resetConfirm: document.createElement('button'),
|
||||
resetCancel: document.createElement('button')
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
testRequire(modules, maps,
|
||||
function(FactoryReset) {
|
||||
realNavigatorPower = navigator.mozPower;
|
||||
navigator.mozPower = MockPower;
|
||||
|
||||
factoryReset = FactoryReset();
|
||||
elements.resetDialog.hidden = true;
|
||||
factoryReset._elements = elements;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozPower = realNavigatorPower;
|
||||
realNavigatorPower = null;
|
||||
});
|
||||
|
||||
suite('initiation', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(factoryReset, '_resetClick');
|
||||
});
|
||||
|
||||
test('resetButton is enabled when mozPower exist', function() {
|
||||
factoryReset.init(elements);
|
||||
assert.equal(factoryReset._elements.resetButton.disabled, false);
|
||||
});
|
||||
|
||||
test('resetButton is disabled when mozPower does not exist', function() {
|
||||
navigator.mozPower = null;
|
||||
factoryReset.init(elements);
|
||||
assert.equal(factoryReset._elements.resetButton.disabled, true);
|
||||
});
|
||||
|
||||
test('resetButton is enabled when mozPower exist', function() {
|
||||
factoryReset.init(elements);
|
||||
factoryReset._elements.resetButton.click();
|
||||
assert.ok(factoryReset._resetClick.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('resetClick', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(factoryReset, '_factoryReset');
|
||||
factoryReset.init(elements);
|
||||
});
|
||||
|
||||
test('resetDialog is shown when calling resetClick', function() {
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, true);
|
||||
factoryReset._resetClick();
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, false);
|
||||
});
|
||||
|
||||
test('resetDialog is hidden when cancel button is clicked', function() {
|
||||
factoryReset._resetClick();
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, false);
|
||||
factoryReset._elements.resetCancel.click();
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, true);
|
||||
});
|
||||
|
||||
test('factoryReset is called when confirm button is clicked', function() {
|
||||
factoryReset._resetClick();
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, false);
|
||||
factoryReset._elements.resetConfirm.click();
|
||||
assert.ok(factoryReset._factoryReset.called);
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, true);
|
||||
});
|
||||
|
||||
test('if mozPower is not defined, dialog is still hidden ' +
|
||||
'when confirm button is clicked', function() {
|
||||
navigator.mozPower = null;
|
||||
factoryReset._resetClick();
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, false);
|
||||
factoryReset._elements.resetConfirm.click();
|
||||
assert.ok(factoryReset._factoryReset.called);
|
||||
assert.equal(factoryReset._elements.resetDialog.hidden, true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('factoryReset', function() {
|
||||
setup(function() {
|
||||
this.sinon.spy(navigator.mozPower, 'factoryReset');
|
||||
this.sinon.stub(console, 'error');
|
||||
});
|
||||
|
||||
test('mozPower factoryReset is called', function() {
|
||||
factoryReset._factoryReset();
|
||||
assert.ok(navigator.mozPower.factoryReset.called);
|
||||
});
|
||||
|
||||
test('if mozPower is not defined, return error',
|
||||
function() {
|
||||
navigator.mozPower = null;
|
||||
factoryReset._factoryReset();
|
||||
assert.ok(console.error.calledWith('Cannot get mozPower'));
|
||||
});
|
||||
|
||||
test('if mozPower factoryReset is not defined, ' +
|
||||
'mozPower factoryReset should not be called', function() {
|
||||
navigator.mozPower.factoryReset = null;
|
||||
factoryReset._factoryReset();
|
||||
assert.ok(
|
||||
console.error.calledWith('Cannot invoke mozPower.factoryReset()'));
|
||||
});
|
||||
});
|
||||
});
|
||||
227
gaia/apps/settings/test/unit/panels/about/hardware_info_test.js
Executable file
227
gaia/apps/settings/test/unit/panels/about/hardware_info_test.js
Executable file
|
|
@ -0,0 +1,227 @@
|
|||
/* global MockNavigatorMozMobileConnections, MockNavigatorMozIccManager */
|
||||
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_navigator_moz_icc_manager.js');
|
||||
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
|
||||
|
||||
suite('about > hardware_info', function() {
|
||||
var hardwareInfo;
|
||||
var realL10n;
|
||||
var realNavigatorSettings;
|
||||
var realMobileConnections;
|
||||
var realIccManager;
|
||||
|
||||
var modules = [
|
||||
'shared_mocks/mock_l20n',
|
||||
'shared_mocks/mock_navigator_moz_settings',
|
||||
'panels/about/hardware_info'
|
||||
];
|
||||
var maps = {};
|
||||
|
||||
var elements = {
|
||||
updateStatus: document.createElement('li'),
|
||||
deviceInfoPhoneNum: document.createElement('li'),
|
||||
deviceInfoMsisdns: document.createElement('li')
|
||||
};
|
||||
|
||||
setup(function(done) {
|
||||
testRequire(modules, maps,
|
||||
function(MockL10n, MockNavigatorSettings, HardwareInfo) {
|
||||
realL10n = document.l10n;
|
||||
document.l10n = MockL10n;
|
||||
|
||||
realIccManager = navigator.mozIccManager;
|
||||
navigator.mozIccManager = MockNavigatorMozIccManager;
|
||||
|
||||
realMobileConnections = navigator.mozMobileConnections;
|
||||
navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
|
||||
|
||||
realNavigatorSettings = navigator.mozSettings;
|
||||
navigator.mozSettings = MockNavigatorSettings;
|
||||
|
||||
hardwareInfo = HardwareInfo();
|
||||
hardwareInfo._elements = elements;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
document.l10n = realL10n;
|
||||
realL10n = null;
|
||||
|
||||
navigator.mozSettings = realNavigatorSettings;
|
||||
realNavigatorSettings = null;
|
||||
|
||||
navigator.mozMobileConnections = realMobileConnections;
|
||||
realMobileConnections = null;
|
||||
|
||||
navigator.mozIccManager = realIccManager;
|
||||
realIccManager = null;
|
||||
});
|
||||
|
||||
suite('initiation', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(hardwareInfo, '_loadHardwareInfo');
|
||||
hardwareInfo.init(elements);
|
||||
});
|
||||
|
||||
test('_loadHardwareInfo and _loadLastUpdated are called while initiate',
|
||||
function() {
|
||||
assert.ok(hardwareInfo._loadHardwareInfo.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('loadHardwareInfo >', function() {
|
||||
var iccIds = ['12345', '22345'];
|
||||
|
||||
setup(function() {
|
||||
MockNavigatorMozIccManager.addIcc(iccIds[0]);
|
||||
MockNavigatorMozMobileConnections[0].iccId = iccIds[0];
|
||||
this.sinon.spy(hardwareInfo, '_renderPhoneNumberElement');
|
||||
});
|
||||
|
||||
suite('single sim', function() {
|
||||
test('the list item should be hidden when without iccinfo',
|
||||
function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo = null;
|
||||
hardwareInfo.init(elements);
|
||||
assert.isTrue(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
|
||||
test('should show unknown phone number when no msisdn and mdn',
|
||||
function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo = {};
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{}, 0, false));
|
||||
assert.isFalse(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
|
||||
test('should show correct value when with mdn', function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo =
|
||||
{ mdn: 'mdn' };
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{ mdn: 'mdn' }, 0, false));
|
||||
assert.isFalse(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
|
||||
test('should show correct value when with msisdn', function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo =
|
||||
{ msisdn: 'msisdn' };
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{ msisdn: 'msisdn' }, 0, false));
|
||||
assert.isFalse(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
});
|
||||
|
||||
suite('multiple sim', function() {
|
||||
setup(function() {
|
||||
MockNavigatorMozIccManager.addIcc(iccIds[1]);
|
||||
MockNavigatorMozMobileConnections.mAddMobileConnection();
|
||||
MockNavigatorMozMobileConnections[1].iccId = iccIds[1];
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo =
|
||||
{ mdn: 'mdn1' };
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[1]).iccInfo =
|
||||
{ mdn: 'mdn2' };
|
||||
});
|
||||
|
||||
test('the list item should be hidden when without iccinfo',
|
||||
function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo = null;
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[1]).iccInfo = null;
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.isTrue(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
|
||||
test('should show the list item when there are iccinfos', function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo = null;
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[1]).iccInfo = {};
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.isFalse(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
});
|
||||
|
||||
test('should show unknown phone number when no msisdn and mdn',
|
||||
function() {
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[0]).iccInfo = {};
|
||||
MockNavigatorMozIccManager.getIccById(iccIds[1]).iccInfo = {};
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{}, 0, true));
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{}, 1, true));
|
||||
});
|
||||
|
||||
test('should show correct sim indicator', function() {
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{ mdn: 'mdn1' }, 0, true));
|
||||
assert.ok(hardwareInfo._renderPhoneNumberElement.calledWith(
|
||||
{ mdn: 'mdn2' }, 1, true));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('_renderPhoneNumberElement >', function() {
|
||||
suite('single sim', function() {
|
||||
test('should show unknown phone number when no msisdn and mdn',
|
||||
function() {
|
||||
var span = hardwareInfo._renderPhoneNumberElement({}, 0, false);
|
||||
assert.ok(span.getAttribute('data-l10n-id', 'unknown-phoneNumber'));
|
||||
});
|
||||
|
||||
test('should show correct value when with mdn', function() {
|
||||
var span = hardwareInfo._renderPhoneNumberElement(
|
||||
{ mdn: 'mdn' }, 0, false);
|
||||
assert.equal(span.textContent, 'mdn');
|
||||
});
|
||||
|
||||
test('should show correct value when with msisdn', function() {
|
||||
var span = hardwareInfo._renderPhoneNumberElement(
|
||||
{ msisdn: 'msisdn' }, 0, false);
|
||||
assert.isFalse(hardwareInfo._elements.deviceInfoPhoneNum.hidden);
|
||||
assert.equal(span.textContent, 'msisdn');
|
||||
});
|
||||
});
|
||||
|
||||
suite('multiple sim', function() {
|
||||
test('should show unknown phone number when no msisdn and mdn',
|
||||
function() {
|
||||
this.sinon.spy(document.l10n, 'setAttributes');
|
||||
var spans0 = hardwareInfo._renderPhoneNumberElement({}, 0, true);
|
||||
assert.equal(document.l10n.setAttributes.args[0][0], spans0);
|
||||
assert.equal(document.l10n.setAttributes.args[0][1],
|
||||
'unknown-phoneNumber-sim');
|
||||
assert.equal(document.l10n.setAttributes.args[0][2].index,
|
||||
1);
|
||||
var spans1 = hardwareInfo._renderPhoneNumberElement({}, 1, true);
|
||||
assert.equal(document.l10n.setAttributes.args[1][0], spans1);
|
||||
assert.equal(document.l10n.setAttributes.args[1][1],
|
||||
'unknown-phoneNumber-sim');
|
||||
assert.equal(document.l10n.setAttributes.args[1][2].index,
|
||||
2);
|
||||
});
|
||||
|
||||
test('should show correct sim indicator', function() {
|
||||
hardwareInfo._loadHardwareInfo();
|
||||
var spans0 = hardwareInfo._renderPhoneNumberElement(
|
||||
{ mdn: 'mdn1' }, 0, true);
|
||||
var spans1 = hardwareInfo._renderPhoneNumberElement(
|
||||
{ mdn: 'mdn2' }, 1, true);
|
||||
|
||||
var sim1Args = JSON.parse(spans0.getAttribute('data-l10n-args'));
|
||||
var sim2Args = JSON.parse(spans1.getAttribute('data-l10n-args'));
|
||||
assert.equal(spans0.getAttribute('data-l10n-id'),
|
||||
'deviceInfo-MSISDN-with-index');
|
||||
assert.equal(spans1.getAttribute('data-l10n-id'),
|
||||
'deviceInfo-MSISDN-with-index');
|
||||
assert.equal(sim1Args.index, 1);
|
||||
assert.equal(sim1Args.msisdn, 'mdn1');
|
||||
assert.equal(sim2Args.index, 2);
|
||||
assert.equal(sim2Args.msisdn, 'mdn2');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue