BigW Consortium Gitlab

Commit fc861658 by Dmitriy Zaporozhets

Merge pull request #7011 from erbunao/drag-and-drop_markdown

Implements drag and drop upload of image in every markdown-area
parents 696b9903 6a85cdf1
...@@ -69,6 +69,9 @@ gem "haml-rails" ...@@ -69,6 +69,9 @@ gem "haml-rails"
# Files attachments # Files attachments
gem "carrierwave" gem "carrierwave"
# Drag and Drop UI
gem 'dropzonejs-rails'
# for aws storage # for aws storage
gem "fog", "~> 1.14", group: :aws gem "fog", "~> 1.14", group: :aws
gem "unf", group: :aws gem "unf", group: :aws
......
...@@ -103,6 +103,8 @@ GEM ...@@ -103,6 +103,8 @@ GEM
diffy (3.0.3) diffy (3.0.3)
docile (1.1.1) docile (1.1.1)
dotenv (0.9.0) dotenv (0.9.0)
dropzonejs-rails (0.4.14)
rails (> 3.1)
email_spec (1.5.0) email_spec (1.5.0)
launchy (~> 2.1) launchy (~> 2.1)
mail (~> 2.2) mail (~> 2.2)
...@@ -579,6 +581,7 @@ DEPENDENCIES ...@@ -579,6 +581,7 @@ DEPENDENCIES
devise (= 3.0.4) devise (= 3.0.4)
devise-async (= 0.8.0) devise-async (= 0.8.0)
diffy (~> 3.0.3) diffy (~> 3.0.3)
dropzonejs-rails
email_spec email_spec
email_validator (~> 1.4.0) email_validator (~> 1.4.0)
enumerize enumerize
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#= require underscore #= require underscore
#= require nprogress #= require nprogress
#= require nprogress-turbolinks #= require nprogress-turbolinks
#= require dropzone
#= require_tree . #= require_tree .
window.slugify = (text) -> window.slugify = (text) ->
......
$ -> $ ->
$("body").on "click", ".js-toggler-target", -> $("body").on "click", ".js-toggler-target", ->
container = $(@).closest(".js-toggler-container") container = $(".notes-container")
container.toggleClass("on") container.toggleClass("on")
# Toggle button. Show/hide content inside parent container. # Toggle button. Show/hide content inside parent container.
......
formatLink = (str) ->
"![" + str.alt + "](" + str.url + ")"
$(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 + ">&times;</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
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*= require_self *= require_self
*= require nprogress *= require nprogress
*= require nprogress-bootstrap *= require nprogress-bootstrap
*= require dropzone/basic
*/ */
@import "main/*"; @import "main/*";
......
...@@ -5,10 +5,19 @@ ...@@ -5,10 +5,19 @@
.js-details-container.open .content { display: block; } .js-details-container.open .content { display: block; }
.js-details-container.open .content.hide { display: none; } .js-details-container.open .content.hide { display: none; }
// Toggler // 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 .turn-off { display: none; }
.js-toggler-container.on .turn-on { display: none; } .js-toggler-container.on .turn-on { display: none; }
.js-toggler-container.on .turn-off { display: inherit; } .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; }
}
.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;
}
...@@ -272,21 +272,16 @@ ul.notes { ...@@ -272,21 +272,16 @@ ul.notes {
margin-bottom: 0; margin-bottom: 0;
} }
.note_text_and_preview { .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 { .note_preview {
background: #f5f5f5; background: #f5f5f5;
border: 1px solid #ddd; border: 1px solid #ddd;
@include border-radius(4px); @include border-radius(4px);
min-height: 80px; min-height: 80px;
padding: 4px 6px; padding: 4px 6px;
> p {
overflow-x: auto;
}
} }
.note_text { .note_text {
border: 1px solid #DDD; border: 1px solid #DDD;
...@@ -310,7 +305,6 @@ ul.notes { ...@@ -310,7 +305,6 @@ ul.notes {
float: none; float: none;
} }
.common-note-form { .common-note-form {
margin: 0; margin: 0;
background: #F9F9F9; background: #F9F9F9;
...@@ -318,7 +312,6 @@ ul.notes { ...@@ -318,7 +312,6 @@ ul.notes {
border: 1px solid #DDD; border: 1px solid #DDD;
} }
.note-form-actions { .note-form-actions {
background: #F9F9F9; background: #F9F9F9;
height: 45px; height: 45px;
...@@ -333,6 +326,18 @@ ul.notes { ...@@ -333,6 +326,18 @@ ul.notes {
.js-notify-commit-author { .js-notify-commit-author {
float: left; 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 { .note-edit-form {
...@@ -367,3 +372,8 @@ ul.notes { ...@@ -367,3 +372,8 @@ ul.notes {
.parallel-comment { .parallel-comment {
padding: 6px; padding: 6px;
} }
.error-alert > .alert {
margin-top: 5px;
margin-bottom: 5px;
}
...@@ -14,4 +14,3 @@ class FilesController < ApplicationController ...@@ -14,4 +14,3 @@ class FilesController < ApplicationController
end end
end end
end end
...@@ -69,7 +69,9 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -69,7 +69,9 @@ class Projects::IssuesController < Projects::ApplicationController
render :new render :new
end end
end end
format.js format.js do |format|
@link = @issue.attachment.url.to_js
end
end end
end end
......
...@@ -162,8 +162,28 @@ class ProjectsController < ApplicationController ...@@ -162,8 +162,28 @@ class ProjectsController < ApplicationController
end end
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 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 def set_title
@title = 'New Project' @title = 'New Project'
end end
......
...@@ -15,8 +15,12 @@ ...@@ -15,8 +15,12 @@
# milestone_id :integer # milestone_id :integer
# state :string(255) # state :string(255)
# iid :integer # iid :integer
# attachment :string(255)
# #
require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Issue < ActiveRecord::Base class Issue < ActiveRecord::Base
include Issuable include Issuable
include InternalId include InternalId
......
# 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
...@@ -10,3 +10,4 @@ ...@@ -10,3 +10,4 @@
.container .container
.content= yield .content= yield
= yield :embedded_scripts
\ No newline at end of file
...@@ -14,3 +14,4 @@ ...@@ -14,3 +14,4 @@
.container .container
.content= yield .content= yield
= yield :embedded_scripts
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
- contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) - 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 .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 ="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| = form_for [@project, @issue], html: { class: 'form-horizontal issue-form' } do |f|
-if @issue.errors.any? -if @issue.errors.any?
.alert.alert-danger .alert.alert-danger
...@@ -19,8 +20,12 @@ ...@@ -19,8 +20,12 @@
.form-group .form-group
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_area :description, class: "form-control js-gfm-input", rows: 14 = f.text_area :description, class: 'form-control js-gfm-input markdown-area', rows: 14
%p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. .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 %hr
.form-group .form-group
.issue-assignee .issue-assignee
...@@ -57,9 +62,6 @@ ...@@ -57,9 +62,6 @@
- cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue) - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue)
= link_to "Cancel", cancel_path, class: 'btn btn-cancel' = link_to "Cancel", cancel_path, class: 'btn btn-cancel'
:javascript :javascript
$("#issue_label_list") $("#issue_label_list")
.bind( "keydown", function( event ) { .bind( "keydown", function( event ) {
...@@ -94,3 +96,5 @@ ...@@ -94,3 +96,5 @@
$('#issue_assignee_id').val("#{current_user.id}").trigger("change"); $('#issue_assignee_id').val("#{current_user.id}").trigger("change");
e.preventDefault(); e.preventDefault();
}); });
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -22,8 +22,12 @@ ...@@ -22,8 +22,12 @@
.form-group .form-group
= f.label :description, "Description", class: 'control-label' = f.label :description, "Description", class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_area :description, class: "form-control js-gfm-input", rows: 14 = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 14
%p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. .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 %hr
.form-group .form-group
.issue-assignee .issue-assignee
...@@ -98,3 +102,5 @@ ...@@ -98,3 +102,5 @@
return false; return false;
} }
}); });
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -23,8 +23,12 @@ ...@@ -23,8 +23,12 @@
.form-group .form-group
.light .light
= f.label :description, "Description" = f.label :description, "Description"
= f.text_area :description, class: "form-control js-gfm-input", rows: 10 = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 10
%p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. .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 .form-group
.issue-assignee .issue-assignee
= f.label :assignee_id do = f.label :assignee_id do
...@@ -80,3 +84,5 @@ ...@@ -80,3 +84,5 @@
$('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
e.preventDefault(); e.preventDefault();
}); });
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -21,8 +21,12 @@ ...@@ -21,8 +21,12 @@
.form-group .form-group
= f.label :description, "Description", class: "control-label" = f.label :description, "Description", class: "control-label"
.col-sm-10 .col-sm-10
= f.text_area :description, maxlength: 2000, class: "form-control", rows: 10 = f.text_area :description, maxlength: 2000, class: "form-control markdown-area", rows: 10
%p.hint Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. .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 .col-md-6
.form-group .form-group
= f.label :due_date, "Due Date", class: "control-label" = f.label :due_date, "Due Date", class: "control-label"
...@@ -45,3 +49,5 @@ ...@@ -45,3 +49,5 @@
dateFormat: "yy-mm-dd", dateFormat: "yy-mm-dd",
onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) } onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
}).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val())); }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val()));
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -5,20 +5,15 @@ ...@@ -5,20 +5,15 @@
= f.hidden_field :noteable_id = f.hidden_field :noteable_id
= f.hidden_field :noteable_type = f.hidden_field :noteable_type
.note_text_and_preview.js-toggler-container .note_text_and_preview.js-toggler-container.notes-container
%a.btn.js-note-preview-button.js-toggler-target.turn-off{ href: "javascript:;", data: {url: preview_project_notes_path(@project)} } = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on markdown-area'
%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_preview.js-note-preview.turn-off .note_preview.js-note-preview.turn-off
.hint .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 .clearfix
.error-alert
.note-form-actions .note-form-actions
.buttons .buttons
...@@ -35,4 +30,14 @@ ...@@ -35,4 +30,14 @@
%span.file_name.js-attachment-filename File name... %span.file_name.js-attachment-filename File name...
= f.file_field :attachment, class: "js-note-attachment-input hidden" = 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 .clearfix
:javascript
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
%p.cgray %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 To link to a (new) page you can just type
%code [Link Title](page-slug) %code [Link Title](page-slug)
\. \.
...@@ -23,8 +22,12 @@ ...@@ -23,8 +22,12 @@
.form-group .form-group
= f.label :content, class: 'control-label' = f.label :content, class: 'control-label'
.col-sm-10 .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 .form-group
= f.label :commit_message, class: 'control-label' = f.label :commit_message, class: 'control-label'
.col-sm-10= f.text_field :message, class: 'form-control', rows: 18 .col-sm-10= f.text_field :message, class: 'form-control', rows: 18
...@@ -36,3 +39,7 @@ ...@@ -36,3 +39,7 @@
- else - else
= f.submit 'Create page', class: "btn-create btn" = f.submit 'Create page', class: "btn-create btn"
= link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel" = link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel"
:javascript
window.project_image_path_upload = "#{upload_image_project_path @project}";
...@@ -136,8 +136,6 @@ Gitlab::Application.routes.draw do ...@@ -136,8 +136,6 @@ Gitlab::Application.routes.draw do
match "/u/:username" => "users#show", as: :user, constraints: { username: /.*/ }, via: :get match "/u/:username" => "users#show", as: :user, constraints: { username: /.*/ }, via: :get
# #
# Dashboard Area # Dashboard Area
# #
...@@ -178,6 +176,7 @@ Gitlab::Application.routes.draw do ...@@ -178,6 +176,7 @@ Gitlab::Application.routes.draw do
post :fork post :fork
post :archive post :archive
post :unarchive post :unarchive
post :upload_image
get :autocomplete_sources get :autocomplete_sources
get :import get :import
put :retry_import put :retry_import
......
...@@ -6,8 +6,7 @@ describe Projects::CommitsController do ...@@ -6,8 +6,7 @@ describe Projects::CommitsController do
before do before do
sign_in(user) sign_in(user)
project.creator = user
project.team << [user, :master]
end end
describe "GET show" do describe "GET show" do
......
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
...@@ -201,7 +201,7 @@ FactoryGirl.define do ...@@ -201,7 +201,7 @@ FactoryGirl.define do
end end
trait :with_attachment do 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
end end
......
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment