\ No newline at end of file
diff --git a/app/assets/javascripts/admin/addon/templates/permalinks-index.hbs b/app/assets/javascripts/admin/addon/templates/permalinks-index.hbs
index 31e9d14a423..9e6cb6c37c4 100644
--- a/app/assets/javascripts/admin/addon/templates/permalinks-index.hbs
+++ b/app/assets/javascripts/admin/addon/templates/permalinks-index.hbs
@@ -68,7 +68,7 @@
class="btn-small admin-permalink-item__edit"
@route="adminPermalinks.edit"
@routeModels={{pl}}
- @label="admin.config_areas.flags.edit"
+ @label="admin.config_areas.permalinks.edit"
/>
diff --git a/app/assets/javascripts/admin/addon/templates/permalinks.hbs b/app/assets/javascripts/admin/addon/templates/permalinks.hbs
index 893db076511..58c1369daff 100644
--- a/app/assets/javascripts/admin/addon/templates/permalinks.hbs
+++ b/app/assets/javascripts/admin/addon/templates/permalinks.hbs
@@ -16,7 +16,6 @@
@route="adminPermalinks.new"
@title="admin.permalink.add"
@label="admin.permalink.add"
- @icon="plus"
class="admin-permalinks__header-add-permalink"
/>
diff --git a/app/assets/javascripts/discourse/tests/integration/components/admin-config-area-card-test.gjs b/app/assets/javascripts/discourse/tests/integration/components/admin-config-area-card-test.gjs
index 5bfa9ec5748..96298a0ef84 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/admin-config-area-card-test.gjs
+++ b/app/assets/javascripts/discourse/tests/integration/components/admin-config-area-card-test.gjs
@@ -36,6 +36,20 @@ module("Integration | Component | AdminConfigAreaCard", function (hooks) {
assert.dom(".admin-config-area-card__content").exists();
});
+ test("renders admin config area card with toggle button and collapsed by default", async function (assert) {
+ await render(
+ <:content>test
+ );
+
+ assert.dom(".admin-config-area-card__title").exists();
+ assert.dom(".admin-config-area-card__toggle-button").exists();
+ assert.dom(".admin-config-area-card__content").doesNotExist();
+ });
+
test("renders admin config area card with header action", async function (assert) {
await render(
Paste the following HTML code into your site to create and embed Discourse topics. Replace EMBED_URL with the canonical URL of the page you are embedding it on.
@@ -7318,16 +7325,18 @@ en:
Replace DISCOURSE_USERNAME with the Discourse username of the author that should create the topic. Discourse will automatically lookup the user by the content attribute of the <meta> tags with name attribute set to discourse-username or author. The discourseUserName parameter has been deprecated and will be removed in Discourse 3.2.
title: "Embedding"
- host: "Allowed Hosts"
- allowed_paths: "Path Allowlist"
- edit: "edit"
- category: "Post to Category"
- tags: "Topic Tags"
- post_author: "Post Author - Defaults to %{author}"
- add_host: "Add Host"
- settings: "Embedding Settings"
- crawling_settings: "Crawler Settings"
- crawling_description: "When Discourse creates topics for your posts, if no RSS/ATOM feed is present it will attempt to parse your content out of your HTML. Sometimes it can be challenging to extract your content, so we provide the ability to specify CSS rules to make extraction easier."
+ description: "Discourse has the ability to embed the comments from a topic in a remote site using a Javascript API that creates an IFRAME"
+ host: "Allowed hosts"
+ allowed_paths: "Path allowlist"
+ edit: "Edit"
+ category: "Post to category"
+ tags: "Topic tags"
+ post_author: "Post author"
+ post_author_with_default: "Post author (defaults to %{author})"
+ add_host: "Add host"
+ posts_and_topics: "Posts and Topics configuration"
+ crawlers: "Crawlers configuration"
+ crawlers_description: "When Discourse creates topics for your posts, if no RSS/ATOM feed is present it will attempt to parse your content out of your HTML. Sometimes it can be challenging to extract your content, so we provide the ability to specify CSS rules to make extraction easier."
embed_by_username: "Username for topic creation"
embed_post_limit: "Maximum number of posts to embed"
@@ -7337,7 +7346,20 @@ en:
allowed_embed_selectors: "CSS selector for elements that are allowed in embeds"
blocked_embed_selectors: "CSS selector for elements that are removed from embeds"
allowed_embed_classnames: "Allowed CSS class names"
- save: "Save Embedding Settings"
+ save: "Save"
+ posts_and_topics_settings_saved: "Posts and Topics settings saved"
+ crawler_settings_saved: "Crawler settings saved"
+ back: "Back to Embedding"
+ configuration_snippet: "Configuration snippet"
+ host_form:
+ add_header: "Add host"
+ edit_header: "Edit host"
+ save: "Save"
+ nav:
+ hosts: "Hosts"
+ settings: "Settings"
+ posts_and_topics: "Posts and Topics"
+ crawlers: "Crawlers"
permalink:
title: "Permalinks"
diff --git a/config/routes.rb b/config/routes.rb
index 2568503daa0..00c02d78a28 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -223,6 +223,7 @@ Discourse::Application.routes.draw do
get "config/permalinks" => "permalinks#index", :constraints => AdminConstraint.new
get "customize/embedding" => "embedding#show", :constraints => AdminConstraint.new
put "customize/embedding" => "embedding#update", :constraints => AdminConstraint.new
+ get "customize/embedding/:id" => "embedding#edit", :constraints => AdminConstraint.new
resources :themes,
only: %i[index create show update destroy],
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 494cbb64955..1c6a0c8063d 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -1212,14 +1212,30 @@ posting:
choices:
- code-fences
- 4-spaces-indent
- embed_any_origin: false
- embed_topics_list: false
- embed_set_canonical_url: false
- embed_unlisted: false
- import_embed_unlisted: true
- embed_truncate: true
- embed_support_markdown: false
- allowed_embed_selectors: ""
+ embed_any_origin:
+ default: false
+ area: "embedding"
+ embed_topics_list:
+ default: false
+ area: "embedding"
+ embed_set_canonical_url:
+ default: false
+ area: "embedding"
+ embed_unlisted:
+ default: false
+ area: "embedding"
+ import_embed_unlisted:
+ default: true
+ area: "embedding"
+ embed_truncate:
+ default: true
+ area: "embedding"
+ embed_support_markdown:
+ default: false
+ area: "embedding"
+ allowed_embed_selectors:
+ default: ""
+ area: "embedding"
allowed_href_schemes:
client: true
default: ""
diff --git a/spec/requests/admin/embedding_controller_spec.rb b/spec/requests/admin/embedding_controller_spec.rb
index 26595eeeda2..0f092f93a63 100644
--- a/spec/requests/admin/embedding_controller_spec.rb
+++ b/spec/requests/admin/embedding_controller_spec.rb
@@ -43,10 +43,11 @@ RSpec.describe Admin::EmbeddingController do
context "when logged in as an admin" do
before { sign_in(admin) }
- it "updates embedding" do
+ it "updates posts and topics settings" do
put "/admin/customize/embedding.json",
params: {
embedding: {
+ type: "posts_and_topics",
embed_by_username: "system",
embed_post_limit: 200,
},
@@ -56,6 +57,21 @@ RSpec.describe Admin::EmbeddingController do
expect(response.parsed_body["embedding"]["embed_by_username"]).to eq("system")
expect(response.parsed_body["embedding"]["embed_post_limit"]).to eq(200)
end
+
+ it "updates crawlers settings" do
+ put "/admin/customize/embedding.json",
+ params: {
+ embedding: {
+ type: "crawlers",
+ allowed_embed_selectors: "article",
+ blocked_embed_selectors: "p",
+ },
+ }
+
+ expect(response.status).to eq(200)
+ expect(response.parsed_body["embedding"]["allowed_embed_selectors"]).to eq("article")
+ expect(response.parsed_body["embedding"]["blocked_embed_selectors"]).to eq("p")
+ end
end
shared_examples "embedding updates not allowed" do
@@ -63,6 +79,7 @@ RSpec.describe Admin::EmbeddingController do
put "/admin/customize/embedding.json",
params: {
embedding: {
+ type: "posts_and_topics",
embed_by_username: "system",
embed_post_limit: 200,
},
diff --git a/spec/system/admin_embeddable_hosts_spec.rb b/spec/system/admin_embeddable_hosts_spec.rb
index 26fd6525cd0..c0bdda9bab6 100644
--- a/spec/system/admin_embeddable_hosts_spec.rb
+++ b/spec/system/admin_embeddable_hosts_spec.rb
@@ -3,59 +3,75 @@
RSpec.describe "Admin EmbeddableHost Management", type: :system do
fab!(:admin)
fab!(:author) { Fabricate(:admin) }
+ fab!(:author_2) { Fabricate(:admin) }
fab!(:category)
- fab!(:category2) { Fabricate(:category) }
+ fab!(:category_2) { Fabricate(:category) }
fab!(:tag)
- fab!(:tag2) { Fabricate(:tag) }
+ fab!(:tag_2) { Fabricate(:tag) }
before { sign_in(admin) }
- it "allows admin to add and edit embeddable hosts" do
- visit "/admin/customize/embedding"
+ let(:admin_embedding_page) { PageObjects::Pages::AdminEmbedding.new }
+ let(:admin_embedding_host_form_page) { PageObjects::Pages::AdminEmbeddingHostForm.new }
+ let(:admin_embedding_posts_and_topics_page) do
+ PageObjects::Pages::AdminEmbeddingPostsAndTopics.new
+ end
- find("button.btn-icon-text", text: "Add Host").click
- within find("tr.ember-view") do
- find('input[placeholder="example.com"]').set("awesome-discourse-site.local")
- find('input[placeholder="/blog/.*"]').set("/blog/.*")
+ it "allows admin to add, edit and delete embeddable hosts" do
+ admin_embedding_page.visit
- category_chooser = PageObjects::Components::SelectKit.new(".category-chooser")
- category_chooser.expand
- category_chooser.select_row_by_name(category.name)
+ expect(page).not_to have_css(".admin-embedding-index__code")
- tag_chooser = PageObjects::Components::SelectKit.new(".tag-chooser")
- tag_chooser.expand
- tag_chooser.select_row_by_name(tag.name)
+ admin_embedding_page.click_add_host
+
+ admin_embedding_host_form_page.fill_in_allowed_hosts("awesome-discourse-site.local")
+ admin_embedding_host_form_page.fill_in_path_allow_list("/blog/.*")
+ admin_embedding_host_form_page.fill_in_category(category)
+ admin_embedding_host_form_page.fill_in_tags(tag)
+ admin_embedding_host_form_page.fill_in_post_author(author)
+ admin_embedding_host_form_page.click_save
- find(".user-chooser").click
- find(".select-kit-body .select-kit-filter input").fill_in with: author.username
- find(".select-kit-body", text: author.username).click
- end
- find("td.editing-controls .btn.btn-primary").click
expect(page).to have_content("awesome-discourse-site.local")
expect(page).to have_content("/blog/.*")
- expect(page).not_to have_content("#{tag.name},#{tag2.name}")
expect(page).to have_content("#{tag.name}")
+ expect(page).to have_content("#{category.name}")
+ expect(page).to have_content("#{author.username}")
- # Editing
+ expect(page).to have_css(".admin-embedding-index__code")
- find(".embeddable-hosts tr:first-child .controls svg.d-icon-pencil").find(:xpath, "..").click
+ admin_embedding_page.click_edit_host
- within find(".embeddable-hosts tr:first-child.ember-view") do
- find('input[placeholder="example.com"]').set("updated-example.com")
- find('input[placeholder="/blog/.*"]').set("/updated-blog/.*")
+ admin_embedding_host_form_page.fill_in_allowed_hosts("updated-example.com")
+ admin_embedding_host_form_page.fill_in_path_allow_list("/updated-blog/.*")
+ admin_embedding_host_form_page.fill_in_category(category_2)
+ admin_embedding_host_form_page.fill_in_tags(tag_2)
+ admin_embedding_host_form_page.fill_in_post_author(author_2)
+ admin_embedding_host_form_page.click_save
- category_chooser = PageObjects::Components::SelectKit.new(".category-chooser")
- category_chooser.expand
- category_chooser.select_row_by_name(category2.name)
-
- tag_chooser = PageObjects::Components::SelectKit.new(".tag-chooser")
- tag_chooser.expand
- tag_chooser.select_row_by_name(tag2.name)
- end
-
- find("td.editing-controls .btn.btn-primary").click
expect(page).to have_content("updated-example.com")
expect(page).to have_content("/updated-blog/.*")
- expect(page).to have_content("#{tag.name},#{tag2.name}")
+ expect(page).to have_content("#{tag.name}, #{tag_2.name}")
+ expect(page).to have_content("#{category_2.name}")
+ expect(page).to have_content("#{author_2.username}")
+
+ admin_embedding_page.click_delete
+ admin_embedding_page.confirm_delete
+
+ expect(page).not_to have_css(".admin-embedding-index__code")
+ end
+
+ it "allows admin to save posts and topics settings" do
+ Fabricate(:embeddable_host)
+
+ admin_embedding_page.visit
+ expect(page).not_to have_content("#{author.username}")
+
+ admin_embedding_page.click_posts_and_topics_tab
+
+ admin_embedding_posts_and_topics_page.fill_in_embed_by_username(author)
+ admin_embedding_posts_and_topics_page.click_save
+
+ admin_embedding_page.click_hosts_tab
+ expect(page).to have_content("#{author.username}")
end
end
diff --git a/spec/system/page_objects/pages/admin_embedding.rb b/spec/system/page_objects/pages/admin_embedding.rb
new file mode 100644
index 00000000000..50b358034c7
--- /dev/null
+++ b/spec/system/page_objects/pages/admin_embedding.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module PageObjects
+ module Pages
+ class AdminEmbedding < PageObjects::Pages::Base
+ def visit
+ page.visit("/admin/customize/embedding")
+ self
+ end
+
+ def click_posts_and_topics_tab
+ find(".admin-embedding-tabs__posts-and-topics").click
+ end
+
+ def click_hosts_tab
+ find(".admin-embedding-tabs__hosts").click
+ end
+
+ def click_add_host
+ find(".admin-embedding__header-add-host").click
+ self
+ end
+
+ def click_edit_host
+ find(".admin-embeddable-host-item__edit").click
+ self
+ end
+
+ def click_delete
+ find(".admin-embeddable-host-item__delete").click
+ self
+ end
+
+ def confirm_delete
+ find(".dialog-footer .btn-primary").click
+ expect(page).to have_no_css(".dialog-body", wait: Capybara.default_max_wait_time * 3)
+ self
+ end
+ end
+ end
+end
diff --git a/spec/system/page_objects/pages/admin_embedding_host_form.rb b/spec/system/page_objects/pages/admin_embedding_host_form.rb
new file mode 100644
index 00000000000..0c2876bf3ef
--- /dev/null
+++ b/spec/system/page_objects/pages/admin_embedding_host_form.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module PageObjects
+ module Pages
+ class AdminEmbeddingHostForm < PageObjects::Pages::Base
+ def fill_in_allowed_hosts(url)
+ form.field("host").fill_in(url)
+ self
+ end
+
+ def fill_in_path_allow_list(path)
+ form.field("allowed_paths").fill_in(path)
+ self
+ end
+
+ def fill_in_category(category)
+ dropdown = PageObjects::Components::SelectKit.new(".admin-embedding-host-form__category")
+ dropdown.expand
+ dropdown.search(category.name)
+ dropdown.select_row_by_value(category.id)
+ dropdown.collapse
+ self
+ end
+
+ def fill_in_tags(tag)
+ dropdown = PageObjects::Components::SelectKit.new(".admin-embedding-host-form__tags")
+ dropdown.expand
+ dropdown.search(tag.name)
+ dropdown.select_row_by_value(tag.name)
+ dropdown.collapse
+ self
+ end
+
+ def fill_in_post_author(author)
+ dropdown = PageObjects::Components::SelectKit.new(".admin-embedding-host-form__post_author")
+ dropdown.expand
+ dropdown.search(author.username)
+ dropdown.select_row_by_value(author.username)
+ dropdown.collapse
+ self
+ end
+
+ def click_save
+ form.submit
+ expect(page).to have_css(".d-admin-table")
+ end
+
+ def form
+ @form ||= PageObjects::Components::FormKit.new(".admin-embedding-host-form .form-kit")
+ end
+ end
+ end
+end
diff --git a/spec/system/page_objects/pages/admin_embedding_posts_and_topics.rb b/spec/system/page_objects/pages/admin_embedding_posts_and_topics.rb
new file mode 100644
index 00000000000..1be11a2a37e
--- /dev/null
+++ b/spec/system/page_objects/pages/admin_embedding_posts_and_topics.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module PageObjects
+ module Pages
+ class AdminEmbeddingPostsAndTopics < PageObjects::Pages::Base
+ def fill_in_embed_by_username(author)
+ dropdown =
+ PageObjects::Components::SelectKit.new(
+ ".admin-embedding-posts-and-topics-form__embed_by_username",
+ )
+ dropdown.expand
+ dropdown.search(author.username)
+ dropdown.select_row_by_value(author.username)
+ dropdown.collapse
+ self
+ end
+
+ def click_save
+ form = PageObjects::Components::FormKit.new(".admin-embedding .form-kit")
+ form.submit
+ end
+ end
+ end
+end