Move app to own repo

https://github.com/nextcloud/bruteforcesettings

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2017-04-02 21:26:02 +02:00
parent ed00bab80b
commit e09c386f70
No known key found for this signature in database
GPG Key ID: F941078878347C0C
13 changed files with 0 additions and 876 deletions

View File

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<info>
<id>bruteforcesettings</id>
<name>Brute force settings</name>
<description>
This applications allows admins to configure the brute force settings.
</description>
<licence>AGPL</licence>
<author>Roeland Jago Douma</author>
<default_enable/>
<version>1.0.0</version>
<category>other</category>
<dependencies>
<nextcloud min-version="12" max-version="12" />
</dependencies>
<namespace>BruteForceSettings</namespace>
<settings>
<admin>OCA\BruteForceSettings\Settings\IPWhitelist</admin>
</settings>
</info>

View File

@ -1,30 +0,0 @@
<?php
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
return [
'routes' => [
[ 'name' => 'IPWhitelist#getAll', 'url' => '/ipwhitelist', 'verb' => 'GET' ],
[ 'name' => 'IPWhitelist#add', 'url' => '/ipwhitelist', 'verb' => 'POST' ],
[ 'name' => 'IPWhitelist#remove', 'url' => '/ipwhitelist/{id}', 'verb' => 'DELETE' ],
]
];

View File

@ -1,17 +0,0 @@
#whitelist-list {
min-width: 262px;
}
#whitelist-list td span {
padding: 10px 15px;
display: inline-block;
}
#whitelist-list .action-column {
width: 46px;
}
#whitelist-list .action-column a {
display: inline-block;
}

View File

@ -1,44 +0,0 @@
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
(function() {
OCA.BruteForceSettings = OCA.BruteForceSettings || {};
OCA.BruteForceSettings.WhiteList = {
collection: null,
view: null,
init: function () {
this.collection = new OCA.BruteForceSettings.WhitelistCollection();
this.view = new OCA.BruteForceSettings.WhitelistView({
collection: this.collection
});
this.view.reload();
}
};
})();
$(document).ready(function() {
OCA.BruteForceSettings.WhiteList.init();
});

View File

@ -1,34 +0,0 @@
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
(function() {
OCA.BruteForceSettings = OCA.BruteForceSettings || {};
OCA.BruteForceSettings.WhitelistCollection = OC.Backbone.Collection.extend({
model: OCA.BruteForceSettings.WhitelistModel,
url: function() {
return OC.generateUrl('/apps/bruteforcesettings/ipwhitelist');
}
});
})();

View File

@ -1,29 +0,0 @@
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
(function() {
OCA.BruteForceSettings = OCA.BruteForceSettings || {};
OCA.BruteForceSettings.WhitelistModel = OC.Backbone.Model.extend({
});
})();

View File

@ -1,128 +0,0 @@
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
(function () {
OCA.BruteForceSettings = OCA.BruteForceSettings || {};
var TEMPLATE_WHITELIST =
'<tr data-id="{{id}}">'
+ '<td><span>{{ip}}/{{mask}}</span></td>'
+ '<td class="action-column"><span><a class="icon-delete has-tooltip" title="' + t('bruteforcesettings', 'Delete') + '"></a></span></td>'
+ '</tr>';
OCA.BruteForceSettings.WhitelistView = OC.Backbone.View.extend({
collection: null,
ipInput: undefined,
maskInput: undefined,
submit: undefined,
list: undefined,
listHeader: undefined,
initialize: function(options) {
this.collection = options.collection;
this.ipInput = $('#whitelist_ip');
this.maskInput = $('#whitelist_mask');
this.submit = $('#whitelist_submit');
this.submit.click(_.bind(this._addWhitelist, this));
this.list = $('#whitelist-list');
this.listHeader = $('#whitelist-list-header');
this.list.on('click', 'a.icon-delete', _.bind(this._onDeleteRetention, this));
this.listenTo(this.collection, 'sync', this.render);
},
reload: function() {
var _this = this;
var loadingWhitelists = this.collection.fetch();
$.when(loadingWhitelists).done(function () {
_this.render();
});
$.when(loadingWhitelists).fail(function () {
OC.Notification.showTemporary(t('bruteforcesettings', 'Error while whitelists.'));
});
},
template: function (data) {
if (_.isUndefined(this._template)) {
this._template = Handlebars.compile(TEMPLATE_WHITELIST);
}
return this._template(data);
},
render: function () {
var _this = this;
this.list.html('');
this.collection.forEach(function (model) {
var data = {
id: model.attributes.id,
ip: model.attributes.ip,
mask: model.attributes.mask
};
var html = _this.template(data);
var $html = $(html);
_this.list.append($html);
});
},
_onDeleteRetention: function(event) {
var $target = $(event.target);
var $row = $target.closest('tr');
var id = $row.data('id');
var whitelist = this.collection.get(id);
if (_.isUndefined(whitelist)) {
// Ignore event
return;
}
var destroyingRetention = whitelist.destroy();
$row.find('.icon-delete').tooltip('hide');
var _this = this;
$.when(destroyingRetention).fail(function () {
OC.Notification.showTemporary(t('bruteforcesettings', 'Error while deleting a whitelist'));
});
$.when(destroyingRetention).always(function () {
_this.render();
});
},
_addWhitelist: function() {
this.collection.create({
ip: this.ipInput.val(),
mask: this.maskInput.val()
});
}
});
})();

