Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ def show
end

def new
@story = Story.new.decorate
if params[:story_idea_id].present?
@story_idea = StoryIdea.find(params[:story_idea_id])
@story = StoryFromIdeaService.new(@story_idea, user: current_user).call
else
@story = Story.new
end
@story = @story.decorate
set_form_variables
end
Expand Down
44 changes: 44 additions & 0 deletions app/services/story_from_idea_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

class StoryFromIdeaService
def initialize(story_idea, user:)
@story_idea = story_idea
@user = user
end

def call
Story.new(attributes_from_idea).tap do |story|
duplicate_assets(story)
end
end

private

attr_reader :story_idea, :user

def attributes_from_idea
story_idea.attributes.slice(
"title", "body", "youtube_url",
"windows_type_id", "project_id", "workshop_id", "external_workshop_title"
).merge(
created_by_id: user.id,
updated_by_id: user.id,
story_idea_id: story_idea.id,
published: false
)
end

def duplicate_assets(story)
# Duplicate primary asset with correct type
if story_idea.primary_asset&.file&.attached?
story.build_primary_asset(file: story_idea.primary_asset.file.blob)
end

# Duplicate gallery assets with correct type
story_idea.gallery_assets.each do |gallery_asset|
next unless gallery_asset.file&.attached?

story.gallery_assets.build(file: gallery_asset.file.blob)
end
end
end
12 changes: 10 additions & 2 deletions app/services/workshop_from_idea_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,16 @@ def duplicate_series_children(workshop)
end

def duplicate_assets(workshop)
workshop_idea.assets.each do |image|
workshop.assets.build(file: image.file.blob)
# Duplicate primary asset with correct type
if workshop_idea.primary_asset&.file&.attached?
workshop.build_primary_asset(file: workshop_idea.primary_asset.file.blob)
end

# Duplicate gallery assets with correct type
workshop_idea.gallery_assets.each do |gallery_asset|
next unless gallery_asset.file&.attached?

workshop.gallery_assets.build(file: gallery_asset.file.blob)
end
end
end
17 changes: 15 additions & 2 deletions app/views/workshop_ideas/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,21 @@
<div class="max-w-5xl mx-auto bg-white border border-gray-200 rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-200 p-6">
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-semibold text-gray-900">Edit <%= @workshop_idea.class.model_name.human %></h1>
<%= link_to 'View', workshop_idea_path(@workshop_idea),
class: "btn btn-secondary-outline" %>
<div class="text-end text-right items-end items-right">
<% if @workshop_idea.workshops.any? %>
<% @workshop_idea.workshops.each do |workshop| %>
<%= link_to "View Workshop", workshop_path(workshop),
class: "btn btn-secondary-outline" %>
<% end %>
<% else %>
<% if current_user.super_user && @workshop_idea.persisted? %>
<%= link_to "Promote to Workshop", new_workshop_path(workshop_idea_id: @workshop_idea.id),
class: "admin-only bg-blue-100 btn btn-secondary-outline ms-2" %>
<% end %>
<% end %>
<%= link_to "View", workshop_idea_path(@workshop_idea),
class: "btn btn-secondary-outline" %>
</div>
</div>

<div class="space-y-6">
Expand Down
Binary file added spec/fixtures/test_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions spec/services/story_from_idea_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe StoryFromIdeaService do
subject(:service) { described_class.new(story_idea, user: user) }

let(:user) { create(:user) }
let(:story_idea) { create(:story_idea, created_by: user, updated_by: user) }

describe "#call" do
let(:story) { service.call }

it "returns a new Story" do
expect(story).to be_a(Story)
expect(story).to be_new_record
end

it "copies basic attributes from story_idea" do
expect(story).to have_attributes(
title: story_idea.title,
body: story_idea.body,
youtube_url: story_idea.youtube_url,
windows_type_id: story_idea.windows_type_id,
project_id: story_idea.project_id,
workshop_id: story_idea.workshop_id,
story_idea_id: story_idea.id,
created_by_id: user.id,
updated_by_id: user.id
)
end

it "sets the story as unpublished by default" do
expect(story.published).to be false
end

context "when story_idea has a primary_asset" do
let(:story_idea) do
create(:story_idea, created_by: user, updated_by: user).tap do |si|
si.create_primary_asset!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates the primary_asset to the story" do
expect(story.primary_asset).to be_present
expect(story.primary_asset).to be_a(PrimaryAsset)
expect(story.primary_asset.file).to be_attached
end
end

context "when story_idea has gallery_assets" do
let(:story_idea) do
create(:story_idea, created_by: user, updated_by: user).tap do |si|
si.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
si.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates all gallery_assets to the story" do
expect(story.gallery_assets.size).to eq(2)
story.gallery_assets.each do |asset|
expect(asset).to be_a(GalleryAsset)
expect(asset.file).to be_attached
end
end
end

context "when story_idea has both primary and gallery assets" do
let(:story_idea) do
create(:story_idea, created_by: user, updated_by: user).tap do |si|
si.create_primary_asset!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
si.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates both asset types correctly" do
expect(story.primary_asset).to be_a(PrimaryAsset)
expect(story.gallery_assets.size).to eq(1)
expect(story.gallery_assets.first).to be_a(GalleryAsset)
end
end
end
end
84 changes: 84 additions & 0 deletions spec/services/workshop_from_idea_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe WorkshopFromIdeaService do
subject(:service) { described_class.new(workshop_idea, user: user) }

let(:user) { create(:user) }
let(:workshop_idea) { create(:workshop_idea, created_by: user, updated_by: user) }

describe "#call" do
let(:workshop) { service.call }

it "returns a new Workshop" do
expect(workshop).to be_a(Workshop)
expect(workshop).to be_new_record
end

it "copies basic attributes from workshop_idea" do
expect(workshop).to have_attributes(
title: workshop_idea.title,
objective: workshop_idea.objective,
materials: workshop_idea.materials,
windows_type_id: workshop_idea.windows_type_id,
workshop_idea_id: workshop_idea.id,
user_id: user.id
)
end

it "sets the workshop as inactive by default" do
expect(workshop.inactive).to be true
end

it "sets the workshop as not featured by default" do
expect(workshop.featured).to be false
end

context "when workshop_idea has a primary_asset" do
let(:workshop_idea) do
create(:workshop_idea, created_by: user, updated_by: user).tap do |wi|
wi.create_primary_asset!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates the primary_asset to the workshop" do
expect(workshop.primary_asset).to be_present
expect(workshop.primary_asset).to be_a(PrimaryAsset)
expect(workshop.primary_asset.file).to be_attached
end
end

context "when workshop_idea has gallery_assets" do
let(:workshop_idea) do
create(:workshop_idea, created_by: user, updated_by: user).tap do |wi|
wi.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
wi.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates all gallery_assets to the workshop" do
expect(workshop.gallery_assets.size).to eq(2)
workshop.gallery_assets.each do |asset|
expect(asset).to be_a(GalleryAsset)
expect(asset.file).to be_attached
end
end
end

context "when workshop_idea has both primary and gallery assets" do
let(:workshop_idea) do
create(:workshop_idea, created_by: user, updated_by: user).tap do |wi|
wi.create_primary_asset!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
wi.gallery_assets.create!(file: fixture_file_upload("spec/fixtures/test_image.jpg", "image/jpeg"))
end
end

it "duplicates both asset types correctly" do
expect(workshop.primary_asset).to be_a(PrimaryAsset)
expect(workshop.gallery_assets.size).to eq(1)
expect(workshop.gallery_assets.first).to be_a(GalleryAsset)
end
end
end
end