diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js index 8dac9550c416..f0bf569a732e 100644 --- a/core/js/sharedialogshareelistview.js +++ b/core/js/sharedialogshareelistview.js @@ -69,7 +69,7 @@ '
' + '{{#each shareAttributes}}' + '' + - '' + + '' + '' + '' + '{{/each}}' + @@ -129,6 +129,9 @@ var cid = this.cid; var shareWith = model.getShareWith(shareIndex); + // Check if reshare, and if so disable the checkboxes + var isReshare = model.hasReshare(); + // Returns OC.Share.Types.ShareAttribute[] which were set for this // share (and stored in DB) var attributes = model.getShareAttributes(shareIndex); @@ -137,19 +140,20 @@ attributes.map(function(attribute) { // Check if the share attribute set for this file is still in // registered share attributes and get its label - var label = model.getRegisteredShareAttributeLabel( + var regAttr = model.getRegisteredShareAttribute( attribute.scope, attribute.key ); - if (label) { + if (regAttr && regAttr.label) { list.push({ cid: cid, + isReshare: isReshare, shareWith: shareWith, enabled: attribute.enabled, scope: attribute.scope, name: attribute.key, - label: label + label: regAttr.label }); } else { OC.Notification.showTemporary(t('core', 'Share with ' + diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index 021a8e1cf8de..05bb83d5da56 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -38,7 +38,7 @@ * @typedef {object} OC.Share.Types.ShareInfo * @property {number} share_type * @property {number} permissions - * @property {string} attributes + * @property {OC.Share.Types.ShareAttribute[]} attributes * @property {number} file_source optional * @property {number} item_source * @property {string} token @@ -73,6 +73,7 @@ * @property {string} description * @property {number[]} shareType * @property {number[]} incompatiblePermissions + * @property {number[]} requiredPermissions * @property {OC.Share.Types.ShareAttribute[]} incompatibleAttributes */ @@ -85,6 +86,13 @@ 'storage', 'share_type', 'parent', 'stime' ]; + /** + * Properties which are json and need to be parsed + */ + var SHARE_RESPONSE_JSON_PROPS = [ + 'attributes' + ]; + /** * @class OCA.Share.ShareItemModel * @classdesc @@ -171,10 +179,11 @@ } properties.permissions = defaultPermissions & possiblePermissions; + // FIXME: simplify the logic by merging and then filtering // Set default attributes for this share based on registered // attributes (filtered by their incompatible permissions) var newShareAttributes = []; - var filteredRegisteredAttributes = this.filterRegisteredAttributes(properties.permissions); + var filteredRegisteredAttributes = this._filterRegisteredAttributes(properties.permissions); _.map(filteredRegisteredAttributes, function(filteredRegisteredAttribute) { var isCompatible = true; // Check if this attribute can be added due to its incompatible attributes @@ -233,12 +242,13 @@ var self = this; options = options || {}; + // FIXME: simplify the logic by merging and then filtering // Set share attributes for this share based on registered // attributes (filtered by their incompatible permissions // and incompatible attributes) var newShareAttributes = []; var filteredAttributes = []; - var filteredRegisteredAttributes = this.filterRegisteredAttributes(properties.permissions); + var filteredRegisteredAttributes = this._filterRegisteredAttributes(properties.permissions); _.map(filteredRegisteredAttributes, function(filteredRegisteredAttribute) { // Check if this allowed registered attribute // is on the list of currently set properties, @@ -785,9 +795,15 @@ // returns integers as string... var i; for (i = 0; i < SHARE_RESPONSE_INT_PROPS.length; i++) { - var prop = SHARE_RESPONSE_INT_PROPS[i]; - if (!_.isUndefined(share[prop])) { - share[prop] = parseInt(share[prop], 10); + var propInt = SHARE_RESPONSE_INT_PROPS[i]; + if (!_.isUndefined(share[propInt])) { + share[propInt] = parseInt(share[propInt], 10); + } + } + for (i = 0; i < SHARE_RESPONSE_JSON_PROPS.length; i++) { + var propJson = SHARE_RESPONSE_JSON_PROPS[i]; + if (!_.isUndefined(share[propJson])) { + share[propJson] = JSON.parse(share.attributes); } } return share; @@ -868,6 +884,25 @@ return _.uniq(result); }, + /** + * Returns share attributes for given share index + * + * @param shareIndex + * @returns OC.Share.Types.ShareAttribute[] + */ + getShareAttributes: function(shareIndex) { + /** @type OC.Share.Types.ShareInfo **/ + var share = this.get('shares')[shareIndex]; + if(!_.isObject(share)) { + throw "Unknown Share"; + } + + if (_.isNull(share.attributes) || _.isUndefined(share.attributes)) { + return []; + } + return share.attributes; + }, + /** * Filter registered attributes by current share permissions * @@ -875,7 +910,7 @@ * @returns {OC.Share.Types.RegisteredShareAttribute[]} * @private */ - filterRegisteredAttributes: function(permissions) { + _filterRegisteredAttributes: function(permissions) { var filteredByPermissions = []; for(var i in this._registeredAttributes) { var compatible = true; @@ -885,6 +920,11 @@ compatible = false; } } + for(var ii in attr.requiredPermissions) { + if (!this._hasPermission(permissions, attr.requiredPermissions[ii])) { + compatible = false; + } + } if (compatible) { filteredByPermissions.push(attr); @@ -894,51 +934,30 @@ return filteredByPermissions; }, - /** - * Returns share attributes for given share index - * - * @param shareIndex - * @returns OC.Share.Types.ShareAttribute[] - */ - getShareAttributes: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex]; - if(!_.isObject(share)) { - throw "Unknown Share"; - } - - if (_.isUndefined(share.attributes) || _.isUndefined(share.permissions)) { - return []; - } - - // Add attributes for this share - var currentAttributes = JSON.parse(share.attributes); - if (currentAttributes) { - return currentAttributes; - } - return []; - }, - /** * Returns share attribute label for given attribute scope and name. If * attribute does not exist, null is returned. * * @param scope * @param key - * @returns string|null + * @returns {OC.Share.Types.RegisteredShareAttribute} */ - getRegisteredShareAttributeLabel: function(scope, key) { + getRegisteredShareAttribute: function(scope, key) { for(var i in this._registeredAttributes) { if (this._registeredAttributes[i].scope === scope && this._registeredAttributes[i].key === key) { - return this._registeredAttributes[i].label; + return this._registeredAttributes[i]; } } return null; }, /** - * Apps can register default share attributes + * Apps can register default share attributes. The applications + * registering share attributes are required to follow the rules: + * attribute enabled -> functionality is added (e.g. can download) + * attribute disabled -> functionality is restricted + * incompatible attribute -> functionality is ignored * * @param {OC.Share.Types.RegisteredShareAttribute} $shareAttribute */ diff --git a/core/js/tests/specs/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js index 910dc93269c4..ee2fc72b4bfe 100644 --- a/core/js/tests/specs/sharedialogshareelistview.js +++ b/core/js/tests/specs/sharedialogshareelistview.js @@ -45,14 +45,14 @@ describe('OC.Share.ShareDialogShareeListView', function () { sharePermissions: 31 }); - var attributes = { + var properties = { itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', itemSource: fileInfoModel.get('id'), possiblePermissions: 31, permissions: 31 }; - shareModel = new OC.Share.ShareItemModel(attributes, { + shareModel = new OC.Share.ShareItemModel(properties, { configModel: configModel, fileInfoModel: fileInfoModel }); @@ -91,7 +91,8 @@ describe('OC.Share.ShareDialogShareeListView', function () { describe('rendering', function() { it('Renders shares', function() { - shareModel.set('shares', [{ + shareModel.set('shares', [ + { id: 100, item_source: 123, permissions: 1, @@ -99,10 +100,12 @@ describe('OC.Share.ShareDialogShareeListView', function () { share_with: 'user1', share_with_displayname: 'User One', share_with_additional_info: 'user1@example.com' - }, { + }, + { id: 101, item_source: 123, permissions: 1, + attributes: [], share_type: OC.Share.SHARE_TYPE_GROUP, share_with: 'group1', share_with_displayname: 'Group One' @@ -122,9 +125,39 @@ describe('OC.Share.ShareDialogShareeListView', function () { expect($li.find('.username').text()).toEqual('Group One (group)'); expect($li.find('.user-additional-info').length).toEqual(0); }); + + it('renders share attribute correctly', function () { + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute", + default: true, + label: "test attribute", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [], + incompatibleAttributes: [] + }); + + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'test-attribute', enabled: true }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + + listView.render(); + var $li = listView.$('li').eq(0); + var input = $li.find("input[name='test-attribute']"); + expect(input.is(':checked')).toEqual(true); + expect($("label[for='" + input.attr('id') + "']").text()).toEqual('test attribute'); + }); }); describe('Manages checkbox events correctly', function () { + it('Checks cruds boxes when edit box checked', function () { shareModel.set('shares', [{ id: 100, @@ -196,6 +229,7 @@ describe('OC.Share.ShareDialogShareeListView', function () { expect(listView.$el.find("input[name='mailNotification']").length).toEqual(0); }); + it('displays error if email notification not sent', function () { var notifStub = sinon.stub(OC.dialogs, 'alert'); shareModel.set('shares', [{ @@ -222,6 +256,197 @@ describe('OC.Share.ShareDialogShareeListView', function () { expect(listView.$el.find("input[name='mailNotification']").hasClass('hidden')).toEqual(false); }); + it('unchecks share attribute when clicked on checked', function () { + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute", + default: true, + label: "test attribute", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [], + incompatibleAttributes: [] + }); + + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'test-attribute', enabled: true }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + + listView.render(); + listView.$el.find("input[name='test-attribute']").click(); + expect(listView.$el.find("input[name='test-attribute']").is(':checked')).toEqual(false); + expect(updateShareStub.calledOnce).toEqual(true); + }); + + it('shows share attribute checkbox when checking required permission', function () { + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute", + default: true, + label: "test attribute", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [ OC.PERMISSION_UPDATE ], + incompatibleAttributes: [] + }); + + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + + listView.render(); + + expect(listView.$el.find("input[name='test-attribute']").length > 0).toEqual(false); + + updateShareStub.callsFake(function() { + // Updated share permission should now enable the permission + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'test-attribute', enabled: true }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + }); + + // Click on update should cause attribute test-attribute + // to appear as requiredPermissions got satisfied + listView.$el.find("input[name='update']").click(); + expect(listView.$el.find("input[name='test-attribute']").is(':checked')).toEqual(true); + expect(updateShareStub.calledOnce).toEqual(true); + }); + + it('shows share attribute checkbox when unchecking incompatible attribute', function () { + shareModel.registerShareAttribute({ + scope: "test", + key: "incompatible-attribute", + default: true, + label: "incompatible attribute", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [ ], + incompatibleAttributes: [] + }); + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute", + default: true, + label: "test attribute", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [ ], + incompatibleAttributes: [{ scope: 'test', key: 'incompatible-attribute', enabled: true }] + }); + + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'incompatible-attribute', enabled: true }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + + listView.render(); + + expect(listView.$el.find("input[name='incompatible-attribute']").is(':checked')).toEqual(true); + expect(listView.$el.find("input[name='test-attribute']").length > 0).toEqual(false); + + updateShareStub.callsFake(function() { + // Updated share permission should now enable the permission + shareModel.set('shares', [{ + id: 100, + item_source: 123, + permissions: 1, + attributes: [ + { scope: 'test', key: 'incompatible-attribute', enabled: false }, + { scope: 'test', key: 'test-attribute', enabled: true } + ], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }]); + }); + + listView.$el.find("input[name='incompatible-attribute']").click(); + + expect(listView.$el.find("input[name='incompatible-attribute']").is(':checked')).toEqual(false); + expect(listView.$el.find("input[name='test-attribute']").is(':checked')).toEqual(true); + expect(updateShareStub.calledOnce).toEqual(true); + }); + + it('prevents checking/unchecking attribute when reshared', function () { + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute-checked", + default: true, + label: "test attribute checked", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [], + incompatibleAttributes: [] + }); + shareModel.registerShareAttribute({ + scope: "test", + key: "test-attribute-unchecked", + default: false, + label: "test attribute unchecked", + shareType : [], + incompatiblePermissions: [], + requiredPermissions: [], + incompatibleAttributes: [] + }); + + shareModel.set('reshare', { + uid_owner: 100 + }); + shareModel.set('shares', [ + { + id: 100, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'test-attribute-checked', enabled: true }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + }, + { + id: 101, + item_source: 123, + permissions: 1, + attributes: [{ scope: 'test', key: 'test-attribute-unchecked', enabled: false }], + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user2', + share_with_displayname: 'User Two' + } + ]); + + listView.render(); + + // Click should have no action + listView.$el.find("input[name='test-attribute-checked']").click(); + expect(listView.$el.find("input[name='test-attribute-checked']").is(':checked')).toEqual(true); + listView.$el.find("input[name='test-attribute-unchecked']").click(); + expect(listView.$el.find("input[name='test-attribute-unchecked']").is(':checked')).toEqual(false); + + // Update never called when clicked + expect(updateShareStub.called).toEqual(false); + }); }); }); diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js index c71fec21700a..261408d42f11 100644 --- a/core/js/tests/specs/shareitemmodelSpec.js +++ b/core/js/tests/specs/shareitemmodelSpec.js @@ -47,13 +47,13 @@ describe('OC.Share.ShareItemModel', function() { sharePermissions: 31 }); - var attributes = { + var properties = { itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', itemSource: fileInfoModel.get('id'), possiblePermissions: fileInfoModel.get('sharePermissions') }; configModel = new OC.Share.ShareConfigModel(); - model = new OC.Share.ShareItemModel(attributes, { + model = new OC.Share.ShareItemModel(properties, { configModel: configModel, fileInfoModel: fileInfoModel }); @@ -118,7 +118,7 @@ describe('OC.Share.ShareItemModel', function() { fetchReshareStub = null; }); - it('populates attributes with parsed response', function() { + it('populates properties with parsed response', function() { /* jshint camelcase: false */ fetchReshareDeferred.resolve(makeOcsResponse([ { @@ -133,6 +133,7 @@ describe('OC.Share.ShareItemModel', function() { id: 100, item_source: 123, permissions: 31, + attributes: '[{"scope":"test","key":"test","enabled":false}]', share_type: OC.Share.SHARE_TYPE_USER, share_with: 'user1', share_with_displayname: 'User One' @@ -140,6 +141,7 @@ describe('OC.Share.ShareItemModel', function() { id: 101, item_source: 123, permissions: 31, + attributes: '[]', share_type: OC.Share.SHARE_TYPE_GROUP, share_with: 'group', share_with_displayname: 'group' @@ -147,6 +149,7 @@ describe('OC.Share.ShareItemModel', function() { id: 102, item_source: 123, permissions: 31, + attributes: '[]', share_type: OC.Share.SHARE_TYPE_REMOTE, share_with: 'foo@bar.com/baz', share_with_displayname: 'foo@bar.com/baz' @@ -200,6 +203,7 @@ describe('OC.Share.ShareItemModel', function() { expect(shares.length).toEqual(3); expect(shares[0].id).toEqual(100); expect(shares[0].permissions).toEqual(31); + expect(shares[0].attributes).toEqual([{ scope: 'test', key: 'test', enabled: false }]); expect(shares[0].share_type).toEqual(OC.Share.SHARE_TYPE_USER); expect(shares[0].share_with).toEqual('user1'); expect(shares[0].share_with_displayname).toEqual('User One'); @@ -587,6 +591,328 @@ describe('OC.Share.ShareItemModel', function() { }); }); + describe('share attributes', function() { + beforeEach(function() { + model.set({ + reshare: {}, + shares: [], + _registeredAttributes: [] + }); + }); + + /** + * Creates dummy attribute + * + * @return {OC.Share.Types.RegisteredShareAttribute} registered attribute + */ + function createRegisteredAttribute() { + return { + scope: "test", + key: "test", + default: true, + label: "test", + shareType : [ + OC.Share.SHARE_TYPE_GROUP, + OC.Share.SHARE_TYPE_USER + ], + incompatiblePermissions: [], + requiredPermissions: [], + incompatibleAttributes: [] + }; + } + + /** + * Parses attributes of share creation + * request (request send to the server) + * + * @return {OC.Share.Types.ShareAttribute[]} + */ + function parseLastRequestAttributes() { + var requestBody = OC.parseQueryString(fakeServer.requests[0].requestBody); + + var i = -1; + var attributes = []; + _.map(Object.keys(requestBody), function(key) { + if (key.indexOf('attributes') !== -1) { + if (key.indexOf('scope') !== -1) { + i = i + 1; + attributes.push({}); + attributes[i].scope = requestBody[key]; + } + if (key.indexOf('key') !== -1) { + attributes[i].key = requestBody[key]; + } + if (key.indexOf('enabled') !== -1) { + attributes[i].enabled = JSON.parse(requestBody[key]); + } + } + }); + + //console.log(requestBody); + return attributes; + } + + /** + * Tests sharing with the given possible attributes + * + * @param {int} permissionsToSet + * @param {OC.Share.Types.RegisteredShareAttribute[]} attributesToRegister + * @param {Object} sharePropertiesToUpdate + * @return {OC.Share.Types.ShareAttribute[]} + */ + function testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) { + model.set({ + permissions: permissionsToSet, + possiblePermissions: permissionsToSet + }); + + _.map(attributesToRegister, function (attributeToRegister) { + model.registerShareAttribute(attributeToRegister); + }); + + if (Object.keys(sharePropertiesToUpdate).length > 0) { + // if there are properties to update, update share + model.updateShare(123, sharePropertiesToUpdate, {}); + } { + // no share properties to update, so new share + model.addShare({ + shareType: OC.Share.SHARE_TYPE_USER, + shareWith: 'user2' + }); + } + + return parseLastRequestAttributes(); + } + + describe('new share', function() { + + it('returns no attributes when no registered attributes', function () { + // define test + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE; + var attributesToRegister = []; + var sharePropertiesToUpdate = {}; + + // define expected result and test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual([]); + }); + + it('uses registered attributes as default attributes', function () { + // define test + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE; + var attr1 = createRegisteredAttribute(); + var attributesToRegister = [ + attr1 + ]; + var sharePropertiesToUpdate = {}; + + // define expected result + var attributesToExpect = [ + {scope: "test", key: "test", enabled: true} + ]; + + // test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual(attributesToExpect); + }); + + it('properly filters registered attributes', function () { + var attr1 = createRegisteredAttribute(); + attr1.key = "requires-create"; + attr1.incompatiblePermissions = []; + attr1.requiredPermissions = [OC.PERMISSION_CREATE]; + attr1.incompatibleAttributes = []; + + var attr2 = createRegisteredAttribute(); + attr2.key = "requires-update"; + attr2.incompatiblePermissions = []; + attr2.requiredPermissions = [OC.PERMISSION_UPDATE]; + attr2.incompatibleAttributes = []; + + var attr3 = createRegisteredAttribute(); + attr3.key = "incompatible-create"; + attr3.incompatiblePermissions = [OC.PERMISSION_CREATE]; + attr3.requiredPermissions = []; + attr3.incompatibleAttributes = []; + + var attr4 = createRegisteredAttribute(); + attr4.key = "incompatible-update"; + attr4.incompatiblePermissions = [OC.PERMISSION_UPDATE]; + attr4.requiredPermissions = []; + attr4.incompatibleAttributes = []; + + var attr5 = createRegisteredAttribute(); + attr5.key = "incompatible-attribute-requires-update-true"; + attr5.incompatiblePermissions = []; + attr5.requiredPermissions = []; + attr5.incompatibleAttributes = [{ + scope: "test", + key: "requires-update", + enabled: true + }]; + + var attr6 = createRegisteredAttribute(); + attr6.key = "incompatible-attribute-requires-update-false"; + attr6.incompatiblePermissions = []; + attr6.requiredPermissions = []; + attr6.incompatibleAttributes = [{ + scope: "test", + key: "requires-update", + enabled: false + }]; + + // register attribute + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE; + var attributesToRegister = [ + attr1, attr2, attr3, attr4, attr5, attr6 + ]; + + // this test does not update existing share + var sharePropertiesToUpdate = {}; + + // expect that new created share will have following attributes + var attributesToExpect = [ + {scope: "test", key: "requires-update", enabled: true}, + {scope: "test", key: "incompatible-create", enabled: true}, + { + scope: "test", + key: "incompatible-attribute-requires-update-false", + enabled: true + } + ]; + + // test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual(attributesToExpect); + }); + }); + + describe('update share', function() { + it('returns no attributes when update with new attribute but none registered (error handling scenario)', function() { + // define test + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE; + var attributesToRegister = []; + var sharePropertiesToUpdate = { + attributes: [ + { scope: "test", key: "test", enabled: false } + ], + permissions: permissionsToSet + }; + + // define expected result and test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual([]); + }); + + it('updates attribute with new enabled value correctly', function() { + // define test + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE; + + var attr1 = createRegisteredAttribute(); + attr1.scope = "test"; + attr1.key = "test"; + attr1.default = true; + var attributesToRegister = [attr1]; + + var sharePropertiesToUpdate = { + attributes: [ + { scope: "test", key: "test", enabled: false } + ], + permissions: permissionsToSet + }; + + // define expected result + var attributesToExpect = [ + { scope: "test", key: "test", enabled: false } + ]; + + // test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual(attributesToExpect); + }); + + it('uses/hides attributes with permission filters of registered attributes', function() { + // define test + var permissionsToSet = OC.PERMISSION_READ; + + var attr1 = createRegisteredAttribute(); + attr1.key = "incompatible-create"; + attr1.incompatiblePermissions = [ OC.PERMISSION_CREATE ]; + attr1.requiredPermissions = []; + attr1.incompatibleAttributes = []; + var attr2 = createRegisteredAttribute(); + attr2.key = "required-create"; + attr2.incompatiblePermissions = []; + attr2.requiredPermissions = [ OC.PERMISSION_CREATE ]; + attr2.incompatibleAttributes = []; + + var attributesToRegister = [attr1, attr2]; + + var sharePropertiesToUpdate = { + permissions: OC.PERMISSION_READ | OC.PERMISSION_CREATE + }; + + // define expected result + var attributesToExpect = [ + { scope: "test", key: "required-create", enabled: true } + ]; + + // test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual(attributesToExpect); + }); + + it('uses/hides attributes with attribute filter of registered attributes when permission changes', function() { + // define test + var permissionsToSet = OC.PERMISSION_READ | OC.PERMISSION_UPDATE; + + // test attribute which is enabled only without update permission + var attr1 = createRegisteredAttribute(); + attr1.key = "incompatible-update"; + attr1.incompatiblePermissions = [ OC.PERMISSION_UPDATE ]; + attr1.requiredPermissions = [ ]; + attr1.incompatibleAttributes = []; + + // test attribute which is not available when review attr is enabled + var attr2 = createRegisteredAttribute(); + attr2.key = "incompatible-with-attribute"; + attr2.incompatiblePermissions = []; + attr2.requiredPermissions = []; + attr2.incompatibleAttributes = [{ scope: "test", key: "incompatible-update", enabled: true }]; + + // test attribute that can always be registered + var attr3 = createRegisteredAttribute(); + attr3.key = "test-attribute"; + attr3.incompatiblePermissions = []; + attr3.requiredPermissions = []; + attr3.incompatibleAttributes = []; + + var attributesToRegister = [attr1, attr2, attr3]; + + var sharePropertiesToUpdate = { + permissions: OC.PERMISSION_READ + }; + + // define expected result - restricted-options should not appear + var attributesToExpect = [ + { scope: "test", key: "incompatible-update", enabled: true }, + { scope: "test", key: "test-attribute", enabled: true } + ]; + + // test + expect( + testShareWithAttributes(permissionsToSet, attributesToRegister, sharePropertiesToUpdate) + ).toEqual(attributesToExpect); + }); + }); + }); + describe('creating shares', function() { it('sends POST method to endpoint with passed values', function() { model.addShare({