View File

@ -1,123 +0,0 @@
<?php
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\BruteForceSettings\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IConfig;
use OCP\IRequest;
class IPWhitelistController extends Controller {
/** @var IConfig */
private $config;
/**
* IPWhitelistController constructor.
*
* @param string $appName
* @param IRequest $request
* @param IConfig $config
*/
public function __construct($appName,
IRequest $request,
IConfig $config) {
parent::__construct($appName, $request);
$this->config = $config;
}
/**
* @return JSONResponse
*/
public function getAll() {
$keys = $this->config->getAppKeys('bruteForce');
$keys = array_filter($keys, function($key) {
$regex = '/^whitelist_/S';
return preg_match($regex, $key) === 1;
});
$result = [];
foreach ($keys as $key) {
$value = $this->config->getAppValue('bruteForce', $key);
$values = explode('/', $value);
$result[] = [
'id' => (int)substr($key, 10),
'ip' => $values[0],
'mask' => $values[1],
];
}
return new JSONResponse($result);
}
/**
* @param string $ip
* @param int $mask
* @return JSONResponse
*/
public function add($ip, $mask) {
if (!filter_var($ip, FILTER_VALIDATE_IP) ||
(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && ($mask < 0 || $mask > 32)) ||
(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && ($mask < 0 || $mask > 128))) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST);
}
$keys = $this->config->getAppKeys('bruteForce');
$keys = array_filter($keys, function($key) {
$regex = '/^whitelist_/S';
return preg_match($regex, $key) === 1;
});
$id = 0;
foreach ($keys as $key) {
$tmp = (int)substr($key, 10);
if ($tmp > $id) {
$id = $tmp;
}
}
$id++;
$value = $ip . '/' . $mask;
$this->config->setAppValue('bruteForce', 'whitelist_'.$id, $value);
return new JSONResponse([
'id' => $id,
'ip' => $ip,
'mask' => $mask,
]);
}
/**
* @param int $id
* @return JSONResponse
*/
public function remove($id) {
$this->config->deleteAppValue('bruteForce', 'whitelist_'.$id);
return new JSONResponse([]);
}
}

View File

@ -1,42 +0,0 @@
<?php
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\BruteForceSettings\Settings;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Settings\ISettings;
class IPWhitelist implements ISettings {
public function getForm() {
return new TemplateResponse('bruteforcesettings', 'ipwhitelist');
}
public function getSection() {
return 'security';
}
public function getPriority() {
return 50;
}
}

View File

