You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sharedialogviewSpec.js 66KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600
  1. /**
  2. * ownCloud
  3. *
  4. * @author Vincent Petry
  5. * @copyright 2015 Vincent Petry <pvince81@owncloud.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  9. * License as published by the Free Software Foundation; either
  10. * version 3 of the License, or any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public
  18. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. /* global sinon, OC */
  22. describe('OC.Share.ShareDialogView', function() {
  23. var $container;
  24. var oldConfig;
  25. var oldAppConfig;
  26. var autocompleteStub;
  27. var avatarStub;
  28. var placeholderStub;
  29. var oldCurrentUser;
  30. var saveLinkShareStub;
  31. var fetchStub;
  32. var configModel;
  33. var shareModel;
  34. var fileInfoModel;
  35. var dialog;
  36. beforeEach(function() {
  37. // horrible parameters
  38. $('#testArea').append('<input id="allowShareWithLink" type="hidden" value="yes">');
  39. $container = $('#shareContainer');
  40. oldConfig = OC.config;
  41. OC.config['sharing.maxAutocompleteResults'] = 0;
  42. /* jshint camelcase:false */
  43. oldAppConfig = _.extend({}, OC.appConfig.core);
  44. OC.appConfig.core.enforcePasswordForPublicLink = false;
  45. fetchStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'fetch');
  46. saveLinkShareStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'saveLinkShare');
  47. fileInfoModel = new OCA.Files.FileInfoModel({
  48. id: 123,
  49. name: 'shared_file_name.txt',
  50. path: '/subdir',
  51. size: 100,
  52. mimetype: 'text/plain',
  53. permissions: 31,
  54. sharePermissions: 31
  55. });
  56. var attributes = {
  57. itemType: fileInfoModel.isDirectory() ? 'folder' : 'file',
  58. itemSource: fileInfoModel.get('id'),
  59. possiblePermissions: 31,
  60. permissions: 31
  61. };
  62. configModel = new OC.Share.ShareConfigModel({
  63. enforcePasswordForPublicLink: false,
  64. isResharingAllowed: true,
  65. isDefaultExpireDateEnabled: false,
  66. isDefaultExpireDateEnforced: false,
  67. defaultExpireDate: 7
  68. });
  69. shareModel = new OC.Share.ShareItemModel(attributes, {
  70. configModel: configModel,
  71. fileInfoModel: fileInfoModel
  72. });
  73. dialog = new OC.Share.ShareDialogView({
  74. configModel: configModel,
  75. model: shareModel
  76. });
  77. // required for proper event propagation when simulating clicks in some cases (jquery bugs)
  78. $('#testArea').append(dialog.$el);
  79. // triggers rendering
  80. shareModel.set({
  81. shares: [],
  82. linkShares: []
  83. });
  84. autocompleteStub = sinon.stub($.fn, 'autocomplete').callsFake(function() {
  85. // dummy container with the expected attributes
  86. if (!$(this).length) {
  87. // simulate the real autocomplete that returns
  88. // nothing at all when no element is specified
  89. // (and potentially break stuff)
  90. return null;
  91. }
  92. var $el = $('<div></div>').data('ui-autocomplete', {});
  93. return $el;
  94. });
  95. avatarStub = sinon.stub($.fn, 'avatar');
  96. placeholderStub = sinon.stub($.fn, 'imageplaceholder');
  97. oldCurrentUser = OC.currentUser;
  98. OC.currentUser = 'user0';
  99. });
  100. afterEach(function() {
  101. OC.currentUser = oldCurrentUser;
  102. OC.config = oldConfig;
  103. /* jshint camelcase:false */
  104. OC.appConfig.core = oldAppConfig;
  105. dialog.remove();
  106. fetchStub.restore();
  107. saveLinkShareStub.restore();
  108. autocompleteStub.restore();
  109. avatarStub.restore();
  110. placeholderStub.restore();
  111. });
  112. describe('Share with link', function() {
  113. // TODO: test ajax calls
  114. // TODO: test password field visibility (whenever enforced or not)
  115. it('update password on enter', function() {
  116. $('#allowShareWithLink').val('yes');
  117. dialog.model.set({
  118. linkShares: [{
  119. id: 123
  120. }]
  121. });
  122. dialog.render();
  123. // Enable password and enter password
  124. dialog.$el.find('[name=showPassword]').click();
  125. dialog.$el.find('.linkPassText').focus();
  126. dialog.$el.find('.linkPassText').val('foo');
  127. dialog.$el.find('.linkPassText').trigger(new $.Event('keyup', {keyCode: 13}));
  128. expect(saveLinkShareStub.calledOnce).toEqual(true);
  129. expect(saveLinkShareStub.firstCall.args[0]).toEqual({
  130. cid: 123,
  131. password: 'foo'
  132. });
  133. });
  134. it('update password on submit', function() {
  135. $('#allowShareWithLink').val('yes');
  136. dialog.model.set({
  137. linkShares: [{
  138. id: 123
  139. }]
  140. });
  141. dialog.render();
  142. // Enable password and enter password
  143. dialog.$el.find('[name=showPassword]').click();
  144. dialog.$el.find('.linkPassText').focus();
  145. dialog.$el.find('.linkPassText').val('foo');
  146. dialog.$el.find('.linkPassText + .icon-confirm').click();
  147. expect(saveLinkShareStub.calledOnce).toEqual(true);
  148. expect(saveLinkShareStub.firstCall.args[0]).toEqual({
  149. cid: 123,
  150. password: 'foo'
  151. });
  152. });
  153. it('shows add share with link button when allowed', function() {
  154. $('#allowShareWithLink').val('yes');
  155. dialog.render();
  156. expect(dialog.$el.find('.new-share').length).toEqual(1);
  157. });
  158. it('does not show add share with link button when not allowed', function() {
  159. $('#allowShareWithLink').val('no');
  160. dialog.render();
  161. expect(dialog.$el.find('.new-share').length).toEqual(0);
  162. expect(dialog.$el.find('.shareWithField').length).toEqual(1);
  163. });
  164. it('shows populated link share when a link share exists', function() {
  165. // this is how the OC.Share class does it...
  166. var link = parent.location.protocol + '//' + location.host +
  167. OC.generateUrl('/s/') + 'thetoken';
  168. shareModel.set({
  169. linkShares: [{
  170. id: 123,
  171. url: link
  172. }]
  173. });
  174. dialog.render();
  175. expect(dialog.$el.find('.share-menu .icon-more').length).toEqual(1);
  176. expect(dialog.$el.find('.linkText').val()).toEqual(link);
  177. });
  178. it('autofocus link text when clicked', function() {
  179. $('#allowShareWithLink').val('yes');
  180. dialog.model.set({
  181. linkShares: [{
  182. id: 123
  183. }]
  184. });
  185. dialog.render();
  186. var focusStub = sinon.stub($.fn, 'focus');
  187. var selectStub = sinon.stub($.fn, 'select');
  188. dialog.$el.find('.linkText').click();
  189. expect(focusStub.calledOnce).toEqual(true);
  190. expect(selectStub.calledOnce).toEqual(true);
  191. focusStub.restore();
  192. selectStub.restore();
  193. });
  194. });
  195. describe('check for avatar', function() {
  196. beforeEach(function() {
  197. shareModel.set({
  198. reshare: {
  199. share_type: OC.Share.SHARE_TYPE_USER,
  200. uid_owner: 'owner',
  201. displayname_owner: 'Owner',
  202. permissions: 31
  203. },
  204. shares: [{
  205. id: 100,
  206. item_source: 123,
  207. permissions: 31,
  208. share_type: OC.Share.SHARE_TYPE_USER,
  209. share_with: 'user1',
  210. share_with_displayname: 'User One'
  211. },{
  212. id: 101,
  213. item_source: 123,
  214. permissions: 31,
  215. share_type: OC.Share.SHARE_TYPE_GROUP,
  216. share_with: 'group',
  217. share_with_displayname: 'group'
  218. },{
  219. id: 102,
  220. item_source: 123,
  221. permissions: 31,
  222. share_type: OC.Share.SHARE_TYPE_REMOTE,
  223. share_with: 'foo@bar.com/baz',
  224. share_with_displayname: 'foo@bar.com/baz'
  225. },{
  226. id: 103,
  227. item_source: 123,
  228. permissions: 31,
  229. share_type: OC.Share.SHARE_TYPE_CIRCLE,
  230. share_with: 'circle-0',
  231. share_with_displayname: 'Circle (Personal circle, user0)',
  232. share_with_avatar: 'path/to/the/avatar'
  233. },{
  234. id: 104,
  235. item_source: 123,
  236. permissions: 31,
  237. share_type: OC.Share.SHARE_TYPE_CIRCLE,
  238. share_with: 'circle-1',
  239. share_with_displayname: 'Circle (Public circle, user0)',
  240. }]
  241. });
  242. });
  243. describe('avatars enabled', function() {
  244. beforeEach(function() {
  245. avatarStub.reset();
  246. dialog.render();
  247. });
  248. it('test correct function calls', function() {
  249. expect(avatarStub.calledThrice).toEqual(true);
  250. expect(placeholderStub.callCount).toEqual(4);
  251. expect(dialog.$('.shareWithList').children().length).toEqual(6);
  252. expect(dialog.$('.avatar').length).toEqual(7);
  253. });
  254. it('test avatar owner', function() {
  255. var args = avatarStub.getCall(0).args;
  256. expect(args.length).toEqual(2);
  257. expect(args[0]).toEqual('owner');
  258. });
  259. it('test avatar user', function() {
  260. var args = avatarStub.getCall(1).args;
  261. expect(args.length).toEqual(6);
  262. expect(args[0]).toEqual('user1');
  263. expect(args[5]).toEqual('User One');
  264. });
  265. it('test avatar for groups', function() {
  266. var args = placeholderStub.getCall(0).args;
  267. expect(args.length).toEqual(1);
  268. expect(args[0]).toEqual('group ' + OC.Share.SHARE_TYPE_GROUP);
  269. });
  270. it('test avatar for remotes', function() {
  271. var args = placeholderStub.getCall(1).args;
  272. expect(args.length).toEqual(1);
  273. expect(args[0]).toEqual('foo@bar.com/baz ' + OC.Share.SHARE_TYPE_REMOTE);
  274. });
  275. it('test avatar for circle', function() {
  276. var avatarElement = dialog.$('.avatar').eq(5);
  277. expect(avatarElement.css('background')).toContain('path/to/the/avatar');
  278. });
  279. it('test avatar for circle without avatar', function() {
  280. var args = avatarStub.getCall(2).args;
  281. expect(args.length).toEqual(6);
  282. // Note that "data-username" is set to "circle-{shareIndex}",
  283. // not to the "shareWith" field.
  284. expect(args[0]).toEqual('circle-4');
  285. expect(args[5]).toEqual('Circle (Public circle, user0)');
  286. });
  287. });
  288. });
  289. describe('get suggestions', function() {
  290. it('no matches', function() {
  291. var doneStub = sinon.stub();
  292. var failStub = sinon.stub();
  293. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  294. var jsonData = JSON.stringify({
  295. 'ocs': {
  296. 'meta': {
  297. 'status': 'success',
  298. 'statuscode': 100,
  299. 'message': null
  300. },
  301. 'data': {
  302. 'exact': {
  303. 'users': [],
  304. 'groups': [],
  305. 'remotes': [],
  306. 'remote_groups': [],
  307. },
  308. 'users': [],
  309. 'groups': [],
  310. 'remotes': [],
  311. 'remote_groups': [],
  312. 'lookup': [],
  313. 'lookupEnabled': true,
  314. }
  315. }
  316. });
  317. expect(doneStub.called).toEqual(false);
  318. expect(failStub.called).toEqual(false);
  319. fakeServer.requests[0].respond(
  320. 200,
  321. {'Content-Type': 'application/json'},
  322. jsonData
  323. );
  324. expect(doneStub.calledOnce).toEqual(true);
  325. sinon.assert.calledWithExactly(doneStub, [{
  326. label: t('core', 'Search globally'),
  327. value: {},
  328. lookup: true
  329. }], [], false, true);
  330. expect(failStub.called).toEqual(false);
  331. });
  332. it('single partial match', function() {
  333. var doneStub = sinon.stub();
  334. var failStub = sinon.stub();
  335. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  336. var jsonData = JSON.stringify({
  337. 'ocs': {
  338. 'meta': {
  339. 'status': 'success',
  340. 'statuscode': 100,
  341. 'message': null
  342. },
  343. 'data': {
  344. 'exact': {
  345. 'users': [],
  346. 'groups': [],
  347. 'remotes': [],
  348. 'remote_groups': [],
  349. },
  350. 'users': [
  351. {
  352. 'label': 'bobby',
  353. 'value': {
  354. 'shareType': OC.Share.SHARE_TYPE_USER,
  355. 'shareWith': 'imbob'
  356. }
  357. }
  358. ],
  359. 'groups': [],
  360. 'remotes': [],
  361. 'remote_groups': [],
  362. 'lookup': [],
  363. 'lookupEnabled': true,
  364. }
  365. }
  366. });
  367. expect(doneStub.called).toEqual(false);
  368. expect(failStub.called).toEqual(false);
  369. fakeServer.requests[0].respond(
  370. 200,
  371. {'Content-Type': 'application/json'},
  372. jsonData
  373. );
  374. expect(doneStub.calledOnce).toEqual(true);
  375. sinon.assert.calledWithExactly(doneStub,
  376. [{
  377. 'label': 'bobby',
  378. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  379. },
  380. {
  381. label: t('core', 'Search globally'),
  382. value: {},
  383. lookup: true
  384. }],
  385. [],
  386. false,
  387. true
  388. );
  389. expect(failStub.called).toEqual(false);
  390. });
  391. it('single exact match', function() {
  392. var doneStub = sinon.stub();
  393. var failStub = sinon.stub();
  394. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  395. var jsonData = JSON.stringify({
  396. 'ocs': {
  397. 'meta': {
  398. 'status': 'success',
  399. 'statuscode': 100,
  400. 'message': null
  401. },
  402. 'data': {
  403. 'exact': {
  404. 'users': [
  405. {
  406. 'label': 'bob',
  407. 'value': {
  408. 'shareType': OC.Share.SHARE_TYPE_USER,
  409. 'shareWith': 'user1'
  410. }
  411. }
  412. ],
  413. 'groups': [],
  414. 'remotes': [],
  415. 'remote_groups': [],
  416. },
  417. 'users': [],
  418. 'groups': [],
  419. 'remotes': [],
  420. 'remote_groups': [],
  421. 'lookup': [],
  422. 'lookupEnabled': true,
  423. }
  424. }
  425. });
  426. expect(doneStub.called).toEqual(false);
  427. expect(failStub.called).toEqual(false);
  428. fakeServer.requests[0].respond(
  429. 200,
  430. {'Content-Type': 'application/json'},
  431. jsonData
  432. );
  433. expect(doneStub.calledOnce).toEqual(true);
  434. sinon.assert.calledWithExactly(doneStub,
  435. [{
  436. 'label': 'bob',
  437. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  438. },
  439. {
  440. label: t('core', 'Search globally'),
  441. value: {},
  442. lookup: true
  443. }],
  444. [{
  445. 'label': 'bob',
  446. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  447. }],
  448. false,
  449. true
  450. );
  451. expect(failStub.called).toEqual(false);
  452. });
  453. it('mixed matches', function() {
  454. var doneStub = sinon.stub();
  455. var failStub = sinon.stub();
  456. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  457. var jsonData = JSON.stringify({
  458. 'ocs': {
  459. 'meta': {
  460. 'status': 'success',
  461. 'statuscode': 100,
  462. 'message': null
  463. },
  464. 'data': {
  465. 'exact': {
  466. 'users': [
  467. {
  468. 'label': 'bob',
  469. 'value': {
  470. 'shareType': OC.Share.SHARE_TYPE_USER,
  471. 'shareWith': 'user1'
  472. }
  473. }
  474. ],
  475. 'groups': [
  476. {
  477. 'label': 'bob',
  478. 'value': {
  479. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  480. 'shareWith': 'group1'
  481. }
  482. }
  483. ],
  484. 'remotes': [],
  485. 'remote_groups': [],
  486. },
  487. 'users': [
  488. {
  489. 'label': 'bobby',
  490. 'value': {
  491. 'shareType': OC.Share.SHARE_TYPE_USER,
  492. 'shareWith': 'imbob'
  493. }
  494. },
  495. {
  496. 'label': 'bob the second',
  497. 'value': {
  498. 'shareType': OC.Share.SHARE_TYPE_USER,
  499. 'shareWith': 'user2'
  500. }
  501. }
  502. ],
  503. 'groups': [
  504. {
  505. 'label': 'bobfans',
  506. 'value': {
  507. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  508. 'shareWith': 'fans'
  509. }
  510. }
  511. ],
  512. 'remotes': [],
  513. 'remote_groups': [],
  514. 'lookup': [],
  515. 'lookupEnabled': true
  516. }
  517. }
  518. });
  519. expect(doneStub.called).toEqual(false);
  520. expect(failStub.called).toEqual(false);
  521. fakeServer.requests[0].respond(
  522. 200,
  523. {'Content-Type': 'application/json'},
  524. jsonData
  525. );
  526. expect(doneStub.calledOnce).toEqual(true);
  527. sinon.assert.calledWithExactly(doneStub,
  528. [{
  529. 'label': 'bob',
  530. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  531. }, {
  532. 'label': 'bob',
  533. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
  534. }, {
  535. 'label': 'bobby',
  536. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  537. }, {
  538. 'label': 'bob the second',
  539. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user2'}
  540. }, {
  541. 'label': 'bobfans',
  542. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'}
  543. },
  544. {
  545. label: t('core', 'Search globally'),
  546. value: {},
  547. lookup: true
  548. }],
  549. [{
  550. 'label': 'bob',
  551. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  552. }, {
  553. 'label': 'bob',
  554. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
  555. }],
  556. false,
  557. true
  558. );
  559. expect(failStub.called).toEqual(false);
  560. });
  561. it('capped mixed matches', function() {
  562. OC.config['sharing.maxAutocompleteResults'] = 3;
  563. var doneStub = sinon.stub();
  564. var failStub = sinon.stub();
  565. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  566. var jsonData = JSON.stringify({
  567. 'ocs': {
  568. 'meta': {
  569. 'status': 'success',
  570. 'statuscode': 100,
  571. 'message': null
  572. },
  573. 'data': {
  574. 'exact': {
  575. 'users': [
  576. {
  577. 'label': 'bob',
  578. 'value': {
  579. 'shareType': OC.Share.SHARE_TYPE_USER,
  580. 'shareWith': 'user1'
  581. }
  582. }
  583. ],
  584. 'groups': [
  585. {
  586. 'label': 'bob',
  587. 'value': {
  588. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  589. 'shareWith': 'group1'
  590. }
  591. }
  592. ],
  593. 'remotes': [],
  594. 'remote_groups': [],
  595. },
  596. 'users': [
  597. {
  598. 'label': 'bobby',
  599. 'value': {
  600. 'shareType': OC.Share.SHARE_TYPE_USER,
  601. 'shareWith': 'imbob'
  602. }
  603. },
  604. {
  605. 'label': 'bob the second',
  606. 'value': {
  607. 'shareType': OC.Share.SHARE_TYPE_USER,
  608. 'shareWith': 'user2'
  609. }
  610. }
  611. ],
  612. 'groups': [
  613. {
  614. 'label': 'bobfans',
  615. 'value': {
  616. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  617. 'shareWith': 'fans'
  618. }
  619. }
  620. ],
  621. 'remotes': [],
  622. 'remote_groups': [],
  623. 'lookup': [],
  624. 'lookupEnabled': true
  625. }
  626. }
  627. });
  628. expect(doneStub.called).toEqual(false);
  629. expect(failStub.called).toEqual(false);
  630. fakeServer.requests[0].respond(
  631. 200,
  632. {'Content-Type': 'application/json'},
  633. jsonData
  634. );
  635. expect(doneStub.calledOnce).toEqual(true);
  636. sinon.assert.calledWithExactly(doneStub,
  637. [{
  638. 'label': 'bob',
  639. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  640. }, {
  641. 'label': 'bob',
  642. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
  643. }, {
  644. 'label': 'bobby',
  645. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  646. }, {
  647. 'label': 'bob the second',
  648. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user2'}
  649. }, {
  650. 'label': 'bobfans',
  651. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'}
  652. },
  653. {
  654. label: t('core', 'Search globally'),
  655. value: {},
  656. lookup: true
  657. }],
  658. [{
  659. 'label': 'bob',
  660. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  661. }, {
  662. 'label': 'bob',
  663. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
  664. }],
  665. true,
  666. true
  667. );
  668. expect(failStub.called).toEqual(false);
  669. });
  670. it('does not send a request to the server again for the same parameters', function() {
  671. var doneStub = sinon.stub();
  672. var failStub = sinon.stub();
  673. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  674. var jsonData = JSON.stringify({
  675. 'ocs': {
  676. 'meta': {
  677. 'status': 'success',
  678. 'statuscode': 100,
  679. 'message': null
  680. },
  681. 'data': {
  682. 'exact': {
  683. 'users': [
  684. {
  685. 'label': 'bob',
  686. 'value': {
  687. 'shareType': OC.Share.SHARE_TYPE_USER,
  688. 'shareWith': 'user1'
  689. }
  690. }
  691. ],
  692. 'groups': [],
  693. 'remotes': [],
  694. 'remote_groups': [],
  695. },
  696. 'users': [],
  697. 'groups': [],
  698. 'remotes': [],
  699. 'remote_groups': [],
  700. 'lookup': [],
  701. 'lookupEnabled': true
  702. }
  703. }
  704. });
  705. expect(doneStub.called).toEqual(false);
  706. expect(failStub.called).toEqual(false);
  707. fakeServer.requests[0].respond(
  708. 200,
  709. {'Content-Type': 'application/json'},
  710. jsonData
  711. );
  712. expect(doneStub.calledOnce).toEqual(true);
  713. expect(doneStub.calledWithExactly(
  714. [{
  715. 'label': 'bob',
  716. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  717. },
  718. {
  719. label: t('core', 'Search globally'),
  720. value: {},
  721. lookup: true
  722. }],
  723. [{
  724. 'label': 'bob',
  725. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  726. }],
  727. false,
  728. true
  729. )).toEqual(true);
  730. expect(failStub.called).toEqual(false);
  731. var done2Stub = sinon.stub();
  732. var fail2Stub = sinon.stub();
  733. dialog._getSuggestions('bob', 42, shareModel).done(done2Stub).fail(fail2Stub);
  734. expect(doneStub.calledOnce).toEqual(true);
  735. expect(failStub.called).toEqual(false);
  736. expect(done2Stub.calledOnce).toEqual(true);
  737. sinon.assert.calledWithExactly(doneStub,
  738. [{
  739. 'label': 'bob',
  740. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  741. },
  742. {
  743. label: t('core', 'Search globally'),
  744. value: {},
  745. lookup: true
  746. }],
  747. [{
  748. 'label': 'bob',
  749. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  750. }],
  751. false,
  752. true
  753. );
  754. expect(fail2Stub.called).toEqual(false);
  755. });
  756. it('sends a request to the server again for the same parameters if the calls are not consecutive', function() {
  757. var doneStub = sinon.stub();
  758. var failStub = sinon.stub();
  759. dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub);
  760. var jsonData = JSON.stringify({
  761. 'ocs': {
  762. 'meta': {
  763. 'status': 'success',
  764. 'statuscode': 100,
  765. 'message': null
  766. },
  767. 'data': {
  768. 'exact': {
  769. 'users': [
  770. {
  771. 'label': 'bob',
  772. 'value': {
  773. 'shareType': OC.Share.SHARE_TYPE_USER,
  774. 'shareWith': 'user1'
  775. }
  776. }
  777. ],
  778. 'groups': [],
  779. 'remotes': [],
  780. 'remote_groups': [],
  781. },
  782. 'users': [],
  783. 'groups': [],
  784. 'remotes': [],
  785. 'remote_groups': [],
  786. 'lookup': [],
  787. 'lookupEnabled': true
  788. }
  789. }
  790. });
  791. expect(doneStub.called).toEqual(false);
  792. expect(failStub.called).toEqual(false);
  793. fakeServer.requests[0].respond(
  794. 200,
  795. {'Content-Type': 'application/json'},
  796. jsonData
  797. );
  798. expect(doneStub.calledOnce).toEqual(true);
  799. sinon.assert.calledWithExactly(doneStub,
  800. [{
  801. 'label': 'bob',
  802. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  803. },
  804. {
  805. label: t('core', 'Search globally'),
  806. value: {},
  807. lookup: true
  808. }],
  809. [{
  810. 'label': 'bob',
  811. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  812. }],
  813. false,
  814. true
  815. );
  816. expect(failStub.called).toEqual(false);
  817. var done2Stub = sinon.stub();
  818. var fail2Stub = sinon.stub();
  819. dialog._getSuggestions('bob', 108, shareModel).done(done2Stub).fail(fail2Stub);
  820. expect(done2Stub.called).toEqual(false);
  821. expect(fail2Stub.called).toEqual(false);
  822. fakeServer.requests[1].respond(
  823. 200,
  824. {'Content-Type': 'application/json'},
  825. jsonData
  826. );
  827. expect(done2Stub.calledOnce).toEqual(true);
  828. expect(fail2Stub.called).toEqual(false);
  829. var done3Stub = sinon.stub();
  830. var fail3Stub = sinon.stub();
  831. dialog._getSuggestions('bob', 42, shareModel).done(done3Stub).fail(fail3Stub);
  832. expect(done3Stub.called).toEqual(false);
  833. expect(fail3Stub.called).toEqual(false);
  834. fakeServer.requests[2].respond(
  835. 200,
  836. {'Content-Type': 'application/json'},
  837. jsonData
  838. );
  839. expect(doneStub.calledOnce).toEqual(true);
  840. expect(failStub.called).toEqual(false);
  841. expect(done2Stub.calledOnce).toEqual(true);
  842. expect(fail2Stub.called).toEqual(false);
  843. expect(done3Stub.calledOnce).toEqual(true);
  844. sinon.assert.calledWithExactly(done3Stub,
  845. [{
  846. 'label': 'bob',
  847. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  848. },
  849. {
  850. label: t('core', 'Search globally'),
  851. value: {},
  852. lookup: true
  853. }],
  854. [{
  855. 'label': 'bob',
  856. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  857. }],
  858. false,
  859. true
  860. );
  861. expect(fail3Stub.called).toEqual(false);
  862. });
  863. });
  864. describe('autocompletion of users', function() {
  865. var showTemporaryNotificationStub;
  866. beforeEach(function() {
  867. showTemporaryNotificationStub = sinon.stub(OC.Notification, 'showTemporary');
  868. });
  869. afterEach(function() {
  870. showTemporaryNotificationStub.restore();
  871. });
  872. describe('triggers autocomplete display and focus with data when ajax search succeeds', function () {
  873. it('users', function () {
  874. dialog.render();
  875. var response = sinon.stub();
  876. dialog.autocompleteHandler({term: 'bob'}, response);
  877. var jsonData = JSON.stringify({
  878. 'ocs': {
  879. 'meta': {
  880. 'status': 'success',
  881. 'statuscode': 100,
  882. 'message': null
  883. },
  884. 'data': {
  885. 'exact': {
  886. 'users': [
  887. {
  888. 'label': 'bob',
  889. 'value': {
  890. 'shareType': OC.Share.SHARE_TYPE_USER,
  891. 'shareWith': 'user1'
  892. }
  893. }
  894. ],
  895. 'groups': [],
  896. 'remotes': [],
  897. 'remote_groups': [],
  898. },
  899. 'users': [
  900. {
  901. 'label': 'bobby',
  902. 'value': {
  903. 'shareType': OC.Share.SHARE_TYPE_USER,
  904. 'shareWith': 'imbob'
  905. }
  906. }
  907. ],
  908. 'groups': [],
  909. 'remotes': [],
  910. 'remote_groups': [],
  911. 'lookup': [],
  912. 'lookupEnabled': true
  913. }
  914. }
  915. });
  916. fakeServer.requests[0].respond(
  917. 200,
  918. {'Content-Type': 'application/json'},
  919. jsonData
  920. );
  921. sinon.assert.calledWithExactly(response, [{
  922. 'label': 'bob',
  923. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
  924. }, {
  925. 'label': 'bobby',
  926. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  927. }, {
  928. label: t('core', 'Search globally'),
  929. value: {},
  930. lookup: true
  931. }]);
  932. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  933. });
  934. it('groups', function () {
  935. dialog.render();
  936. var response = sinon.stub();
  937. dialog.autocompleteHandler({term: 'group'}, response);
  938. var jsonData = JSON.stringify({
  939. 'ocs': {
  940. 'meta': {
  941. 'status': 'success',
  942. 'statuscode': 100,
  943. 'message': null
  944. },
  945. 'data': {
  946. 'exact': {
  947. 'users': [],
  948. 'groups': [
  949. {
  950. 'label': 'group',
  951. 'value': {
  952. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  953. 'shareWith': 'group'
  954. }
  955. }
  956. ],
  957. 'remotes': [],
  958. 'remote_groups': [],
  959. },
  960. 'users': [],
  961. 'groups': [
  962. {
  963. 'label': 'group2',
  964. 'value': {
  965. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  966. 'shareWith': 'group2'
  967. }
  968. }
  969. ],
  970. 'remotes': [],
  971. 'remote_groups': [],
  972. 'lookup': [],
  973. 'lookupEnabled': true
  974. }
  975. }
  976. });
  977. fakeServer.requests[0].respond(
  978. 200,
  979. {'Content-Type': 'application/json'},
  980. jsonData
  981. );
  982. sinon.assert.calledWithExactly(response, [{
  983. 'label': 'group',
  984. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group'}
  985. }, {
  986. 'label': 'group2',
  987. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'}
  988. }, {
  989. label: t('core', 'Search globally'),
  990. value: {},
  991. lookup: true
  992. }]);
  993. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  994. });
  995. it('remotes', function () {
  996. dialog.render();
  997. var response = sinon.stub();
  998. dialog.autocompleteHandler({term: 'foo@bar.com/baz'}, response);
  999. var jsonData = JSON.stringify({
  1000. 'ocs': {
  1001. 'meta': {
  1002. 'status': 'success',
  1003. 'statuscode': 100,
  1004. 'message': null
  1005. },
  1006. 'data': {
  1007. 'exact': {
  1008. 'users': [],
  1009. 'groups': [],
  1010. 'remotes': [
  1011. {
  1012. 'label': 'foo@bar.com/baz',
  1013. 'value': {
  1014. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1015. 'shareWith': 'foo@bar.com/baz'
  1016. }
  1017. }
  1018. ],
  1019. 'remote_groups': [],
  1020. },
  1021. 'users': [],
  1022. 'groups': [],
  1023. 'remotes': [
  1024. {
  1025. 'label': 'foo@bar.com/baz2',
  1026. 'value': {
  1027. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1028. 'shareWith': 'foo@bar.com/baz2'
  1029. }
  1030. }
  1031. ],
  1032. 'remote_groups': [],
  1033. 'lookup': []
  1034. }
  1035. }
  1036. });
  1037. fakeServer.requests[0].respond(
  1038. 200,
  1039. {'Content-Type': 'application/json'},
  1040. jsonData
  1041. );
  1042. expect(response.calledWithExactly([{
  1043. 'label': 'foo@bar.com/baz',
  1044. 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz'}
  1045. }, {
  1046. 'label': 'foo@bar.com/baz2',
  1047. 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'}
  1048. }])).toEqual(true);
  1049. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1050. });
  1051. it('emails', function () {
  1052. dialog.render();
  1053. var response = sinon.stub();
  1054. dialog.autocompleteHandler({term: 'foo@bar.com'}, response);
  1055. var jsonData = JSON.stringify({
  1056. 'ocs': {
  1057. 'meta': {
  1058. 'status': 'success',
  1059. 'statuscode': 100,
  1060. 'message': null
  1061. },
  1062. 'data': {
  1063. 'exact': {
  1064. 'users': [],
  1065. 'groups': [],
  1066. 'remotes': [],
  1067. 'remote_groups': [],
  1068. 'emails': [
  1069. {
  1070. 'label': 'foo@bar.com',
  1071. 'value': {
  1072. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1073. 'shareWith': 'foo@bar.com'
  1074. }
  1075. }
  1076. ]
  1077. },
  1078. 'users': [],
  1079. 'groups': [],
  1080. 'remotes': [],
  1081. 'remote_groups': [],
  1082. 'lookup': [],
  1083. 'emails': [
  1084. {
  1085. 'label': 'foo@bar.com2',
  1086. 'value': {
  1087. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1088. 'shareWith': 'foo@bar.com2'
  1089. }
  1090. }
  1091. ]
  1092. }
  1093. }
  1094. });
  1095. fakeServer.requests[0].respond(
  1096. 200,
  1097. {'Content-Type': 'application/json'},
  1098. jsonData
  1099. );
  1100. expect(response.calledWithExactly([{
  1101. 'label': 'foo@bar.com',
  1102. 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com'}
  1103. }, {
  1104. 'label': 'foo@bar.com2',
  1105. 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'}
  1106. }])).toEqual(true);
  1107. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1108. });
  1109. it('circles', function () {
  1110. dialog.render();
  1111. var response = sinon.stub();
  1112. dialog.autocompleteHandler({term: 'CircleName'}, response);
  1113. var jsonData = JSON.stringify({
  1114. 'ocs': {
  1115. 'meta': {
  1116. 'status': 'success',
  1117. 'statuscode': 100,
  1118. 'message': null
  1119. },
  1120. 'data': {
  1121. 'exact': {
  1122. 'users': [],
  1123. 'groups': [],
  1124. 'remotes': [],
  1125. 'remote_groups': [],
  1126. 'circles': [
  1127. {
  1128. 'label': 'CircleName (type, owner)',
  1129. 'value': {
  1130. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1131. 'shareWith': 'shortId'
  1132. }
  1133. },
  1134. {
  1135. 'label': 'CircleName (type2, owner)',
  1136. 'value': {
  1137. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1138. 'shareWith': 'shortId2'
  1139. }
  1140. }
  1141. ]
  1142. },
  1143. 'users': [],
  1144. 'groups': [],
  1145. 'remotes': [],
  1146. 'remote_groups': [],
  1147. 'lookup': [],
  1148. 'circles': [
  1149. {
  1150. 'label': 'CircleName2 (type, owner)',
  1151. 'value': {
  1152. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1153. 'shareWith': 'shortId3'
  1154. }
  1155. }
  1156. ]
  1157. }
  1158. }
  1159. });
  1160. fakeServer.requests[0].respond(
  1161. 200,
  1162. {'Content-Type': 'application/json'},
  1163. jsonData
  1164. );
  1165. expect(response.calledWithExactly([{
  1166. 'label': 'CircleName (type, owner)',
  1167. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId'}
  1168. }, {
  1169. 'label': 'CircleName (type2, owner)',
  1170. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'}
  1171. }, {
  1172. 'label': 'CircleName2 (type, owner)',
  1173. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'}
  1174. }])).toEqual(true);
  1175. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1176. });
  1177. });
  1178. describe('filter out', function() {
  1179. it('the current user', function () {
  1180. dialog.render();
  1181. var response = sinon.stub();
  1182. dialog.autocompleteHandler({term: 'bob'}, response);
  1183. var jsonData = JSON.stringify({
  1184. 'ocs': {
  1185. 'meta': {
  1186. 'status': 'success',
  1187. 'statuscode': 100,
  1188. 'message': null
  1189. },
  1190. 'data': {
  1191. 'exact': {
  1192. 'users': [],
  1193. 'groups': [],
  1194. 'remotes': [],
  1195. 'remote_groups': [],
  1196. },
  1197. 'users': [
  1198. {
  1199. 'label': 'bob',
  1200. 'value': {
  1201. 'shareType': 0,
  1202. 'shareWith': OC.currentUser
  1203. }
  1204. },
  1205. {
  1206. 'label': 'bobby',
  1207. 'value': {
  1208. 'shareType': 0,
  1209. 'shareWith': 'imbob'
  1210. }
  1211. }
  1212. ],
  1213. 'groups': [],
  1214. 'remotes': [],
  1215. 'remote_groups': [],
  1216. 'lookup': []
  1217. }
  1218. }
  1219. });
  1220. fakeServer.requests[0].respond(
  1221. 200,
  1222. {'Content-Type': 'application/json'},
  1223. jsonData
  1224. );
  1225. expect(response.calledWithExactly([{
  1226. 'label': 'bobby',
  1227. 'value': {'shareType': 0, 'shareWith': 'imbob'}
  1228. }])).toEqual(true);
  1229. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1230. });
  1231. it('the share owner', function () {
  1232. shareModel.set({
  1233. reshare: {
  1234. uid_owner: 'user1'
  1235. },
  1236. shares: [],
  1237. permissions: OC.PERMISSION_READ
  1238. });
  1239. dialog.render();
  1240. var response = sinon.stub();
  1241. dialog.autocompleteHandler({term: 'bob'}, response);
  1242. var jsonData = JSON.stringify({
  1243. 'ocs': {
  1244. 'meta': {
  1245. 'status': 'success',
  1246. 'statuscode': 100,
  1247. 'message': null
  1248. },
  1249. 'data': {
  1250. 'exact': {
  1251. 'users': [],
  1252. 'groups': [],
  1253. 'remotes': [],
  1254. 'remote_groups': [],
  1255. },
  1256. 'users': [
  1257. {
  1258. 'label': 'bob',
  1259. 'value': {
  1260. 'shareType': 0,
  1261. 'shareWith': 'user1'
  1262. }
  1263. },
  1264. {
  1265. 'label': 'bobby',
  1266. 'value': {
  1267. 'shareType': 0,
  1268. 'shareWith': 'imbob'
  1269. }
  1270. }
  1271. ],
  1272. 'groups': [],
  1273. 'remotes': [],
  1274. 'remote_groups': [],
  1275. 'lookup': []
  1276. }
  1277. }
  1278. });
  1279. fakeServer.requests[0].respond(
  1280. 200,
  1281. {'Content-Type': 'application/json'},
  1282. jsonData
  1283. );
  1284. expect(response.calledWithExactly([{
  1285. 'label': 'bobby',
  1286. 'value': {'shareType': 0, 'shareWith': 'imbob'}
  1287. }])).toEqual(true);
  1288. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1289. });
  1290. describe('already shared with', function () {
  1291. beforeEach(function() {
  1292. shareModel.set({
  1293. reshare: {},
  1294. shares: [{
  1295. id: 100,
  1296. item_source: 123,
  1297. permissions: 31,
  1298. share_type: OC.Share.SHARE_TYPE_USER,
  1299. share_with: 'user1',
  1300. share_with_displayname: 'User One'
  1301. },{
  1302. id: 101,
  1303. item_source: 123,
  1304. permissions: 31,
  1305. share_type: OC.Share.SHARE_TYPE_GROUP,
  1306. share_with: 'group',
  1307. share_with_displayname: 'group'
  1308. },{
  1309. id: 102,
  1310. item_source: 123,
  1311. permissions: 31,
  1312. share_type: OC.Share.SHARE_TYPE_REMOTE,
  1313. share_with: 'foo@bar.com/baz',
  1314. share_with_displayname: 'foo@bar.com/baz'
  1315. },{
  1316. id: 103,
  1317. item_source: 123,
  1318. permissions: 31,
  1319. share_type: OC.Share.SHARE_TYPE_EMAIL,
  1320. share_with: 'foo@bar.com',
  1321. share_with_displayname: 'foo@bar.com'
  1322. },{
  1323. id: 104,
  1324. item_source: 123,
  1325. permissions: 31,
  1326. share_type: OC.Share.SHARE_TYPE_CIRCLE,
  1327. share_with: 'shortId',
  1328. share_with_displayname: 'CircleName (type, owner)'
  1329. }]
  1330. });
  1331. });
  1332. it('users', function () {
  1333. dialog.render();
  1334. var response = sinon.stub();
  1335. dialog.autocompleteHandler({term: 'bo'}, response);
  1336. var jsonData = JSON.stringify({
  1337. 'ocs': {
  1338. 'meta': {
  1339. 'status': 'success',
  1340. 'statuscode': 100,
  1341. 'message': null
  1342. },
  1343. 'data': {
  1344. 'exact': {
  1345. 'users': [],
  1346. 'groups': [],
  1347. 'remotes': [],
  1348. 'remote_groups': [],
  1349. },
  1350. 'users': [
  1351. {
  1352. 'label': 'bob',
  1353. 'value': {
  1354. 'shareType': OC.Share.SHARE_TYPE_USER,
  1355. 'shareWith': 'user1'
  1356. }
  1357. },
  1358. {
  1359. 'label': 'bobby',
  1360. 'value': {
  1361. 'shareType': OC.Share.SHARE_TYPE_USER,
  1362. 'shareWith': 'imbob'
  1363. }
  1364. }
  1365. ],
  1366. 'groups': [],
  1367. 'remotes': [],
  1368. 'remote_groups': [],
  1369. 'lookup': []
  1370. }
  1371. }
  1372. });
  1373. fakeServer.requests[0].respond(
  1374. 200,
  1375. {'Content-Type': 'application/json'},
  1376. jsonData
  1377. );
  1378. expect(response.calledWithExactly([{
  1379. 'label': 'bobby',
  1380. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  1381. }])).toEqual(true);
  1382. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1383. });
  1384. it('users (exact)', function () {
  1385. dialog.render();
  1386. var response = sinon.stub();
  1387. dialog.autocompleteHandler({term: 'bob'}, response);
  1388. var jsonData = JSON.stringify({
  1389. 'ocs': {
  1390. 'meta': {
  1391. 'status': 'success',
  1392. 'statuscode': 100,
  1393. 'message': null
  1394. },
  1395. 'data': {
  1396. 'exact': {
  1397. 'users': [
  1398. {
  1399. 'label': 'bob',
  1400. 'value': {
  1401. 'shareType': OC.Share.SHARE_TYPE_USER,
  1402. 'shareWith': 'user1'
  1403. }
  1404. }
  1405. ],
  1406. 'groups': [],
  1407. 'remotes': [],
  1408. 'remote_groups': [],
  1409. },
  1410. 'users': [
  1411. {
  1412. 'label': 'bobby',
  1413. 'value': {
  1414. 'shareType': OC.Share.SHARE_TYPE_USER,
  1415. 'shareWith': 'imbob'
  1416. }
  1417. }
  1418. ],
  1419. 'groups': [],
  1420. 'remotes': [],
  1421. 'remote_groups': [],
  1422. 'lookup': []
  1423. }
  1424. }
  1425. });
  1426. fakeServer.requests[0].respond(
  1427. 200,
  1428. {'Content-Type': 'application/json'},
  1429. jsonData
  1430. );
  1431. expect(response.calledWithExactly([{
  1432. 'label': 'bobby',
  1433. 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
  1434. }])).toEqual(true);
  1435. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1436. });
  1437. it('groups', function () {
  1438. dialog.render();
  1439. var response = sinon.stub();
  1440. dialog.autocompleteHandler({term: 'grou'}, response);
  1441. var jsonData = JSON.stringify({
  1442. 'ocs': {
  1443. 'meta': {
  1444. 'status': 'success',
  1445. 'statuscode': 100,
  1446. 'message': null
  1447. },
  1448. 'data': {
  1449. 'exact': {
  1450. 'users': [],
  1451. 'groups': [],
  1452. 'remotes': [],
  1453. 'remote_groups': [],
  1454. },
  1455. 'users': [],
  1456. 'groups': [
  1457. {
  1458. 'label': 'group',
  1459. 'value': {
  1460. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  1461. 'shareWith': 'group'
  1462. }
  1463. },
  1464. {
  1465. 'label': 'group2',
  1466. 'value': {
  1467. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  1468. 'shareWith': 'group2'
  1469. }
  1470. }
  1471. ],
  1472. 'remotes': [],
  1473. 'remote_groups': [],
  1474. 'lookup': []
  1475. }
  1476. }
  1477. });
  1478. fakeServer.requests[0].respond(
  1479. 200,
  1480. {'Content-Type': 'application/json'},
  1481. jsonData
  1482. );
  1483. expect(response.calledWithExactly([{
  1484. 'label': 'group2',
  1485. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'}
  1486. }])).toEqual(true);
  1487. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1488. });
  1489. it('groups (exact)', function () {
  1490. dialog.render();
  1491. var response = sinon.stub();
  1492. dialog.autocompleteHandler({term: 'group'}, response);
  1493. var jsonData = JSON.stringify({
  1494. 'ocs': {
  1495. 'meta': {
  1496. 'status': 'success',
  1497. 'statuscode': 100,
  1498. 'message': null
  1499. },
  1500. 'data': {
  1501. 'exact': {
  1502. 'users': [],
  1503. 'groups': [
  1504. {
  1505. 'label': 'group',
  1506. 'value': {
  1507. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  1508. 'shareWith': 'group'
  1509. }
  1510. }
  1511. ],
  1512. 'remotes': [],
  1513. 'remote_groups': [],
  1514. },
  1515. 'users': [],
  1516. 'groups': [
  1517. {
  1518. 'label': 'group2',
  1519. 'value': {
  1520. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  1521. 'shareWith': 'group2'
  1522. }
  1523. }
  1524. ],
  1525. 'remotes': [],
  1526. 'remote_groups': [],
  1527. 'lookup': []
  1528. }
  1529. }
  1530. });
  1531. fakeServer.requests[0].respond(
  1532. 200,
  1533. {'Content-Type': 'application/json'},
  1534. jsonData
  1535. );
  1536. expect(response.calledWithExactly([{
  1537. 'label': 'group2',
  1538. 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'}
  1539. }])).toEqual(true);
  1540. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1541. });
  1542. it('remotes', function () {
  1543. dialog.render();
  1544. var response = sinon.stub();
  1545. dialog.autocompleteHandler({term: 'foo'}, response);
  1546. var jsonData = JSON.stringify({
  1547. 'ocs': {
  1548. 'meta': {
  1549. 'status': 'success',
  1550. 'statuscode': 100,
  1551. 'message': null
  1552. },
  1553. 'data': {
  1554. 'exact': {
  1555. 'users': [],
  1556. 'groups': [],
  1557. 'remotes': [],
  1558. 'remote_groups': [],
  1559. },
  1560. 'users': [],
  1561. 'groups': [],
  1562. 'remotes': [
  1563. {
  1564. 'label': 'foo@bar.com/baz',
  1565. 'value': {
  1566. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1567. 'shareWith': 'foo@bar.com/baz'
  1568. }
  1569. },
  1570. {
  1571. 'label': 'foo2@bar.com/baz',
  1572. 'value': {
  1573. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1574. 'shareWith': 'foo2@bar.com/baz'
  1575. }
  1576. }
  1577. ],
  1578. 'remote_groups': [],
  1579. 'lookup': []
  1580. }
  1581. }
  1582. });
  1583. fakeServer.requests[0].respond(
  1584. 200,
  1585. {'Content-Type': 'application/json'},
  1586. jsonData
  1587. );
  1588. expect(response.calledWithExactly([{
  1589. 'label': 'foo2@bar.com/baz',
  1590. 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo2@bar.com/baz'}
  1591. }])).toEqual(true);
  1592. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1593. });
  1594. it('remotes (exact)', function () {
  1595. dialog.render();
  1596. var response = sinon.stub();
  1597. dialog.autocompleteHandler({term: 'foo@bar.com/baz'}, response);
  1598. var jsonData = JSON.stringify({
  1599. 'ocs': {
  1600. 'meta': {
  1601. 'status': 'success',
  1602. 'statuscode': 100,
  1603. 'message': null
  1604. },
  1605. 'data': {
  1606. 'exact': {
  1607. 'users': [],
  1608. 'groups': [],
  1609. 'remotes': [
  1610. {
  1611. 'label': 'foo@bar.com/baz',
  1612. 'value': {
  1613. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1614. 'shareWith': 'foo@bar.com/baz'
  1615. }
  1616. }
  1617. ],
  1618. 'remote_groups': [],
  1619. },
  1620. 'users': [],
  1621. 'groups': [],
  1622. 'remotes': [
  1623. {
  1624. 'label': 'foo@bar.com/baz2',
  1625. 'value': {
  1626. 'shareType': OC.Share.SHARE_TYPE_REMOTE,
  1627. 'shareWith': 'foo@bar.com/baz2'
  1628. }
  1629. }
  1630. ],
  1631. 'remote_groups': [],
  1632. 'lookup': []
  1633. }
  1634. }
  1635. });
  1636. fakeServer.requests[0].respond(
  1637. 200,
  1638. {'Content-Type': 'application/json'},
  1639. jsonData
  1640. );
  1641. expect(response.calledWithExactly([{
  1642. 'label': 'foo@bar.com/baz2',
  1643. 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'}
  1644. }])).toEqual(true);
  1645. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1646. });
  1647. it('emails', function () {
  1648. dialog.render();
  1649. var response = sinon.stub();
  1650. dialog.autocompleteHandler({term: 'foo'}, response);
  1651. var jsonData = JSON.stringify({
  1652. 'ocs': {
  1653. 'meta': {
  1654. 'status': 'success',
  1655. 'statuscode': 100,
  1656. 'message': null
  1657. },
  1658. 'data': {
  1659. 'exact': {
  1660. 'users': [],
  1661. 'groups': [],
  1662. 'remotes': [],
  1663. 'remote_groups': [],
  1664. 'emails': []
  1665. },
  1666. 'users': [],
  1667. 'groups': [],
  1668. 'remotes': [],
  1669. 'lookup': [],
  1670. 'remote_groups': [],
  1671. 'emails': [
  1672. {
  1673. 'label': 'foo@bar.com',
  1674. 'value': {
  1675. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1676. 'shareWith': 'foo@bar.com'
  1677. }
  1678. },
  1679. {
  1680. 'label': 'foo2@bar.com',
  1681. 'value': {
  1682. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1683. 'shareWith': 'foo2@bar.com'
  1684. }
  1685. }
  1686. ]
  1687. }
  1688. }
  1689. });
  1690. fakeServer.requests[0].respond(
  1691. 200,
  1692. {'Content-Type': 'application/json'},
  1693. jsonData
  1694. );
  1695. expect(response.calledWithExactly([{
  1696. 'label': 'foo2@bar.com',
  1697. 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo2@bar.com'}
  1698. }])).toEqual(true);
  1699. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1700. });
  1701. it('emails (exact)', function () {
  1702. dialog.render();
  1703. var response = sinon.stub();
  1704. dialog.autocompleteHandler({term: 'foo@bar.com'}, response);
  1705. var jsonData = JSON.stringify({
  1706. 'ocs': {
  1707. 'meta': {
  1708. 'status': 'success',
  1709. 'statuscode': 100,
  1710. 'message': null
  1711. },
  1712. 'data': {
  1713. 'exact': {
  1714. 'users': [],
  1715. 'groups': [],
  1716. 'remotes': [],
  1717. 'remote_groups': [],
  1718. 'emails': [
  1719. {
  1720. 'label': 'foo@bar.com',
  1721. 'value': {
  1722. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1723. 'shareWith': 'foo@bar.com'
  1724. }
  1725. }
  1726. ]
  1727. },
  1728. 'users': [],
  1729. 'groups': [],
  1730. 'remotes': [],
  1731. 'remote_groups': [],
  1732. 'lookup': [],
  1733. 'emails': [
  1734. {
  1735. 'label': 'foo@bar.com2',
  1736. 'value': {
  1737. 'shareType': OC.Share.SHARE_TYPE_EMAIL,
  1738. 'shareWith': 'foo@bar.com2'
  1739. }
  1740. }
  1741. ]
  1742. }
  1743. }
  1744. });
  1745. fakeServer.requests[0].respond(
  1746. 200,
  1747. {'Content-Type': 'application/json'},
  1748. jsonData
  1749. );
  1750. expect(response.calledWithExactly([{
  1751. 'label': 'foo@bar.com2',
  1752. 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'}
  1753. }])).toEqual(true);
  1754. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1755. });
  1756. it('circles', function () {
  1757. dialog.render();
  1758. var response = sinon.stub();
  1759. dialog.autocompleteHandler({term: 'CircleNam'}, response);
  1760. var jsonData = JSON.stringify({
  1761. 'ocs': {
  1762. 'meta': {
  1763. 'status': 'success',
  1764. 'statuscode': 100,
  1765. 'message': null
  1766. },
  1767. 'data': {
  1768. 'exact': {
  1769. 'users': [],
  1770. 'groups': [],
  1771. 'remotes': [],
  1772. 'remote_groups': [],
  1773. 'circles': []
  1774. },
  1775. 'users': [],
  1776. 'groups': [],
  1777. 'remotes': [],
  1778. 'remote_groups': [],
  1779. 'lookup': [],
  1780. 'circles': [
  1781. {
  1782. 'label': 'CircleName (type, owner)',
  1783. 'value': {
  1784. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1785. 'shareWith': 'shortId'
  1786. }
  1787. },
  1788. {
  1789. 'label': 'CircleName (type2, owner)',
  1790. 'value': {
  1791. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1792. 'shareWith': 'shortId2'
  1793. }
  1794. }
  1795. ]
  1796. }
  1797. }
  1798. });
  1799. fakeServer.requests[0].respond(
  1800. 200,
  1801. {'Content-Type': 'application/json'},
  1802. jsonData
  1803. );
  1804. expect(response.calledWithExactly([{
  1805. 'label': 'CircleName (type2, owner)',
  1806. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'}
  1807. }])).toEqual(true);
  1808. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1809. });
  1810. it('circles (exact)', function () {
  1811. dialog.render();
  1812. var response = sinon.stub();
  1813. dialog.autocompleteHandler({term: 'CircleName'}, response);
  1814. var jsonData = JSON.stringify({
  1815. 'ocs': {
  1816. 'meta': {
  1817. 'status': 'success',
  1818. 'statuscode': 100,
  1819. 'message': null
  1820. },
  1821. 'data': {
  1822. 'exact': {
  1823. 'users': [],
  1824. 'groups': [],
  1825. 'remotes': [],
  1826. 'remote_groups': [],
  1827. 'circles': [
  1828. {
  1829. 'label': 'CircleName (type, owner)',
  1830. 'value': {
  1831. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1832. 'shareWith': 'shortId'
  1833. }
  1834. },
  1835. {
  1836. 'label': 'CircleName (type2, owner)',
  1837. 'value': {
  1838. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1839. 'shareWith': 'shortId2'
  1840. }
  1841. }
  1842. ]
  1843. },
  1844. 'users': [],
  1845. 'groups': [],
  1846. 'remotes': [],
  1847. 'remote_groups': [],
  1848. 'lookup': [],
  1849. 'circles': [
  1850. {
  1851. 'label': 'CircleName2 (type, owner)',
  1852. 'value': {
  1853. 'shareType': OC.Share.SHARE_TYPE_CIRCLE,
  1854. 'shareWith': 'shortId3'
  1855. }
  1856. }
  1857. ]
  1858. }
  1859. }
  1860. });
  1861. fakeServer.requests[0].respond(
  1862. 200,
  1863. {'Content-Type': 'application/json'},
  1864. jsonData
  1865. );
  1866. expect(response.calledWithExactly([{
  1867. 'label': 'CircleName (type2, owner)',
  1868. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'}
  1869. }, {
  1870. 'label': 'CircleName2 (type, owner)',
  1871. 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'}
  1872. }])).toEqual(true);
  1873. expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
  1874. });
  1875. });
  1876. });
  1877. it('throws a notification for a successful ajax call with failure content', function () {
  1878. dialog.render();
  1879. var response = sinon.stub();
  1880. dialog.autocompleteHandler({term: 'bob'}, response);
  1881. var jsonData = JSON.stringify({
  1882. 'ocs' : {
  1883. 'meta' : {
  1884. 'status': 'failure',
  1885. 'statuscode': 400,
  1886. 'message': 'error message'
  1887. }
  1888. }
  1889. });
  1890. fakeServer.requests[0].respond(
  1891. 200,
  1892. {'Content-Type': 'application/json'},
  1893. jsonData
  1894. );
  1895. expect(response.called).toEqual(false);
  1896. expect(showTemporaryNotificationStub.calledOnce).toEqual(true);
  1897. expect(showTemporaryNotificationStub.firstCall.args[0]).toContain('error message');
  1898. });
  1899. it('throws a notification when the ajax search lookup fails', function () {
  1900. dialog.render();
  1901. dialog.autocompleteHandler({term: 'bob'}, sinon.stub());
  1902. fakeServer.requests[0].respond(500);
  1903. expect(showTemporaryNotificationStub.calledOnce).toEqual(true);
  1904. });
  1905. describe('renders the autocomplete elements', function() {
  1906. it('renders a group element', function() {
  1907. dialog.render();
  1908. var el = dialog.autocompleteRenderItem(
  1909. $("<ul></ul>"),
  1910. {label: "1", value: { shareType: OC.Share.SHARE_TYPE_GROUP }}
  1911. );
  1912. expect(el.is('li')).toEqual(true);
  1913. expect(el.hasClass('group')).toEqual(true);
  1914. });
  1915. it('renders a remote element', function() {
  1916. dialog.render();
  1917. var el = dialog.autocompleteRenderItem(
  1918. $("<ul></ul>"),
  1919. {label: "1", value: { shareType: OC.Share.SHARE_TYPE_REMOTE }}
  1920. );
  1921. expect(el.is('li')).toEqual(true);
  1922. expect(el.hasClass('user')).toEqual(true);
  1923. });
  1924. });
  1925. it('calls addShare after selection', function() {
  1926. dialog.render();
  1927. var shareWith = $('.shareWithField')[0];
  1928. var $shareWith = $(shareWith);
  1929. var addShareStub = sinon.stub(shareModel, 'addShare');
  1930. var autocompleteOptions = autocompleteStub.getCall(0).args[0];
  1931. autocompleteOptions.select(new $.Event('select', {target: shareWith}), {
  1932. item: {
  1933. label: 'User Two',
  1934. value: {
  1935. shareType: OC.Share.SHARE_TYPE_USER,
  1936. shareWith: 'user2'
  1937. }
  1938. }
  1939. });
  1940. expect(addShareStub.calledOnce).toEqual(true);
  1941. expect(addShareStub.firstCall.args[0]).toEqual({
  1942. shareType: OC.Share.SHARE_TYPE_USER,
  1943. shareWith: 'user2'
  1944. });
  1945. //Input is locked
  1946. expect($shareWith.val()).toEqual('User Two');
  1947. expect($shareWith.attr('disabled')).toEqual('disabled');
  1948. //Callback is called
  1949. addShareStub.firstCall.args[1].success();
  1950. //Input is unlocked
  1951. expect($shareWith.val()).toEqual('');
  1952. expect($shareWith.attr('disabled')).toEqual(undefined);
  1953. addShareStub.restore();
  1954. });
  1955. it('calls addShare after selection and fail to share', function() {
  1956. dialog.render();
  1957. var shareWith = $('.shareWithField')[0];
  1958. var $shareWith = $(shareWith);
  1959. var addShareStub = sinon.stub(shareModel, 'addShare');
  1960. var autocompleteOptions = autocompleteStub.getCall(0).args[0];
  1961. autocompleteOptions.select(new $.Event('select', {target: shareWith}), {
  1962. item: {
  1963. label: 'User Two',
  1964. value: {
  1965. shareType: OC.Share.SHARE_TYPE_USER,
  1966. shareWith: 'user2'
  1967. }
  1968. }
  1969. });
  1970. expect(addShareStub.calledOnce).toEqual(true);
  1971. expect(addShareStub.firstCall.args[0]).toEqual({
  1972. shareType: OC.Share.SHARE_TYPE_USER,
  1973. shareWith: 'user2'
  1974. });
  1975. //Input is locked
  1976. expect($shareWith.val()).toEqual('User Two');
  1977. expect($shareWith.attr('disabled')).toEqual('disabled');
  1978. //Callback is called
  1979. addShareStub.firstCall.args[1].error();
  1980. //Input is unlocked
  1981. expect($shareWith.val()).toEqual('User Two');
  1982. expect($shareWith.attr('disabled')).toEqual(undefined);
  1983. addShareStub.restore();
  1984. });
  1985. it('hides the loading icon when all the pending operations finish', function() {
  1986. dialog.render();
  1987. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  1988. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  1989. var response = sinon.stub();
  1990. dialog.autocompleteHandler({term: 'bob'}, response);
  1991. dialog.autocompleteHandler({term: 'bobby'}, response);
  1992. var jsonData = JSON.stringify({
  1993. 'ocs': {
  1994. 'meta': {
  1995. 'status': 'success',
  1996. 'statuscode': 100,
  1997. 'message': null
  1998. },
  1999. 'data': {
  2000. 'exact': {
  2001. 'users': [],
  2002. 'groups': [],
  2003. 'remotes': [],
  2004. 'remote_groups': [],
  2005. },
  2006. 'users': [],
  2007. 'groups': [],
  2008. 'remotes': [],
  2009. 'remote_groups': [],
  2010. 'lookup': []
  2011. }
  2012. }
  2013. });
  2014. fakeServer.requests[0].respond(
  2015. 200,
  2016. {'Content-Type': 'application/json'},
  2017. jsonData
  2018. );
  2019. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
  2020. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
  2021. fakeServer.requests[1].respond(
  2022. 200,
  2023. {'Content-Type': 'application/json'},
  2024. jsonData
  2025. );
  2026. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2027. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2028. });
  2029. });
  2030. describe('confirm share', function() {
  2031. var addShareStub;
  2032. var tooltipStub;
  2033. var showTemporaryNotificationStub;
  2034. beforeEach(function() {
  2035. addShareStub = sinon.stub(shareModel, 'addShare');
  2036. tooltipStub = sinon.stub($.fn, 'tooltip').callsFake(function() {
  2037. return $('<div></div>');
  2038. });
  2039. showTemporaryNotificationStub = sinon.stub(OC.Notification, 'showTemporary');
  2040. dialog.render();
  2041. });
  2042. afterEach(function() {
  2043. addShareStub.restore();
  2044. tooltipStub.restore();
  2045. showTemporaryNotificationStub.restore();
  2046. });
  2047. it('sets the appropriate UI state while waiting to get the suggestions', function() {
  2048. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2049. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2050. expect(autocompleteStub.callCount).toEqual(1);
  2051. expect(typeof autocompleteStub.firstCall.args[0]).toEqual('object');
  2052. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2053. dialog.$el.find('.shareWithField').val('bob');
  2054. dialog._confirmShare();
  2055. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
  2056. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
  2057. expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
  2058. expect(autocompleteStub.calledWith('close')).toEqual(true);
  2059. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
  2060. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2061. });
  2062. it('calls addShare with the only suggestion', function() {
  2063. dialog.$el.find('.shareWithField').val('bob');
  2064. dialog._confirmShare();
  2065. var jsonData = JSON.stringify({
  2066. 'ocs': {
  2067. 'meta': {
  2068. 'status': 'success',
  2069. 'statuscode': 100,
  2070. 'message': null
  2071. },
  2072. 'data': {
  2073. 'exact': {
  2074. 'users': [
  2075. {
  2076. 'label': 'bob',
  2077. 'value': {
  2078. 'shareType': OC.Share.SHARE_TYPE_USER,
  2079. 'shareWith': 'user1'
  2080. }
  2081. }
  2082. ],
  2083. 'groups': [],
  2084. 'remotes': [],
  2085. 'remote_groups': [],
  2086. },
  2087. 'users': [],
  2088. 'groups': [],
  2089. 'remotes': [],
  2090. 'remote_groups': [],
  2091. 'lookup': []
  2092. }
  2093. }
  2094. });
  2095. fakeServer.requests[0].respond(
  2096. 200,
  2097. {'Content-Type': 'application/json'},
  2098. jsonData
  2099. );
  2100. // Ensure that the UI is not restored before adding the share
  2101. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
  2102. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
  2103. expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
  2104. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
  2105. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2106. expect(addShareStub.calledOnce).toEqual(true);
  2107. expect(addShareStub.firstCall.args[0]).toEqual({
  2108. shareType: OC.Share.SHARE_TYPE_USER,
  2109. shareWith: 'user1'
  2110. });
  2111. // "yield" and "callArg" from SinonJS can not be used, as the
  2112. // callback is a property not in the first argument.
  2113. addShareStub.firstCall.args[1]['success'].apply(shareModel);
  2114. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2115. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2116. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2117. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2118. expect(dialog.$el.find('.shareWithField').val()).toEqual('');
  2119. });
  2120. it('handles a failure to share', function() {
  2121. expect(showTemporaryNotificationStub.called).toEqual(false);
  2122. dialog.$el.find('.shareWithField').val('bob');
  2123. dialog._confirmShare();
  2124. var jsonData = JSON.stringify({
  2125. 'ocs': {
  2126. 'meta': {
  2127. 'status': 'success',
  2128. 'statuscode': 100,
  2129. 'message': null
  2130. },
  2131. 'data': {
  2132. 'exact': {
  2133. 'users': [
  2134. {
  2135. 'label': 'bob',
  2136. 'value': {
  2137. 'shareType': OC.Share.SHARE_TYPE_USER,
  2138. 'shareWith': 'user1'
  2139. }
  2140. }
  2141. ],
  2142. 'groups': [],
  2143. 'remotes': [],
  2144. 'remote_groups': [],
  2145. },
  2146. 'users': [],
  2147. 'groups': [],
  2148. 'remotes': [],
  2149. 'remote_groups': [],
  2150. 'lookup': []
  2151. }
  2152. }
  2153. });
  2154. fakeServer.requests[0].respond(
  2155. 200,
  2156. {'Content-Type': 'application/json'},
  2157. jsonData
  2158. );
  2159. // Ensure that the UI is not restored before adding the share
  2160. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
  2161. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
  2162. expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
  2163. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
  2164. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2165. expect(addShareStub.calledOnce).toEqual(true);
  2166. expect(addShareStub.firstCall.args[0]).toEqual({
  2167. shareType: OC.Share.SHARE_TYPE_USER,
  2168. shareWith: 'user1'
  2169. });
  2170. // "yield" and "callArg" from SinonJS can not be used, as the
  2171. // callback is a property not in the first argument.
  2172. addShareStub.firstCall.args[1]['error'].apply(shareModel);
  2173. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2174. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2175. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2176. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2177. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2178. expect(showTemporaryNotificationStub.calledOnce).toEqual(true);
  2179. });
  2180. it('restores UI if there are no matches at all', function() {
  2181. dialog.$el.find('.shareWithField').val('bob');
  2182. dialog._confirmShare();
  2183. var jsonData = JSON.stringify({
  2184. 'ocs': {
  2185. 'meta': {
  2186. 'status': 'success',
  2187. 'statuscode': 100,
  2188. 'message': null
  2189. },
  2190. 'data': {
  2191. 'exact': {
  2192. 'users': [],
  2193. 'groups': [],
  2194. 'remotes': [],
  2195. 'remote_groups': [],
  2196. },
  2197. 'users': [],
  2198. 'groups': [],
  2199. 'remotes': [],
  2200. 'lookup': [],
  2201. 'remote_groups': [],
  2202. }
  2203. }
  2204. });
  2205. fakeServer.requests[0].respond(
  2206. 200,
  2207. {'Content-Type': 'application/json'},
  2208. jsonData
  2209. );
  2210. expect(addShareStub.called).toEqual(false);
  2211. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2212. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2213. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2214. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2215. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2216. // No explicit tooltip is shown; it is automatically shown when the
  2217. // autocomplete is activated again and it finds no matches.
  2218. expect(tooltipStub.lastCall.args[0]).not.toEqual('show');
  2219. });
  2220. it('shows tooltip if there are matches but no exact matches', function() {
  2221. dialog.$el.find('.shareWithField').val('bo');
  2222. dialog._confirmShare();
  2223. var jsonData = JSON.stringify({
  2224. 'ocs': {
  2225. 'meta': {
  2226. 'status': 'success',
  2227. 'statuscode': 100,
  2228. 'message': null
  2229. },
  2230. 'data': {
  2231. 'exact': {
  2232. 'users': [],
  2233. 'groups': [],
  2234. 'remotes': [],
  2235. 'remote_groups': [],
  2236. },
  2237. 'users': [
  2238. {
  2239. 'label': 'bob',
  2240. 'value': {
  2241. 'shareType': OC.Share.SHARE_TYPE_USER,
  2242. 'shareWith': 'user1'
  2243. }
  2244. }
  2245. ],
  2246. 'groups': [],
  2247. 'remotes': [],
  2248. 'remote_groups': [],
  2249. 'lookup': []
  2250. }
  2251. }
  2252. });
  2253. fakeServer.requests[0].respond(
  2254. 200,
  2255. {'Content-Type': 'application/json'},
  2256. jsonData
  2257. );
  2258. expect(addShareStub.called).toEqual(false);
  2259. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2260. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2261. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2262. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2263. expect(dialog.$el.find('.shareWithField').val()).toEqual('bo');
  2264. });
  2265. it('shows tooltip if there is more than one exact match', function() {
  2266. dialog.$el.find('.shareWithField').val('bob');
  2267. dialog._confirmShare();
  2268. var jsonData = JSON.stringify({
  2269. 'ocs': {
  2270. 'meta': {
  2271. 'status': 'success',
  2272. 'statuscode': 100,
  2273. 'message': null
  2274. },
  2275. 'data': {
  2276. 'exact': {
  2277. 'users': [
  2278. {
  2279. 'label': 'bob',
  2280. 'value': {
  2281. 'shareType': OC.Share.SHARE_TYPE_USER,
  2282. 'shareWith': 'user1'
  2283. }
  2284. }
  2285. ],
  2286. 'groups': [
  2287. {
  2288. 'label': 'bob',
  2289. 'value': {
  2290. 'shareType': OC.Share.SHARE_TYPE_GROUP,
  2291. 'shareWith': 'group1'
  2292. }
  2293. }
  2294. ],
  2295. 'remotes': [],
  2296. 'remote_groups': [],
  2297. },
  2298. 'users': [],
  2299. 'groups': [],
  2300. 'remotes': [],
  2301. 'remote_groups': [],
  2302. 'lookup': []
  2303. }
  2304. }
  2305. });
  2306. fakeServer.requests[0].respond(
  2307. 200,
  2308. {'Content-Type': 'application/json'},
  2309. jsonData
  2310. );
  2311. expect(addShareStub.called).toEqual(false);
  2312. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2313. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2314. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2315. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2316. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2317. });
  2318. it('throws a notification for a successful ajax call with failure content', function () {
  2319. dialog.$el.find('.shareWithField').val('bob');
  2320. dialog._confirmShare();
  2321. var jsonData = JSON.stringify({
  2322. 'ocs' : {
  2323. 'meta' : {
  2324. 'status': 'failure',
  2325. 'statuscode': 400,
  2326. 'message': 'error message'
  2327. }
  2328. }
  2329. });
  2330. fakeServer.requests[0].respond(
  2331. 200,
  2332. {'Content-Type': 'application/json'},
  2333. jsonData
  2334. );
  2335. expect(addShareStub.called).toEqual(false);
  2336. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2337. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2338. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2339. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2340. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2341. expect(showTemporaryNotificationStub.called).toEqual(false);
  2342. });
  2343. it('throws a notification when the ajax search lookup fails', function () {
  2344. dialog.$el.find('.shareWithField').val('bob');
  2345. dialog._confirmShare();
  2346. fakeServer.requests[0].respond(500);
  2347. expect(addShareStub.called).toEqual(false);
  2348. expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
  2349. expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
  2350. expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
  2351. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
  2352. expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
  2353. expect(showTemporaryNotificationStub.called).toEqual(false);
  2354. });
  2355. });
  2356. describe('reshare permissions', function() {
  2357. it('does not show sharing options when sharing not allowed', function() {
  2358. shareModel.set({
  2359. reshare: {},
  2360. shares: [],
  2361. permissions: OC.PERMISSION_READ
  2362. });
  2363. dialog.render();
  2364. expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
  2365. });
  2366. it('shows reshare owner for single user share', function() {
  2367. shareModel.set({
  2368. reshare: {
  2369. uid_owner: 'user1',
  2370. displayname_owner: 'User One',
  2371. share_type: OC.Share.SHARE_TYPE_USER
  2372. },
  2373. shares: [],
  2374. permissions: OC.PERMISSION_READ
  2375. });
  2376. dialog.render();
  2377. expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(1);
  2378. expect(dialog.$el.find('.resharerInfoView .reshare').text().trim()).toEqual('Shared with you by User One');
  2379. });
  2380. it('shows reshare owner for single user share', function() {
  2381. shareModel.set({
  2382. reshare: {
  2383. uid_owner: 'user1',
  2384. displayname_owner: 'User One',
  2385. share_with: 'group2',
  2386. share_with_displayname: 'Group Two',
  2387. share_type: OC.Share.SHARE_TYPE_GROUP
  2388. },
  2389. shares: [],
  2390. permissions: OC.PERMISSION_READ
  2391. });
  2392. dialog.render();
  2393. expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(1);
  2394. expect(dialog.$el.find('.resharerInfoView .reshare').text().trim()).toEqual('Shared with you and the group Group Two by User One');
  2395. });
  2396. it('does not show reshare owner if owner is current user', function() {
  2397. shareModel.set({
  2398. reshare: {
  2399. uid_owner: OC.currentUser
  2400. },
  2401. shares: [],
  2402. permissions: OC.PERMISSION_READ
  2403. });
  2404. dialog.render();
  2405. expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(0);
  2406. });
  2407. });
  2408. });