FIX: import/export theme should work with uploads

This commit is contained in:
Sam 2017-11-14 16:30:23 +11:00
parent 075a458489
commit 47e4c9bb46
3 changed files with 85 additions and 2 deletions

View File

@ -1,4 +1,5 @@
require_dependency 'upload_creator'
require 'base64'
class Admin::ThemesController < Admin::AdminController
@ -31,7 +32,28 @@ class Admin::ThemesController < Admin::AdminController
@theme = Theme.new(name: theme["name"], user_id: current_user.id)
theme["theme_fields"]&.each do |field|
@theme.set_field(target: field["target"], name: field["name"], value: field["value"])
if field["raw_upload"]
begin
tmp = Tempfile.new
tmp.binmode
file = Base64.decode64(field["raw_upload"])
tmp.write(file)
tmp.rewind
upload = UploadCreator.new(tmp, field["filename"]).create_for(current_user.id)
field["upload_id"] = upload.id
ensure
tmp.unlink
end
end
@theme.set_field(
target: field["target"],
name: field["name"],
value: field["value"],
type_id: field["type_id"],
upload_id: field["upload_id"]
)
end
if @theme.save
@ -168,7 +190,7 @@ class Admin::ThemesController < Admin::AdminController
response.headers['Content-Disposition'] = "attachment; filename=#{@theme.name.parameterize}.dcstyle.json"
response.sending_file = true
render json: ThemeSerializer.new(@theme)
render json: ThemeWithEmbeddedUploadsSerializer.new(@theme, root: 'theme')
end
end

View File

@ -1,3 +1,5 @@
require 'base64'
class ThemeFieldSerializer < ApplicationSerializer
attributes :name, :target, :value, :error, :type_id, :upload_id, :url, :filename
@ -68,3 +70,28 @@ class ThemeSerializer < ChildThemeSerializer
object.child_themes.order(:name)
end
end
class ThemeFieldWithEmbeddedUploadsSerializer < ThemeFieldSerializer
attributes :raw_upload
def include_raw_upload?
object.upload
end
def raw_upload
filename = Discourse.store.path_for(object.upload)
raw = nil
if filename
raw = File.read(filename)
else
raw = Discourse.store.download(object.upload).read
end
Base64.encode64(raw)
end
end
class ThemeWithEmbeddedUploadsSerializer < ThemeSerializer
has_many :theme_fields, serializer: ThemeFieldWithEmbeddedUploadsSerializer, embed: :objects
end

View File

@ -1,4 +1,5 @@
require 'rails_helper'
require_dependency 'theme_serializer'
describe Admin::ThemesController do
@ -34,6 +35,39 @@ describe Admin::ThemesController do
Rack::Test::UploadedFile.new(file_from_fixtures("sam-s-simple-theme.dcstyle.json", "json"))
end
let :image do
file_from_fixtures("logo.png")
end
it 'can import a theme with an upload' do
upload = Fabricate(:upload)
theme = Theme.new(name: 'with-upload', user_id: -1)
upload = UploadCreator.new(image, "logo.png").create_for(-1)
theme.set_field(target: :common, name: :logo, upload_id: upload.id, type: :theme_upload_var)
theme.save
json = ThemeWithEmbeddedUploadsSerializer.new(theme, root: 'theme').to_json
theme.destroy
temp = Tempfile.new
temp.write(json)
temp.rewind
uploaded_json = Rack::Test::UploadedFile.new(temp)
upload.destroy
post :import, params: { theme: uploaded_json }, format: :json
expect(response).to be_success
temp.unlink
theme = Theme.last
expect(theme.theme_fields.count).to eq(1)
expect(theme.theme_fields.first.upload).not_to eq(nil)
expect(theme.theme_fields.first.upload.filesize).to eq(upload.filesize)
expect(theme.theme_fields.first.upload.sha1).to eq(upload.sha1)
expect(theme.theme_fields.first.upload.original_filename).to eq(upload.original_filename)
end
it 'imports a theme' do
post :import, params: { theme: theme_file }, format: :json
expect(response).to be_success