/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2015-2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
describe('OCA.Files_External.Settings tests', function() {
var clock;
var select2Stub;
var select2ApplicableUsers;
beforeEach(function() {
clock = sinon.useFakeTimers();
select2ApplicableUsers = [];
select2Stub = sinon.stub($.fn, 'select2').callsFake(function(args) {
if (args === 'val') {
return select2ApplicableUsers;
}
return {
on: function() { return this; }
};
});
// view still requires an existing DOM table
$('#testArea').append(
'
'
);
// these are usually appended into the data attribute
// within the DOM by the server template
$('#externalStorage .selectBackend:first').data('configurations', {
'\\OC\\TestBackend': {
'identifier': '\\OC\\TestBackend',
'name': 'Test Backend',
'configuration': {
'field1': {
'value': 'Display Name 1'
},
'field2': {
'value': 'Display Name 2',
'flags': 1
}
},
'authSchemes': {
'builtin': true,
},
'priority': 11
},
'\\OC\\AnotherTestBackend': {
'identifier': '\\OC\\AnotherTestBackend',
'name': 'Another Test Backend',
'configuration': {
'field1': {
'value': 'Display Name 1'
},
'field2': {
'value': 'Display Name 2',
'flags': 1
}
},
'authSchemes': {
'builtin': true,
},
'priority': 12
},
'\\OC\\InputsTestBackend': {
'identifier': '\\OC\\InputsTestBackend',
'name': 'Inputs test backend',
'configuration': {
'field_text': {
'value': 'Text field'
},
'field_password': {
'value': ',Password field',
'type': 2
},
'field_bool': {
'value': 'Boolean field',
'type': 1
},
'field_hidden': {
'value': 'Hidden field',
'type': 3
},
'field_text_optional': {
'value': 'Text field optional',
'flags': 1
},
'field_password_optional': {
'value': 'Password field optional',
'flags': 1,
'type': 2
}
},
'authSchemes': {
'builtin': true,
},
'priority': 13
}
}
);
$('#externalStorage #addMountPoint .authentication:first').data('mechanisms', {
'mechanism1': {
'identifier': 'mechanism1',
'name': 'Mechanism 1',
'configuration': {
},
'scheme': 'builtin',
'visibility': 3
},
});
});
afterEach(function() {
select2Stub.restore();
clock.restore();
});
describe('storage configuration', function() {
var view;
function selectBackend(backendName) {
view.$el.find('.selectBackend:first').val(backendName).trigger('change');
view.$el.find('.applicableToAllUsers').prop('checked', true).trigger('change');
}
beforeEach(function() {
var $el = $('#externalStorage');
view = new OCA.Files_External.Settings.MountConfigListView($el, {encryptionEnabled: false});
});
afterEach(function() {
view = null;
});
describe('selecting backend', function() {
it('populates the row and creates a new empty one', function() {
selectBackend('\\OC\\TestBackend');
var $firstRow = view.$el.find('tr:first');
expect($firstRow.find('.backend').text()).toEqual('Test Backend');
expect($firstRow.find('.selectBackend').length).toEqual(0);
// TODO: check "remove" button visibility
// the suggested mount point name
expect($firstRow.find('[name=mountPoint]').val()).toEqual('TestBackend');
// TODO: check that the options have been created
// TODO: check select2 call on the ".applicableUsers" element
var $emptyRow = $firstRow.next('tr');
expect($emptyRow.length).toEqual(1);
expect($emptyRow.find('.selectBackend').length).toEqual(1);
expect($emptyRow.find('.applicable select').length).toEqual(0);
// TODO: check "remove" button visibility
});
it('shows row even if selection row is hidden', function() {
selectBackend('\\OC\\TestBackend');
view.$el.find('tr#addMountPoint').hide();
expect(view.$el.find('tr:first').is(':visible')).toBe(true);
expect(view.$el.find('tr#addMountPoint').is(':visible')).toBe(false);
});
// TODO: test with personal mounts (no applicable fields)
// TODO: test suggested mount point logic
});
describe('saving storages', function() {
var $tr;
beforeEach(function() {
selectBackend('\\OC\\TestBackend');
$tr = view.$el.find('tr:first');
});
it('saves storage after clicking the save button', function() {
var $field1 = $tr.find('input[data-parameter=field1]');
expect($field1.length).toEqual(1);
$field1.val('test');
$field1.trigger(new $.Event('keyup', {keyCode: 97}));
var $mountOptionsField = $tr.find('input.mountOptions');
expect($mountOptionsField.length).toEqual(1);
$mountOptionsField.val(JSON.stringify({previews:true}));
var $saveButton = $tr.find('td.save .icon-checkmark');
$saveButton.click();
expect(fakeServer.requests.length).toEqual(1);
var request = fakeServer.requests[0];
expect(request.url).toEqual(OC.getRootPath() + '/index.php/apps/files_external/globalstorages');
expect(JSON.parse(request.requestBody)).toEqual({
backend: '\\OC\\TestBackend',
authMechanism: 'mechanism1',
backendOptions: {
'field1': 'test',
'field2': ''
},
mountPoint: 'TestBackend',
priority: 11,
applicableUsers: [],
applicableGroups: [],
mountOptions: {
'previews': true
},
testOnly: true
});
// TODO: respond and check data-id
});
it('saves storage with applicable users', function() {
var $field1 = $tr.find('input[data-parameter=field1]');
expect($field1.length).toEqual(1);
$field1.val('test');
$field1.trigger(new $.Event('keyup', {keyCode: 97}));
$tr.find('.applicableToAllUsers').prop('checked', false).trigger('change');
select2ApplicableUsers = ['user1', 'user2', 'group1(group)', 'group2(group)'];
var $saveButton = $tr.find('td.save .icon-checkmark');
$saveButton.click();
expect(fakeServer.requests.length).toEqual(1);
var request = fakeServer.requests[0];
expect(request.url).toEqual(OC.getRootPath() + '/index.php/apps/files_external/globalstorages');
expect(JSON.parse(request.requestBody)).toEqual({
backend: '\\OC\\TestBackend',
authMechanism: 'mechanism1',
backendOptions: {
'field1': 'test',
'field2': ''
},
mountPoint: 'TestBackend',
priority: 11,
applicableUsers: ['user1', 'user2'],
applicableGroups: ['group1', 'group2'],
mountOptions: {
encrypt: true,
previews: true,
enable_sharing: false,
filesystem_check_changes: 1,
encoding_compatibility: false,
readonly: false,
},
testOnly: true
});
// TODO: respond and check data-id
});
it('does not saves storage without applicable users and unchecked all users checkbox', function() {
var $field1 = $tr.find('input[data-parameter=field1]');
expect($field1.length).toEqual(1);
$field1.val('test');
$field1.trigger(new $.Event('keyup', {keyCode: 97}));
$tr.find('.applicableToAllUsers').prop('checked', false).trigger('change');
var $saveButton = $tr.find('td.save .icon-checkmark');
$saveButton.click();
expect(fakeServer.requests.length).toEqual(0);
});
it('saves storage after closing mount options popovermenu', function() {
$tr.find('.mountOptionsToggle .icon-more').click();
$tr.find('[name=previews]').trigger(new $.Event('keyup', {keyCode: 97}));
$tr.find('input[data-parameter=field1]').val('test');
// does not save inside the popovermenu
expect(fakeServer.requests.length).toEqual(0);
$('body').mouseup();
// but after closing the popovermenu
expect(fakeServer.requests.length).toEqual(1);
});
// TODO: status indicator
});
describe('validate storage configuration', function() {
var $tr;
beforeEach(function() {
selectBackend('\\OC\\InputsTestBackend');
$tr = view.$el.find('tr:first');
});
it('lists missing fields in storage errors', function() {
$tr.find('.applicableToAllUsers').prop('checked', false).trigger('change');
var storage = view.getStorageConfig($tr);
expect(storage.errors).toEqual({
backendOptions: ['field_text', 'field_password'],
requiredApplicable: true,
});
});
it('does not list applicable when all users checkbox is ticked', function() {
var storage = view.getStorageConfig($tr);
expect(storage.errors).toEqual({
backendOptions: ['field_text', 'field_password']
});
});
it('highlights missing non-optional fields', function() {
_.each([
'field_text',
'field_password'
], function(param) {
expect($tr.find('input[data-parameter='+param+']').hasClass('warning-input')).toBe(true);
});
_.each([
'field_bool',
'field_hidden',
'field_text_optional',
'field_password_optional'
], function(param) {
expect($tr.find('input[data-parameter='+param+']').hasClass('warning-input')).toBe(false);
});
});
it('validates correct storage', function() {
$tr.find('[name=mountPoint]').val('mountpoint');
$tr.find('input[data-parameter=field_text]').val('foo');
$tr.find('input[data-parameter=field_password]').val('bar');
$tr.find('input[data-parameter=field_text_optional]').val('foobar');
// don't set field_password_optional
$tr.find('input[data-parameter=field_hidden]').val('baz');
var storage = view.getStorageConfig($tr);
expect(storage.validate()).toBe(true);
});
it('checks missing mount point', function() {
$tr.find('[name=mountPoint]').val('');
$tr.find('input[data-parameter=field_text]').val('foo');
$tr.find('input[data-parameter=field_password]').val('bar');
var storage = view.getStorageConfig($tr);
expect(storage.validate()).toBe(false);
});
});
describe('update storage', function() {
// TODO
});
describe('delete storage', function() {
// TODO
});
describe('recheck storages', function() {
// TODO
});
describe('mount options popovermenu', function() {
var $tr;
var $td;
beforeEach(function() {
selectBackend('\\OC\\TestBackend');
$tr = view.$el.find('tr:first');
$td = $tr.find('.mountOptionsToggle');
});
it('shows popovermenu when clicking on toggle button, hides when clicking outside', function() {
$td.find('.icon-more').click();
expect($td.find('.popovermenu.open').length).toEqual(1);
$('body').mouseup();
expect($td.find('.popovermenu.open').length).toEqual(0);
});
it('doesnt show the encryption option when encryption is disabled', function () {
view._encryptionEnabled = false;
$td.find('.icon-more').click();
expect($td.find('.popovermenu [name=encrypt]:visible').length).toEqual(0);
$('body').mouseup();
expect($td.find('.popovermenu.open').length).toEqual(0);
});
it('reads config from mountOptions field', function() {
$tr.find('input.mountOptions').val(JSON.stringify({previews:false}));
$td.find('.icon-more').click();
expect($td.find('.popovermenu [name=previews]').prop('checked')).toEqual(false);
$('body').mouseup();
$tr.find('input.mountOptions').val(JSON.stringify({previews:true}));
$td.find('.icon-more').click();
expect($td.find('.popovermenu [name=previews]').prop('checked')).toEqual(true);
});
it('writes config into mountOptions field', function() {
$td.find('.icon-more').click();
// defaults to true
var $field = $td.find('.popovermenu [name=previews]');
expect($field.prop('checked')).toEqual(true);
$td.find('.popovermenu [name=filesystem_check_changes]').val(0);
$('body').mouseup();
expect(JSON.parse($tr.find('input.mountOptions').val())).toEqual({
encrypt: true,
previews: true,
enable_sharing: false,
filesystem_check_changes: 0,
encoding_compatibility: false,
readonly: false
});
});
});
});
describe('allow user mounts section', function() {
// TODO: test allowUserMounting section
});
});