2 QUnit
.module( 'mediawiki.api.options', QUnit
.newMwEnvironment( {
7 this.server
= this.sandbox
.useFakeServer();
8 this.server
.respondImmediately
= true;
12 QUnit
.test( 'saveOption', function ( assert
) {
13 var api
= new mw
.Api(),
14 stub
= this.sandbox
.stub( mw
.Api
.prototype, 'saveOptions' );
16 api
.saveOption( 'foo', 'bar' );
18 assert
.ok( stub
.calledOnce
, '#saveOptions called once' );
19 assert
.deepEqual( stub
.getCall( 0 ).args
, [ { foo
: 'bar' } ], '#saveOptions called correctly' );
22 QUnit
.test( 'saveOptions without Unit Separator', function ( assert
) {
23 var api
= new mw
.Api( { useUS
: false } );
25 // We need to respond to the request for token first, otherwise the other requests won't be sent
26 // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
27 api
.getToken( 'options' );
29 /meta=tokens&type=csrf/,
30 [ 200, { 'Content-Type': 'application/json' },
31 '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
34 // Requests are POST, match requestBody instead of url
35 this.server
.respond( function ( request
) {
38 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C',
40 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C',
42 'action=options&format=json&formatversion=2&optionname=foo&optionvalue=bar%7Cquux&token=%2B%5C',
43 'action=options&format=json&formatversion=2&optionname=bar&optionvalue=a%7Cb%7Cc&token=%2B%5C',
44 'action=options&format=json&formatversion=2&change=baz%3Dquux&token=%2B%5C',
46 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C',
47 // reset an option, not bundleable
48 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C'
49 ].indexOf( request
.requestBody
) !== -1 ) {
50 assert
.ok( true, 'Repond to ' + request
.requestBody
);
51 request
.respond( 200, { 'Content-Type': 'application/json' },
52 '{ "options": "success" }' );
54 assert
.ok( false, 'Unexpected request: ' + request
.requestBody
);
58 return QUnit
.whenPromisesComplete(
59 api
.saveOptions( {} ).then( function () {
60 assert
.ok( true, 'Request completed: empty case' );
62 api
.saveOptions( { foo
: 'bar' } ).then( function () {
63 assert
.ok( true, 'Request completed: simple' );
65 api
.saveOptions( { foo
: 'bar', baz
: 'quux' } ).then( function () {
66 assert
.ok( true, 'Request completed: two options' );
68 api
.saveOptions( { foo
: 'bar|quux', bar
: 'a|b|c', baz
: 'quux' } ).then( function () {
69 assert
.ok( true, 'Request completed: not bundleable' );
71 api
.saveOptions( { foo
: null } ).then( function () {
72 assert
.ok( true, 'Request completed: reset an option' );
74 api
.saveOptions( { 'foo|bar=quux': null } ).then( function () {
75 assert
.ok( true, 'Request completed: reset an option, not bundleable' );
80 QUnit
.test( 'saveOptions with Unit Separator', function ( assert
) {
81 var api
= new mw
.Api( { useUS
: true } );
83 // We need to respond to the request for token first, otherwise the other requests won't be sent
84 // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
85 api
.getToken( 'options' );
87 /meta=tokens&type=csrf/,
88 [ 200, { 'Content-Type': 'application/json' },
89 '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
92 // Requests are POST, match requestBody instead of url
93 this.server
.respond( function ( request
) {
96 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C',
98 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C',
99 // bundleable with unit separator
100 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C',
101 // not bundleable with unit separator
102 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C',
103 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C',
105 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C',
106 // reset an option, not bundleable
107 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C'
108 ].indexOf( request
.requestBody
) !== -1 ) {
109 assert
.ok( true, 'Repond to ' + request
.requestBody
);
112 { 'Content-Type': 'application/json' },
113 '{ "options": "success" }'
116 assert
.ok( false, 'Unexpected request: ' + request
.requestBody
);
120 return QUnit
.whenPromisesComplete(
121 api
.saveOptions( {} ).done( function () {
122 assert
.ok( true, 'Request completed: empty case' );
124 api
.saveOptions( { foo
: 'bar' } ).done( function () {
125 assert
.ok( true, 'Request completed: simple' );
127 api
.saveOptions( { foo
: 'bar', baz
: 'quux' } ).done( function () {
128 assert
.ok( true, 'Request completed: two options' );
130 api
.saveOptions( { foo
: 'bar|quux', bar
: 'a|b|c', baz
: 'quux' } ).done( function () {
131 assert
.ok( true, 'Request completed: bundleable with unit separator' );
133 api
.saveOptions( { foo
: 'bar|quux', bar
: 'a|b|c', 'baz=baz': 'quux' } ).done( function () {
134 assert
.ok( true, 'Request completed: not bundleable with unit separator' );
136 api
.saveOptions( { foo
: null } ).done( function () {
137 assert
.ok( true, 'Request completed: reset an option' );
139 api
.saveOptions( { 'foo|bar=quux': null } ).done( function () {
140 assert
.ok( true, 'Request completed: reset an option, not bundleable' );
145 QUnit
.test( 'saveOptions (anonymous)', function ( assert
) {
146 var promise
, test
= this;
148 mw
.config
.set( 'wgUserName', null );
149 promise
= new mw
.Api().saveOptions( { foo
: 'bar' } );
151 assert
.rejects( promise
, /notloggedin/, 'Can not save options while not logged in' );
154 .catch( function () {
155 return $.Deferred().resolve();
158 assert
.strictEqual( test
.server
.requests
.length
, 0, 'No requests made' );