Added warning for improper ending of a token
[lhc/web/wiklou.git] / tests / qunit / suites / resources / mediawiki.api / mediawiki.api.options.test.js
1 ( function ( mw ) {
2 QUnit.module( 'mediawiki.api.options', QUnit.newMwEnvironment( {
3 setup: function () {
4 this.server = this.sandbox.useFakeServer();
5 }
6 } ) );
7
8 QUnit.test( 'saveOption', function ( assert ) {
9 QUnit.expect( 2 );
10
11 var
12 api = new mw.Api(),
13 stub = this.sandbox.stub( mw.Api.prototype, 'saveOptions' );
14
15 api.saveOption( 'foo', 'bar' );
16
17 assert.ok( stub.calledOnce, '#saveOptions called once' );
18 assert.deepEqual( stub.getCall( 0 ).args, [ { foo: 'bar' } ], '#saveOptions called correctly' );
19 } );
20
21 QUnit.test( 'saveOptions without Unit Separator', function ( assert ) {
22 QUnit.expect( 13 );
23
24 var api = new mw.Api( { useUS: false } );
25
26 // We need to respond to the request for token first, otherwise the other requests won't be sent
27 // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
28 api.getToken( 'options' );
29 this.server.respond(
30 /meta=tokens&type=csrf/,
31 [ 200, { 'Content-Type': 'application/json' },
32 '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
33 );
34
35 api.saveOptions( {} ).done( function () {
36 assert.ok( true, 'Request completed: empty case' );
37 } );
38 api.saveOptions( { foo: 'bar' } ).done( function () {
39 assert.ok( true, 'Request completed: simple' );
40 } );
41 api.saveOptions( { foo: 'bar', baz: 'quux' } ).done( function () {
42 assert.ok( true, 'Request completed: two options' );
43 } );
44 api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', baz: 'quux' } ).done( function () {
45 assert.ok( true, 'Request completed: not bundleable' );
46 } );
47 api.saveOptions( { foo: null } ).done( function () {
48 assert.ok( true, 'Request completed: reset an option' );
49 } );
50 api.saveOptions( { 'foo|bar=quux': null } ).done( function () {
51 assert.ok( true, 'Request completed: reset an option, not bundleable' );
52 } );
53
54 // Requests are POST, match requestBody instead of url
55 this.server.respond( function ( request ) {
56 switch ( request.requestBody ) {
57 // simple
58 case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
59 // two options
60 case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
61 // not bundleable
62 case 'action=options&format=json&formatversion=2&optionname=foo&optionvalue=bar%7Cquux&token=%2B%5C':
63 case 'action=options&format=json&formatversion=2&optionname=bar&optionvalue=a%7Cb%7Cc&token=%2B%5C':
64 case 'action=options&format=json&formatversion=2&change=baz%3Dquux&token=%2B%5C':
65 // reset an option
66 case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
67 // reset an option, not bundleable
68 case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
69 assert.ok( true, 'Repond to ' + request.requestBody );
70 request.respond( 200, { 'Content-Type': 'application/json' },
71 '{ "options": "success" }' );
72 break;
73 default:
74 assert.ok( false, 'Unexpected request: ' + request.requestBody );
75 }
76 } );
77 } );
78
79 QUnit.test( 'saveOptions with Unit Separator', function ( assert ) {
80 QUnit.expect( 14 );
81
82 var api = new mw.Api( { useUS: true } );
83
84 // We need to respond to the request for token first, otherwise the other requests won't be sent
85 // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
86 api.getToken( 'options' );
87 this.server.respond(
88 /meta=tokens&type=csrf/,
89 [ 200, { 'Content-Type': 'application/json' },
90 '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
91 );
92
93 api.saveOptions( {} ).done( function () {
94 assert.ok( true, 'Request completed: empty case' );
95 } );
96 api.saveOptions( { foo: 'bar' } ).done( function () {
97 assert.ok( true, 'Request completed: simple' );
98 } );
99 api.saveOptions( { foo: 'bar', baz: 'quux' } ).done( function () {
100 assert.ok( true, 'Request completed: two options' );
101 } );
102 api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', baz: 'quux' } ).done( function () {
103 assert.ok( true, 'Request completed: bundleable with unit separator' );
104 } );
105 api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', 'baz=baz': 'quux' } ).done( function () {
106 assert.ok( true, 'Request completed: not bundleable with unit separator' );
107 } );
108 api.saveOptions( { foo: null } ).done( function () {
109 assert.ok( true, 'Request completed: reset an option' );
110 } );
111 api.saveOptions( { 'foo|bar=quux': null } ).done( function () {
112 assert.ok( true, 'Request completed: reset an option, not bundleable' );
113 } );
114
115 // Requests are POST, match requestBody instead of url
116 this.server.respond( function ( request ) {
117 switch ( request.requestBody ) {
118 // simple
119 case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
120 // two options
121 case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
122 // bundleable with unit separator
123 case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C':
124 // not bundleable with unit separator
125 case 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C':
126 case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C':
127 // reset an option
128 case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
129 // reset an option, not bundleable
130 case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
131 assert.ok( true, 'Repond to ' + request.requestBody );
132 request.respond( 200, { 'Content-Type': 'application/json' },
133 '{ "options": "success" }' );
134 break;
135 default:
136 assert.ok( false, 'Unexpected request: ' + request.requestBody );
137 }
138 } );
139 } );
140 }( mediaWiki ) );