From 588d96a0c0f6928ec932f390afc757504d76e452 Mon Sep 17 00:00:00 2001 From: guange <8863824@gmail.com> Date: Fri, 15 May 2015 16:18:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=B4=E5=83=8F=E4=B8=8A=E4=BC=A0=E5=8F=AA?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jq-upload/jquery.fileupload-validate.js | 122 ++++++++++++++++++ public/javascripts/jq-upload/upload.js | 13 ++ spec/factories/courses.rb | 10 +- spec/fixtures/hah.txt | 5 + spec/fixtures/test.jpg | Bin 0 -> 29158 bytes spec/rails_helper.rb | 4 + spec/requests/course_request_spec.rb | 26 ++-- spec/seeds.rb | 18 +++ 8 files changed, 182 insertions(+), 16 deletions(-) create mode 100644 public/javascripts/jq-upload/jquery.fileupload-validate.js create mode 100644 spec/fixtures/hah.txt create mode 100644 spec/fixtures/test.jpg diff --git a/public/javascripts/jq-upload/jquery.fileupload-validate.js b/public/javascripts/jq-upload/jquery.fileupload-validate.js new file mode 100644 index 000000000..cb0d9f8b6 --- /dev/null +++ b/public/javascripts/jq-upload/jquery.fileupload-validate.js @@ -0,0 +1,122 @@ +/* + * jQuery File Upload Validation Plugin 1.1.3 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2013, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* global define, require, window */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + './jquery.fileupload-process' + ], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS: + factory(require('jquery')); + } else { + // Browser globals: + factory( + window.jQuery + ); + } +}(function ($) { + 'use strict'; + + // Append to the default processQueue: + $.blueimp.fileupload.prototype.options.processQueue.push( + { + action: 'validate', + // Always trigger this action, + // even if the previous action was rejected: + always: true, + // Options taken from the global options map: + acceptFileTypes: '@', + maxFileSize: '@', + minFileSize: '@', + maxNumberOfFiles: '@', + disabled: '@disableValidation' + } + ); + + // The File Upload Validation plugin extends the fileupload widget + // with file validation functionality: + $.widget('blueimp.fileupload', $.blueimp.fileupload, { + + options: { + /* + // The regular expression for allowed file types, matches + // against either file type or file name: + acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, + // The maximum allowed file size in bytes: + maxFileSize: 10000000, // 10 MB + // The minimum allowed file size in bytes: + minFileSize: undefined, // No minimal file size + // The limit of files to be uploaded: + maxNumberOfFiles: 10, + */ + + // Function returning the current number of files, + // has to be overriden for maxNumberOfFiles validation: + getNumberOfFiles: $.noop, + + // Error and info messages: + messages: { + maxNumberOfFiles: 'Maximum number of files exceeded', + acceptFileTypes: 'File type not allowed', + maxFileSize: 'File is too large', + minFileSize: 'File is too small' + } + }, + + processActions: { + + validate: function (data, options) { + if (options.disabled) { + return data; + } + var dfd = $.Deferred(), + settings = this.options, + file = data.files[data.index], + fileSize; + if (options.minFileSize || options.maxFileSize) { + fileSize = file.size; + } + if ($.type(options.maxNumberOfFiles) === 'number' && + (settings.getNumberOfFiles() || 0) + data.files.length > + options.maxNumberOfFiles) { + file.error = settings.i18n('maxNumberOfFiles'); + } else if (options.acceptFileTypes && + !(options.acceptFileTypes.test(file.type) || + options.acceptFileTypes.test(file.name))) { + file.error = settings.i18n('acceptFileTypes'); + } else if (fileSize > options.maxFileSize) { + file.error = settings.i18n('maxFileSize'); + } else if ($.type(fileSize) === 'number' && + fileSize < options.minFileSize) { + file.error = settings.i18n('minFileSize'); + } else { + delete file.error; + } + if (file.error || data.files.error) { + data.files.error = true; + dfd.rejectWith(this, [data]); + } else { + dfd.resolveWith(this, [data]); + } + return dfd.promise(); + } + + } + + }); + +})); diff --git a/public/javascripts/jq-upload/upload.js b/public/javascripts/jq-upload/upload.js index eb653b25b..59ed96882 100644 --- a/public/javascripts/jq-upload/upload.js +++ b/public/javascripts/jq-upload/upload.js @@ -1,8 +1,21 @@ $(function() { var $upload_file = $('.upload_file'); + var validateImage = function(file){ + if(!/^image\//.test(file.type)){ + alert($upload_file.attr("data-type-support-message") + $upload_file.attr("data-file-type")); + return false; + } + return true; + }; $('.upload_file').fileupload({ url: '/upload_avatar.json?source_type=' + $('.upload_file').attr('data-source-type') + '&source_id=' + $('.upload_file').attr('data-source-id'), + add: function(e,data){ + if(!validateImage(data.files[0])){ + return false; + } + data.submit(); + }, formData: function(form) { var data = form.serializeArray(); var auth = null; diff --git a/spec/factories/courses.rb b/spec/factories/courses.rb index bcdfa99fa..f17f614d1 100644 --- a/spec/factories/courses.rb +++ b/spec/factories/courses.rb @@ -1,11 +1,13 @@ +#coding=utf-8 +# FactoryGirl.define do factory :course do - name '课程名' + name 'name' time '2015' - term '春季课程' - period 1 + term 'term' + class_period 1 password '111' - description '课程描述' + description 'description' is_public 1 open_student 1 association :teacher, factory: :user diff --git a/spec/fixtures/hah.txt b/spec/fixtures/hah.txt new file mode 100644 index 000000000..b7f13a714 --- /dev/null +++ b/spec/fixtures/hah.txt @@ -0,0 +1,5 @@ + + + + + diff --git a/spec/fixtures/test.jpg b/spec/fixtures/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f912467d99878aed72fe2fe690847346dfaa49f6 GIT binary patch literal 29158 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 literal 0 HcmV?d00001 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1c8e743d1..0661be9c9 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -29,6 +29,10 @@ RSpec.configure do |config| # instead of true. config.use_transactional_fixtures = true + config.before(:suite) do + require_relative "seeds" + end + # RSpec Rails can automatically mix in different behaviours to your tests # based on their file location, for example enabling you to call `get` and # `post` in specs under `spec/controllers`. diff --git a/spec/requests/course_request_spec.rb b/spec/requests/course_request_spec.rb index 8360a0bd4..d58df398e 100644 --- a/spec/requests/course_request_spec.rb +++ b/spec/requests/course_request_spec.rb @@ -11,12 +11,12 @@ RSpec.describe "课程", :type => :request do } context "参数正确,成功创建课程" do before{ - uu = current_user - allow(User).to receive(:current).and_return(uu) - allow(uu).to receive(:allowed_to?).and_return(123) + # uu = current_user + # allow(User).to receive(:current).and_return(uu) + # allow(uu).to receive(:allowed_to?).and_return(123) post courses_path, "course[name]"=> course[:name], - "class_period"=> course[:period], + "class_period"=> course[:class_period], "time"=> course[:time], "term"=> course[:term], "course[password]"=>course[:password], @@ -24,19 +24,21 @@ RSpec.describe "课程", :type => :request do "course[is_public]"=> course[:is_public], "course[open_student]"=> course[:open_student] } - it{ - puts User.current.allowed_to?(1,2) - binding.pry - } - it{expect(response).to have_http_status(:success)} - it{expect(assigns(:course)).to be_a_new(Course)} - it{expect(response).to redirect_to(course_url(assigns(:course)))} + it{expect(assigns(:course)).to be_instance_of(Course)} + it{expect(response).to redirect_to(settings_course_url(assigns(:course), course_type: 1))} end end describe "配置课程" do + let (:course) {FactoryGirl.create(:course)} + context "修改课程图片" do - it "正常图片上传成功" do + include Rack::Test::Methods + let(:avatar) {Rack::Test::UploadedFile.new("#{Rails.root}/spec/fixtures/test.jpg",'image/jpg')} + context "正常图片上传成功" do + subject(:resp) {post upload_avatar_path(source_type: 'Course', source_id: course.id, format: :json),"avatar"=>{image: avatar}} + it{ expect(subject).to be_ok } + it{ expect(subject.body).not_to be_empty } end it "不是图片,上传失败" diff --git a/spec/seeds.rb b/spec/seeds.rb index e69de29bb..60727530a 100644 --- a/spec/seeds.rb +++ b/spec/seeds.rb @@ -0,0 +1,18 @@ +if Role.count <= 0 +ActiveRecord::Base.connection.execute( + +%Q{ +INSERT INTO `roles` (`id`, `name`, `position`, `assignable`, `builtin`, `permissions`, `issues_visibility`) +VALUES + (1,'Non member',1,1,1,'---\n- :upload_attachments\n- :memos_attachments_download\n- :add_project\n- :projects_attachments_download\n- :add_course\n- :course_attachments_download\n- :view_course_files\n- :add_messages\n- :delete_own_messages\n- :view_calendar\n- :view_documents\n- :view_files\n- :view_gantt\n- :view_issues\n- :save_queries\n- :comment_news\n- :browse_repository\n- :view_changesets\n- :view_time_entries\n- :view_wiki_pages\n- :view_wiki_edits\n','default'), + (2,'Anonymous',2,1,2,'---\n- :memos_attachments_download\n- :view_course_files\n- :view_calendar\n- :view_documents\n- :view_files\n- :view_gantt\n- :view_issues\n- :browse_repository\n- :view_changesets\n- :view_time_entries\n- :view_wiki_pages\n- :view_wiki_edits\n','default'), + (3,'Manager',3,1,0,'---\n- :upload_attachments\n- :memos_attachments_download\n- :add_project\n- :edit_project\n- :close_project\n- :select_project_modules\n- :manage_members\n- :manage_versions\n- :add_subprojects\n- :is_manager\n- :projects_attachments_download\n- :as_teacher\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :quote_project\n- :manage_boards\n- :add_messages\n- :edit_messages\n- :edit_own_messages\n- :delete_messages\n- :delete_own_messages\n- :view_calendar\n- :view_code_review\n- :add_code_review\n- :edit_code_review\n- :delete_code_review\n- :assign_code_review\n- :code_review_setting\n- :add_documents\n- :edit_documents\n- :delete_documents\n- :view_documents\n- :manage_files\n- :view_files\n- :view_gantt\n- :manage_categories\n- :view_issues\n- :add_issues\n- :edit_issues\n- :manage_issue_relations\n- :manage_subtasks\n- :set_issues_private\n- :set_own_issues_private\n- :add_issue_notes\n- :edit_issue_notes\n- :edit_own_issue_notes\n- :view_private_notes\n- :set_notes_private\n- :move_issues\n- :delete_issues\n- :manage_public_queries\n- :save_queries\n- :view_issue_watchers\n- :add_issue_watchers\n- :delete_issue_watchers\n- :manage_news\n- :comment_news\n- :manage_repository\n- :browse_repository\n- :view_changesets\n- :commit_access\n- :manage_related_issues\n- :log_time\n- :view_time_entries\n- :edit_time_entries\n- :edit_own_time_entries\n- :manage_project_activities\n- :manage_wiki\n- :rename_wiki_pages\n- :delete_wiki_pages\n- :view_wiki_pages\n- :export_wiki_pages\n- :view_wiki_edits\n- :edit_wiki_pages\n- :delete_wiki_pages_attachments\n- :protect_wiki_pages\n','all'), + (4,'Developer',4,1,0,'---\n- :add_project\n- :manage_members\n- :manage_versions\n- :projects_attachments_download\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :paret_in_homework\n- :select_contest_modules\n- :quote_project\n- :contest_attachments_download\n- :manage_contestnotifications\n- :notificationcomment_contestnotifications\n- :manage_boards\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :view_documents\n- :do_dts\n- :manage_files\n- :view_files\n- :view_gantt\n- :manage_categories\n- :view_issues\n- :add_issues\n- :edit_issues\n- :manage_issue_relations\n- :manage_subtasks\n- :set_issues_private\n- :set_own_issues_private\n- :add_issue_notes\n- :edit_own_issue_notes\n- :view_private_notes\n- :set_notes_private\n- :move_issues\n- :manage_public_queries\n- :save_queries\n- :view_issue_watchers\n- :add_issue_watchers\n- :delete_issue_watchers\n- :manage_news\n- :comment_news\n- :manage_repository\n- :browse_repository\n- :view_changesets\n- :commit_access\n- :manage_related_issues\n- :log_time\n- :view_time_entries\n- :edit_own_time_entries\n- :view_wiki_pages\n- :export_wiki_pages\n- :view_wiki_edits\n- :protect_wiki_pages\n','default'), + (5,'Reporter',5,1,0,'---\n- :upload_attachments\n- :memos_attachments_download\n- :add_project\n- :projects_attachments_download\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :manage_boards\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :view_code_review\n- :add_documents\n- :view_documents\n- :view_files\n- :view_gantt\n- :view_issues\n- :add_issues\n- :add_issue_notes\n- :edit_own_issue_notes\n- :save_queries\n- :comment_news\n- :browse_repository\n- :view_changesets\n- :log_time\n- :view_time_entries\n- :view_wiki_pages\n- :export_wiki_pages\n- :view_wiki_edits\n- :edit_wiki_pages\n- :delete_wiki_pages_attachments\n','default'), + (7,'TeachingAsistant',6,1,0,'---\n- :add_project\n- :edit_project\n- :manage_members\n- :projects_attachments_download\n- :as_teacher\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :manage_boards\n- :add_messages\n- :delete_own_messages\n- :view_calendar\n- :view_documents\n- :manage_files\n- :view_files\n- :view_gantt\n- :view_issues\n- :add_issues\n- :add_issue_notes\n- :save_queries\n- :manage_news\n- :comment_news\n- :browse_repository\n- :view_changesets\n- :view_time_entries\n- :view_wiki_pages\n- :export_wiki_pages\n- :view_wiki_edits\n- :edit_wiki_pages\n- :delete_wiki_pages_attachments\n','default'), + (9,'Teacher',7,1,0,'---\n- :upload_attachments\n- :memos_attachments_download\n- :add_project\n- :edit_project\n- :close_project\n- :select_project_modules\n- :manage_members\n- :manage_versions\n- :add_subprojects\n- :projects_attachments_download\n- :as_teacher\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :manage_boards\n- :add_messages\n- :edit_messages\n- :edit_own_messages\n- :delete_messages\n- :delete_own_messages\n- :view_calendar\n- :add_documents\n- :edit_documents\n- :delete_documents\n- :view_documents\n- :manage_files\n- :view_files\n- :view_gantt\n- :manage_categories\n- :view_issues\n- :add_issues\n- :edit_issues\n- :manage_issue_relations\n- :manage_subtasks\n- :set_issues_private\n- :set_own_issues_private\n- :add_issue_notes\n- :edit_own_issue_notes\n- :view_private_notes\n- :set_notes_private\n- :move_issues\n- :delete_issues\n- :manage_public_queries\n- :save_queries\n- :view_issue_watchers\n- :add_issue_watchers\n- :delete_issue_watchers\n- :manage_news\n- :comment_news\n- :manage_repository\n- :browse_repository\n- :view_changesets\n- :commit_access\n- :manage_related_issues\n- :log_time\n- :view_time_entries\n- :edit_time_entries\n- :edit_own_time_entries\n- :manage_project_activities\n- :manage_wiki\n- :rename_wiki_pages\n- :delete_wiki_pages\n- :view_wiki_pages\n- :export_wiki_pages\n- :view_wiki_edits\n- :edit_wiki_pages\n- :delete_wiki_pages_attachments\n- :protect_wiki_pages\n','default'), + (10,'Student',8,1,0,'---\n- :upload_attachments\n- :memos_attachments_download\n- :add_project\n- :projects_attachments_download\n- :as_student\n- :add_course\n- :edit_course\n- :close_course\n- :select_course_modules\n- :view_course_journals_for_messages\n- :course_attachments_download\n- :view_course_files\n- :view_homework_attaches\n- :paret_in_homework\n- :manage_boards\n- :add_messages\n- :edit_own_messages\n- :delete_own_messages\n- :view_calendar\n- :view_documents\n- :view_files\n- :view_gantt\n- :view_issues\n- :add_issues\n- :add_issue_notes\n- :save_queries\n- :comment_news\n- :browse_repository\n- :view_changesets\n- :view_time_entries\n- :view_wiki_pages\n- :view_wiki_edits\n','default'); +} + +) +end