diff --git a/Gemfile b/Gemfile index f7e3fe7b6dd14f98ee33c58d3ee85576bcfffdd1..9775334a7c1ea4c71cc7a44b5acdf8112dc607e1 100644 --- a/Gemfile +++ b/Gemfile @@ -69,6 +69,9 @@ gem "haml-rails" # Files attachments gem "carrierwave" +# Drag and Drop UI +gem 'dropzonejs-rails' + # for aws storage gem "fog", "~> 1.14", group: :aws gem "unf", group: :aws diff --git a/Gemfile.lock b/Gemfile.lock index 86c752505bdb643339545b191d942b0bf4428cd7..3d4a673af1ca5677397480c6c2009369dbb2a3dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -103,6 +103,8 @@ GEM diffy (3.0.3) docile (1.1.1) dotenv (0.9.0) + dropzonejs-rails (0.4.14) + rails (> 3.1) email_spec (1.5.0) launchy (~> 2.1) mail (~> 2.2) @@ -579,6 +581,7 @@ DEPENDENCIES devise (= 3.0.4) devise-async (= 0.8.0) diffy (~> 3.0.3) + dropzonejs-rails email_spec email_validator (~> 1.4.0) enumerize diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 587e51a7a83880c23ab8bb82e4c03e27f31d3bd7..35e435546611b160be2a1114b7827aa6fcff8b1c 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -29,6 +29,7 @@ #= require underscore #= require nprogress #= require nprogress-turbolinks +#= require dropzone #= require_tree . window.slugify = (text) -> diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index d06cb116dfed8ae3421a3fabbff941df9e9e4f32..8ac5bfe95d874686458970bf25c80c24c2a9e8d1 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -1,6 +1,6 @@ $ -> $("body").on "click", ".js-toggler-target", -> - container = $(@).closest(".js-toggler-container") + container = $(".notes-container") container.toggleClass("on") # Toggle button. Show/hide content inside parent container. diff --git a/app/assets/javascripts/markdown_area.js.coffee b/app/assets/javascripts/markdown_area.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..def5d12a820f91d6c88cd5497715f210c0c9b79a --- /dev/null +++ b/app/assets/javascripts/markdown_area.js.coffee @@ -0,0 +1,85 @@ +formatLink = (str) -> + "" + +$(document).ready -> + alertClass = "alert alert-danger alert-dismissable div-dropzone-alert" + alertAttr = "class=\"close\" data-dismiss=\"alert\"" + "aria-hidden=\"true\"" + divHover = "<div class=\"div-dropzone-hover\"></div>" + divSpinner = "<div class=\"div-dropzone-spinner\"></div>" + divAlert = "<div class=\"" + alertClass + "\"></div>" + iconPicture = "<i class=\"icon-picture div-dropzone-icon\"></i>" + iconSpinner = "<i class=\"icon-spinner icon-spin div-dropzone-icon\"></i>" + btnAlert = "<button type=\"button\"" + alertAttr + ">×</button>" + project_image_path_upload = window.project_image_path_upload or null + + $("textarea.markdown-area").wrap "<div class=\"div-dropzone\"></div>" + + $(".div-dropzone").parent().addClass "div-dropzone-wrapper" + + $(".div-dropzone").append divHover + $(".div-dropzone-hover").append iconPicture + $(".div-dropzone").append divSpinner + $(".div-dropzone-spinner").append iconSpinner + + + dropzone = $(".div-dropzone").dropzone( + url: project_image_path_upload + dictDefaultMessage: "" + clickable: true + paramName: "markdown_img" + maxFilesize: 10 + uploadMultiple: false + acceptedFiles: "image/jpg,image/jpeg,image/gif,image/png" + headers: + "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content") + + previewContainer: false + + processing: -> + $(".div-dropzone-alert").alert "close" + + dragover: -> + $(".div-dropzone > textarea").addClass "div-dropzone-focus" + $(".div-dropzone-hover").css "opacity", 0.7 + return + + dragleave: -> + $(".div-dropzone > textarea").removeClass "div-dropzone-focus" + $(".div-dropzone-hover").css "opacity", 0 + return + + drop: -> + $(".div-dropzone > textarea").removeClass "div-dropzone-focus" + $(".div-dropzone-hover").css "opacity", 0 + $(".div-dropzone > textarea").focus() + return + + success: (header, response) -> + child = $(dropzone[0]).children("textarea") + $(child).val $(child).val() + formatLink(response.link) + "\n" + return + + error: (temp, errorMessage) -> + checkIfMsgExists = $(".error-alert").children().length + if checkIfMsgExists is 0 + $(".error-alert").append divAlert + $(".div-dropzone-alert").append btnAlert + errorMessage + return + + sending: -> + $(".div-dropzone-spinner").css "opacity", 0.7 + return + + complete: -> + $(".dz-preview").remove() + $(".markdown-area").trigger "input" + $(".div-dropzone-spinner").css "opacity", 0 + return + ) + + $(".markdown-selector").click (e) -> + e.preventDefault() + $(".div-dropzone").click() + return + + return \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c53873f95a2afc2914822191a4730107a73bd443..0b372a87a111cc0be7a1ee885426ff579c1c501d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -10,6 +10,7 @@ *= require_self *= require nprogress *= require nprogress-bootstrap + *= require dropzone/basic */ @import "main/*"; diff --git a/app/assets/stylesheets/behaviors.scss b/app/assets/stylesheets/behaviors.scss index 3fdc20485f2787d84785eeb361825a9dd05222d9..64e3c8d9ace2b2786a435779cceaeda98f26e41e 100644 --- a/app/assets/stylesheets/behaviors.scss +++ b/app/assets/stylesheets/behaviors.scss @@ -5,10 +5,19 @@ .js-details-container.open .content { display: block; } .js-details-container.open .content.hide { display: none; } - // Toggler //-------- -.js-toggler-container .turn-on { display: inherit; } +.write-preview-btn .turn-on { display: inherit; } +.write-preview-btn .turn-off { display: none; } + .js-toggler-container .turn-off { display: none; } .js-toggler-container.on .turn-on { display: none; } .js-toggler-container.on .turn-off { display: inherit; } + +.js-toggler-container.on ~ .note-form-actions { + .write-preview-btn .turn-on { display: none; } +} + +.js-toggler-container.on ~ .note-form-actions { + .write-preview-btn .turn-off { display: inherit; } +} diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss new file mode 100644 index 0000000000000000000000000000000000000000..a1fe18b02fa38ecbe78c3a0c33fbaf214a1dd199 --- /dev/null +++ b/app/assets/stylesheets/generic/markdown_area.scss @@ -0,0 +1,58 @@ +.div-dropzone-wrapper { + .div-dropzone { + position: relative; + padding: 0; + border: 0; + margin-bottom: 5px; + + .div-dropzone-focus { + border-color: #66afe9 !important; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6) !important; + outline: 0 !important; + } + + .div-dropzone-hover { + position: absolute; + top: 50%; + left: 50%; + margin-top: -0.5em; + margin-left: -0.6em; + opacity: 0; + font-size: 50px; + transition: opacity 200ms ease-in-out; + } + + .div-dropzone-spinner { + position: absolute; + top: 100%; + left: 100%; + margin-top: -1.1em; + margin-left: -1.1em; + opacity: 0; + font-size: 30px; + transition: opacity 200ms ease-in-out; + } + + .div-dropzone-icon { + display: block; + text-align: center; + font-size: inherit; + } + + .dz-preview { + display: none; + } + } + + .hint { + float: left; + padding: 0; + margin: 0; + } +} + +.div-dropzone-alert { + margin-top: 5px; + margin-bottom: 0; + transition: opacity 200ms ease-in-out; +} diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss index 7e56781f56a8709edc37b3b665950fba33d69c2d..755295be1f403ba123f0d92562d48592b7288605 100644 --- a/app/assets/stylesheets/sections/notes.scss +++ b/app/assets/stylesheets/sections/notes.scss @@ -272,21 +272,16 @@ ul.notes { margin-bottom: 0; } .note_text_and_preview { - // makes the "absolute" position for links relative to this - position: relative; - - // preview/edit buttons - > a { - position: absolute; - right: 5px; - bottom: -60px; - } .note_preview { background: #f5f5f5; border: 1px solid #ddd; @include border-radius(4px); min-height: 80px; padding: 4px 6px; + + > p { + overflow-x: auto; + } } .note_text { border: 1px solid #DDD; @@ -310,7 +305,6 @@ ul.notes { float: none; } - .common-note-form { margin: 0; background: #F9F9F9; @@ -318,7 +312,6 @@ ul.notes { border: 1px solid #DDD; } - .note-form-actions { background: #F9F9F9; height: 45px; @@ -333,6 +326,18 @@ ul.notes { .js-notify-commit-author { float: left; } + + .write-preview-btn { + // makes the "absolute" position for links relative to this + position: relative; + + // preview/edit buttons + > a { + position: absolute; + right: 5px; + top: 8px; + } + } } .note-edit-form { @@ -367,3 +372,8 @@ ul.notes { .parallel-comment { padding: 6px; } + +.error-alert > .alert { + margin-top: 5px; + margin-bottom: 5px; +} diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index bf30de565ed0976a5714b139a4cc6a1596fc1a61..7937454810d9929279b9e84fcc86552d5aa882a3 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -14,4 +14,3 @@ def download end end end - diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 4e7a716bfe411deafd8bd3e7cc7ece5781b2b772..6eec2094f86bb2af55062ff78b1eaf2e4d721bfb 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -69,7 +69,9 @@ def create render :new end end - format.js + format.js do |format| + @link = @issue.attachment.url.to_js + end end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index e356d09a270e6943987695890d1aef88837adde3..c15205fb68fb6b16a375b0c228c818646ca46198 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -162,8 +162,28 @@ def unarchive end end + def upload_image + uploader = FileUploader.new('uploads', upload_path, accepted_images) + alt = params['markdown_img'].original_filename + uploader.store!(params['markdown_img']) + link = { 'alt' => File.basename(alt, '.*'), + 'url' => File.join(root_url, uploader.url) } + respond_to do |format| + format.json { render json: { link: link } } + end + end + private + def upload_path + base_dir = FileUploader.generate_dir + File.join(repository.path_with_namespace, base_dir) + end + + def accepted_images + %w(png jpg jpeg gif) + end + def set_title @title = 'New Project' end diff --git a/app/models/issue.rb b/app/models/issue.rb index 16d51345e5a164427c2079fcad2528c780dd5cd8..f0c2e5522738b076e4f26e468189342c5284351a 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -15,8 +15,12 @@ # milestone_id :integer # state :string(255) # iid :integer +# attachment :string(255) # +require 'carrierwave/orm/activerecord' +require 'file_size_validator' + class Issue < ActiveRecord::Base include Issuable include InternalId diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb new file mode 100644 index 0000000000000000000000000000000000000000..cbc9271ac14c828d0b64492fcc1cf79adfc6dc8f --- /dev/null +++ b/app/uploaders/file_uploader.rb @@ -0,0 +1,41 @@ +# encoding: utf-8 +class FileUploader < CarrierWave::Uploader::Base + storage :file + + def initialize(base_dir, path = '', allowed_extensions = nil) + @base_dir = base_dir + @path = path + @allowed_extensions = allowed_extensions + end + + def base_dir + @base_dir + end + + def store_dir + File.join(@base_dir, @path) + end + + def cache_dir + File.join(@base_dir, 'tmp', @path) + end + + def extension_white_list + @allowed_extensions + end + + def store!(file) + file.original_filename = self.class.generate_filename(file) + super + end + + def self.generate_filename(file) + original_filename = File.basename(file.original_filename, '.*') + extension = File.extname(file.original_filename) + new_filename = Digest::MD5.hexdigest(original_filename) + extension + end + + def self.generate_dir + SecureRandom.hex(5) + end +end diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 53e0dbaef9ba4a8ebd1a6dccb5bb4d5c69e90c30..c7a827555a7a43cf782e06df41dd3e496707137c 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -10,3 +10,4 @@ .container .content= yield + = yield :embedded_scripts \ No newline at end of file diff --git a/app/views/layouts/projects.html.haml b/app/views/layouts/projects.html.haml index 3ae4961b13752527eefa068117000819a17d0379..11c815c52a764855efd6dfc8e2f88b7410ae7c45 100644 --- a/app/views/layouts/projects.html.haml +++ b/app/views/layouts/projects.html.haml @@ -14,3 +14,4 @@ .container .content= yield + = yield :embedded_scripts \ No newline at end of file diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml index 84703229fe6be21a05027218ac28e6c9a711a9ec..49d1a87743f1305e88e6c65193a967b04794a7e8 100644 --- a/app/views/projects/issues/_form.html.haml +++ b/app/views/projects/issues/_form.html.haml @@ -5,6 +5,7 @@ - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) .alert.alert-info.col-sm-10.col-sm-offset-2 ="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe + = form_for [@project, @issue], html: { class: 'form-horizontal issue-form' } do |f| -if @issue.errors.any? .alert.alert-danger @@ -19,8 +20,12 @@ .form-group = f.label :description, 'Description', class: 'control-label' .col-sm-10 - = f.text_area :description, class: "form-control js-gfm-input", rows: 14 - %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + = f.text_area :description, class: 'form-control js-gfm-input markdown-area', rows: 14 + .col-sm-12.hint + .pull-left Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix + .error-alert %hr .form-group .issue-assignee @@ -57,9 +62,6 @@ - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue) = link_to "Cancel", cancel_path, class: 'btn btn-cancel' - - - :javascript $("#issue_label_list") .bind( "keydown", function( event ) { @@ -94,3 +96,5 @@ $('#issue_assignee_id').val("#{current_user.id}").trigger("change"); e.preventDefault(); }); + + window.project_image_path_upload = "#{upload_image_project_path @project}"; diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index b6d3a8edf4da9a22cfb07d8614ac613ea888ddab..2c816e788deccb289e9117f87b9eafa031f029cb 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -73,4 +73,4 @@ = label.name -.voting_notes#notes= render "projects/notes/notes_with_form" +.voting_notes#notes= render "projects/notes/notes_with_form" \ No newline at end of file diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml index 290a15e2664d5874f2e75a097bfd36d61fa35489..3088f0cf864a3d31a10899514d7117ac66fc70d0 100644 --- a/app/views/projects/merge_requests/_form.html.haml +++ b/app/views/projects/merge_requests/_form.html.haml @@ -22,8 +22,12 @@ .form-group = f.label :description, "Description", class: 'control-label' .col-sm-10 - = f.text_area :description, class: "form-control js-gfm-input", rows: 14 - %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 14 + .col-sm-12.hint + .pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix + .error-alert %hr .form-group .issue-assignee @@ -98,3 +102,5 @@ return false; } }); + + window.project_image_path_upload = "#{upload_image_project_path @project}"; diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index b5479be708b4d39ace998377743dd8d9f4e8e97a..dc41ef8135e08c98c8700a1c269f3a3c919f3a65 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -23,8 +23,12 @@ .form-group .light = f.label :description, "Description" - = f.text_area :description, class: "form-control js-gfm-input", rows: 10 - %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 10 + .col-sm-12.hint + .pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix + .error-alert .form-group .issue-assignee = f.label :assignee_id do @@ -80,3 +84,5 @@ $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); e.preventDefault(); }); + + window.project_image_path_upload = "#{upload_image_project_path @project}"; diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml index d770bb5b3710b52958034f8a9aaa556a4a401b3d..7e0fd19d0abfd338959075d7c971c92591905eb2 100644 --- a/app/views/projects/milestones/_form.html.haml +++ b/app/views/projects/milestones/_form.html.haml @@ -21,8 +21,12 @@ .form-group = f.label :description, "Description", class: "control-label" .col-sm-10 - = f.text_area :description, maxlength: 2000, class: "form-control", rows: 10 - %p.hint Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + = f.text_area :description, maxlength: 2000, class: "form-control markdown-area", rows: 10 + .hint + .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-left Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix + .error-alert .col-md-6 .form-group = f.label :due_date, "Due Date", class: "control-label" @@ -45,3 +49,5 @@ dateFormat: "yy-mm-dd", onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) } }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val())); + + window.project_image_path_upload = "#{upload_image_project_path @project}"; diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index 3db551e993b074a9e99af3d21c501ca3c5d419e8..cadae9da8050efc9c6992ec9d40c82b3a660d49f 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -5,20 +5,15 @@ = f.hidden_field :noteable_id = f.hidden_field :noteable_type - .note_text_and_preview.js-toggler-container - %a.btn.js-note-preview-button.js-toggler-target.turn-off{ href: "javascript:;", data: {url: preview_project_notes_path(@project)} } - %i.icon-eye-open - Preview - %a.btn.btn-primary.js-note-edit-button.js-toggler-target.turn-off{ href: "javascript:;" } - %i.icon-edit - Write - - = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on' + .note_text_and_preview.js-toggler-container.notes-container + = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on markdown-area' .note_preview.js-note-preview.turn-off .hint - .pull-right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. .clearfix + .error-alert .note-form-actions .buttons @@ -35,4 +30,14 @@ %span.file_name.js-attachment-filename File name... = f.file_field :attachment, class: "js-note-attachment-input hidden" + .write-preview-btn + %a.btn.js-note-preview-button.js-toggler-target.turn-off{ href: "javascript:;", data: {url: preview_project_notes_path(@project)} } + %i.icon-eye-open + Preview + %a.btn.btn-primary.js-note-edit-button.js-toggler-target.turn-off{ href: "javascript:;" } + %i.icon-edit + Write .clearfix + +:javascript + window.project_image_path_upload = "#{upload_image_project_path @project}"; diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index 0c2e33f22820c1ded31f13263f12b07f1c6323c5..a43e6f073e15511067a11c9e8f84cbee4f3e9907 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -15,7 +15,6 @@ .col-sm-2 .col-sm-10 %p.cgray - Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. To link to a (new) page you can just type %code [Link Title](page-slug) \. @@ -23,8 +22,12 @@ .form-group = f.label :content, class: 'control-label' .col-sm-10 - = f.text_area :content, class: 'form-control js-gfm-input', rows: 18 - + = f.text_area :content, class: 'form-control js-gfm-input markdown-area', rows: 18 + .col-sm-12.hint + .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix + .error-alert .form-group = f.label :commit_message, class: 'control-label' .col-sm-10= f.text_field :message, class: 'form-control', rows: 18 @@ -36,3 +39,7 @@ - else = f.submit 'Create page', class: "btn-create btn" = link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel" + +:javascript + window.project_image_path_upload = "#{upload_image_project_path @project}"; + diff --git a/config/routes.rb b/config/routes.rb index 7641fe430889bbe469856c4d9926e033c023c431..da5a1ba7a871c00a60fce53e72344cd9de6f1ab7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -136,8 +136,6 @@ match "/u/:username" => "users#show", as: :user, constraints: { username: /.*/ }, via: :get - - # # Dashboard Area # @@ -178,6 +176,7 @@ post :fork post :archive post :unarchive + post :upload_image get :autocomplete_sources get :import put :retry_import diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb index fbf4f29acfd693000cf4537bc8b19f5b610ec1d3..308cfa692192e2f28286ac29f0fc792e4d6c5f57 100644 --- a/spec/controllers/commits_controller_spec.rb +++ b/spec/controllers/commits_controller_spec.rb @@ -6,8 +6,7 @@ before do sign_in(user) - - project.team << [user, :master] + project.creator = user end describe "GET show" do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..07ca8d25026654a4fcb620067f52864a9a371c0e --- /dev/null +++ b/spec/controllers/projects_controller_spec.rb @@ -0,0 +1,44 @@ +require('spec_helper') + +describe ProjectsController do + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:png) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', 'image/png') } + let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') } + let(:gif) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') } + let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') } + + describe "POST #upload_image" do + before do + sign_in(user) + end + + context "without params['markdown_img']" do + it "returns an error" do + post :upload_image, id: project.to_param + expect(response.status).to eq(404) + end + end + + context "with invalid file" do + before do + post :upload_image, id: project.to_param, markdown_img: @img + end + + it "returns an error" do + expect(response.status).to eq(404) + end + end + + context "with valid file" do + before do + post :upload_image, id: project.to_param, markdown_img: @img + end + + it "returns a content with original filename and new link." do + link = { alt: 'rails_sample', link: '' }.to_json + expect(response.body).to have_content link + end + end + end +end \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb index 148477d6389017fc7c19a36b0b816f986d3bed35..41cc99cbcb91e47d4790fd2cc104a6bee792d2ed 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -201,7 +201,7 @@ end trait :with_attachment do - attachment { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png") } + attachment { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "`/png") } end end diff --git a/spec/fixtures/banana_sample.gif b/spec/fixtures/banana_sample.gif new file mode 100644 index 0000000000000000000000000000000000000000..1322ac92d141f2240f3b68b1c4a10b5e18b49e2b Binary files /dev/null and b/spec/fixtures/banana_sample.gif differ diff --git a/spec/fixtures/doc_sample.txt b/spec/fixtures/doc_sample.txt new file mode 100644 index 0000000000000000000000000000000000000000..45dbc1aadde033b088b32769bcf60c8589e21750 --- /dev/null +++ b/spec/fixtures/doc_sample.txt @@ -0,0 +1,3 @@ +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? \ No newline at end of file diff --git a/spec/fixtures/rails_sample.jpg b/spec/fixtures/rails_sample.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a847b19332535844fe83840e16d3872902bb7441 Binary files /dev/null and b/spec/fixtures/rails_sample.jpg differ