mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Rename from Active Text to Action Text
This is more like Action View than Active Model.
This commit is contained in:
parent
3bc244abc1
commit
f1d74871e7
27 changed files with 69 additions and 69 deletions
|
@ -1,4 +1,4 @@
|
||||||
# Active Text
|
# Action Text
|
||||||
|
|
||||||
🤸♂️💰📝
|
🤸♂️💰📝
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Assumes a Rails 5.2+ application with Active Storage and Webpacker installed.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# Gemfile
|
# Gemfile
|
||||||
gem "activetext", github: "basecamp/activetext", require: "active_text"
|
gem "activetext", github: "basecamp/activetext", require: "action_text"
|
||||||
gem "mini_magick" # for Active Storage variants
|
gem "mini_magick" # for Active Storage variants
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ Assumes a Rails 5.2+ application with Active Storage and Webpacker installed.
|
||||||
import "activetext"
|
import "activetext"
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Declare text columns as Active Text attributes:
|
1. Declare text columns as Action Text attributes:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# app/models/message.rb
|
# app/models/message.rb
|
||||||
|
|
2
Rakefile
2
Rakefile
|
@ -8,7 +8,7 @@ require 'rdoc/task'
|
||||||
|
|
||||||
RDoc::Task.new(:rdoc) do |rdoc|
|
RDoc::Task.new(:rdoc) do |rdoc|
|
||||||
rdoc.rdoc_dir = 'rdoc'
|
rdoc.rdoc_dir = 'rdoc'
|
||||||
rdoc.title = 'Active Text'
|
rdoc.title = 'Action Text'
|
||||||
rdoc.options << '--line-numbers'
|
rdoc.options << '--line-numbers'
|
||||||
rdoc.rdoc_files.include('README.md')
|
rdoc.rdoc_files.include('README.md')
|
||||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
$:.push File.expand_path("lib", __dir__)
|
$:.push File.expand_path("lib", __dir__)
|
||||||
|
|
||||||
# Maintain your gem's version:
|
# Maintain your gem's version:
|
||||||
require "active_text/version"
|
require "action_text/version"
|
||||||
|
|
||||||
# Describe your gem and declare its dependencies:
|
# Describe your gem and declare its dependencies:
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = "activetext"
|
s.name = "activetext"
|
||||||
s.version = ActiveText::VERSION
|
s.version = ActionText::VERSION
|
||||||
s.authors = ["Javan Makhmali", "Sam Stephenson"]
|
s.authors = ["Javan Makhmali", "Sam Stephenson"]
|
||||||
s.email = ["javan@javan.us", "sstephenson@gmail.com"]
|
s.email = ["javan@javan.us", "sstephenson@gmail.com"]
|
||||||
s.summary = "Edit and display rich text in Rails applications"
|
s.summary = "Edit and display rich text in Rails applications"
|
|
@ -1,11 +1,11 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module TagHelper
|
module TagHelper
|
||||||
cattr_accessor(:id, instance_accessor: false) { 0 }
|
cattr_accessor(:id, instance_accessor: false) { 0 }
|
||||||
|
|
||||||
def rich_text_field_tag(name, value = nil, options = {})
|
def rich_text_field_tag(name, value = nil, options = {})
|
||||||
options = options.symbolize_keys
|
options = options.symbolize_keys
|
||||||
|
|
||||||
options[:input] ||= "trix_input_#{ActiveText::TagHelper.id += 1}"
|
options[:input] ||= "trix_input_#{ActionText::TagHelper.id += 1}"
|
||||||
options[:data] ||= {}
|
options[:data] ||= {}
|
||||||
options[:data][:direct_upload_url] = rails_direct_uploads_url
|
options[:data][:direct_upload_url] = rails_direct_uploads_url
|
||||||
options[:data][:blob_url_template] = rails_service_blob_url(":signed_id", ":filename")
|
options[:data][:blob_url_template] = rails_service_blob_url(":signed_id", ":filename")
|
||||||
|
@ -19,7 +19,7 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
module ActionView::Helpers
|
module ActionView::Helpers
|
||||||
class Tags::ActiveText < Tags::Base
|
class Tags::ActionText < Tags::Base
|
||||||
delegate :dom_id, to: ActionView::RecordIdentifier
|
delegate :dom_id, to: ActionView::RecordIdentifier
|
||||||
|
|
||||||
def render
|
def render
|
||||||
|
@ -36,7 +36,7 @@ module ActionView::Helpers
|
||||||
|
|
||||||
module FormHelper
|
module FormHelper
|
||||||
def rich_text_field(object_name, method, options = {})
|
def rich_text_field(object_name, method, options = {})
|
||||||
Tags::ActiveText.new(object_name, method, self, options).render
|
Tags::ActionText.new(object_name, method, self, options).render
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require "active_record"
|
require "active_record"
|
||||||
require "active_text/engine"
|
require "action_text/engine"
|
||||||
require "nokogiri"
|
require "nokogiri"
|
||||||
|
|
||||||
module ActiveText
|
module ActionText
|
||||||
extend ActiveSupport::Autoload
|
extend ActiveSupport::Autoload
|
||||||
|
|
||||||
mattr_accessor(:renderer)
|
mattr_accessor(:renderer)
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachable
|
module Attachable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@ module ActiveText
|
||||||
def from_node(node)
|
def from_node(node)
|
||||||
if attachable = attachable_from_sgid(node["sgid"])
|
if attachable = attachable_from_sgid(node["sgid"])
|
||||||
attachable
|
attachable
|
||||||
elsif attachable = ActiveText::Attachables::ContentAttachment.from_node(node)
|
elsif attachable = ActionText::Attachables::ContentAttachment.from_node(node)
|
||||||
attachable
|
attachable
|
||||||
elsif attachable = ActiveText::Attachables::RemoteImage.from_node(node)
|
elsif attachable = ActionText::Attachables::RemoteImage.from_node(node)
|
||||||
attachable
|
attachable
|
||||||
else
|
else
|
||||||
ActiveText::Attachables::MissingAttachable
|
ActionText::Attachables::MissingAttachable
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ module ActiveText
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def from_attachable_sgid(sgid)
|
def from_attachable_sgid(sgid)
|
||||||
ActiveText::Attachable.from_attachable_sgid(sgid, only: self)
|
ActionText::Attachable.from_attachable_sgid(sgid, only: self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachables
|
module Attachables
|
||||||
class ContentAttachment
|
class ContentAttachment
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
@ -25,11 +25,11 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_partial_path
|
def to_partial_path
|
||||||
"active_text/attachables/content_attachment"
|
"action_text/attachables/content_attachment"
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_trix_content_attachment_partial_path
|
def to_trix_content_attachment_partial_path
|
||||||
"active_text/attachables/content_attachments/#{name.underscore}"
|
"action_text/attachables/content_attachments/#{name.underscore}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,10 +1,10 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachables
|
module Attachables
|
||||||
module MissingAttachable
|
module MissingAttachable
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
|
|
||||||
def self.to_partial_path
|
def self.to_partial_path
|
||||||
"active_text/attachables/missing_attachable"
|
"action_text/attachables/missing_attachable"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachables
|
module Attachables
|
||||||
class RemoteImage
|
class RemoteImage
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
|
@ -37,7 +37,7 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_partial_path
|
def to_partial_path
|
||||||
"active_text/attachables/remote_image"
|
"action_text/attachables/remote_image"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
class Attachment
|
class Attachment
|
||||||
include Attachments::TrixConversion, Attachments::Minification, Attachments::Caching
|
include Attachments::TrixConversion, Attachments::Minification, Attachments::Caching
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_node(node, attachable = nil)
|
def from_node(node, attachable = nil)
|
||||||
new(node, attachable || ActiveText::Attachable.from_node(node))
|
new(node, attachable || ActionText::Attachable.from_node(node))
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_attachables(attachables)
|
def from_attachables(attachables)
|
||||||
|
@ -34,7 +34,7 @@ module ActiveText
|
||||||
private
|
private
|
||||||
def node_from_attributes(attributes)
|
def node_from_attributes(attributes)
|
||||||
if attributes = process_attributes(attributes).presence
|
if attributes = process_attributes(attributes).presence
|
||||||
ActiveText::HtmlConversion.create_element(TAG_NAME, attributes)
|
ActionText::HtmlConversion.create_element(TAG_NAME, attributes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachments
|
module Attachments
|
||||||
module Caching
|
module Caching
|
||||||
def cache_key(*args)
|
def cache_key(*args)
|
|
@ -1,11 +1,11 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachments
|
module Attachments
|
||||||
module Minification
|
module Minification
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def fragment_by_minifying_attachments(content)
|
def fragment_by_minifying_attachments(content)
|
||||||
Fragment.wrap(content).replace(ActiveText::Attachment::SELECTOR) do |node|
|
Fragment.wrap(content).replace(ActionText::Attachment::SELECTOR) do |node|
|
||||||
node.tap { |n| n.inner_html = "" }
|
node.tap { |n| n.inner_html = "" }
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attachments
|
module Attachments
|
||||||
module TrixConversion
|
module TrixConversion
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
@ -24,7 +24,7 @@ module ActiveText
|
||||||
private
|
private
|
||||||
def trix_attachment_content
|
def trix_attachment_content
|
||||||
if partial_path = attachable.try(:to_trix_content_attachment_partial_path)
|
if partial_path = attachable.try(:to_trix_content_attachment_partial_path)
|
||||||
ActiveText.renderer.render(partial: partial_path, object: self, as: model_name.element)
|
ActionText.renderer.render(partial: partial_path, object: self, as: model_name.element)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,10 +1,10 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Attribute
|
module Attribute
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def has_rich_text(attribute_name)
|
def has_rich_text(attribute_name)
|
||||||
serialize(attribute_name, ActiveText::Content)
|
serialize(attribute_name, ActionText::Content)
|
||||||
|
|
||||||
has_many_attached "#{attribute_name}_attachments"
|
has_many_attached "#{attribute_name}_attachments"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
class Content
|
class Content
|
||||||
include Serialization
|
include Serialization
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ module ActiveText
|
||||||
delegate :blank?, :empty?, :html_safe, :present?, to: :to_s
|
delegate :blank?, :empty?, :html_safe, :present?, to: :to_s
|
||||||
|
|
||||||
def initialize(content = nil)
|
def initialize(content = nil)
|
||||||
@fragment = ActiveText::Attachment.fragment_by_canonicalizing_attachments(content)
|
@fragment = ActionText::Attachment.fragment_by_canonicalizing_attachments(content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def links
|
def links
|
||||||
|
@ -22,17 +22,17 @@ module ActiveText
|
||||||
|
|
||||||
def attachables
|
def attachables
|
||||||
@attachables ||= attachment_nodes.map do |node|
|
@attachables ||= attachment_nodes.map do |node|
|
||||||
ActiveText::Attachable.from_node(node)
|
ActionText::Attachable.from_node(node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_attachables(attachables)
|
def append_attachables(attachables)
|
||||||
attachments = ActiveText::Attachment.from_attachables(attachables)
|
attachments = ActionText::Attachment.from_attachables(attachables)
|
||||||
self.class.new([self.to_s.presence, *attachments].compact.join("\n"))
|
self.class.new([self.to_s.presence, *attachments].compact.join("\n"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_attachments(**options, &block)
|
def render_attachments(**options, &block)
|
||||||
fragment.replace(ActiveText::Attachment::SELECTOR) do |node|
|
fragment.replace(ActionText::Attachment::SELECTOR) do |node|
|
||||||
block.call(attachment_for_node(node, **options))
|
block.call(attachment_for_node(node, **options))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -48,7 +48,7 @@ module ActiveText
|
||||||
def to_html
|
def to_html
|
||||||
render_attachments do |attachment|
|
render_attachments do |attachment|
|
||||||
attachment.node.tap do |node|
|
attachment.node.tap do |node|
|
||||||
node.inner_html = ActiveText.renderer.render(attachment)
|
node.inner_html = ActionText.renderer.render(attachment)
|
||||||
end
|
end
|
||||||
end.to_html
|
end.to_html
|
||||||
end
|
end
|
||||||
|
@ -73,11 +73,11 @@ module ActiveText
|
||||||
|
|
||||||
private
|
private
|
||||||
def attachment_nodes
|
def attachment_nodes
|
||||||
@attachment_nodes ||= fragment.find_all(ActiveText::Attachment::SELECTOR)
|
@attachment_nodes ||= fragment.find_all(ActionText::Attachment::SELECTOR)
|
||||||
end
|
end
|
||||||
|
|
||||||
def attachment_for_node(node, with_full_attributes: true)
|
def attachment_for_node(node, with_full_attributes: true)
|
||||||
attachment = ActiveText::Attachment.from_node(node)
|
attachment = ActionText::Attachment.from_node(node)
|
||||||
with_full_attributes ? attachment.with_full_attributes : attachment
|
with_full_attributes ? attachment.with_full_attributes : attachment
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,21 +1,21 @@
|
||||||
require "rails/engine"
|
require "rails/engine"
|
||||||
|
|
||||||
module ActiveText
|
module ActionText
|
||||||
class Engine < Rails::Engine
|
class Engine < Rails::Engine
|
||||||
isolate_namespace ActiveText
|
isolate_namespace ActionText
|
||||||
config.eager_load_namespaces << ActiveText
|
config.eager_load_namespaces << ActionText
|
||||||
|
|
||||||
initializer "active_text.attribute" do
|
initializer "action_text.attribute" do
|
||||||
ActiveSupport.on_load(:active_record) do
|
ActiveSupport.on_load(:active_record) do
|
||||||
include ActiveText::Attribute
|
include ActionText::Attribute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "active_text.active_storage_extension" do
|
initializer "action_text.active_storage_extension" do
|
||||||
require "active_storage/blob"
|
require "active_storage/blob"
|
||||||
|
|
||||||
class ActiveStorage::Blob
|
class ActiveStorage::Blob
|
||||||
include ActiveText::Attachable
|
include ActionText::Attachable
|
||||||
|
|
||||||
def previewable_attachable?
|
def previewable_attachable?
|
||||||
representable?
|
representable?
|
||||||
|
@ -23,21 +23,21 @@ module ActiveText
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "active_text.helper" do
|
initializer "action_text.helper" do
|
||||||
ActiveSupport.on_load(:action_controller_base) do
|
ActiveSupport.on_load(:action_controller_base) do
|
||||||
helper ActiveText::TagHelper
|
helper ActionText::TagHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "active_text.config" do
|
initializer "action_text.config" do
|
||||||
config.after_initialize do |app|
|
config.after_initialize do |app|
|
||||||
ActiveText.renderer ||= ApplicationController.renderer
|
ActionText.renderer ||= ApplicationController.renderer
|
||||||
|
|
||||||
# FIXME: ApplicationController should have a per-request specific renderer
|
# FIXME: ApplicationController should have a per-request specific renderer
|
||||||
# that's been set with the request.env env, and ActiveText should just piggyback off
|
# that's been set with the request.env env, and ActionText should just piggyback off
|
||||||
# that by default rather than doing this work directly.
|
# that by default rather than doing this work directly.
|
||||||
ApplicationController.before_action do
|
ApplicationController.before_action do
|
||||||
ActiveText.renderer = ActiveText.renderer.new(request.env)
|
ActionText.renderer = ActionText.renderer.new(request.env)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
class Fragment
|
class Fragment
|
||||||
class << self
|
class << self
|
||||||
def wrap(fragment_or_html)
|
def wrap(fragment_or_html)
|
||||||
|
@ -13,7 +13,7 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_html(html)
|
def from_html(html)
|
||||||
new(ActiveText::HtmlConversion.fragment_for_html(html.to_s.strip))
|
new(ActionText::HtmlConversion.fragment_for_html(html.to_s.strip))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module HtmlConversion
|
module HtmlConversion
|
||||||
extend self
|
extend self
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module PlainTextConversion
|
module PlainTextConversion
|
||||||
extend self
|
extend self
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
module Serialization
|
module Serialization
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
class TrixAttachment
|
class TrixAttachment
|
||||||
TAG_NAME = "figure"
|
TAG_NAME = "figure"
|
||||||
SELECTOR = "[data-trix-attachment]"
|
SELECTOR = "[data-trix-attachment]"
|
||||||
|
@ -19,7 +19,7 @@ module ActiveText
|
||||||
trix_attachment_attributes = attributes.except("caption")
|
trix_attachment_attributes = attributes.except("caption")
|
||||||
trix_attributes = attributes.slice("caption")
|
trix_attributes = attributes.slice("caption")
|
||||||
|
|
||||||
node = ActiveText::HtmlConversion.create_element(TAG_NAME)
|
node = ActionText::HtmlConversion.create_element(TAG_NAME)
|
||||||
node["data-trix-attachment"] = JSON.generate(trix_attachment_attributes)
|
node["data-trix-attachment"] = JSON.generate(trix_attachment_attributes)
|
||||||
node["data-trix-attributes"] = JSON.generate(trix_attributes) if trix_attributes.any?
|
node["data-trix-attributes"] = JSON.generate(trix_attributes) if trix_attributes.any?
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ module ActiveText
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_html
|
def to_html
|
||||||
ActiveText::HtmlConversion.node_to_html(node)
|
ActionText::HtmlConversion.node_to_html(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
|
@ -1,3 +1,3 @@
|
||||||
module ActiveText
|
module ActionText
|
||||||
VERSION = '0.1.0'
|
VERSION = '0.1.0'
|
||||||
end
|
end
|
|
@ -1,8 +1,8 @@
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
before_action :set_active_text_renderer
|
before_action :set_action_text_renderer
|
||||||
|
|
||||||
private
|
private
|
||||||
def set_active_text_renderer
|
def set_action_text_renderer
|
||||||
ActiveText.renderer = self.class.renderer.new(request.env)
|
ActionText.renderer = self.class.renderer.new(request.env)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ require_relative 'boot'
|
||||||
require 'rails/all'
|
require 'rails/all'
|
||||||
|
|
||||||
Bundler.require(*Rails.groups)
|
Bundler.require(*Rails.groups)
|
||||||
require "active_text"
|
require "action_text"
|
||||||
|
|
||||||
module Dummy
|
module Dummy
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require_relative '../test_helper'
|
require_relative '../test_helper'
|
||||||
|
|
||||||
module ActiveText
|
module ActionText
|
||||||
class ContentTest < ActiveSupport::TestCase
|
class ContentTest < ActiveSupport::TestCase
|
||||||
test "plain text conversion" do
|
test "plain text conversion" do
|
||||||
message = Message.create!(subject: "Greetings", content: "<h1>Hello world</h1>")
|
message = Message.create!(subject: "Greetings", content: "<h1>Hello world</h1>")
|
||||||
|
|
Loading…
Reference in a new issue