@ -1,49 +0,0 @@
<?php
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
script('core', [
'oc-backbone-webdav',
]);
script('bruteforcesettings', [
'IPWhitelist',
'IPWhitelistModel',
'IPWhitelistCollection',
'IPWhitelistView',
]);
style('bruteforcesettings', [
'settings'
])
/** @var \OCP\IL10N $l */
?>
<form id="IPWhiteList" class="section">
<h2><?php p($l->t('Brute force ip whitelist')); ?></h2>
<table id="whitelist-list">
</table>
<input type="text" name="whitelist_ip" id="whitelist_ip" placeholder="1.2.3.4" style="width: 200px;" />/
<input type="number" id="whitelist_mask" name="whitelist_mask" placeholder="24" style="width: 50px;">
<input type="button" id="whitelist_submit" value="<?php p($l->t('Add')); ?>">
</form>

View File

@ -1,151 +0,0 @@
<?php
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\BruteForceSettings\Tests\Controller;
use OCA\BruteForceSettings\Controller\IPWhitelistController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IConfig;
use OCP\IRequest;
use Test\TestCase;
class IPWhitelistControllerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var IPWhitelistController */
private $controller;
public function setUp() {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->controller = new IPWhitelistController(
'bruteforce',
$this->createMock(IRequest::class),
$this->config
);
}
public function testGetAll() {
$this->config->method('getAppKeys')
->with($this->equalTo('bruteForce'))
->willReturn([
'foobar',
'whitelist_0',
'whitelist_99',
]);
$this->config->method('getAppValue')
->will($this->returnCallback(function($app, $key) {
if ($app !== 'bruteForce') {
$this->fail();
}
if ($key === 'whitelist_0') {
return '192.168.2.0/24';
} else if ($key === 'whitelist_99') {
return 'dead:beef:cafe::/92';
}
$this->fail();
}));
$expected = new JSONResponse([
[
'id' => 0,
'ip' => '192.168.2.0',
'mask' => '24',
],
[
'id' => 99,
'ip' => 'dead:beef:cafe::',
'mask' => '92',
]
]);
$this->assertEquals($expected, $this->controller->getAll());
}
public function dataAdd() {
return [
['8.500.2.3', 24, false],
['1.2.3.4', 24, true],
['1.2.3.4', -1, false],
['1.2.3.4', 33, false],
['dead:nope::8', 24, false],
['1234:567:abef::1a2b', 24, true],
['1234:567:abef::1a2b', -1, false],
['1234:567:abef::1a2b', 129, false],
];
}
/**
* @dataProvider dataAdd
*
* @param string $ip
* @param int $mask
* @param bool $valid
*/
public function testAdd($ip, $mask, $valid) {
if (!$valid) {
$expected = new JSONResponse([], Http::STATUS_BAD_REQUEST);
} else {
$this->config->method('getAppKeys')
->with($this->equalTo('bruteForce'))
->willReturn([
'foobar',
'whitelist_0',
'whitelist_99',
]);
$this->config->expects($this->once())
->method('setAppValue')
->with(
$this->equalTo('bruteForce'),
$this->equalTo('whitelist_100'),
$this->equalTo($ip.'/'.$mask)
);
$expected = new JSONResponse([
'id' => 100,
'ip' => $ip,
'mask' => $mask,
]);
}
$this->assertEquals($expected, $this->controller->add($ip, $mask));
}
public function testRemove() {
$this->config->expects($this->once())
->method('deleteAppValue')
->with(
$this->equalTo('bruteForce'),
$this->equalTo('whitelist_42')
);
$expected = new JSONResponse([]);
$this->assertEquals($expected, $this->controller->remove(42));
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace OCA\BruteForceSettings\Tests\Settings;
use OCA\BruteForceSettings\Settings\IPWhitelist;
use OCP\AppFramework\Http\TemplateResponse;
use Test\TestCase;
class IPWhitelistTest extends TestCase {
/** @var IPWhitelist */
private $settings;
public function setUp() {
parent::setUp();
$this->settings = new IPWhitelist();
}
public function testGetForm() {
$expected = new TemplateResponse('bruteforcesettings', 'ipwhitelist');
$this->assertEquals($expected, $this->settings->getForm());
}
public function testGetSection() {
$this->assertSame('security', $this->settings->getSection());
}
public function testGetPriority() {
$this->assertSame(50, $this->settings->getPriority());
}
}

View File

@ -1,174 +0,0 @@
/**
* @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
describe('OCA.BruteForceSettings.IPWhiteList tests', function() {
beforeEach(function() {
// init parameters and test table elements
$('#testArea').append(
'<table>'+
'<tbody id="whitelist-list">' +
'</tbody>' +
'</table>' +
'<input type="text" name="whitelist_ip" id="whitelist_ip" placeholder="1.2.3.4" style="width: 200px;" />/' +
'<input type="number" id="whitelist_mask" name="whitelist_mask" placeholder="24" style="width: 50px;">' +
'<input type="button" id="whitelist_submit" value="Add">'
);
});
it('get intial empty', function() {
OCA.BruteForceSettings.WhiteList.init();
expect(fakeServer.requests.length).toEqual(1);
expect(fakeServer.requests[0].method).toEqual('GET');
expect(fakeServer.requests[0].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist')
);
fakeServer.requests[0].respond(
200,
{ 'Content-Type': 'application/json' },
'[]'
);
expect($('#whitelist-list > tr').length).toEqual(0);
});
it('get intial filled', function() {
OCA.BruteForceSettings.WhiteList.init();
expect(fakeServer.requests.length).toEqual(1);
expect(fakeServer.requests[0].method).toEqual('GET');
expect(fakeServer.requests[0].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist')
);
fakeServer.requests[0].respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify([
{
id: 1,
ip: '11.22.0.0',
mask: 16
},
{
id: 12,
ip: 'cafe:cafe::',
mask: 80
}
])
);
expect($('#whitelist-list > tr').length).toEqual(2);
var el1 = $($('#whitelist-list > tr').get(0));
expect(el1.data('id')).toEqual(1);
expect($(el1.find('td > span')[0]).html()).toEqual('11.22.0.0/16');
var el2 = $($('#whitelist-list > tr').get(1));
expect(el2.data('id')).toEqual(12);
expect($(el2.find('td > span')[0]).html()).toEqual('cafe:cafe::/80');
});
it('add whitelist', function() {
OCA.BruteForceSettings.WhiteList.init();
expect(fakeServer.requests.length).toEqual(1);
expect(fakeServer.requests[0].method).toEqual('GET');
expect(fakeServer.requests[0].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist')
);
fakeServer.requests[0].respond(
200,
{ 'Content-Type': 'application/json' },
'[]'
);
expect($('#whitelist-list > tr').length).toEqual(0);
$('#whitelist_ip').val('2.4.8.16');
$('#whitelist_mask').val('8');
$('#whitelist_submit').click();
expect(fakeServer.requests.length).toEqual(2);
expect(fakeServer.requests[1].method).toEqual('POST');
expect(JSON.parse(fakeServer.requests[1].requestBody)).toEqual({
ip: '2.4.8.16',
mask: '8'
});
expect(fakeServer.requests[1].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist')
);
fakeServer.requests[1].respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify({
id: 99,
ip: '2.4.8.16',
mask: 8
})
);
expect($('#whitelist-list > tr').length).toEqual(1);
var el1 = $($('#whitelist-list > tr').get(0));
expect(el1.data('id')).toEqual(99);
expect($(el1.find('td > span')[0]).html()).toEqual('2.4.8.16/8');
});
it('delete whitelist', function() {
OCA.BruteForceSettings.WhiteList.init();
expect(fakeServer.requests.length).toEqual(1);
expect(fakeServer.requests[0].method).toEqual('GET');
expect(fakeServer.requests[0].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist')
);
fakeServer.requests[0].respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify([
{
id: 1,
ip: '1.2.3.4',
mask: 8
}
])
);
expect($('#whitelist-list > tr').length).toEqual(1);
var el1 = $($('#whitelist-list > tr').get(0));
expect(el1.data('id')).toEqual(1);
expect($(el1.find('td > span')[0]).html()).toEqual('1.2.3.4/8');
el1.find('.icon-delete').click();
expect(fakeServer.requests.length).toEqual(2);
expect(fakeServer.requests[1].method).toEqual('DELETE');
expect(fakeServer.requests[1].url).toEqual(
OC.generateUrl('/apps/bruteforcesettings/ipwhitelist/1')
);
fakeServer.requests[1].respond(
200,
{ 'Content-Type': 'application/json' },
'[]'
);
expect($('#whitelist-list > tr').length).toEqual(0);
});
});