We can just undo this commit for the new one to be used in the create form as soon as it is ready.pull/4338/head
parent
9c6c56bf00
commit
d67dd289ac
@ -0,0 +1,65 @@ |
||||
<div class="work-packages--attachments attributes-group"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text"> |
||||
{{ ::I18n.t('js.label_attachments') }} |
||||
</h3> |
||||
</div> |
||||
</div> |
||||
<div class="work-package--attachments--files" |
||||
data-ng-show="attachments.length > 0"> |
||||
<div class="work-package--details--long-field"> |
||||
<span class="inplace-edit--read" |
||||
data-ng-repeat="attachment in attachments"> |
||||
<span class="inplace-editing--trigger-container"> |
||||
<span class="inplace-editing--trigger-link" |
||||
ng-class="{'-focus': focussing(attachment)}"> |
||||
<span class="inplace-editing--container"> |
||||
<span class="inplace-edit--read-value"> |
||||
<i class="icon-attachment"></i> |
||||
<a class="work-package--attachments--filename" |
||||
data-ng-href="{{attachment._links.downloadLocation.href}}" |
||||
download |
||||
data-ng-focus="focus(attachment)" |
||||
data-ng-blur="focus(null)"> |
||||
{{::attachment.fileName}} |
||||
</a> |
||||
</span> |
||||
<a href='' |
||||
class="inplace-edit--icon-wrapper" |
||||
data-ng-focus="focus(attachment)" |
||||
data-ng-blur="focus(null)" |
||||
data-ng-click="remove(attachment)" |
||||
data-confirm-popup="{{I18n.t('js.text_attachment_destroy_confirmation')}}"> |
||||
|
||||
<icon-wrapper icon-name="delete" |
||||
data-icon-title="{{::I18n.t('js.label_remove_file', |
||||
{ fileName: attachment.fileName })}}"> |
||||
</icon-wrapper> |
||||
</a> |
||||
</span> |
||||
</span> |
||||
</span> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
<div data-ng-show="hasRightToUpload" |
||||
data-ngf-drop |
||||
data-ng-model="files" |
||||
data-ng-model-rejected="rejectedFiles" |
||||
data-ngf-select |
||||
class="work-package--attachments--drop-box" |
||||
data-ngf-multiple="true" |
||||
data-ngf-change="uploadFilteredFiles($files)" |
||||
data-ngf-max-size="{{::maximumFileSize}}" |
||||
data-click-on-keypress="[13, 32]"> |
||||
<div class="work-package--attachments--label"> |
||||
<i class="icon-attachment"></i> |
||||
<p> |
||||
{{ ::I18n.t('js.label_drop_files') }} |
||||
<br> |
||||
{{ ::I18n.t('js.label_drop_files_hint') }} |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,72 @@ |
||||
<div class="work-packages--attachments attributes-group"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text"> |
||||
{{ ::I18n.t('js.label_attachments') }} |
||||
</h3> |
||||
</div> |
||||
</div> |
||||
<div class="work-package--attachments--files" |
||||
data-ng-show="files.length > 0"> |
||||
<div class="work-package--details--long-field"> |
||||
<span class="inplace-edit--read" |
||||
data-ng-repeat="attachment in files"> |
||||
<span class="inplace-editing--trigger-container"> |
||||
<span class="inplace-editing--trigger-link" |
||||
ng-class="{'-focus': focussing(attachment)}"> |
||||
<span class="inplace-editing--container"> |
||||
<span class="inplace-edit--read-value"> |
||||
<i class="icon-attachment"></i> |
||||
<a class="work-package--attachments--filename -no-decoration" |
||||
href="" |
||||
data-ng-focus="focus(attachment)" |
||||
data-ng-blur="focus(null)" |
||||
ng-click="true"> |
||||
{{::attachment.name}} |
||||
</a> |
||||
</span> |
||||
<a href='' |
||||
class="inplace-edit--icon-wrapper" |
||||
data-ng-focus="focus(attachment)" |
||||
data-ng-blur="focus(null)" |
||||
data-ng-click="remove(attachment)" |
||||
data-confirm-popup="{{I18n.t('js.text_attachment_destroy_confirmation')}}"> |
||||
|
||||
<icon-wrapper icon-name="delete" |
||||
data-icon-title="{{::I18n.t('js.label_remove_file', |
||||
{ fileName: attachment.name })}}"> |
||||
</icon-wrapper> |
||||
</a> |
||||
</span> |
||||
</span> |
||||
</span> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
<div data-ngf-drop |
||||
data-ng-show="hasRightToUpload" |
||||
data-ng-model="files" |
||||
data-ng-model-rejected="rejectedFiles" |
||||
data-ngf-select |
||||
class="work-package--attachments--drop-box" |
||||
data-ngf-multiple="true" |
||||
data-ngf-allow-dir="true" |
||||
data-ngf-keep-distinct |
||||
data-ngf-max-size="{{::maximumFileSize}}" |
||||
data-ng-disabled="fetchingConfiguration" |
||||
data-ngf-keep="true" |
||||
data-ngf-change="filterFiles($files)" |
||||
data-click-on-keypress="[13, 32]"> |
||||
<div class="work-package--attachments--label"> |
||||
<i class="icon-attachment"></i> |
||||
<p data-ng-hide="fetchingConfiguration"> |
||||
{{ ::I18n.t('js.label_drop_files') }} |
||||
<br> |
||||
{{ ::I18n.t('js.label_drop_files_hint') }} |
||||
</p> |
||||
<p data-ng-show="fetchingConfiguration"> |
||||
{{ ::I18n.t('js.label_wait') }} |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,155 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
module.exports = function( |
||||
workPackageAttachmentsService, |
||||
NotificationsService, |
||||
I18n, |
||||
ConfigurationService, |
||||
ConversionService |
||||
) { |
||||
'use strict'; |
||||
var editMode = function(attrs) { |
||||
return typeof attrs.edit !== 'undefined'; |
||||
}; |
||||
|
||||
var attachmentsController = function(scope, element, attrs) { |
||||
scope.files = []; |
||||
scope.element = element; |
||||
|
||||
var workPackage = scope.workPackage(), |
||||
upload = function(event, workPackage) { |
||||
if (angular.isUndefined(scope.files)) { |
||||
return; |
||||
} |
||||
if (scope.files.length > 0) { |
||||
workPackageAttachmentsService.upload(workPackage, scope.files).then(function() { |
||||
scope.files = []; |
||||
loadAttachments(); |
||||
}); |
||||
} |
||||
}, |
||||
loadAttachments = function() { |
||||
if (!editMode(attrs)) { |
||||
return; |
||||
} |
||||
scope.loading = true; |
||||
workPackageAttachmentsService.load(workPackage, true).then(function(attachments) { |
||||
scope.attachments = attachments; |
||||
}).finally(function() { |
||||
scope.loading = false; |
||||
}); |
||||
}; |
||||
|
||||
scope.I18n = I18n; |
||||
scope.rejectedFiles = []; |
||||
scope.size = ConversionService.fileSize; |
||||
|
||||
scope.hasRightToUpload = !!(workPackage.links.addAttachment || workPackage.isNew); |
||||
|
||||
var currentlyRemoving = []; |
||||
scope.remove = function(file) { |
||||
currentlyRemoving.push(file); |
||||
workPackageAttachmentsService.remove(file).then(function(file) { |
||||
_.remove(scope.attachments, file); |
||||
_.remove(scope.files, file); |
||||
}).finally(function() { |
||||
_.remove(currentlyRemoving, file); |
||||
}); |
||||
}; |
||||
|
||||
scope.deleting = function(attachment) { |
||||
return _.findIndex(currentlyRemoving, attachment) > -1; |
||||
}; |
||||
|
||||
var currentlyFocusing = null; |
||||
|
||||
scope.focus = function(attachment) { |
||||
currentlyFocusing = attachment; |
||||
}; |
||||
|
||||
scope.focussing = function(attachment) { |
||||
return currentlyFocusing === attachment; |
||||
}; |
||||
|
||||
scope.$on('uploadPendingAttachments', upload); |
||||
|
||||
scope.filterFiles = function(files) { |
||||
// Directories cannot be uploaded and as such, should not become files in
|
||||
// the sense of this directive. The files within the direcotories will
|
||||
// be taken though.
|
||||
_.remove(files, function(file) { |
||||
return file.type === 'directory'; |
||||
}); |
||||
}; |
||||
|
||||
scope.uploadFilteredFiles = function(files) { |
||||
scope.filterFiles(files); |
||||
|
||||
scope.$emit('uploadPendingAttachments', workPackage); |
||||
}; |
||||
|
||||
scope.$watch('rejectedFiles', function(rejectedFiles) { |
||||
if (rejectedFiles.length === 0) { |
||||
return; |
||||
} |
||||
var errors = _.map(rejectedFiles, function(file) { |
||||
return file.name + ' (' + scope.size(file.size) + ')'; |
||||
}), |
||||
message = I18n.t('js.label_rejected_files_reason', |
||||
{ maximumFilesize: scope.size(scope.maximumFileSize) } |
||||
); |
||||
NotificationsService.addError(message, errors); |
||||
}); |
||||
|
||||
scope.fetchingConfiguration = true; |
||||
ConfigurationService.api().then(function(settings) { |
||||
scope.maximumFileSize = settings.maximumAttachmentFileSize; |
||||
// somehow, I18n cannot interpolate function results, so we need to cache this once
|
||||
scope.maxFileSize = scope.size(settings.maximumAttachmentFileSize); |
||||
scope.fetchingConfiguration = false; |
||||
}); |
||||
|
||||
loadAttachments(); |
||||
}; |
||||
|
||||
return { |
||||
restrict: 'E', |
||||
replace: true, |
||||
scope: { |
||||
workPackage: '&' |
||||
}, |
||||
templateUrl: function(element, attrs) { |
||||
if (editMode(attrs)) { |
||||
return '/templates/work_packages/attachments-edit.html'; |
||||
} |
||||
return '/templates/work_packages/attachments.html'; |
||||
}, |
||||
link: attachmentsController |
||||
}; |
||||
}; |
@ -0,0 +1,105 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
module.exports = function(Upload, PathHelper, I18n, NotificationsService, $q, $timeout, $http) { |
||||
'use strict'; |
||||
var upload = function(workPackage, files) { |
||||
var uploadPath = workPackage.links.addAttachment.url(); |
||||
// for file in files build some promises, create a notification per WP,
|
||||
// notify the noticiation (wat?) about progress
|
||||
var uploads = _.map(files, function(file) { |
||||
var options = { |
||||
url: uploadPath, |
||||
fields: { |
||||
metadata: { |
||||
fileName: file.name, |
||||
description: file.description |
||||
} |
||||
}, |
||||
file: file |
||||
}; |
||||
return Upload.upload(options); |
||||
}); |
||||
|
||||
// notify the user
|
||||
var message = I18n.t('js.label_upload_notification', { |
||||
id: workPackage.props.id, |
||||
subject: workPackage.props.subject |
||||
}); |
||||
|
||||
var notification = NotificationsService.addWorkPackageUpload(message, uploads); |
||||
var allUploadsDone = $q.defer(); |
||||
$q.all(uploads).then(function() { |
||||
$timeout(function() { // let the notification linger for a bit
|
||||
NotificationsService.remove(notification); |
||||
allUploadsDone.resolve(); |
||||
}, 700); |
||||
}, function(err) { |
||||
allUploadsDone.reject(err); |
||||
}); |
||||
return allUploadsDone.promise; |
||||
}, |
||||
load = function(workPackage, reload) { |
||||
var path = workPackage.links.attachments.url(), |
||||
attachments = $q.defer(); |
||||
$http.get(path, { cache: !reload }).success(function(response) { |
||||
attachments.resolve(response._embedded.elements); |
||||
}).error(function(err) { |
||||
attachments.reject(err); |
||||
}); |
||||
return attachments.promise; |
||||
}, |
||||
remove = function(fileOrAttachment) { |
||||
var removal = $q.defer(); |
||||
if (angular.isObject(fileOrAttachment._links)) { |
||||
var path = fileOrAttachment._links.self.href; |
||||
$http.delete(path).success(function() { |
||||
removal.resolve(fileOrAttachment); |
||||
}).error(function(err) { |
||||
removal.reject(err); |
||||
}); |
||||
} else { |
||||
removal.resolve(fileOrAttachment); |
||||
} |
||||
return removal.promise; |
||||
}, |
||||
hasAttachments = function(workPackage) { |
||||
var existance = $q.defer(); |
||||
load(workPackage).then(function(attachments) { |
||||
existance.resolve(attachments.length > 0); |
||||
}); |
||||
return existance.promise; |
||||
}; |
||||
|
||||
return { |
||||
upload: upload, |
||||
remove: remove, |
||||
load: load, |
||||
hasAttachments: hasAttachments |
||||
}; |
||||
}; |
@ -0,0 +1,120 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
describe('WorkPackageAttachmentsDirective', function() { |
||||
var compile, element, rootScope, scope, isolatedScope, |
||||
workPackage = {links: {}}; |
||||
|
||||
beforeEach(angular.mock.module('openproject.workPackages.directives')); |
||||
beforeEach(module('openproject.templates')); |
||||
|
||||
var loadPromise, |
||||
workPackageAttachmentsService = { |
||||
load: function() { |
||||
return loadPromise; |
||||
} |
||||
}, |
||||
apiPromise, |
||||
configurationService = { |
||||
api: function() { |
||||
return apiPromise; |
||||
} |
||||
}; |
||||
|
||||
beforeEach(module('openproject.workPackages.services', function($provide) { |
||||
$provide.constant('WorkPackageAttachmentsService', workPackageAttachmentsService); |
||||
})); |
||||
|
||||
beforeEach(module('openproject.config', function($provide) { |
||||
$provide.constant('ConfigurationService', configurationService); |
||||
})); |
||||
|
||||
beforeEach(inject(function($rootScope, $compile, $q) { |
||||
apiPromise = $q(function(resolve) { |
||||
return resolve(''); |
||||
}); |
||||
|
||||
loadPromise = $q(function(resolve) { |
||||
return resolve([]); |
||||
}); |
||||
|
||||
var html = '<work-package-attachments edit work-package="workPackage">' + |
||||
'</work-package-attachments>'; |
||||
|
||||
element = angular.element(html); |
||||
rootScope = $rootScope; |
||||
scope = $rootScope.$new(); |
||||
|
||||
scope.workPackage = workPackage; |
||||
|
||||
compile = function() { |
||||
$compile(element)(scope); |
||||
scope.$digest(); |
||||
console.log('ISO SCOPEEEEEE', element.isolateScope()); |
||||
}; |
||||
})); |
||||
|
||||
describe('filterFiles', function() { |
||||
beforeEach(function() { |
||||
compile(); |
||||
isolatedScope = element.isolateScope(); |
||||
}); |
||||
|
||||
it('filters out attachments of type directory', function() { |
||||
var files = [{type: 'directory'}, {type: 'file'}]; |
||||
|
||||
isolatedScope.filterFiles(files, {}, {}, false); |
||||
|
||||
expect(files).to.eql([{type: 'file'}]); |
||||
}); |
||||
}); |
||||
|
||||
|
||||
describe('uploadFilteredFiles', function() { |
||||
var files = [{type: 'directory'}, {type: 'file'}], |
||||
dumbPromise = { |
||||
then: function(call) { return call(); } |
||||
}; |
||||
|
||||
beforeEach(function() { |
||||
compile(); |
||||
isolatedScope = element.isolateScope(); |
||||
}); |
||||
|
||||
it('triggers uploading of non directory files', function() { |
||||
//need to have files to be able to trigger uploads
|
||||
isolatedScope.files = files; |
||||
|
||||
var uploadStub = workPackageAttachmentsService.upload = sinon.stub().returns(dumbPromise); |
||||
|
||||
isolatedScope.uploadFilteredFiles(files, {}, {}, true); |
||||
|
||||
expect(uploadStub.calledWith(workPackage, [{type: 'file'}])).to.be.true; |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,127 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
/* jshint expr: true */ |
||||
/* globals WebKitBlobBuilder */ |
||||
|
||||
describe('workPackageAttachmentsService', function() { |
||||
'use strict'; |
||||
var WorkPackageAttachmentsService, $httpBackend; |
||||
|
||||
// mock me a work package
|
||||
// TODO: remove that hyperagent.js nonsense asap
|
||||
var workPackage = { |
||||
props: { |
||||
id: 1 |
||||
}, |
||||
links: { |
||||
attachments: { |
||||
url: function() { |
||||
return '/api/v3/work_packages/1/attachments'; |
||||
} |
||||
}, |
||||
addAttachment: { |
||||
url: function() { |
||||
return '/api/v3/work_packages/1/attachments'; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
// mock me an attachment
|
||||
var attachment = { |
||||
_links: { |
||||
self: { |
||||
href: '/attachments/1234' |
||||
} |
||||
} |
||||
}; |
||||
|
||||
beforeEach(module('openproject.workPackages')); |
||||
|
||||
beforeEach(inject(function(_WorkPackageAttachmentsService_, _$httpBackend_){ |
||||
WorkPackageAttachmentsService = _WorkPackageAttachmentsService_; |
||||
$httpBackend = _$httpBackend_; |
||||
})); |
||||
|
||||
afterEach(function() { |
||||
$httpBackend.verifyNoOutstandingRequest(); |
||||
$httpBackend.verifyNoOutstandingExpectation(); |
||||
}); |
||||
|
||||
describe('loading attachments', function() { |
||||
beforeEach(function() { |
||||
$httpBackend.expectGET('/api/v3/work_packages/1/attachments').respond({ |
||||
_embedded: { |
||||
elements: [1,2,3] |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
it('should retrieve attachments for a given work pacakge', function () { |
||||
WorkPackageAttachmentsService.load(workPackage).then(function(result) { |
||||
expect(result).to.eql([1,2,3]); |
||||
}); |
||||
$httpBackend.flush(); |
||||
}); |
||||
}); |
||||
|
||||
describe('creating an attachment', function() { |
||||
beforeEach(function() { |
||||
$httpBackend.expectPOST('/api/v3/work_packages/1/attachments').respond({}); |
||||
}); |
||||
|
||||
function createFiles() { |
||||
var blob; |
||||
try { |
||||
var builder = new WebKitBlobBuilder(); |
||||
builder.append(['I am a TestFile for WebKit browsers']); |
||||
blob = builder.getBlob(); |
||||
} catch(Error) { |
||||
blob = new Blob(['I am a testfile']); |
||||
} |
||||
return [blob]; |
||||
} |
||||
|
||||
it('should create an attachment for a given work package', function () { |
||||
var files = createFiles(); |
||||
WorkPackageAttachmentsService.upload(workPackage, files); |
||||
$httpBackend.flush(); |
||||
}); |
||||
}); |
||||
|
||||
describe('deleting an attachment', function() { |
||||
beforeEach(function() { |
||||
$httpBackend.expectDELETE('/attachments/1234').respond({}); |
||||
}); |
||||
|
||||
it('should remove an attachment', function () { |
||||
WorkPackageAttachmentsService.remove(attachment); |
||||
$httpBackend.flush(); |
||||
}); |
||||
}); |
||||
}); |
Loading…
Reference in new issue